Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Fri, 04 May 2012 19:16:35 -0700
changeset 106198 080fe4327259783bf01cd24cc561cbc21e61d959
parent 106197 65c019632ba05d3f96ae67716321f652118562cf (current diff)
parent 93238 6d6e9cc558f0154390c9e347b7957b5e0641587e (diff)
child 106199 02fbff5051a3688e0761faf0f61016329e17d84f
push id14706
push usereakhgari@mozilla.com
push dateTue, 11 Sep 2012 20:39:52 +0000
treeherdermozilla-inbound@d50bf1edaabe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone15.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge from mozilla-central.
accessible/src/atk/nsAccessibleWrap.cpp
accessible/src/atk/nsAccessibleWrap.h
accessible/src/atk/nsRootAccessibleWrap.cpp
accessible/src/atk/nsRootAccessibleWrap.h
accessible/src/base/Makefile.in
accessible/src/base/nsAccDocManager.cpp
accessible/src/base/nsAccessNode.cpp
accessible/src/base/nsAccessNode.h
accessible/src/base/nsAccessibilityService.cpp
accessible/src/base/nsAccessible.cpp
accessible/src/base/nsAccessible.h
accessible/src/base/nsCaretAccessible.cpp
accessible/src/base/nsDocAccessible.cpp
accessible/src/base/nsRootAccessible.cpp
accessible/src/base/nsRootAccessible.h
accessible/src/generic/RootAccessible.cpp
accessible/src/generic/RootAccessible.h
accessible/src/html/nsHTMLTableAccessible.cpp
accessible/src/mac/nsRootAccessibleWrap.h
accessible/src/mac/nsRootAccessibleWrap.mm
accessible/src/msaa/nsAccessNodeWrap.cpp
accessible/src/msaa/nsAccessibleWrap.cpp
accessible/src/msaa/nsDocAccessibleWrap.cpp
accessible/src/msaa/nsRootAccessibleWrap.cpp
accessible/src/msaa/nsRootAccessibleWrap.h
accessible/src/other/nsRootAccessibleWrap.cpp
accessible/src/other/nsRootAccessibleWrap.h
browser/app/profile/firefox.js
browser/base/content/browser.js
browser/components/nsBrowserGlue.js
browser/components/tabview/test/head.js
browser/devtools/shared/Templater.jsm
browser/locales/en-US/chrome/browser/devtools/inspector.properties
caps/src/nsScriptSecurityManager.cpp
configure.in
content/base/src/nsContentUtils.cpp
content/base/src/nsDocument.cpp
content/base/src/nsGkAtomList.h
content/base/src/nsObjectLoadingContent.cpp
content/base/src/nsXMLHttpRequest.cpp
content/base/src/nsXMLHttpRequest.h
content/canvas/src/WebGLContextGL.cpp
content/canvas/src/nsCanvasRenderingContext2D.cpp
content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
content/events/public/nsEventNameList.h
content/events/public/nsIPrivateDOMEvent.h
content/events/src/nsDOMEvent.cpp
content/events/src/nsDOMEvent.h
content/events/src/nsDOMKeyboardEvent.cpp
content/events/src/nsEventListenerManager.cpp
content/html/content/public/nsHTMLMediaElement.h
content/html/content/src/nsHTMLInputElement.cpp
content/html/content/src/nsHTMLInputElement.h
content/html/content/src/nsHTMLMediaElement.cpp
content/html/content/test/test_bug408231.html
content/html/document/test/test_bug404320.html
content/html/document/test/test_bug468353.html
content/html/document/test/test_bug742261.html
content/media/ogg/nsOggCodecState.cpp
content/media/ogg/nsOggCodecState.h
content/media/ogg/nsOggReader.cpp
content/media/ogg/nsOggReader.h
content/svg/content/src/SVGTransformListParser.cpp
content/svg/content/src/nsSVGAngle.cpp
content/svg/content/src/nsSVGMarkerElement.cpp
content/svg/content/src/nsSVGSVGElement.cpp
content/svg/content/src/nsSVGSVGElement.h
content/svg/content/src/nsSVGViewBox.h
content/xbl/src/nsXBLDocumentInfo.cpp
content/xbl/src/nsXBLProtoImplProperty.cpp
content/xslt/src/base/txList.h
content/xslt/src/xpath/txExprLexer.cpp
content/xslt/src/xpath/txExprLexer.h
content/xslt/src/xpath/txExprParser.cpp
content/xul/document/src/nsXULPrototypeDocument.cpp
docshell/base/nsDocShell.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/base/nsDOMWindowUtils.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsJSEnvironment.cpp
dom/bindings/Utils.cpp
dom/bindings/Utils.h
dom/bluetooth/BluetoothDevice.cpp
dom/bluetooth/BluetoothDevice.h
dom/bluetooth/nsIDOMBluetoothDevice.idl
dom/interfaces/base/nsIDOMWindowUtils.idl
dom/interfaces/events/nsIDOMEventTarget.idl
dom/locales/en-US/chrome/layout/HtmlForm.properties
dom/plugins/base/nsPluginHost.cpp
dom/plugins/base/nsPluginTags.cpp
dom/src/events/nsJSEventListener.cpp
dom/system/nsDeviceSensors.cpp
dom/system/nsDeviceSensors.h
dom/workers/RuntimeService.cpp
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerScope.cpp
dom/workers/XMLHttpRequest.cpp
editor/libeditor/html/nsHTMLEditRules.cpp
editor/libeditor/html/nsHTMLEditor.cpp
editor/libeditor/html/nsHTMLEditor.h
editor/libeditor/html/nsHTMLEditorStyle.cpp
extensions/spellcheck/hunspell/src/mozHunspell.cpp
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
gfx/gl/GLContextProviderEGL.cpp
gfx/gl/GLContextProviderGLX.cpp
gfx/layers/ImageLayers.h
gfx/layers/Layers.cpp
gfx/layers/Layers.h
gfx/layers/ThebesLayerBuffer.cpp
gfx/layers/ThebesLayerBuffer.h
gfx/layers/basic/BasicLayers.cpp
gfx/layers/d3d10/CanvasLayerD3D10.cpp
gfx/layers/d3d10/ContainerLayerD3D10.cpp
gfx/layers/d3d10/ImageLayerD3D10.cpp
gfx/layers/d3d10/ImageLayerD3D10.h
gfx/layers/d3d10/LayerManagerD3D10.cpp
gfx/layers/d3d10/LayerManagerD3D10.h
gfx/layers/d3d9/CanvasLayerD3D9.cpp
gfx/layers/d3d9/ContainerLayerD3D9.cpp
gfx/layers/d3d9/ImageLayerD3D9.cpp
gfx/layers/d3d9/ImageLayerD3D9.h
gfx/layers/d3d9/LayerManagerD3D9.h
gfx/layers/d3d9/ThebesLayerD3D9.cpp
gfx/layers/ipc/PLayers.ipdl
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/ipc/ShadowLayers.h
gfx/layers/ipc/ShadowLayersParent.cpp
gfx/layers/opengl/CanvasLayerOGL.cpp
gfx/layers/opengl/ContainerLayerOGL.cpp
gfx/layers/opengl/ImageLayerOGL.cpp
gfx/layers/opengl/ImageLayerOGL.h
gfx/layers/opengl/LayerManagerOGL.cpp
gfx/layers/opengl/LayerManagerOGL.h
gfx/layers/opengl/ThebesLayerOGL.cpp
gfx/thebes/gfxContext.cpp
gfx/thebes/gfxUtils.cpp
gfx/thebes/gfxUtils.h
hal/fallback/FallbackHal.cpp
hal/fallback/ScreenOrientationFallback.cpp
hal/linux/LinuxHal.cpp
hal/linux/Power.cpp
hal/windows/WindowsHal.cpp
ipc/testshell/XPCShellEnvironment.cpp
js/jsd/jsd_xpc.cpp
js/src/Makefile.in
js/src/MemoryMetrics.cpp
js/src/assembler/jit/ExecutableAllocator.h
js/src/configure.in
js/src/frontend/ParseNode.h
js/src/frontend/Parser.cpp
js/src/frontend/SemanticAnalysis.cpp
js/src/gc/Barrier.h
js/src/gc/Heap.h
js/src/gc/Marking.cpp
js/src/gc/Marking.h
js/src/gc/Statistics.h
js/src/ion/CodeGenerator.cpp
js/src/ion/Ion.cpp
js/src/ion/IonCode.h
js/src/ion/IonFrames.cpp
js/src/ion/IonMacroAssembler.h
js/src/ion/arm/Assembler-arm.cpp
js/src/ion/shared/Assembler-x86-shared.cpp
js/src/ion/x64/Assembler-x64.cpp
js/src/ion/x86/Assembler-x86.cpp
js/src/js.msg
js/src/jsanalyze.cpp
js/src/jsanalyze.h
js/src/jsapi-tests/testDebugger.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsarray.cpp
js/src/jsatom.cpp
js/src/jsatom.h
js/src/jscell.h
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jscntxtinlines.h
js/src/jscompartment.cpp
js/src/jscompartment.h
js/src/jsdbgapi.cpp
js/src/jsdbgapi.h
js/src/jsexn.cpp
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
js/src/jsfun.cpp
js/src/jsgc.cpp
js/src/jsgc.h
js/src/jsgcmark.cpp
js/src/jsgcmark.h
js/src/jsinfer.cpp
js/src/jsinfer.h
js/src/jsinferinlines.h
js/src/jsinterp.cpp
js/src/jsinterpinlines.h
js/src/jsiter.cpp
js/src/jsnum.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/jsproto.tbl
js/src/jsproxy.cpp
js/src/jsscope.cpp
js/src/jsscript.cpp
js/src/jsscript.h
js/src/jsscriptinlines.h
js/src/jsstr.h
js/src/jstypedarray.cpp
js/src/jstypedarray.h
js/src/jstypedarrayinlines.h
js/src/jsweakcache.h
js/src/jsweakmap.cpp
js/src/jswrapper.cpp
js/src/jsxml.cpp
js/src/methodjit/Compiler.cpp
js/src/methodjit/InvokeHelpers.cpp
js/src/methodjit/LoopState.cpp
js/src/methodjit/MethodJIT.h
js/src/methodjit/PolyIC.cpp
js/src/methodjit/StubCalls.cpp
js/src/shell/js.cpp
js/src/vm/Debugger.cpp
js/src/vm/GlobalObject.cpp
js/src/vm/RegExpObject-inl.h
js/src/vm/RegExpObject.cpp
js/src/vm/RegExpObject.h
js/src/vm/Stack.cpp
js/src/vm/String.cpp
js/src/vm/String.h
js/xpconnect/shell/xpcshell.cpp
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/src/XPCInlines.h
js/xpconnect/src/XPCJSID.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCThreadContext.cpp
js/xpconnect/src/XPCVariant.cpp
js/xpconnect/src/XPCWrappedJS.cpp
js/xpconnect/src/XPCWrappedJSClass.cpp
js/xpconnect/src/XPCWrappedNative.cpp
js/xpconnect/src/XPCWrappedNativeJSOps.cpp
js/xpconnect/src/XPCWrappedNativeScope.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/src/xpcpublic.h
js/xpconnect/wrappers/WrapperFactory.cpp
js/xpconnect/wrappers/XrayWrapper.cpp
layout/base/FrameLayerBuilder.cpp
layout/base/FrameLayerBuilder.h
layout/base/crashtests/crashtests.list
layout/base/nsCSSRendering.cpp
layout/base/nsCSSRendering.h
layout/base/nsDisplayList.cpp
layout/base/nsDisplayList.h
layout/base/nsIPresShell.h
layout/base/nsLayoutDebugger.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/base/nsPresArena.cpp
layout/base/nsPresContext.cpp
layout/base/nsPresContext.h
layout/base/nsPresShell.cpp
layout/base/nsPresShell.h
layout/forms/nsListControlFrame.h
layout/generic/nsBlockFrame.cpp
layout/generic/nsBlockFrame.h
layout/generic/nsCanvasFrame.h
layout/generic/nsContainerFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsHTMLCanvasFrame.cpp
layout/generic/nsImageFrame.cpp
layout/generic/nsImageFrame.h
layout/generic/nsLineBox.cpp
layout/generic/nsLineBox.h
layout/generic/nsObjectFrame.cpp
layout/generic/nsObjectFrame.h
layout/generic/nsQueryFrame.h
layout/generic/nsSelection.cpp
layout/generic/nsTextRunTransformations.cpp
layout/generic/nsVideoFrame.cpp
layout/ipc/RenderFrameParent.h
layout/reftests/border-radius/reftest.list
layout/reftests/bugs/388980-1-ref.html
layout/reftests/bugs/388980-1.html
layout/reftests/bugs/reftest.list
layout/reftests/editor/338427-1-ref.html
layout/reftests/editor/338427-1.html
layout/reftests/editor/338427-2-ref.html
layout/reftests/editor/338427-2.html
layout/reftests/editor/338427-3-ref.html
layout/reftests/editor/338427-3.html
layout/reftests/editor/462758-grabbers-resizers-ref.html
layout/reftests/editor/462758-grabbers-resizers.html
layout/reftests/editor/642800-iframe.html
layout/reftests/editor/642800-ref.html
layout/reftests/editor/642800.html
layout/reftests/editor/672709-ref.html
layout/reftests/editor/672709.html
layout/reftests/editor/674212-spellcheck-ref.html
layout/reftests/editor/674212-spellcheck.html
layout/reftests/editor/694880-1.html
layout/reftests/editor/694880-2.html
layout/reftests/editor/694880-3.html
layout/reftests/editor/694880-ref.html
layout/reftests/editor/caret_after_reframe-ref.html
layout/reftests/editor/caret_after_reframe.html
layout/reftests/editor/caret_on_focus-ref.html
layout/reftests/editor/caret_on_focus.html
layout/reftests/editor/caret_on_positioned-ref.html
layout/reftests/editor/caret_on_positioned.html
layout/reftests/editor/caret_on_presshell_reinit-2.html
layout/reftests/editor/caret_on_presshell_reinit-ref.html
layout/reftests/editor/caret_on_presshell_reinit.html
layout/reftests/editor/caret_on_textarea_lastline-ref.html
layout/reftests/editor/caret_on_textarea_lastline.html
layout/reftests/editor/dynamic-1.html
layout/reftests/editor/dynamic-overflow-change-ref.html
layout/reftests/editor/dynamic-overflow-change.html
layout/reftests/editor/dynamic-ref.html
layout/reftests/editor/dynamic-type-1.html
layout/reftests/editor/dynamic-type-2.html
layout/reftests/editor/dynamic-type-3.html
layout/reftests/editor/dynamic-type-4.html
layout/reftests/editor/emptypasswd-1.html
layout/reftests/editor/emptypasswd-2.html
layout/reftests/editor/emptypasswd-ref.html
layout/reftests/editor/input-text-notheme-onfocus-reframe-ref.html
layout/reftests/editor/input-text-notheme-onfocus-reframe.html
layout/reftests/editor/input-text-onfocus-reframe-ref.html
layout/reftests/editor/input-text-onfocus-reframe.html
layout/reftests/editor/newline-1.html
layout/reftests/editor/newline-2.html
layout/reftests/editor/newline-3.html
layout/reftests/editor/newline-4.html
layout/reftests/editor/newline-ref.html
layout/reftests/editor/nobogusnode-1.html
layout/reftests/editor/nobogusnode-2.html
layout/reftests/editor/nobogusnode-ref.html
layout/reftests/editor/passwd-1.html
layout/reftests/editor/passwd-2.html
layout/reftests/editor/passwd-3.html
layout/reftests/editor/passwd-4.html
layout/reftests/editor/passwd-ref.html
layout/reftests/editor/reftest.list
layout/reftests/editor/selection_visibility_after_reframe-2.html
layout/reftests/editor/selection_visibility_after_reframe-3.html
layout/reftests/editor/selection_visibility_after_reframe-ref.html
layout/reftests/editor/selection_visibility_after_reframe.html
layout/reftests/editor/spellcheck-comma-valid-ref.html
layout/reftests/editor/spellcheck-comma-valid.html
layout/reftests/editor/spellcheck-dotafterquote-valid-ref.html
layout/reftests/editor/spellcheck-dotafterquote-valid.html
layout/reftests/editor/spellcheck-hyphen-invalid-ref.html
layout/reftests/editor/spellcheck-hyphen-invalid.html
layout/reftests/editor/spellcheck-hyphen-multiple-invalid-ref.html
layout/reftests/editor/spellcheck-hyphen-multiple-invalid.html
layout/reftests/editor/spellcheck-hyphen-multiple-valid-ref.html
layout/reftests/editor/spellcheck-hyphen-multiple-valid.html
layout/reftests/editor/spellcheck-hyphen-valid-ref.html
layout/reftests/editor/spellcheck-hyphen-valid.html
layout/reftests/editor/spellcheck-input-attr-after.html
layout/reftests/editor/spellcheck-input-attr-before.html
layout/reftests/editor/spellcheck-input-attr-dynamic-inherit.html
layout/reftests/editor/spellcheck-input-attr-dynamic-override-inherit.html
layout/reftests/editor/spellcheck-input-attr-dynamic-override.html
layout/reftests/editor/spellcheck-input-attr-dynamic.html
layout/reftests/editor/spellcheck-input-attr-inherit.html
layout/reftests/editor/spellcheck-input-disabled.html
layout/reftests/editor/spellcheck-input-nofocus-ref.html
layout/reftests/editor/spellcheck-input-property-dynamic-inherit.html
layout/reftests/editor/spellcheck-input-property-dynamic-override-inherit.html
layout/reftests/editor/spellcheck-input-property-dynamic-override.html
layout/reftests/editor/spellcheck-input-property-dynamic.html
layout/reftests/editor/spellcheck-input-ref.html
layout/reftests/editor/spellcheck-period-valid-ref.html
layout/reftests/editor/spellcheck-period-valid.html
layout/reftests/editor/spellcheck-slash-valid-ref.html
layout/reftests/editor/spellcheck-slash-valid.html
layout/reftests/editor/spellcheck-space-valid-ref.html
layout/reftests/editor/spellcheck-space-valid.html
layout/reftests/editor/spellcheck-textarea-attr-dynamic-inherit.html
layout/reftests/editor/spellcheck-textarea-attr-dynamic-override-inherit.html
layout/reftests/editor/spellcheck-textarea-attr-dynamic-override.html
layout/reftests/editor/spellcheck-textarea-attr-dynamic.html
layout/reftests/editor/spellcheck-textarea-attr-inherit.html
layout/reftests/editor/spellcheck-textarea-attr.html
layout/reftests/editor/spellcheck-textarea-disabled.html
layout/reftests/editor/spellcheck-textarea-focused-notreadonly.html
layout/reftests/editor/spellcheck-textarea-focused-reframe.html
layout/reftests/editor/spellcheck-textarea-focused.html
layout/reftests/editor/spellcheck-textarea-nofocus-ref.html
layout/reftests/editor/spellcheck-textarea-nofocus.html
layout/reftests/editor/spellcheck-textarea-property-dynamic-inherit.html
layout/reftests/editor/spellcheck-textarea-property-dynamic-override-inherit.html
layout/reftests/editor/spellcheck-textarea-property-dynamic-override.html
layout/reftests/editor/spellcheck-textarea-property-dynamic.html
layout/reftests/editor/spellcheck-textarea-ref.html
layout/reftests/editor/unneeded_scroll-ref.html
layout/reftests/editor/unneeded_scroll.html
layout/reftests/editor/xul/autocomplete-1.xul
layout/reftests/editor/xul/autocomplete-ref.xul
layout/reftests/editor/xul/empty-1.xul
layout/reftests/editor/xul/empty-2.xul
layout/reftests/editor/xul/empty-ref.xul
layout/reftests/editor/xul/emptyautocomplete-1.xul
layout/reftests/editor/xul/emptyautocomplete-ref.xul
layout/reftests/editor/xul/emptymultiline-1.xul
layout/reftests/editor/xul/emptymultiline-2.xul
layout/reftests/editor/xul/emptymultiline-ref.xul
layout/reftests/editor/xul/emptytextbox-1.xul
layout/reftests/editor/xul/emptytextbox-2.xul
layout/reftests/editor/xul/emptytextbox-3.xul
layout/reftests/editor/xul/emptytextbox-4.xul
layout/reftests/editor/xul/emptytextbox-5.xul
layout/reftests/editor/xul/emptytextbox-ref.xul
layout/reftests/editor/xul/input.css
layout/reftests/editor/xul/number-1.xul
layout/reftests/editor/xul/number-2.xul
layout/reftests/editor/xul/number-3.xul
layout/reftests/editor/xul/number-4.xul
layout/reftests/editor/xul/number-5.xul
layout/reftests/editor/xul/number-ref.xul
layout/reftests/editor/xul/numberwithvalue-1.xul
layout/reftests/editor/xul/numberwithvalue-ref.xul
layout/reftests/editor/xul/passwd-1.xul
layout/reftests/editor/xul/passwd-2.xul
layout/reftests/editor/xul/passwd-3.xul
layout/reftests/editor/xul/passwd-ref.xul
layout/reftests/editor/xul/plain-1.xul
layout/reftests/editor/xul/plain-ref.xul
layout/reftests/editor/xul/platform.js
layout/reftests/editor/xul/reftest.list
layout/reftests/editor/xul/textbox-1.xul
layout/reftests/editor/xul/textbox-disabled.xul
layout/reftests/editor/xul/textbox-readonly.xul
layout/reftests/editor/xul/textbox-ref.xul
layout/reftests/reftest.list
layout/reftests/svg/image/image-zoom-01-ref.svg
layout/reftests/svg/image/image-zoom-01a.svg
layout/reftests/svg/image/image-zoom-01b.svg
layout/style/nsCSSValue.cpp
layout/svg/base/src/nsSVGInnerSVGFrame.cpp
layout/svg/base/src/nsSVGInnerSVGFrame.h
layout/svg/base/src/nsSVGOuterSVGFrame.cpp
layout/svg/base/src/nsSVGOuterSVGFrame.h
layout/svg/base/src/nsSVGPatternFrame.cpp
layout/svg/base/src/nsSVGUtils.cpp
layout/svg/base/src/nsSVGUtils.h
layout/tables/BasicTableLayoutStrategy.cpp
layout/tables/SpanningCellSorter.cpp
layout/tables/SpanningCellSorter.h
layout/xul/base/src/nsBoxLayoutState.h
layout/xul/base/src/nsSprocketLayout.cpp
memory/jemalloc/jemalloc.c
mfbt/Util.h
mobile/android/base/AndroidManifest.xml.in
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoAppShell.java
mobile/android/base/Makefile.in
modules/libpref/src/init/all.js
netwerk/base/public/nsNetUtil.h
netwerk/protocol/file/nsFileChannel.cpp
netwerk/protocol/file/nsFileChannel.h
netwerk/protocol/http/nsHttpAuthCache.cpp
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpChannel.h
netwerk/protocol/http/nsHttpConnection.cpp
netwerk/protocol/http/nsHttpConnection.h
netwerk/protocol/http/nsHttpConnectionMgr.cpp
netwerk/streamconv/converters/mozTXTToHTMLConv.cpp
services/sync/modules/service.js
toolkit/components/telemetry/TelemetryPing.js
toolkit/components/telemetry/tests/unit/test_TelemetryPing.js
toolkit/crashreporter/nsExceptionHandler.cpp
toolkit/mozapps/update/test/unit/head_update.js.in
uriloader/exthandler/nsExternalHelperAppService.cpp
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
widget/android/nsAppShell.cpp
widget/android/nsWindow.cpp
widget/cocoa/TextInputHandler.mm
widget/cocoa/nsChildView.mm
widget/gtk2/nsDragService.cpp
widget/gtk2/nsDragService.h
widget/gtk2/nsWindow.cpp
widget/nsGUIEvent.h
widget/qt/nsAppShell.cpp
widget/qt/nsDragService.cpp
widget/qt/nsWindow.cpp
widget/windows/KeyboardLayout.cpp
widget/windows/KeyboardLayout.h
widget/windows/TaskbarPreview.cpp
widget/windows/nsDataObj.cpp
widget/windows/nsIMM32Handler.cpp
widget/windows/nsWindow.cpp
widget/windows/nsWindow.h
widget/windows/nsWindowDefs.h
widget/windows/nsWindowGfx.cpp
xpcom/base/nsCycleCollector.cpp
xpcom/ds/TimeStamp.cpp
xpcom/ds/nsCRT.h
xpcom/glue/nsCRTGlue.cpp
xpcom/glue/nsCRTGlue.h
xpcom/glue/nsCycleCollectionParticipant.cpp
xpcom/glue/nsCycleCollectionParticipant.h
xpcom/io/nsEscape.cpp
xpcom/io/nsLocalFileWin.cpp
new file mode 100644
--- /dev/null
+++ b/.gdbinit
@@ -0,0 +1,175 @@
+# .gdbinit file for debugging Mozilla
+
+# Don't stop for the SIG32/33/etc signals that Flash produces
+handle SIG32 noprint nostop pass
+handle SIG33 noprint nostop pass
+handle SIGPIPE noprint nostop pass
+
+# Show the concrete types behind nsIFoo
+set print object on
+
+# run when using the auto-solib-add trick
+def prun
+        tbreak main
+        run
+	set auto-solib-add 0
+        cont
+end
+
+# run -mail, when using the auto-solib-add trick
+def pmail
+        tbreak main
+        run -mail
+	set auto-solib-add 0
+        cont
+end
+
+# Define a "pu" command to display PRUnichar * strings (100 chars max)
+# Also allows an optional argument for how many chars to print as long as
+# it's less than 100.
+def pu
+  set $uni = $arg0
+  if $argc == 2
+    set $limit = $arg1
+    if $limit > 100
+      set $limit = 100
+    end
+  else
+    set $limit = 100
+  end
+  # scratch array with space for 100 chars plus null terminator.  Make
+  # sure to not use ' ' as the char so this copy/pastes well.
+  set $scratch = "____________________________________________________________________________________________________"
+  set $i = 0
+  set $scratch_idx = 0
+  while (*$uni && $i++ < $limit)
+    if (*$uni < 0x80)
+      set $scratch[$scratch_idx++] = *(char*)$uni++
+    else
+      if ($scratch_idx > 0)
+	set $scratch[$scratch_idx] = '\0'
+	print $scratch
+	set $scratch_idx = 0
+      end
+      print /x *(short*)$uni++
+    end
+  end
+  if ($scratch_idx > 0)
+    set $scratch[$scratch_idx] = '\0'
+    print $scratch
+  end
+end
+
+# Define a "ps" command to display subclasses of nsAC?String.  Note that
+# this assumes strings as of Gecko 1.9 (well, and probably a few
+# releases before that as well); going back far enough will get you
+# to string classes that this function doesn't work for.
+def ps
+  set $str = $arg0
+  if (sizeof(*$str.mData) == 1 && ($str.mFlags & 1) != 0)
+    print $str.mData
+  else
+    pu $str.mData $str.mLength
+  end
+end
+
+# Define a "pa" command to display the string value for an nsIAtom
+def pa
+  set $atom = $arg0
+  if (sizeof(*((&*$atom)->mString)) == 2)
+    pu (&*$atom)->mString
+  end
+end
+
+# define a "pxul" command to display the type of a XUL element from
+# an nsXULDocument* pointer.
+def pxul
+  set $p = $arg0
+  print $p->mNodeInfo.mRawPtr->mInner.mName->mStaticAtom->mString
+end
+
+# define a "prefcnt" command to display the refcount of an XPCOM obj
+def prefcnt
+  set $p = $arg0
+  print ((nsPurpleBufferEntry*)$p->mRefCnt.mTagged)->mRefCnt
+end
+
+# define a "ptag" command to display the tag name of a content node
+def ptag
+  set $p = $arg0
+  pa $p->mNodeInfo.mRawPtr->mInner.mName
+end
+
+##
+## nsTArray
+##
+define ptarray
+        if $argc == 0
+                help ptarray
+        else
+                set $size = $arg0.mHdr->mLength
+                set $capacity = $arg0.mHdr->mCapacity
+                set $size_max = $size - 1
+                set $elts = $arg0.Elements()
+        end
+        if $argc == 1
+                set $i = 0
+                while $i < $size
+                        printf "elem[%u]: ", $i
+                        p *($elts + $i)
+                        set $i++
+                end
+        end
+        if $argc == 2
+                set $idx = $arg1
+                if $idx < 0 || $idx > $size_max
+                        printf "idx1, idx2 are not in acceptable range: [0..%u].\n", $size_max
+                else
+                        printf "elem[%u]: ", $idx
+                        p *($elts + $idx)
+                end
+        end
+        if $argc == 3
+          set $start_idx = $arg1
+          set $stop_idx = $arg2
+          if $start_idx > $stop_idx
+            set $tmp_idx = $start_idx
+            set $start_idx = $stop_idx
+            set $stop_idx = $tmp_idx
+          end
+          if $start_idx < 0 || $stop_idx < 0 || $start_idx > $size_max || $stop_idx > $size_max
+            printf "idx1, idx2 are not in acceptable range: [0..%u].\n", $size_max
+          else
+            set $i = $start_idx
+                while $i <= $stop_idx
+                        printf "elem[%u]: ", $i
+                        p *($elts + $i)
+                        set $i++
+                end
+          end
+        end
+        if $argc > 0
+                printf "nsTArray length = %u\n", $size
+                printf "nsTArray capacity = %u\n", $capacity
+                printf "Element "
+                whatis *$elts
+        end
+end
+
+document ptarray
+        Prints nsTArray information.
+        Syntax: ptarray   
+        Note: idx, idx1 and idx2 must be in acceptable range [0...size()-1].
+        Examples:
+        ptarray a - Prints tarray content, size, capacity and T typedef
+        ptarray a 0 - Prints element[idx] from tarray
+        ptarray a 1 2 - Prints elements in range [idx1..idx2] from tarray
+end
+
+def js
+  call DumpJSStack()
+end
+
+def ft
+  call nsFrame::DumpFrameTree($arg0)
+end
--- a/.hgignore
+++ b/.hgignore
@@ -8,17 +8,17 @@
 (^|/)\.DS_Store$
 
 # Vim swap files.
 ^\.sw.$
 .[^/]*\.sw.$
 
 # User files that may appear at the root
 ^\.mozconfig
-^mozconfig$
+^mozconfig*
 ^configure$
 ^config\.cache$
 ^config\.log$
 
 # Empty marker file that's generated when we check out NSS
 ^security/manager/\.nss\.checkout$
 
 # Build directories
@@ -39,9 +39,8 @@
 
 # SVN directories
 \.svn/
 
 # Ignore the files and directory that Eclipse IDE creates
 \.project$
 \.cproject$
 \.settings/
-
--- a/Makefile.in
+++ b/Makefile.in
@@ -232,16 +232,20 @@ else
 maybe_clobber_profiledbuild:
 endif
 else
 maybe_clobber_profiledbuild:
 	$(RM) $(DIST)/bin/*.pgc
 	find $(DIST)/$(MOZ_APP_NAME) -name "*.pgc" -exec mv {} $(DIST)/bin \;
 endif
 
+# put in our default gdbinit so that the gdb debugging experience is happier.
+libs:: .gdbinit
+	$(INSTALL) $< $(DIST)/bin
+
 .PHONY: maybe_clobber_profiledbuild
 
 # Look for R_386_PC32 relocations in shared libs, these
 # break x86_64 builds and SELinux users.
 ifeq ($(OS_TARGET)_$(TARGET_XPCOM_ABI),Linux_x86-gcc3)
 scheck::
 	@relcount=`find $(DIST)/bin -name "*.so" | xargs objdump -R | grep R_386_PC32 | wc -l` && if test $$relcount -gt 0; then echo "FAILED: R_386_PC32 relocations detected in a shared library.  Did you use a system header without adding it to config/system-headers?"; exit 1; else echo "PASSED"; fi
 endif
--- a/accessible/accessible-docs.html
+++ b/accessible/accessible-docs.html
@@ -832,21 +832,21 @@ the <a
  href="http://lxr.mozilla.org/seamonkey/search?string=WM_GETOBJECT">WM_GETOBJECT</a>
 message in, nsWindow.cpp first generates an internal event called <a
  href="http://lxr.mozilla.org/seamonkey/search?string=NS_GETACCESSIBLE">NS_GETACCESSIBLE</a>,
 which is handled in <a
  href="http://lxr.mozilla.org/seamonkey/source/layout/html/base/src/nsPresShell.cpp#6345">PresShell::HandleEventInternal()</a>
 via the creation of an <a
  href="http://lxr.mozilla.org/seamonkey/find?string=msaa/nsDocAccessibleWrap">nsDocAccessibleWrap</a>
 for an inner window or <a
- href="http://lxr.mozilla.org/seamonkey/find?string=msaa/nsRootAccessibleWrap">nsRootAccessibleWrap</a>
+ href="http://lxr.mozilla.org/seamonkey/find?string=msaa/RootAccessibleWrap">RootAccessibleWrap</a>
 for a top level window. These classes implement both nsIAccessible, our
 cross platform API, as well as IAccessible, which is specific to
 Windows/MSAA/COM. The cross-platform nsDocAccessible and
-nsRootAccessible classes they inherit from are then told to start
+RootAccessible classes they inherit from are then told to start
 listening for DOM, page load and scroll events.&nbsp; These events cause
 MSAA-specific events, such as EVENT_OBJECT_FOCUS or
 EVENT_OBJECT_STATECHANGE, to fire on UI and document objects within the
 applicable window. We'll explain more about events later in this section.<br>
   </p>
   <p>Until the WM_GETOBJECT message is processed, the Gecko
 accessibility service is not used, and thus the accessibility.dll is not
 loaded, so there is almost zero overhead for accessibility API support
@@ -965,17 +965,17 @@ MSAA Events</h3>
 accessibility aids. Therefore we implement only the handful that matter.
 See the <a
  href="file:///c%7C/moz/mozdocs/mozilla-org/html/projects/ui/accessibility/accessible-architecture.html#events">Events</a>
 cheat sheet above for the list of events we implement. By far the most
 important one is EVENT_OBJECT_FOCUS.<br>
   </p>
   <p>When a potential accessibility-related event occurs within
 Mozilla, it is typically listened for by nsDocAccessible or
-nsRootAccessible. The event listeners on these classes call
+RootAccessible. The event listeners on these classes call
 FireToolkitEvent(), which is implemented for every accessible.
 Eventually, the event ends up at nsDocAccessibleWrap::FireToolkitEvent()
 which calls NotifyWinEvent from the Win32 API. NotifyWinEvent is passed
 arguments for the window the event occurred in, and the ID of the child
 within that window. Accessibility aids use the Win32 call
 SetWinEventHook() to register as a listener for these events. Creating
 a unique child ID for every object within a window can be difficult,
 see the problem and solution for <a
--- a/accessible/src/atk/Makefile.in
+++ b/accessible/src/atk/Makefile.in
@@ -47,39 +47,38 @@ EXPORT_LIBRARY = ..
 LIBXUL_LIBRARY = 1
 
 
 CPPSRCS = \
   AtkSocketAccessible.cpp \
   nsAccessNodeWrap.cpp \
   nsAccessibleWrap.cpp \
   nsDocAccessibleWrap.cpp \
-  nsRootAccessibleWrap.cpp \
   ApplicationAccessibleWrap.cpp \
   nsMaiInterfaceComponent.cpp \
   nsMaiInterfaceAction.cpp \
   nsMaiInterfaceText.cpp \
   nsMaiInterfaceEditableText.cpp \
   nsMaiInterfaceSelection.cpp \
   nsMaiInterfaceValue.cpp \
   nsMaiHyperlink.cpp \
   nsMaiInterfaceHypertext.cpp \
   nsMaiInterfaceHyperlinkImpl.cpp \
   nsMaiInterfaceTable.cpp \
   nsMaiInterfaceDocument.cpp \
   nsMaiInterfaceImage.cpp \
+  RootAccessibleWrap.cpp \
   $(NULL)
 
 EXPORTS = \
   ARIAGridAccessibleWrap.h \
   AtkSocketAccessible.h \
   nsAccessNodeWrap.h \
   nsAccessibleWrap.h \
   nsDocAccessibleWrap.h \
-  nsRootAccessibleWrap.h \
   nsTextAccessibleWrap.h \
   nsXULMenuAccessibleWrap.h \
   nsXULListboxAccessibleWrap.h \
   nsXULTreeGridAccessibleWrap.h \
   nsHyperTextAccessibleWrap.h \
   nsHTMLImageAccessibleWrap.h \
   nsHTMLTableAccessibleWrap.h \
   $(NULL)
rename from accessible/src/atk/nsRootAccessibleWrap.cpp
rename to accessible/src/atk/RootAccessibleWrap.cpp
--- a/accessible/src/atk/nsRootAccessibleWrap.cpp
+++ b/accessible/src/atk/RootAccessibleWrap.cpp
@@ -33,27 +33,30 @@
  * 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 "RootAccessibleWrap.h"
+
 #include "nsMai.h"
-#include "nsRootAccessibleWrap.h"
 
-nsNativeRootAccessibleWrap::nsNativeRootAccessibleWrap(AtkObject *aAccessible):
-    nsRootAccessible(nsnull, nsnull, nsnull)
+using namespace mozilla::a11y;
+
+NativeRootAccessibleWrap::NativeRootAccessibleWrap(AtkObject* aAccessible):
+  RootAccessible(nsnull, nsnull, nsnull)
 {
   // XXX: mark the object as defunct to ensure no single internal method is
   // running on it.
   mFlags |= eIsDefunct;
 
   g_object_ref(aAccessible);
   mAtkObject = aAccessible;
 }
 
-nsNativeRootAccessibleWrap::~nsNativeRootAccessibleWrap()
+NativeRootAccessibleWrap::~NativeRootAccessibleWrap()
 {
-    g_object_unref(mAtkObject);
-    mAtkObject = nsnull;
+  g_object_unref(mAtkObject);
+  mAtkObject = nsnull;
 }
rename from accessible/src/atk/nsRootAccessibleWrap.h
rename to accessible/src/atk/RootAccessibleWrap.h
--- a/accessible/src/atk/nsRootAccessibleWrap.h
+++ b/accessible/src/atk/RootAccessibleWrap.h
@@ -33,28 +33,35 @@
  * 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 ***** */
 
-#ifndef __NS_ROOT_ACCESSIBLE_WRAP_H__
-#define __NS_ROOT_ACCESSIBLE_WRAP_H__
+#ifndef mozilla_a11y_RootAccessibleWrap_h__
+#define mozilla_a11y_RootAccessibleWrap_h__
 
-#include "nsRootAccessible.h"
+#include "RootAccessible.h"
 
-typedef nsRootAccessible nsRootAccessibleWrap;
+namespace mozilla {
+namespace a11y {
 
-/* nsNativeRootAccessibleWrap is the accessible class for gtk+ native window.
- * The instance of nsNativeRootAccessibleWrap is a child of MaiAppRoot instance.
+typedef RootAccessible RootAccessibleWrap;
+
+/* NativeRootAccessibleWrap is the accessible class for gtk+ native window.
+ * The instance of NativeRootAccessibleWrap is a child of MaiAppRoot instance.
  * It is added into root when the toplevel window is created, and removed
  * from root when the toplevel window is destroyed.
  */
-class nsNativeRootAccessibleWrap: public nsRootAccessible
+class NativeRootAccessibleWrap : public RootAccessible
 {
 public:
-    nsNativeRootAccessibleWrap(AtkObject *aAccessible);
-    ~nsNativeRootAccessibleWrap();
+  NativeRootAccessibleWrap(AtkObject* aAccessible);
+  virtual ~NativeRootAccessibleWrap();
 };
 
-#endif   /* __NS_ROOT_ACCESSIBLE_WRAP_H__ */
+} // namespace a11y
+} // namespace mozilla
+
+#endif   /* mozilla_a11y_Root_Accessible_Wrap_h__ */
+
--- a/accessible/src/atk/nsAccessibleWrap.cpp
+++ b/accessible/src/atk/nsAccessibleWrap.cpp
@@ -40,26 +40,26 @@
 
 #include "nsAccessibleWrap.h"
 
 #include "Accessible-inl.h"
 #include "ApplicationAccessibleWrap.h"
 #include "InterfaceInitFuncs.h"
 #include "nsAccUtils.h"
 #include "nsIAccessibleRelation.h"
-#include "nsRootAccessible.h"
-#include "nsDocAccessibleWrap.h"
+#include "RootAccessible.h"
 #include "nsIAccessibleValue.h"
 #include "nsMai.h"
 #include "nsMaiHyperlink.h"
 #include "nsString.h"
 #include "nsAutoPtr.h"
 #include "prprf.h"
 #include "nsStateMap.h"
 #include "Relation.h"
+#include "RootAccessible.h"
 #include "States.h"
 
 #include "mozilla/Util.h"
 #include "nsXPCOMStrings.h"
 #include "nsComponentManagerUtils.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
@@ -724,18 +724,31 @@ getRoleCB(AtkObject *aAtkObj)
 #ifdef DEBUG_A11Y
   NS_ASSERTION(nsAccUtils::IsTextInterfaceSupportCorrect(accWrap),
       "Does not support nsIAccessibleText when it should");
 #endif
 
   if (aAtkObj->role != ATK_ROLE_INVALID)
     return aAtkObj->role;
 
-  return aAtkObj->role =
-    static_cast<AtkRole>(nsAccessibleWrap::AtkRoleFor(accWrap->Role()));
+#define ROLE(geckoRole, stringRole, atkRole, macRole, msaaRole, ia2Role) \
+  case roles::geckoRole: \
+    aAtkObj->role = atkRole; \
+    break;
+
+  switch (accWrap->Role()) {
+#include "RoleMap.h"
+    default:
+      MOZ_NOT_REACHED("Unknown role.");
+      aAtkObj->role = ATK_ROLE_UNKNOWN;
+  };
+
+#undef ROLE
+
+  return aAtkObj->role;
 }
 
 AtkAttributeSet*
 ConvertToAtkAttributeSet(nsIPersistentProperties* aAttributes)
 {
     if (!aAttributes)
         return nsnull;
 
@@ -1022,17 +1035,17 @@ nsAccessibleWrap::FirePlatformEvent(AccE
 
     case nsIAccessibleEvent::EVENT_TEXT_REMOVED:
     case nsIAccessibleEvent::EVENT_TEXT_INSERTED:
         return FireAtkTextChangedEvent(aEvent, atkObj);
 
     case nsIAccessibleEvent::EVENT_FOCUS:
       {
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_FOCUS\n"));
-        nsRootAccessible* rootAccWrap = accWrap->RootAccessible();
+        a11y::RootAccessible* rootAccWrap = accWrap->RootAccessible();
         if (rootAccWrap && rootAccWrap->mActivated) {
             atk_focus_tracker_notify(atkObj);
             // Fire state change event for focus
             nsRefPtr<AccEvent> stateChangeEvent =
               new AccStateChangeEvent(accessible, states::FOCUSED, true);
             return FireAtkStateChangeEvent(stateChangeEvent, atkObj);
         }
       } break;
@@ -1215,32 +1228,28 @@ nsAccessibleWrap::FirePlatformEvent(AccE
 
     case nsIAccessibleEvent::EVENT_MENU_END:
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENU_END\n"));
         break;
 
     case nsIAccessibleEvent::EVENT_WINDOW_ACTIVATE:
       {
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_WINDOW_ACTIVATED\n"));
-        nsRootAccessible *rootAcc =
-          static_cast<nsRootAccessible *>(accessible);
-        rootAcc->mActivated = true;
+        accessible->AsRoot()->mActivated = true;
         guint id = g_signal_lookup ("activate", MAI_TYPE_ATK_OBJECT);
         g_signal_emit(atkObj, id, 0);
 
         // Always fire a current focus event after activation.
         FocusMgr()->ForceFocusEvent();
       } break;
 
     case nsIAccessibleEvent::EVENT_WINDOW_DEACTIVATE:
       {
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_WINDOW_DEACTIVATED\n"));
-        nsRootAccessible *rootAcc =
-          static_cast<nsRootAccessible *>(accessible);
-        rootAcc->mActivated = false;
+        accessible->AsRoot()->mActivated = false;
         guint id = g_signal_lookup ("deactivate", MAI_TYPE_ATK_OBJECT);
         g_signal_emit(atkObj, id, 0);
       } break;
 
     case nsIAccessibleEvent::EVENT_WINDOW_MAXIMIZE:
       {
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_WINDOW_MAXIMIZE\n"));
         guint id = g_signal_lookup ("maximize", MAI_TYPE_ATK_OBJECT);
@@ -1385,25 +1394,8 @@ nsAccessibleWrap::FireAtkShowHideEvent(A
     bool isFromUserInput = aEvent->IsFromUserInput();
     char *signal_name = g_strconcat(aIsAdded ? "children_changed::add" :  "children_changed::remove",
                                     isFromUserInput ? "" : kNonUserInputEvent, NULL);
     g_signal_emit_by_name(parentObject, signal_name, indexInParent, aObject, NULL);
     g_free(signal_name);
 
     return NS_OK;
 }
-
-PRUint32
-nsAccessibleWrap::AtkRoleFor(role aRole)
-{
-#define ROLE(geckoRole, stringRole, atkRole, macRole, msaaRole, ia2Role) \
-  case roles::geckoRole: \
-    return atkRole;
-
-  switch (aRole) {
-#include "RoleMap.h"
-    default:
-      MOZ_NOT_REACHED("Unknown role.");
-      return ATK_ROLE_UNKNOWN;
-  }
-
-#undef ROLE
-}
--- a/accessible/src/atk/nsAccessibleWrap.h
+++ b/accessible/src/atk/nsAccessibleWrap.h
@@ -111,21 +111,16 @@ public:
     void SetMaiHyperlink(MaiHyperlink* aMaiHyperlink);
 
     static const char * ReturnString(nsAString &aString) {
       static nsCString returnedString;
       returnedString = NS_ConvertUTF16toUTF8(aString);
       return returnedString.get();
     }
 
-  /**
-   * Function mapping from cross platform roles to ATK roles.
-   */
-  static PRUint32 AtkRoleFor(mozilla::a11y::role aRole);
-
 protected:
     virtual nsresult FirePlatformEvent(AccEvent* aEvent);
 
     nsresult FireAtkStateChangeEvent(AccEvent* aEvent, AtkObject *aObject);
     nsresult FireAtkTextChangedEvent(AccEvent* aEvent, AtkObject *aObject);
     nsresult FireAtkShowHideEvent(AccEvent* aEvent, AtkObject *aObject,
                                   bool aIsAdded);
 
--- a/accessible/src/atk/nsMaiInterfaceText.cpp
+++ b/accessible/src/atk/nsMaiInterfaceText.cpp
@@ -40,27 +40,28 @@
 
 #include "InterfaceInitFuncs.h"
 
 #include "nsHyperTextAccessible.h"
 #include "nsMai.h"
 
 #include "nsIPersistentProperties2.h"
 
+using namespace mozilla::a11y;
+
 AtkAttributeSet* ConvertToAtkAttributeSet(nsIPersistentProperties* aAttributes);
 
 static void
 ConvertTexttoAsterisks(nsAccessibleWrap* accWrap, nsAString& aString)
 {
-    // convert each char to "*" when it's "password text" 
-    PRUint32 atkRole = nsAccessibleWrap::AtkRoleFor(accWrap->NativeRole());
-    if (atkRole == ATK_ROLE_PASSWORD_TEXT) {
-        for (PRUint32 i = 0; i < aString.Length(); i++)
-            aString.Replace(i, 1, NS_LITERAL_STRING("*"));
-    }
+  // convert each char to "*" when it's "password text" 
+  if (accWrap->NativeRole() == roles::PASSWORD_TEXT) {
+    for (PRUint32 i = 0; i < aString.Length(); i++)
+      aString.Replace(i, 1, NS_LITERAL_STRING("*"));
+  }
 }
 
 extern "C" {
 
 static gchar*
 getTextCB(AtkText *aText, gint aStartOffset, gint aEndOffset)
 {
     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
@@ -137,39 +138,39 @@ getTextAtOffsetCB(AtkText *aText, gint a
     NS_ENSURE_SUCCESS(rv, nsnull);
 
     ConvertTexttoAsterisks(accWrap, autoStr);
     NS_ConvertUTF16toUTF8 cautoStr(autoStr);
     return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nsnull;
 }
 
 static gunichar
-getCharacterAtOffsetCB(AtkText *aText, gint aOffset)
+getCharacterAtOffsetCB(AtkText* aText, gint aOffset)
 {
-    nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
-    if (!accWrap)
-        return 0;
+  nsAccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
+  if (!accWrap)
+    return 0;
 
-    nsCOMPtr<nsIAccessibleText> accText;
-    accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText),
-                            getter_AddRefs(accText));
-    NS_ENSURE_TRUE(accText, 0);
+  nsCOMPtr<nsIAccessibleText> accText;
+  accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText),
+                          getter_AddRefs(accText));
+  NS_ENSURE_TRUE(accText, 0);
 
-    /* PRUnichar is unsigned short in Mozilla */
-    /* gnuichar is guint32 in glib */
-    PRUnichar uniChar;
-    nsresult rv =
-        accText->GetCharacterAtOffset(aOffset, &uniChar);
+  // PRUnichar is unsigned short in Mozilla
+  // gnuichar is guint32 in glib
+  PRUnichar uniChar = 0;
+  nsresult rv = accText->GetCharacterAtOffset(aOffset, &uniChar);
+  if (NS_FAILED(rv))
+    return 0;
 
-    // convert char to "*" when it's "password text" 
-    PRUint32 atkRole = nsAccessibleWrap::AtkRoleFor(accWrap->NativeRole());
-    if (atkRole == ATK_ROLE_PASSWORD_TEXT)
-        uniChar = '*';
+  // Convert char to "*" when it's "password text".
+  if (accWrap->NativeRole() == roles::PASSWORD_TEXT)
+    uniChar = '*';
 
-    return (NS_FAILED(rv)) ? 0 : static_cast<gunichar>(uniChar);
+  return static_cast<gunichar>(uniChar);
 }
 
 static gchar*
 getTextBeforeOffsetCB(AtkText *aText, gint aOffset,
                       AtkTextBoundary aBoundaryType,
                       gint *aStartOffset, gint *aEndOffset)
 {
     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
--- a/accessible/src/base/FocusManager.cpp
+++ b/accessible/src/base/FocusManager.cpp
@@ -35,18 +35,18 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "FocusManager.h"
 
 #include "Accessible-inl.h"
 #include "nsAccessibilityService.h"
 #include "nsAccUtils.h"
-#include "nsRootAccessible.h"
 #include "Role.h"
+#include "RootAccessible.h"
 
 #include "nsEventStateManager.h"
 #include "nsFocusManager.h"
 
 namespace dom = mozilla::dom;
 using namespace mozilla::a11y;
 
 FocusManager::FocusManager()
@@ -152,17 +152,17 @@ FocusManager::NotifyOfDOMFocus(nsISuppor
 
   nsCOMPtr<nsINode> targetNode(do_QueryInterface(aTarget));
   if (targetNode) {
     nsDocAccessible* document =
       GetAccService()->GetDocAccessible(targetNode->OwnerDoc());
     if (document) {
       // Set selection listener for focused element.
       if (targetNode->IsElement()) {
-        nsRootAccessible* root = document->RootAccessible();
+        RootAccessible* root = document->RootAccessible();
         nsCaretAccessible* caretAcc = root->GetCaretAccessible();
         caretAcc->SetControlSelectionListener(targetNode->AsElement());
       }
 
       document->HandleNotification<FocusManager, nsINode>
         (this, &FocusManager::ProcessDOMFocus, targetNode);
     }
   }
--- a/accessible/src/base/Makefile.in
+++ b/accessible/src/base/Makefile.in
@@ -63,17 +63,16 @@ CPPSRCS = \
   nsCoreUtils.cpp \
   nsAccUtils.cpp \
   nsAccessibilityService.cpp \
   nsAccessible.cpp \
   nsAccessiblePivot.cpp \
   nsAccTreeWalker.cpp \
   nsBaseWidgetAccessible.cpp \
   nsEventShell.cpp \
-  nsRootAccessible.cpp \
   nsCaretAccessible.cpp \
   nsTextAccessible.cpp \
   nsTextEquivUtils.cpp \
   StyleInfo.cpp \
   TextAttrs.cpp \
   TextUpdater.cpp \
   $(NULL)
 
--- a/accessible/src/base/Role.h
+++ b/accessible/src/base/Role.h
@@ -809,17 +809,17 @@ enum Role {
   /**
    * Represent a term in a definition list (dt in HTML).
    */
   TERM = 127,
 
   /**
    * Represent a definition in a definition list (dd in HTML)
    */
-  DEFINITION = 128,
+  DEFINITION = 128
 };
 
 } // namespace role
 
 typedef enum mozilla::a11y::roles::Role role;
 
 } // namespace a11y
 } // namespace mozilla
--- a/accessible/src/base/nsAccDocManager.cpp
+++ b/accessible/src/base/nsAccDocManager.cpp
@@ -37,17 +37,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsAccDocManager.h"
 
 #include "ApplicationAccessible.h"
 #include "nsAccessibilityService.h"
 #include "nsAccUtils.h"
 #include "nsARIAMap.h"
-#include "nsRootAccessibleWrap.h"
+#include "RootAccessibleWrap.h"
 #include "States.h"
 
 #include "nsCURILoader.h"
 #include "nsDocShellLoadTypes.h"
 #include "nsIChannel.h"
 #include "nsIContentViewer.h"
 #include "nsIDOMDocument.h"
 #include "nsEventListenerManager.h"
@@ -351,17 +351,17 @@ nsAccDocManager::AddListeners(nsIDocumen
   if (aAddDOMContentLoadedListener) {
     elm->AddEventListenerByType(this, NS_LITERAL_STRING("DOMContentLoaded"),
                                 NS_EVENT_FLAG_CAPTURE);
     NS_LOG_ACCDOCCREATE_TEXT("  added 'DOMContentLoaded' listener")
   }
 }
 
 nsDocAccessible*
-nsAccDocManager::CreateDocOrRootAccessible(nsIDocument *aDocument)
+nsAccDocManager::CreateDocOrRootAccessible(nsIDocument* aDocument)
 {
   // Ignore temporary, hiding, resource documents and documents without
   // docshell.
   if (aDocument->IsInitialDocument() || !aDocument->IsVisible() ||
       aDocument->IsResourceDoc() || !aDocument->IsActive())
     return nsnull;
 
   // Ignore documents without presshell and not having root frame.
@@ -386,17 +386,17 @@ nsAccDocManager::CreateDocOrRootAccessib
                  "Can't create an accessible for the document!");
     if (!parentDocAcc)
       return nsnull;
   }
 
   // We only create root accessibles for the true root, otherwise create a
   // doc accessible.
   nsRefPtr<nsDocAccessible> docAcc = isRootDoc ?
-    new nsRootAccessibleWrap(aDocument, rootElm, presShell) :
+    new RootAccessibleWrap(aDocument, rootElm, presShell) :
     new nsDocAccessibleWrap(aDocument, rootElm, presShell);
 
   // Cache the document accessible into document cache.
   if (!docAcc || !mDocAccessibleCache.Put(aDocument, docAcc))
     return nsnull;
 
   // Initialize the document accessible.
   if (!docAcc->Init()) {
--- a/accessible/src/base/nsAccessNode.cpp
+++ b/accessible/src/base/nsAccessNode.cpp
@@ -37,33 +37,35 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsAccessNode.h"
 
 #include "ApplicationAccessibleWrap.h"
 #include "nsAccessibilityService.h"
 #include "nsAccUtils.h"
 #include "nsCoreUtils.h"
-#include "nsRootAccessible.h"
+#include "RootAccessible.h"
 
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDOMWindow.h"
 #include "nsIFrame.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIObserverService.h"
 #include "nsIPrefBranch.h"
 #include "nsIPrefService.h"
 #include "nsIPresShell.h"
 #include "nsIServiceManager.h"
 #include "nsIStringBundle.h"
 #include "nsFocusManager.h"
 #include "nsPresContext.h"
 #include "mozilla/Services.h"
 
+using namespace mozilla::a11y;
+
 /* For documentation of the accessibility architecture, 
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
 nsIStringBundle *nsAccessNode::gStringBundle = 0;
 
 bool nsAccessNode::gIsFormFillEnabled = false;
 
@@ -87,19 +89,16 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DE
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessNode construction/desctruction
 
 nsAccessNode::
   nsAccessNode(nsIContent* aContent, nsDocAccessible* aDoc) :
   mContent(aContent), mDoc(aDoc)
 {
-#ifdef DEBUG_A11Y
-  mIsInitialized = false;
-#endif
 }
 
 nsAccessNode::~nsAccessNode()
 {
   NS_ASSERTION(!mDoc, "LastRelease was never called!?!");
 }
 
 void nsAccessNode::LastRelease()
@@ -202,17 +201,17 @@ void nsAccessNode::ShutdownXPAccessibili
   if (gApplicationAccessible) {
     gApplicationAccessible->Shutdown();
     NS_RELEASE(gApplicationAccessible);
   }
 
   NotifyA11yInitOrShutdown(false);
 }
 
-nsRootAccessible*
+RootAccessible*
 nsAccessNode::RootAccessible() const
 {
   nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
     nsCoreUtils::GetDocShellTreeItemFor(mContent);
   NS_ASSERTION(docShellTreeItem, "No docshell tree item for mContent");
   if (!docShellTreeItem) {
     return nsnull;
   }
--- a/accessible/src/base/nsAccessNode.h
+++ b/accessible/src/base/nsAccessNode.h
@@ -52,17 +52,22 @@
 #include "nsINameSpaceManager.h"
 #include "nsIStringBundle.h"
 #include "nsWeakReference.h"
 
 class ApplicationAccessible;
 class nsAccessNode;
 class nsDocAccessible;
 class nsIAccessibleDocument;
-class nsRootAccessible;
+
+namespace mozilla {
+namespace a11y {
+class RootAccessible;
+}
+}
 
 class nsIPresShell;
 class nsPresContext;
 class nsIFrame;
 class nsIDocShellTreeItem;
 
 #define ACCESSIBLE_BUNDLE_URL "chrome://global-platform/locale/accessible.properties"
 #define PLATFORM_KEYS_BUNDLE_URL "chrome://global-platform/locale/platformKeys.properties"
@@ -88,17 +93,17 @@ public:
   /**
    * Return the document accessible for this access node.
    */
   nsDocAccessible* Document() const { return mDoc; }
 
   /**
    * Return the root document accessible for this accessnode.
    */
-  nsRootAccessible* RootAccessible() const;
+  mozilla::a11y::RootAccessible* RootAccessible() const;
 
   /**
    * Initialize the access node object, add it to the cache.
    */
   virtual bool Init();
 
   /**
    * Shutdown the access node object.
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -52,21 +52,21 @@
 #include "nsIAccessibleProvider.h"
 #include "nsHTMLCanvasAccessible.h"
 #include "nsHTMLImageMapAccessible.h"
 #include "nsHTMLLinkAccessible.h"
 #include "nsHTMLSelectAccessible.h"
 #include "nsHTMLTableAccessibleWrap.h"
 #include "nsHTMLTextAccessible.h"
 #include "nsHyperTextAccessibleWrap.h"
-#include "nsRootAccessibleWrap.h"
 #include "nsXFormsFormControlsAccessible.h"
 #include "nsXFormsWidgetsAccessible.h"
 #include "OuterDocAccessible.h"
 #include "Role.h"
+#include "RootAccessibleWrap.h"
 #include "States.h"
 #include "Statistics.h"
 #ifdef XP_WIN
 #include "nsHTMLWin32ObjectAccessible.h"
 #endif
 
 #include "nsCURILoader.h"
 #include "nsEventStates.h"
@@ -652,17 +652,17 @@ nsAccessibilityService::PresShellDestroy
 
 void
 nsAccessibilityService::PresShellActivated(nsIPresShell* aPresShell)
 {
   nsIDocument* DOMDoc = aPresShell->GetDocument();
   if (DOMDoc) {
     nsDocAccessible* document = GetDocAccessibleFromCache(DOMDoc);
     if (document) {
-      nsRootAccessible* rootDocument = document->RootAccessible();
+      RootAccessible* rootDocument = document->RootAccessible();
       NS_ASSERTION(rootDocument, "Entirely broken tree: no root document!");
       if (rootDocument)
         rootDocument->DocumentActivated(document);
     }
   }
 }
 
 void
@@ -1723,34 +1723,34 @@ nsAccessibilityService::CreateHTMLAccess
   return nsnull;
  }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessibilityService (DON'T put methods here)
 
 nsAccessible*
 nsAccessibilityService::AddNativeRootAccessible(void* aAtkAccessible)
- {
+{
 #ifdef MOZ_ACCESSIBILITY_ATK
   ApplicationAccessible* applicationAcc =
     nsAccessNode::GetApplicationAccessible();
   if (!applicationAcc)
     return nsnull;
 
-  nsRefPtr<nsNativeRootAccessibleWrap> nativeRootAcc =
-     new nsNativeRootAccessibleWrap((AtkObject*)aAtkAccessible);
+  nsRefPtr<NativeRootAccessibleWrap> nativeRootAcc =
+    new NativeRootAccessibleWrap(static_cast<AtkObject*>(aAtkAccessible));
   if (!nativeRootAcc)
     return nsnull;
 
   if (applicationAcc->AppendChild(nativeRootAcc))
     return nativeRootAcc;
 #endif
 
   return nsnull;
- }
+}
 
 void
 nsAccessibilityService::RemoveNativeRootAccessible(nsAccessible* aAccessible)
 {
 #ifdef MOZ_ACCESSIBILITY_ATK
   ApplicationAccessible* applicationAcc =
     nsAccessNode::GetApplicationAccessible();
 
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -45,20 +45,20 @@
 #include "AccIterator.h"
 #include "nsAccUtils.h"
 #include "nsAccEvent.h"
 #include "nsAccessibleRelation.h"
 #include "nsAccessibilityService.h"
 #include "nsAccTreeWalker.h"
 #include "nsIAccessibleRelation.h"
 #include "nsEventShell.h"
-#include "nsRootAccessible.h"
 #include "nsTextEquivUtils.h"
 #include "Relation.h"
 #include "Role.h"
+#include "RootAccessible.h"
 #include "States.h"
 #include "StyleInfo.h"
 
 #include "nsIDOMCSSValue.h"
 #include "nsIDOMCSSPrimitiveValue.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMDocumentXBL.h"
@@ -252,18 +252,17 @@ nsAccessible::GetDOMNode(nsIDOMNode **aD
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccessible::GetRootDocument(nsIAccessibleDocument **aRootDocument)
 {
   NS_ENSURE_ARG_POINTER(aRootDocument);
 
-  nsRootAccessible* rootDocument = RootAccessible();
-  NS_IF_ADDREF(*aRootDocument = rootDocument);
+  NS_IF_ADDREF(*aRootDocument = RootAccessible());
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccessible::GetLanguage(nsAString& aLanguage)
 {
   Language(aLanguage);
   return NS_OK;
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -484,17 +484,17 @@ public:
 
   inline bool IsListControl() const { return mFlags & eListControlAccessible; }
 
   inline bool IsMenuButton() const { return mFlags & eMenuButtonAccessible; }
 
   inline bool IsMenuPopup() const { return mFlags & eMenuPopupAccessible; }
 
   inline bool IsRoot() const { return mFlags & eRootAccessible; }
-  nsRootAccessible* AsRoot();
+  mozilla::a11y::RootAccessible* AsRoot();
 
   virtual mozilla::a11y::TableAccessible* AsTable() { return nsnull; }
 
   inline bool IsTextLeaf() const { return mFlags & eTextLeafAccessible; }
   nsTextAccessible* AsTextLeaf();
 
   //////////////////////////////////////////////////////////////////////////////
   // ActionAccessible
--- a/accessible/src/base/nsCaretAccessible.cpp
+++ b/accessible/src/base/nsCaretAccessible.cpp
@@ -36,45 +36,47 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsCaretAccessible.h"
 
 #include "nsAccessibilityService.h"
 #include "nsAccUtils.h"
 #include "nsCoreUtils.h"
 #include "nsIAccessibleEvent.h"
+#include "RootAccessible.h"
 
 #include "nsCaret.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMHTMLAnchorElement.h"
 #include "nsIDOMHTMLInputElement.h"
 #include "nsIDOMHTMLTextAreaElement.h"
 #include "nsIFrame.h"
 #include "nsIPresShell.h"
-#include "nsRootAccessible.h"
 #include "nsISelectionPrivate.h"
 #include "nsServiceManagerUtils.h"
 
 class nsIWidget;
 
+using namespace mozilla::a11y;
+
 NS_IMPL_ISUPPORTS1(nsCaretAccessible, nsISelectionListener)
   
-nsCaretAccessible::nsCaretAccessible( nsRootAccessible *aRootAccessible):
+nsCaretAccessible::nsCaretAccessible(RootAccessible* aRootAccessible) :
 mLastCaretOffset(-1), mRootAccessible(aRootAccessible)
 {
 }
 
 nsCaretAccessible::~nsCaretAccessible()
 {
 }
 
 void nsCaretAccessible::Shutdown()
 {
-  // The caret accessible isn't shut down until the nsRootAccessible owning it is shut down
-  // Each nsDocAccessible, including the nsRootAccessible, is responsible for clearing the
+  // The caret accessible isn't shut down until the RootAccessible owning it is shut down
+  // Each nsDocAccessible, including the RootAccessible, is responsible for clearing the
   // doc selection listeners they registered in this nsCaretAccessible
 
   ClearControlSelectionListener(); // Clear the selection listener for the currently focused control
   mLastTextAccessible = nsnull;
   mLastUsedSelection = nsnull;
   mRootAccessible = nsnull;
 }
 
--- a/accessible/src/base/nsCaretAccessible.h
+++ b/accessible/src/base/nsCaretAccessible.h
@@ -38,46 +38,44 @@
 #ifndef __nsCaretAccessible_h__
 #define __nsCaretAccessible_h__
 
 #include "NotificationController.h"
 #include "nsHyperTextAccessible.h"
 
 #include "nsISelectionListener.h"
 
-class nsRootAccessible;
-
 /*
  * This special accessibility class is for the caret, which is really the currently focused selection.
- * There is only 1 visible caret per top level window (nsRootAccessible),
+ * There is only 1 visible caret per top level window (RootAccessible),
  * However, there may be several visible selections.
  *
  * The important selections are the one owned by each document, and the one in the currently focused control.
  *
  * The caret accessible is no longer an accessible object in its own right.
  * On Windows it is used to move an invisible system caret that shadows the Mozilla caret. Windows will
  * also automatically map this to the MSAA caret accessible object (via OBJID_CARET).
  * (as opposed to the root accessible tree for a window which is retrieved with OBJID_CLIENT)
  * For ATK and Iaccessible2, the caret accessible is used to fire
  * caret move and selection change events.
  *
- * The caret accessible is owned by the nsRootAccessible for the top level window that it's in.
- * The nsRootAccessible needs to tell the nsCaretAccessible about focus changes via
+ * The caret accessible is owned by the RootAccessible for the top level window that it's in.
+ * The RootAccessible needs to tell the nsCaretAccessible about focus changes via
  * setControlSelectionListener().
  * Each nsDocAccessible needs to tell the nsCaretAccessible owned by the root to
  * listen for selection events via addDocSelectionListener() and then needs to remove the 
  * selection listener when the doc goes away via removeDocSelectionListener().
  */
 
 class nsCaretAccessible : public nsISelectionListener
 {
 public:
   NS_DECL_ISUPPORTS
 
-  nsCaretAccessible(nsRootAccessible *aRootAccessible);
+  nsCaretAccessible(mozilla::a11y::RootAccessible* aRootAccessible);
   virtual ~nsCaretAccessible();
   void Shutdown();
 
   /* ----- nsISelectionListener ---- */
   NS_DECL_NSISELECTIONLISTENER
 
   /**
    * Listen to selection events on the focused control.
@@ -150,12 +148,12 @@ private:
 
   // Info for the the last selection event.
   // If it was on a control, then its control's selection. Otherwise, it's for
   // a document where the selection changed.
   nsCOMPtr<nsIWeakReference> mLastUsedSelection; // Weak ref to nsISelection
   nsRefPtr<nsHyperTextAccessible> mLastTextAccessible;
   PRInt32 mLastCaretOffset;
 
-  nsRootAccessible *mRootAccessible;
+  mozilla::a11y::RootAccessible* mRootAccessible;
 };
 
 #endif
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -38,19 +38,19 @@
 
 #include "Accessible-inl.h"
 #include "AccIterator.h"
 #include "nsAccCache.h"
 #include "nsAccessibilityService.h"
 #include "nsAccessiblePivot.h"
 #include "nsAccTreeWalker.h"
 #include "nsAccUtils.h"
-#include "nsRootAccessible.h"
 #include "nsTextEquivUtils.h"
 #include "Role.h"
+#include "RootAccessible.h"
 #include "States.h"
 
 #include "nsIMutableArray.h"
 #include "nsICommandManager.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDocument.h"
 #include "nsIDOMAttr.h"
@@ -759,17 +759,17 @@ nsresult nsDocAccessible::AddEventListen
     if (commandManager) {
       commandManager->AddCommandObserver(this, "obs_documentCreated");
     }
   }
 
   nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
   docShellTreeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
   if (rootTreeItem) {
-    nsRootAccessible* rootAccessible = RootAccessible();
+    a11y::RootAccessible* rootAccessible = RootAccessible();
     NS_ENSURE_TRUE(rootAccessible, NS_ERROR_FAILURE);
     nsRefPtr<nsCaretAccessible> caretAccessible = rootAccessible->GetCaretAccessible();
     if (caretAccessible) {
       caretAccessible->AddDocSelectionListener(mPresShell);
     }
   }
 
   // add document observer
@@ -806,17 +806,17 @@ nsresult nsDocAccessible::RemoveEventLis
   }
 
   if (mScrollWatchTimer) {
     mScrollWatchTimer->Cancel();
     mScrollWatchTimer = nsnull;
     NS_RELEASE_THIS(); // Kung fu death grip
   }
 
-  nsRootAccessible* rootAccessible = RootAccessible();
+  a11y::RootAccessible* rootAccessible = RootAccessible();
   if (rootAccessible) {
     nsRefPtr<nsCaretAccessible> caretAccessible = rootAccessible->GetCaretAccessible();
     if (caretAccessible)
       caretAccessible->RemoveDocSelectionListener(mPresShell);
   }
 
   return NS_OK;
 }
@@ -1762,21 +1762,16 @@ void
 nsDocAccessible::ProcessPendingEvent(AccEvent* aEvent)
 {
   PRUint32 eventType = aEvent->GetEventType();
   if (eventType == nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED) {
     nsHyperTextAccessible* hyperText = aEvent->GetAccessible()->AsHyperText();
     PRInt32 caretOffset;
     if (hyperText &&
         NS_SUCCEEDED(hyperText->GetCaretOffset(&caretOffset))) {
-#ifdef DEBUG_A11Y
-      PRUnichar chAtOffset;
-      hyperText->GetCharacterAtOffset(caretOffset, &chAtOffset);
-      printf("\nCaret moved to %d with char %c", caretOffset, chAtOffset);
-#endif
       nsRefPtr<AccEvent> caretMoveEvent =
         new AccCaretMoveEvent(hyperText, caretOffset);
       nsEventShell::FireEvent(caretMoveEvent);
 
       PRInt32 selectionCount;
       hyperText->GetSelectionCount(&selectionCount);
       if (selectionCount) {  // There's a selection so fire selection change as well
         nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED,
--- a/accessible/src/generic/Makefile.in
+++ b/accessible/src/generic/Makefile.in
@@ -14,21 +14,24 @@ LIBRARY_NAME = accessibility_generic_s
 LIBXUL_LIBRARY = 1
 
 
 CPPSRCS = \
   ApplicationAccessible.cpp \
   ARIAGridAccessible.cpp \
   FormControlAccessible.cpp \
   OuterDocAccessible.cpp \
+  RootAccessible.cpp \
   $(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/rules.mk
 
 LOCAL_INCLUDES = \
   -I$(srcdir)/../xpcom \
   -I$(srcdir)/../base \
+  -I$(srcdir)/../html \
+  -I$(srcdir)/../xul \
   -I$(srcdir)/../../../layout/generic \
   -I$(srcdir)/../../../layout/xul/base/src \
   $(NULL)
rename from accessible/src/base/nsRootAccessible.cpp
rename to accessible/src/generic/RootAccessible.cpp
--- a/accessible/src/base/nsRootAccessible.cpp
+++ b/accessible/src/generic/RootAccessible.cpp
@@ -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 ***** */
 
+#include "RootAccessible.h"
+
 #include "mozilla/Util.h"
 
 #define CreateEvent CreateEventA
 #include "nsIDOMDocument.h"
 
 #include "Accessible-inl.h"
 #include "nsAccessibilityService.h"
 #include "nsAccUtils.h"
@@ -71,70 +73,70 @@
 #include "nsIFrame.h"
 #include "nsIHTMLDocument.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsISelectionPrivate.h"
 #include "nsIServiceManager.h"
 #include "nsPIDOMWindow.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsReadableUtils.h"
-#include "nsRootAccessible.h"
 #include "nsIPrivateDOMEvent.h"
 #include "nsFocusManager.h"
 
 #ifdef MOZ_XUL
 #include "nsXULTreeAccessible.h"
 #include "nsIXULDocument.h"
 #include "nsIXULWindow.h"
 #endif
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsISupports
 
-NS_IMPL_ISUPPORTS_INHERITED1(nsRootAccessible, nsDocAccessible, nsIAccessibleDocument)
+NS_IMPL_ISUPPORTS_INHERITED1(RootAccessible, nsDocAccessible, nsIAccessibleDocument)
 
 ////////////////////////////////////////////////////////////////////////////////
-// Constructor/desctructor
+// Constructor/destructor
 
-nsRootAccessible::
-  nsRootAccessible(nsIDocument* aDocument, nsIContent* aRootContent,
-                   nsIPresShell* aPresShell) :
+RootAccessible::
+  RootAccessible(nsIDocument* aDocument, nsIContent* aRootContent,
+                 nsIPresShell* aPresShell) :
   nsDocAccessibleWrap(aDocument, aRootContent, aPresShell)
 {
   mFlags |= eRootAccessible;
 }
 
-nsRootAccessible::~nsRootAccessible()
+RootAccessible::~RootAccessible()
 {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessible
 
 ENameValueFlag
-nsRootAccessible::Name(nsString& aName)
+RootAccessible::Name(nsString& aName)
 {
   aName.Truncate();
 
   if (mRoleMapEntry) {
     nsAccessible::Name(aName);
     if (!aName.IsEmpty())
       return eNameOK;
   }
 
   nsCOMPtr<nsIDOMDocument> document = do_QueryInterface(mDocument);
+  NS_ENSURE_TRUE(document, eNameOK);
   document->GetTitle(aName);
   return eNameOK;
 }
 
 role
-nsRootAccessible::NativeRole()
+RootAccessible::NativeRole()
 {
   // If it's a <dialog> or <wizard>, use roles::DIALOG instead
   dom::Element *root = mDocument->GetRootElement();
   if (root) {
     nsCOMPtr<nsIDOMElement> rootElement(do_QueryInterface(root));
     if (rootElement) {
       nsAutoString name;
       rootElement->GetLocalName(name);
@@ -142,19 +144,20 @@ nsRootAccessible::NativeRole()
         return roles::DIALOG; // Always at the root
       }
     }
   }
 
   return nsDocAccessibleWrap::NativeRole();
 }
 
-// nsRootAccessible protected member
+// RootAccessible protected member
 #ifdef MOZ_XUL
-PRUint32 nsRootAccessible::GetChromeFlags()
+PRUint32
+RootAccessible::GetChromeFlags()
 {
   // Return the flag set for the top level window as defined 
   // by nsIWebBrowserChrome::CHROME_WINDOW_[FLAGNAME]
   // Not simple: nsIXULWindow is not just a QI from nsIDOMWindow
   nsCOMPtr<nsIDocShellTreeItem> treeItem =
     nsCoreUtils::GetDocShellTreeItemFor(mDocument);
   NS_ENSURE_TRUE(treeItem, 0);
   nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
@@ -166,17 +169,17 @@ PRUint32 nsRootAccessible::GetChromeFlag
   }
   PRUint32 chromeFlags;
   xulWin->GetChromeFlags(&chromeFlags);
   return chromeFlags;
 }
 #endif
 
 PRUint64
-nsRootAccessible::NativeState()
+RootAccessible::NativeState()
 {
   PRUint64 states = nsDocAccessibleWrap::NativeState();
 
 #ifdef MOZ_XUL
   PRUint32 chromeFlags = GetChromeFlags();
   if (chromeFlags & nsIWebBrowserChrome::CHROME_WINDOW_RESIZE)
     states |= states::SIZEABLE;
     // If it has a titlebar it's movable
@@ -226,17 +229,18 @@ const char* const docEvents[] = {
   "popuphiding",
   "DOMMenuInactive",
   "DOMMenuItemActive",
   "DOMMenuItemInactive",
   "DOMMenuBarActive",
   "DOMMenuBarInactive"
 };
 
-nsresult nsRootAccessible::AddEventListeners()
+nsresult
+RootAccessible::AddEventListeners()
 {
   // nsIDOMEventTarget interface allows to register event listeners to
   // receive untrusted events (synthetic events generated by untrusted code).
   // For example, XBL bindings implementations for elements that are hosted in
   // non chrome document fire untrusted events.
   nsCOMPtr<nsIDOMEventTarget> nstarget(do_QueryInterface(mDocument));
 
   if (nstarget) {
@@ -251,17 +255,18 @@ nsresult nsRootAccessible::AddEventListe
 
   if (!mCaretAccessible) {
     mCaretAccessible = new nsCaretAccessible(this);
   }
 
   return nsDocAccessible::AddEventListeners();
 }
 
-nsresult nsRootAccessible::RemoveEventListeners()
+nsresult
+RootAccessible::RemoveEventListeners()
 {
   nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(mDocument));
   if (target) { 
     for (const char* const* e = docEvents,
                    * const* e_end = ArrayEnd(docEvents);
          e < e_end; ++e) {
       nsresult rv = target->RemoveEventListener(NS_ConvertASCIItoUTF16(*e), this, true);
       NS_ENSURE_SUCCESS(rv, rv);
@@ -279,31 +284,31 @@ nsresult nsRootAccessible::RemoveEventLi
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // public
 
 nsCaretAccessible*
-nsRootAccessible::GetCaretAccessible()
+RootAccessible::GetCaretAccessible()
 {
   return mCaretAccessible;
 }
 
 void
-nsRootAccessible::DocumentActivated(nsDocAccessible* aDocument)
+RootAccessible::DocumentActivated(nsDocAccessible* aDocument)
 {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIDOMEventListener
 
 NS_IMETHODIMP
-nsRootAccessible::HandleEvent(nsIDOMEvent* aDOMEvent)
+RootAccessible::HandleEvent(nsIDOMEvent* aDOMEvent)
 {
   nsCOMPtr<nsIDOMNSEvent> DOMNSEvent(do_QueryInterface(aDOMEvent));
   nsCOMPtr<nsIDOMEventTarget> DOMEventTarget;
   DOMNSEvent->GetOriginalTarget(getter_AddRefs(DOMEventTarget));
   nsCOMPtr<nsINode> origTargetNode(do_QueryInterface(DOMEventTarget));
   if (!origTargetNode)
     return NS_OK;
 
@@ -330,26 +335,26 @@ nsRootAccessible::HandleEvent(nsIDOMEven
              NS_ConvertUTF16toUTF8(tag).get(), id.get(),
              NS_ConvertUTF16toUTF8(eventType).get());
     }
 #endif
 
     // Root accessible exists longer than any of its descendant documents so
     // that we are guaranteed notification is processed before root accessible
     // is destroyed.
-    document->HandleNotification<nsRootAccessible, nsIDOMEvent>
-      (this, &nsRootAccessible::ProcessDOMEvent, aDOMEvent);
+    document->HandleNotification<RootAccessible, nsIDOMEvent>
+      (this, &RootAccessible::ProcessDOMEvent, aDOMEvent);
   }
 
   return NS_OK;
 }
 
-// nsRootAccessible protected
+// RootAccessible protected
 void
-nsRootAccessible::ProcessDOMEvent(nsIDOMEvent* aDOMEvent)
+RootAccessible::ProcessDOMEvent(nsIDOMEvent* aDOMEvent)
 {
   nsCOMPtr<nsIDOMNSEvent> DOMNSEvent(do_QueryInterface(aDOMEvent));
   nsCOMPtr<nsIDOMEventTarget> DOMEventTarget;
   DOMNSEvent->GetOriginalTarget(getter_AddRefs(DOMEventTarget));
   nsCOMPtr<nsINode> origTargetNode(do_QueryInterface(DOMEventTarget));
 
   nsAutoString eventType;
   aDOMEvent->GetType(eventType);
@@ -529,28 +534,28 @@ nsRootAccessible::ProcessDOMEvent(nsIDOM
 #endif
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessNode
 
 void
-nsRootAccessible::Shutdown()
+RootAccessible::Shutdown()
 {
   // Called manually or by nsAccessNode::LastRelease()
   if (!PresShell())
     return;  // Already shutdown
 
   nsDocAccessibleWrap::Shutdown();
 }
 
 // nsIAccessible method
 Relation
-nsRootAccessible::RelationByType(PRUint32 aType)
+RootAccessible::RelationByType(PRUint32 aType)
 {
   if (!mDocument || aType != nsIAccessibleRelation::RELATION_EMBEDS)
     return nsDocAccessibleWrap::RelationByType(aType);
 
   nsIDOMWindow* rootWindow = mDocument->GetWindow();
   if (rootWindow) {
     nsCOMPtr<nsIDOMWindow> contentWindow;
     rootWindow->GetContent(getter_AddRefs(contentWindow));
@@ -570,17 +575,17 @@ nsRootAccessible::RelationByType(PRUint3
 
   return Relation();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Protected members
 
 void
-nsRootAccessible::HandlePopupShownEvent(nsAccessible* aAccessible)
+RootAccessible::HandlePopupShownEvent(nsAccessible* aAccessible)
 {
   roles::Role role = aAccessible->Role();
 
   if (role == roles::MENUPOPUP) {
     // Don't fire menupopup events for combobox and autocomplete lists.
     nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_START,
                             aAccessible);
     return;
@@ -608,17 +613,17 @@ nsRootAccessible::HandlePopupShownEvent(
         new AccStateChangeEvent(combobox, states::EXPANDED, true);
       if (event)
         nsEventShell::FireEvent(event);
     }
   }
 }
 
 void
-nsRootAccessible::HandlePopupHidingEvent(nsINode* aPopupNode)
+RootAccessible::HandlePopupHidingEvent(nsINode* aPopupNode)
 {
   // Get popup accessible. There are cases when popup element isn't accessible
   // but an underlying widget is and behaves like popup, an example is
   // autocomplete popups.
   nsDocAccessible* document = nsAccUtils::GetDocAccessibleFor(aPopupNode);
   if (!document)
     return;
 
@@ -713,18 +718,18 @@ nsRootAccessible::HandlePopupHidingEvent
     nsRefPtr<AccEvent> event =
       new AccStateChangeEvent(widget, states::EXPANDED, false);
     document->FireDelayedAccessibleEvent(event);
   }
 }
 
 #ifdef MOZ_XUL
 void
-nsRootAccessible::HandleTreeRowCountChangedEvent(nsIDOMEvent* aEvent,
-                                                 nsXULTreeAccessible* aAccessible)
+RootAccessible::HandleTreeRowCountChangedEvent(nsIDOMEvent* aEvent,
+                                               nsXULTreeAccessible* aAccessible)
 {
   nsCOMPtr<nsIDOMDataContainerEvent> dataEvent(do_QueryInterface(aEvent));
   if (!dataEvent)
     return;
 
   nsCOMPtr<nsIVariant> indexVariant;
   dataEvent->GetData(NS_LITERAL_STRING("index"),
                      getter_AddRefs(indexVariant));
@@ -740,18 +745,18 @@ nsRootAccessible::HandleTreeRowCountChan
   PRInt32 index, count;
   indexVariant->GetAsInt32(&index);
   countVariant->GetAsInt32(&count);
 
   aAccessible->InvalidateCache(index, count);
 }
 
 void
-nsRootAccessible::HandleTreeInvalidatedEvent(nsIDOMEvent* aEvent,
-                                             nsXULTreeAccessible* aAccessible)
+RootAccessible::HandleTreeInvalidatedEvent(nsIDOMEvent* aEvent,
+                                           nsXULTreeAccessible* aAccessible)
 {
   nsCOMPtr<nsIDOMDataContainerEvent> dataEvent(do_QueryInterface(aEvent));
   if (!dataEvent)
     return;
 
   PRInt32 startRow = 0, endRow = -1, startCol = 0, endCol = -1;
 
   nsCOMPtr<nsIVariant> startRowVariant;
rename from accessible/src/base/nsRootAccessible.h
rename to accessible/src/generic/RootAccessible.h
--- a/accessible/src/base/nsRootAccessible.h
+++ b/accessible/src/generic/RootAccessible.h
@@ -30,56 +30,57 @@
  * 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 ***** */
 
-#ifndef _nsRootAccessible_H_
-#define _nsRootAccessible_H_
+#ifndef mozilla_a11y_RootAccessible_h__
+#define mozilla_a11y_RootAccessible_h__
 
 #include "nsCaretAccessible.h"
 #include "nsDocAccessibleWrap.h"
 
 
 #include "nsHashtable.h"
 #include "nsCaretAccessible.h"
 #include "nsIDocument.h"
 #include "nsIDOMEventListener.h"
 
 class nsXULTreeAccessible;
 class Relation;
 
-const PRInt32 SCROLL_HASH_START_SIZE = 6;
+namespace mozilla {
+namespace a11y {
 
-class nsRootAccessible : public nsDocAccessibleWrap,
-                         public nsIDOMEventListener
+class RootAccessible : public nsDocAccessibleWrap,
+                       public nsIDOMEventListener
 {
   NS_DECL_ISUPPORTS_INHERITED
 
 public:
-  nsRootAccessible(nsIDocument* aDocument, nsIContent* aRootContent,
-                   nsIPresShell* aPresShell);
-  virtual ~nsRootAccessible();
+  RootAccessible(nsIDocument* aDocument, nsIContent* aRootContent,
+                 nsIPresShell* aPresShell);
+  virtual ~RootAccessible();
 
   // nsIDOMEventListener
   NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
 
   // nsAccessNode
   virtual void Shutdown();
 
   // nsAccessible
   virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
   virtual Relation RelationByType(PRUint32 aType);
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 NativeState();
 
-  // nsRootAccessible
+  // RootAccessible
   nsCaretAccessible* GetCaretAccessible();
 
   /**
    * Notify that the sub document presshell was activated.
    */
   virtual void DocumentActivated(nsDocAccessible* aDocument);
 
 protected:
@@ -112,16 +113,19 @@ protected:
                                     nsXULTreeAccessible* aAccessible);
 
     PRUint32 GetChromeFlags();
 #endif
 
     nsRefPtr<nsCaretAccessible> mCaretAccessible;
 };
 
-inline nsRootAccessible*
+} // namespace a11y
+} // namespace mozilla
+
+inline mozilla::a11y::RootAccessible*
 nsAccessible::AsRoot()
 {
   return mFlags & eRootAccessible ?
-    static_cast<nsRootAccessible*>(this) : nsnull;
+    static_cast<mozilla::a11y::RootAccessible*>(this) : nsnull;
 }
 
 #endif
--- a/accessible/src/html/nsHTMLTableAccessible.cpp
+++ b/accessible/src/html/nsHTMLTableAccessible.cpp
@@ -1292,20 +1292,18 @@ nsHTMLTableAccessible::Description(nsStr
     }
   }
 
 #ifdef SHOW_LAYOUT_HEURISTIC
   if (aDescription.IsEmpty()) {
     bool isProbablyForLayout = IsProbablyLayoutTable();
     aDescription = mLayoutHeuristic;
   }
-#ifdef DEBUG_A11Y
   printf("\nTABLE: %s\n", NS_ConvertUTF16toUTF8(mLayoutHeuristic).get());
 #endif
-#endif
 }
 
 bool
 nsHTMLTableAccessible::HasDescendant(const nsAString& aTagName,
                                      bool aAllowEmpty)
 {
   nsCOMPtr<nsIDOMElement> tableElt(do_QueryInterface(mContent));
   NS_ENSURE_TRUE(tableElt, false);
--- a/accessible/src/jsat/AccessFu.jsm
+++ b/accessible/src/jsat/AccessFu.jsm
@@ -11,47 +11,49 @@ const Cr = Components.results;
 
 var EXPORTED_SYMBOLS = ['AccessFu'];
 
 Cu.import('resource://gre/modules/Services.jsm');
 
 Cu.import('resource://gre/modules/accessibility/Presenters.jsm');
 Cu.import('resource://gre/modules/accessibility/VirtualCursorController.jsm');
 
+const ACCESSFU_DISABLE = 0;
+const ACCESSFU_ENABLE = 1;
+const ACCESSFU_AUTO = 2;
+
 var AccessFu = {
   /**
    * Attach chrome-layer accessibility functionality to the given chrome window.
    * If accessibility is enabled on the platform (currently Android-only), then
    * a special accessibility mode is started (see startup()).
    * @param {ChromeWindow} aWindow Chrome window to attach to.
    * @param {boolean} aForceEnabled Skip platform accessibility check and enable
    *  AccessFu.
    */
   attach: function attach(aWindow) {
+    if (this.chromeWin)
+      // XXX: only supports attaching to one window now.
+      throw new Error('Only one window could be attached to AccessFu');
+
     dump('AccessFu attach!! ' + Services.appinfo.OS + '\n');
     this.chromeWin = aWindow;
     this.presenters = [];
 
-    function checkA11y() {
-      if (Services.appinfo.OS == 'Android') {
-        let msg = Cc['@mozilla.org/android/bridge;1'].
-          getService(Ci.nsIAndroidBridge).handleGeckoMessage(
-            JSON.stringify(
-                { gecko: {
-                    type: 'Accessibility:IsEnabled',
-                    eventType: 1,
-                    text: []
-                  }
-                }));
-        return JSON.parse(msg).enabled;
-      }
-      return false;
+    this.prefsBranch = Cc['@mozilla.org/preferences-service;1']
+      .getService(Ci.nsIPrefService).getBranch('accessibility.');
+    this.prefsBranch.addObserver('accessfu', this, false);
+
+    let accessPref = ACCESSFU_DISABLE;
+    try {
+      accessPref = this.prefsBranch.getIntPref('accessfu');
+    } catch (x) {
     }
 
-    if (checkA11y())
+    if (this.amINeeded(accessPref))
       this.enable();
   },
 
   /**
    * Start the special AccessFu mode, this primarily means controlling the virtual
    * cursor with arrow keys. Currently, on platforms other than Android this needs
    * to be called explicitly.
    */
@@ -89,16 +91,38 @@ var AccessFu = {
     this.chromeWin.removeEventListener('DOMActivate', this);
     this.chromeWin.removeEventListener('resize', this);
     this.chromeWin.removeEventListener('scroll', this);
     this.chromeWin.removeEventListener('TabOpen', this);
     this.chromeWin.removeEventListener('TabSelect', this);
     this.chromeWin.removeEventListener('TabClose', this);
   },
 
+  amINeeded: function(aPref) {
+    switch (aPref) {
+      case ACCESSFU_ENABLE:
+        return true;
+      case ACCESSFU_AUTO:
+        if (Services.appinfo.OS == 'Android') {
+          let msg = Cc['@mozilla.org/android/bridge;1'].
+            getService(Ci.nsIAndroidBridge).handleGeckoMessage(
+              JSON.stringify(
+                { gecko: {
+                    type: 'Accessibility:IsEnabled',
+                    eventType: 1,
+                    text: []
+                  }
+                }));
+          return JSON.parse(msg).enabled;
+        }
+      default:
+        return false;
+    }
+  },
+
   addPresenter: function addPresenter(presenter) {
     this.presenters.push(presenter);
     presenter.attach(this.chromeWin);
   },
 
   handleEvent: function handleEvent(aEvent) {
     switch (aEvent.type) {
       case 'TabSelect':
@@ -145,16 +169,24 @@ var AccessFu = {
       this._pendingDocuments[browserApp.selectedBrowser] = aCallback;
     } else {
       aCallback.apply(this, [docAcc]);
     }
   },
 
   observe: function observe(aSubject, aTopic, aData) {
     switch (aTopic) {
+      case 'nsPref:changed':
+        if (aData == 'accessfu') {
+          if (this.amINeeded(this.prefsBranch.getIntPref('accessfu')))
+            this.enable();
+          else
+            this.disable();
+        }
+        break;
       case 'accessible-event':
         let event;
         try {
           event = aSubject.QueryInterface(Ci.nsIAccessibleEvent);
           this.handleAccEvent(event);
         } catch (ex) {
           dump(ex);
           return;
@@ -199,16 +231,44 @@ var AccessFu = {
           let callback = this._pendingDocuments[node];
           if (callback && aEvent.accessible.childCount) {
             // We have a callback associated with a document.
             callback.apply(this, [aEvent.accessible.getChildAt(0)]);
             delete this._pendingDocuments[node];
           }
           break;
         }
+      case Ci.nsIAccessibleEvent.EVENT_TEXT_INSERTED:
+      case Ci.nsIAccessibleEvent.EVENT_TEXT_REMOVED:
+      {
+        if (aEvent.isFromUserInput) {
+          // XXX support live regions as well.
+          let event = aEvent.QueryInterface(Ci.nsIAccessibleTextChangeEvent);
+          let isInserted = event.isInserted();
+          let textIface = aEvent.accessible.QueryInterface(Ci.nsIAccessibleText);
+
+          let text = '';
+          try {
+            text = textIface.
+              getText(0, Ci.nsIAccessibleText.TEXT_OFFSET_END_OF_TEXT);
+          } catch (x) {
+            // XXX we might have gotten an exception with of a
+            // zero-length text. If we did, ignore it (bug #749810).
+            if (textIface.characterCount)
+              throw x;
+          }
+
+          this.presenters.forEach(
+            function(p) {
+              p.textChanged(isInserted, event.start, event.length, text, event.modifiedText);
+            }
+          );
+        }
+        break;
+      }
       default:
         break;
     }
   },
 
   getNewContext: function getNewContext(aOldObject, aNewObject) {
     let newLineage = [];
     let oldLineage = [];
--- a/accessible/src/jsat/Presenters.jsm
+++ b/accessible/src/jsat/Presenters.jsm
@@ -47,17 +47,17 @@ Presenter.prototype = {
    * @param {nsIAccessible} aObject the object that has been invoked.
    * @param {string} aActionName the name of the action.
    */
   actionInvoked: function actionInvoked(aObject, aActionName) {},
 
   /**
    * Text has changed, either by the user or by the system. TODO.
    */
-  textChanged: function textChanged() {},
+  textChanged: function textChanged(aIsInserted, aStartOffset, aLength, aText, aModifiedText) {},
 
   /**
    * Text selection has changed. TODO.
    */
   textSelectionChanged: function textSelectionChanged() {},
 
   /**
    * Selection has changed. TODO.
@@ -249,16 +249,37 @@ AndroidPresenter.prototype.tabSelected =
   let parent = vcDoc.virtualCursor.position || aObject;
   while ((parent = parent.parent))
     context.push(parent);
   context.reverse();
 
   this.pivotChanged(vcDoc.virtualCursor.position || aObject, context);
 };
 
+AndroidPresenter.prototype.textChanged = function(aIsInserted, aStart, aLength, aText, aModifiedText) {
+  let androidEvent = {
+    type: 'Accessibility:Event',
+    eventType: ANDROID_TYPE_VIEW_TEXT_CHANGED,
+    text: [aText],
+    fromIndex: aStart
+  };
+
+  if (aIsInserted) {
+    androidEvent.addedCount = aLength;
+    androidEvent.beforeText =
+      aText.substring(0, aStart) + aText.substring(aStart + aLength);
+  } else {
+    androidEvent.removedCount = aLength;
+    androidEvent.beforeText =
+      aText.substring(0, aStart) + aModifiedText + aText.substring(aStart);
+  }
+
+  this.sendMessageToJava({gecko: androidEvent});
+};
+
 AndroidPresenter.prototype.sendMessageToJava = function(aMessage) {
   return Cc['@mozilla.org/android/bridge;1'].
     getService(Ci.nsIAndroidBridge).
     handleGeckoMessage(JSON.stringify(aMessage));
 };
 
 /**
  * A dummy Android presenter for desktop testing
--- a/accessible/src/jsat/UtteranceGenerator.jsm
+++ b/accessible/src/jsat/UtteranceGenerator.jsm
@@ -45,17 +45,17 @@ var UtteranceGenerator = {
     let func = this.objectUtteranceFunctions[roleString] ||
       this.objectUtteranceFunctions.defaultFunc;
 
     let flags = this.verbosityRoleMap[roleString] || 0;
 
     if (aForceName)
       flags |= INCLUDE_NAME;
 
-    return func(aAccessible, roleString, flags);
+    return func.apply(this, [aAccessible, roleString, flags]);
   },
 
   genForAction: function(aObject, aActionName) {
     return [gStringBundle.GetStringFromName(this.gActionMap[aActionName])];
   },
 
   verbosityRoleMap: {
     'menubar': INCLUDE_ROLE,
@@ -108,18 +108,17 @@ var UtteranceGenerator = {
     'combobox option': INCLUDE_ROLE,
     'image map': INCLUDE_ROLE,
     'option': INCLUDE_ROLE,
     'listbox': INCLUDE_ROLE},
 
   objectUtteranceFunctions: {
     defaultFunc: function defaultFunc(aAccessible, aRoleStr, aFlags) {
       let name = (aFlags & INCLUDE_NAME) ? (aAccessible.name || '') : '';
-      let desc = (aFlags & INCLUDE_ROLE) ?
-        gStringBundle.GetStringFromName(aRoleStr) : '';
+      let desc = (aFlags & INCLUDE_ROLE) ? this._getLocalizedRole(aRoleStr) : '';
 
       if (!name && !desc)
         return [];
 
       let state = {};
       let extState = {};
       aAccessible.getState(state, extState);
 
@@ -144,19 +143,27 @@ var UtteranceGenerator = {
       aAccessible.groupPosition(level, {}, {});
       let desc = gStringBundle.formatStringFromName('headingLevel',
                                                    [level.value], 1);
       return [desc, name];
     },
 
     listitem: function(aAccessible, aRoleStr, aFlags) {
       let name = (aFlags & INCLUDE_NAME) ? (aAccessible.name || '') : '';
-      let localizedRole = gStringBundle.GetStringFromName(aRoleStr);
+      let localizedRole = this._getLocalizedRole(aRoleStr);
       let itemno = {};
       let itemof = {};
       aAccessible.groupPosition({}, itemof, itemno);
       let desc = gStringBundle.formatStringFromName(
           'objItemOf', [localizedRole, itemno.value, itemof.value], 3);
 
       return [desc, name];
     }
+  },
+
+  _getLocalizedRole: function _getLocalizedRole(aRoleStr) {
+    try {
+      return gStringBundle.GetStringFromName(aRoleStr.replace(' ', ''));
+    } catch (x) {
+      return '';
+    }
   }
 };
--- a/accessible/src/jsat/VirtualCursorController.jsm
+++ b/accessible/src/jsat/VirtualCursorController.jsm
@@ -117,27 +117,35 @@ var VirtualCursorController = {
       aRules.value = [];
       return 0;
     },
 
     preFilter: Ci.nsIAccessibleTraversalRule.PREFILTER_DEFUNCT |
       Ci.nsIAccessibleTraversalRule.PREFILTER_INVISIBLE,
 
     match: function(aAccessible) {
-      let rv = Ci.nsIAccessibleTraversalRule.FILTER_IGNORE;
-      if (aAccessible.childCount == 0) {
-        // TODO: Find a better solution for ROLE_STATICTEXT.
-        // Right now it helps filter list bullets, but it is also used
-        // in CSS generated content.
-        let ignoreRoles = [Ci.nsIAccessibleRole.ROLE_WHITESPACE,
-                           Ci.nsIAccessibleRole.ROLE_STATICTEXT];
-        let state = {};
-        aAccessible.getState(state, {});
-        if ((state.value & Ci.nsIAccessibleStates.STATE_FOCUSABLE) ||
-          (aAccessible.name && ignoreRoles.indexOf(aAccessible.role) < 0))
-          rv = Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
-        }
-      return rv;
+      if (aAccessible.childCount)
+        // Non-leafs do not interest us.
+        return Ci.nsIAccessibleTraversalRule.FILTER_IGNORE;
+
+      // XXX: Find a better solution for ROLE_STATICTEXT.
+      // It allows to filter list bullets but the same time it
+      // filters CSS generated content too as unwanted side effect.
+      let ignoreRoles = [Ci.nsIAccessibleRole.ROLE_WHITESPACE,
+                         Ci.nsIAccessibleRole.ROLE_STATICTEXT];
+
+      if (ignoreRoles.indexOf(aAccessible.role) < 0) {
+        let name = aAccessible.name;
+        if (name && name.trim())
+          return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
+      }
+
+      let state = {};
+      aAccessible.getState(state, {});
+      if (state.value & Ci.nsIAccessibleStates.STATE_FOCUSABLE)
+        return Ci.nsIAccessibleTraversalRule.FILTER_MATCH;
+
+      return Ci.nsIAccessibleTraversalRule.FILTER_IGNORE;
     },
 
     QueryInterface: XPCOMUtils.generateQI([Ci.nsIAccessibleTraversalRule])
   }
 };
--- a/accessible/src/mac/Makefile.in
+++ b/accessible/src/mac/Makefile.in
@@ -45,34 +45,33 @@ MODULE = accessibility
 LIBRARY_NAME = accessibility_toolkit_s
 EXPORT_LIBRARY = ..
 LIBXUL_LIBRARY = 1
 
   
   
 CMMSRCS = nsAccessNodeWrap.mm \
           nsDocAccessibleWrap.mm \
-          nsRootAccessibleWrap.mm \
           nsAccessibleWrap.mm \
           mozAccessible.mm \
           mozDocAccessible.mm \
           mozActionElements.mm \
           mozTextAccessible.mm \
           mozHTMLAccessible.mm \
           MacUtils.mm \
+          RootAccessibleWrap.mm \
           $(NULL)
 
 
 EXPORTS = \
   ARIAGridAccessibleWrap.h \
   nsAccessNodeWrap.h \
   nsTextAccessibleWrap.h \
   nsAccessibleWrap.h \
   nsDocAccessibleWrap.h \
-  nsRootAccessibleWrap.h \
   nsXULMenuAccessibleWrap.h \
   nsXULListboxAccessibleWrap.h \
   nsXULTreeGridAccessibleWrap.h \
   nsHyperTextAccessibleWrap.h \
   nsHTMLImageAccessibleWrap.h \
   nsHTMLTableAccessibleWrap.h \
   mozDocAccessible.h \
   mozAccessible.h \
rename from accessible/src/mac/nsRootAccessibleWrap.h
rename to accessible/src/mac/RootAccessibleWrap.h
--- a/accessible/src/mac/nsRootAccessibleWrap.h
+++ b/accessible/src/mac/RootAccessibleWrap.h
@@ -35,31 +35,36 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /* For documentation of the accessibility architecture, 
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
-#ifndef _nsRootAccessibleWrap_H_
-#define _nsRootAccessibleWrap_H_
+#ifndef mozilla_a11y_RootAccessibleWrap_h__
+#define mozilla_a11y_RootAccessibleWrap_h__
 
-#include "nsRootAccessible.h"
+#include "RootAccessible.h"
+
+namespace mozilla {
+namespace a11y {
 
 struct objc_class;
 
-class nsRootAccessibleWrap : public nsRootAccessible
+class RootAccessibleWrap : public RootAccessible
 {
 public:
-  nsRootAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
-                       nsIPresShell* aPresShell);
-  virtual ~nsRootAccessibleWrap();
+  RootAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
+                     nsIPresShell* aPresShell);
+  virtual ~RootAccessibleWrap();
 
     Class GetNativeType ();
     
     // let's our native accessible get in touch with the
     // native cocoa view that is our accessible parent.
     void GetNativeWidget (void **aOutView);
 };
 
+} // namespace a11y
+} // namespace mozilla
 
 #endif
rename from accessible/src/mac/nsRootAccessibleWrap.mm
rename to accessible/src/mac/RootAccessibleWrap.mm
--- a/accessible/src/mac/nsRootAccessibleWrap.mm
+++ b/accessible/src/mac/RootAccessibleWrap.mm
@@ -31,48 +31,50 @@
  * 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 "nsRootAccessibleWrap.h"
+#include "RootAccessibleWrap.h"
 
 #include "mozDocAccessible.h"
 
 #include "nsCOMPtr.h"
 #include "nsObjCExceptions.h"
 #include "nsIWidget.h"
 #include "nsIViewManager.h"
 
-nsRootAccessibleWrap::
-  nsRootAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
-                       nsIPresShell* aPresShell) :
-  nsRootAccessible(aDocument, aRootContent, aPresShell)
+using namespace mozilla::a11y;
+
+RootAccessibleWrap::
+  RootAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
+                     nsIPresShell* aPresShell) :
+  RootAccessible(aDocument, aRootContent, aPresShell)
 {
 }
 
-nsRootAccessibleWrap::~nsRootAccessibleWrap()
+RootAccessibleWrap::~RootAccessibleWrap()
 {
 }
 
 Class
-nsRootAccessibleWrap::GetNativeType ()
+RootAccessibleWrap::GetNativeType()
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
   return [mozRootAccessible class];
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 void
-nsRootAccessibleWrap::GetNativeWidget (void **aOutView)
+RootAccessibleWrap::GetNativeWidget(void** aOutView)
 {
   nsIFrame *frame = GetFrame();
   if (frame) {
     nsIView *view = frame->GetViewExternal();
     if (view) {
       nsIWidget *widget = view->GetWidget();
       if (widget) {
         *aOutView = (void**)widget->GetNativeData (NS_NATIVE_WIDGET);
--- a/accessible/src/mac/mozAccessible.mm
+++ b/accessible/src/mac/mozAccessible.mm
@@ -40,19 +40,19 @@
 
 #import "MacUtils.h"
 #import "mozView.h"
 
 #include "Accessible-inl.h"
 #include "nsIAccessibleRelation.h"
 #include "nsIAccessibleText.h"
 #include "nsIAccessibleEditableText.h"
-#include "nsRootAccessible.h"
 #include "Relation.h"
 #include "Role.h"
+#include "RootAccessible.h"
 
 #include "mozilla/Services.h"
 #include "nsRect.h"
 #include "nsCocoaUtils.h"
 #include "nsCoord.h"
 #include "nsObjCExceptions.h"
 
 using namespace mozilla;
@@ -348,17 +348,17 @@ GetNativeFromGeckoAccessible(nsIAccessib
       return GetClosestInterestingAccessible(nativeParent);
   }
   
   // GetUnignoredParent() returns null when there is no unignored accessible all the way up to
   // the root accessible. so we'll have to return whatever native accessible is above our root accessible 
   // (which might be the owning NSWindow in the application, for example).
   //
   // get the native root accessible, and tell it to return its first parent unignored accessible.
-  nsRootAccessible* root = mGeckoAccessible->RootAccessible();
+  RootAccessible* root = mGeckoAccessible->RootAccessible();
   id nativeParent = GetNativeFromGeckoAccessible(static_cast<nsIAccessible*>(root));
   NSAssert1 (nativeParent, @"!!! we can't find a parent for %@", self);
   
   return GetClosestInterestingAccessible(nativeParent);
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
--- a/accessible/src/mac/mozDocAccessible.h
+++ b/accessible/src/mac/mozDocAccessible.h
@@ -39,17 +39,17 @@
 #import <Cocoa/Cocoa.h>
 #import "mozAccessible.h"
 
 // our protocol that we implement (so cocoa widgets can talk to us)
 #import "mozAccessibleProtocol.h"
 
 /* 
   The root accessible. There is one per window.
-  Created by the nsRootAccessibleWrap.
+  Created by the RootAccessibleWrap.
 */
 @interface mozRootAccessible : mozAccessible
 {
   // the mozView that we're representing.
   // all outside communication goes through the mozView.
   // in reality, it's just piping all calls to us, and we're
   // doing its dirty work!
   //
--- a/accessible/src/mac/mozDocAccessible.mm
+++ b/accessible/src/mac/mozDocAccessible.mm
@@ -31,26 +31,30 @@
  * 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 "nsRootAccessibleWrap.h"
 #include "nsObjCExceptions.h"
+#include "RootAccessibleWrap.h"
 
 #import "mozDocAccessible.h"
 
 #import "mozView.h"
 
-static id <mozAccessible, mozView> getNativeViewFromRootAccessible (nsAccessible *accessible)
+using namespace mozilla::a11y;
+
+static id <mozAccessible, mozView> 
+getNativeViewFromRootAccessible(nsAccessible* aAccessible)
 {
-  nsRootAccessibleWrap *root = static_cast<nsRootAccessibleWrap*>(accessible);
+  RootAccessibleWrap* root =
+    static_cast<RootAccessibleWrap*>(aAccessible->AsRoot());
   id <mozAccessible, mozView> nativeView = nil;
   root->GetNativeWidget ((void**)&nativeView);
   return nativeView;
 }
 
 #pragma mark -
 
 @implementation mozRootAccessible
--- a/accessible/src/msaa/Makefile.in
+++ b/accessible/src/msaa/Makefile.in
@@ -50,17 +50,16 @@ LIBXUL_LIBRARY = 1
 CPPSRCS = \
   ApplicationAccessibleWrap.cpp \
   ARIAGridAccessibleWrap.cpp \
   nsAccessNodeWrap.cpp \
   nsAccessibleWrap.cpp \
   nsTextAccessibleWrap.cpp \
   nsDocAccessibleWrap.cpp \
   nsHTMLWin32ObjectAccessible.cpp \
-  nsRootAccessibleWrap.cpp \
   nsXULMenuAccessibleWrap.cpp \
   nsXULListboxAccessibleWrap.cpp \
   nsXULTreeGridAccessibleWrap.cpp \
   nsHyperTextAccessibleWrap.cpp \
   nsHTMLImageAccessibleWrap.cpp \
   nsHTMLTableAccessibleWrap.cpp \
   nsWinUtils.cpp \
   ia2AccessibleAction.cpp \
@@ -70,25 +69,25 @@ CPPSRCS = \
   CAccessibleEditableText.cpp \
   CAccessibleHyperlink.cpp \
   ia2AccessibleHypertext.cpp \
   ia2AccessibleRelation.cpp \
   CAccessibleTable.cpp \
   CAccessibleTableCell.cpp \
   CAccessibleValue.cpp \
   Compatibility.cpp \
+  RootAccessibleWrap.cpp \
   $(NULL)
 
 EXPORTS = \
   ARIAGridAccessibleWrap.h \
   nsAccessNodeWrap.h \
   nsAccessibleWrap.h \
   nsTextAccessibleWrap.h \
   nsDocAccessibleWrap.h \
-  nsRootAccessibleWrap.h \
   nsHTMLWin32ObjectAccessible.h \
   nsXULMenuAccessibleWrap.h \
   nsXULListboxAccessibleWrap.h \
   nsXULTreeGridAccessibleWrap.h \
   nsHyperTextAccessibleWrap.h \
   nsHTMLImageAccessibleWrap.h \
   nsHTMLTableAccessibleWrap.h \
   ia2AccessibleAction.h \
rename from accessible/src/msaa/nsRootAccessibleWrap.cpp
rename to accessible/src/msaa/RootAccessibleWrap.cpp
--- a/accessible/src/msaa/nsRootAccessibleWrap.cpp
+++ b/accessible/src/msaa/RootAccessibleWrap.cpp
@@ -31,45 +31,45 @@
  * 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 "nsRootAccessibleWrap.h"
+#include "RootAccessibleWrap.h"
 
 #include "Compatibility.h"
 #include "nsWinUtils.h"
 
 #include "nsIDOMEventTarget.h"
 #include "nsEventListenerManager.h"
 
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Constructor/desctructor
 
-nsRootAccessibleWrap::
-  nsRootAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
-                       nsIPresShell* aPresShell) :
-  nsRootAccessible(aDocument, aRootContent, aPresShell)
+RootAccessibleWrap::
+  RootAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
+                     nsIPresShell* aPresShell) :
+  RootAccessible(aDocument, aRootContent, aPresShell)
 {
 }
 
-nsRootAccessibleWrap::~nsRootAccessibleWrap()
+RootAccessibleWrap::~RootAccessibleWrap()
 {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsRootAccessible
+// RootAccessible
 
 void
-nsRootAccessibleWrap::DocumentActivated(nsDocAccessible* aDocument)
+RootAccessibleWrap::DocumentActivated(nsDocAccessible* aDocument)
 {
   if (Compatibility::IsDolphin() &&
       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)
rename from accessible/src/msaa/nsRootAccessibleWrap.h
rename to accessible/src/msaa/RootAccessibleWrap.h
--- a/accessible/src/msaa/nsRootAccessibleWrap.h
+++ b/accessible/src/msaa/RootAccessibleWrap.h
@@ -32,25 +32,31 @@
  * 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 ***** */
 
-#ifndef _nsRootAccessibleWrap_H_
-#define _nsRootAccessibleWrap_H_
+#ifndef mozilla_a11y_RootAccessibleWrap_h__
+#define mozilla_a11y_RootAccessibleWrap_h__
+
+#include "RootAccessible.h"
 
-#include "nsRootAccessible.h"
+namespace mozilla {
+namespace a11y {
 
-class nsRootAccessibleWrap : public nsRootAccessible
+class RootAccessibleWrap : public RootAccessible
 {
 public:
-  nsRootAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
-                       nsIPresShell* aPresShell);
-  virtual ~nsRootAccessibleWrap();
+  RootAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
+                     nsIPresShell* aPresShell);
+  virtual ~RootAccessibleWrap();
 
-  // nsRootAccessible
+  // RootAccessible
   virtual void DocumentActivated(nsDocAccessible* aDocument);
 };
 
+} // namespace a11y
+} // namespace mozilla
+
 #endif
--- a/accessible/src/msaa/nsAccessNodeWrap.cpp
+++ b/accessible/src/msaa/nsAccessNodeWrap.cpp
@@ -40,18 +40,18 @@
 
 #include "AccessibleApplication.h"
 #include "ApplicationAccessibleWrap.h"
 #include "ISimpleDOMNode_i.c"
 
 #include "Compatibility.h"
 #include "nsAccessibilityService.h"
 #include "nsCoreUtils.h"
-#include "nsRootAccessible.h"
 #include "nsWinUtils.h"
+#include "RootAccessible.h"
 #include "Statistics.h"
 
 #include "nsAttrName.h"
 #include "nsIDocument.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIFrame.h"
 #include "nsINameSpaceManager.h"
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -49,51 +49,38 @@
 #include "ia2AccessibleRelation.h"
 
 #include "nsIAccessibleEvent.h"
 #include "nsIAccessibleRelation.h"
 
 #include "Accessible2_i.c"
 #include "AccessibleRole.h"
 #include "AccessibleStates.h"
+#include "RootAccessible.h"
 
 #include "nsIMutableArray.h"
 #include "nsIDOMDocument.h"
 #include "nsIFrame.h"
 #include "nsIScrollableFrame.h"
 #include "nsINameSpaceManager.h"
 #include "nsINodeInfo.h"
-#include "nsRootAccessible.h"
 #include "nsIServiceManager.h"
 #include "nsTextFormatter.h"
 #include "nsIView.h"
 #include "nsIViewManager.h"
 #include "nsEventMap.h"
 #include "nsArrayUtils.h"
 
 #include "OLEACC.H"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 const PRUint32 USE_ROLE_STRING = 0;
 
-#ifndef ROLE_SYSTEM_SPLITBUTTON
-const PRUint32 ROLE_SYSTEM_SPLITBUTTON  = 0x3e; // Not defined in all oleacc.h versions
-#endif
-
-#ifndef ROLE_SYSTEM_IPADDRESS
-const PRUint32 ROLE_SYSTEM_IPADDRESS = 0x3f; // Not defined in all oleacc.h versions
-#endif
-
-#ifndef ROLE_SYSTEM_OUTLINEBUTTON
-const PRUint32 ROLE_SYSTEM_OUTLINEBUTTON = 0x40; // Not defined in all oleacc.h versions
-#endif
-
-
 /* For documentation of the accessibility architecture,
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
 //#define DEBUG_LEAKS
 
 #ifdef DEBUG_LEAKS
 static gAccessibles = 0;
@@ -1888,17 +1875,17 @@ nsAccessibleWrap::GetXPAccessibleFor(con
 }
 
 void nsAccessibleWrap::UpdateSystemCaret()
 {
   // Move the system caret so that Windows Tablet Edition and tradional ATs with 
   // off-screen model can follow the caret
   ::DestroyCaret();
 
-  nsRootAccessible* rootAccessible = RootAccessible();
+  a11y::RootAccessible* rootAccessible = RootAccessible();
   if (!rootAccessible) {
     return;
   }
 
   nsRefPtr<nsCaretAccessible> caretAccessible = rootAccessible->GetCaretAccessible();
   if (!caretAccessible) {
     return;
   }
--- a/accessible/src/msaa/nsDocAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsDocAccessibleWrap.cpp
@@ -37,31 +37,32 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/dom/TabChild.h"
 
 #include "Compatibility.h"
 #include "nsDocAccessibleWrap.h"
 #include "ISimpleDOMDocument_i.c"
 #include "nsIAccessibilityService.h"
-#include "nsRootAccessible.h"
 #include "nsWinUtils.h"
 #include "Role.h"
+#include "RootAccessible.h"
 #include "Statistics.h"
 
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeNode.h"
 #include "nsIFrame.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsISelectionController.h"
 #include "nsIServiceManager.h"
 #include "nsIURI.h"
 #include "nsIViewManager.h"
 #include "nsIWebNavigation.h"
 
+using namespace mozilla;
 using namespace mozilla::a11y;
 
 /* For documentation of the accessibility architecture, 
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsDocAccessibleWrap
@@ -275,17 +276,17 @@ nsDocAccessibleWrap::DoInitialUpdate()
   nsDocAccessible::DoInitialUpdate();
 
   if (nsWinUtils::IsWindowEmulationStarted()) {
     // Create window for tab document.
     if (nsCoreUtils::IsTabDocument(mDocument)) {
       mozilla::dom::TabChild* tabChild =
         mozilla::dom::GetTabChildFrom(mDocument->GetShell());
 
-      nsRootAccessible* rootDocument = RootAccessible();
+      a11y::RootAccessible* rootDocument = RootAccessible();
 
       mozilla::WindowsHandle nativeData = nsnull;
       if (tabChild)
         tabChild->SendGetWidgetNativeData(&nativeData);
       else
         nativeData = reinterpret_cast<mozilla::WindowsHandle>(
           rootDocument->GetNativeWindow());
 
--- a/accessible/src/msaa/nsWinUtils.cpp
+++ b/accessible/src/msaa/nsWinUtils.cpp
@@ -36,18 +36,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 ***** */
 
 #include "nsWinUtils.h"
 
 #include "Compatibility.h"
-#include "nsIWinAccessNode.h"
-#include "nsRootAccessible.h"
+#include "nsDocAccessible.h"
+#include "nsCoreUtils.h"
 
 #include "mozilla/Preferences.h"
 #include "nsArrayUtils.h"
 #include "nsIDocShellTreeItem.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
--- a/accessible/src/other/Makefile.in
+++ b/accessible/src/other/Makefile.in
@@ -45,26 +45,24 @@ MODULE = accessibility
 LIBRARY_NAME = accessibility_toolkit_s
 EXPORT_LIBRARY = ..
 LIBXUL_LIBRARY = 1
 
 
 CPPSRCS = \
   nsAccessNodeWrap.cpp \
   nsAccessibleWrap.cpp \
-  nsRootAccessibleWrap.cpp \
   $(NULL)
 
 EXPORTS = \
   ARIAGridAccessibleWrap.h \
   nsAccessNodeWrap.h \
   nsTextAccessibleWrap.h \
   nsAccessibleWrap.h \
   nsDocAccessibleWrap.h \
-  nsRootAccessibleWrap.h \
   nsXULMenuAccessibleWrap.h \
   nsXULListboxAccessibleWrap.h \
   nsXULTreeGridAccessibleWrap.h \
   nsHyperTextAccessibleWrap.h \
   nsHTMLImageAccessibleWrap.h \
   nsHTMLTableAccessibleWrap.h \
   $(NULL)
 
rename from accessible/src/other/nsRootAccessibleWrap.h
rename to accessible/src/other/RootAccessibleWrap.h
--- a/accessible/src/other/nsRootAccessibleWrap.h
+++ b/accessible/src/other/RootAccessibleWrap.h
@@ -35,23 +35,22 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /* For documentation of the accessibility architecture, 
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
-#ifndef _nsRootAccessibleWrap_H_
-#define _nsRootAccessibleWrap_H_
+#ifndef mozilla_a11y_RootAccessibleWrap_h__
+#define mozilla_a11y_RootAccessibleWrap_h__
 
-#include "nsRootAccessible.h"
+#include "RootAccessible.h"
 
-class nsRootAccessibleWrap: public nsRootAccessible
-{
-public:
-  nsRootAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
-                       nsIPresShell* aPresShell);
-  virtual ~nsRootAccessibleWrap();
-};
+namespace mozilla {
+namespace a11y {
 
+typedef RootAccessible RootAccessibleWrap;
+
+} // namespace a11y
+} // namespace mozilla
 
 #endif
deleted file mode 100644
--- a/accessible/src/other/nsRootAccessibleWrap.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** 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) 2003
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Original Author: Aaron Leventhal (aaronl@netscape.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 ***** */
-
-#include "nsCOMPtr.h"
-#include "nsRootAccessibleWrap.h"
-#include "nsIServiceManager.h"
-#include "nsIAccessibilityService.h"
-
-////////////////////////////////////////////////////////////////////////////////
-// nsRootAccessibleWrap
-////////////////////////////////////////////////////////////////////////////////
-
-nsRootAccessibleWrap::
-  nsRootAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
-                       nsIPresShell* aPresShell) :
-  nsRootAccessible(aDocument, aRootContent, aPresShell)
-{
-}
-
-nsRootAccessibleWrap::~nsRootAccessibleWrap()
-{
-}
-
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -196,20 +196,24 @@ clean clobber repackage::
 	$(RM) -r $(dist_dest)
 
 ifdef LIBXUL_SDK
 APPFILES = Resources
 else
 APPFILES = MacOS
 endif
 
-libs repackage:: $(PROGRAM)
-	$(MKDIR) -p $(dist_dest)/Contents/MacOS
+libs-preqs = \
+  $(call mkdir_deps,$(dist_dest)/Contents/MacOS) \
+  $(call mkdir_deps,$(dist_dest)/Contents/Resources/$(AB).lproj) \
+  $(NULL)
+
+.PHONY: repackage
+libs repackage:: $(PROGRAM) $(libs-preqs)
 	rsync -a --exclude "*.in" $(srcdir)/macbuild/Contents $(dist_dest) --exclude English.lproj
-	$(MKDIR) -p $(dist_dest)/Contents/Resources/$(AB).lproj
 	rsync -a --exclude "*.in" $(srcdir)/macbuild/Contents/Resources/English.lproj/ $(dist_dest)/Contents/Resources/$(AB).lproj
 	sed -e "s/%APP_VERSION%/$(MOZ_APP_VERSION)/" -e "s/%MAC_APP_NAME%/$(MAC_APP_NAME)/" -e "s/%LOWER_MAC_APP_NAME%/$(LOWER_MAC_APP_NAME)/" $(srcdir)/macbuild/Contents/Info.plist.in > $(dist_dest)/Contents/Info.plist
 	sed -e "s/%MAC_APP_NAME%/$(MAC_APP_NAME)/" $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | iconv -f UTF-8 -t UTF-16 > $(dist_dest)/Contents/Resources/$(AB).lproj/InfoPlist.strings
 	rsync -a $(DIST)/bin/ $(dist_dest)/Contents/$(APPFILES)
 ifdef LIBXUL_SDK
 	cp $(LIBXUL_DIST)/bin/$(XR_STUB_NAME) $(dist_dest)/Contents/MacOS/firefox
 else
 	$(RM) $(dist_dest)/Contents/MacOS/$(PROGRAM)
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1053,19 +1053,24 @@ pref("devtools.inspector.sidebarOpen", f
 pref("devtools.inspector.activeSidebar", "ruleview");
 
 // Enable the Layout View
 pref("devtools.layoutview.enabled", false);
 pref("devtools.layoutview.open", false);
 
 // Enable the Debugger
 pref("devtools.debugger.enabled", false);
+pref("devtools.debugger.remote-enabled", false);
+pref("devtools.debugger.remote-host", "localhost");
+pref("devtools.debugger.remote-port", 6000);
 
 // The default Debugger UI height
 pref("devtools.debugger.ui.height", 250);
+pref("devtools.debugger.ui.remote-win.width", 900);
+pref("devtools.debugger.ui.remote-win.height", 400);
 
 // Enable the style inspector
 pref("devtools.styleinspector.enabled", true);
 
 // Enable the Tilt inspector
 pref("devtools.tilt.enabled", true);
 pref("devtools.tilt.intro_transition", true);
 pref("devtools.tilt.outro_transition", true);
index c6907b2006fa30d7aec833e3cff99706014babac..79fc95d49ff1c848c71a2686885ecdf758a9a32d
GIT binary patch
literal 961
zc$@*j13vtTP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F8000AsNkl<Zc-qBR
zNl#N@6crb49HK#u8yC9rM`$7mijfkaprS2SELcjF7Vx#jGWE5EwscgXWmIOxg___-
zFit^46pTh)p`uF@O^n0@mFqo?MR8>xr7ljm+<VS>r{ClI%C~}u{wpL4cgqg%*q2-I
zgfWRap#f4dj%+%3T>nmQaT0(Uy@UnGQI%X5L_fJhy%C^BFChWaa#S*%$xg23ZVGl@
z0U|Yem@Q`jEd9!St?;VO+e(3s!G!>*(ZdX!WebpgP@PrE@4PYGN8Z)}ay50$Ih(rY
zP@{(#ILj75r4`2NJYn*+4Up(-oqI4bWxaL(p;Pp?eMb*7aF!*&Ub$*piODwaZtkJ_
za~H`M>bk-Gjf^dg=R0rnN)Tq?Fn4?01LUboYt8l`d0YCa#vS@L`RqknbaroSB9}k?
zypLZ6IN-)TfZAYrW(&0QyYDBfx8;*cXBtR9q#l;#6%HRStsJy^!e1~0hq+JV8emU$
z{u-T0{DJM}Y3YkRL=b&ssB)5_+7+qo!H!5caI{A8J8M?QCBUwI2a>Xt+HiFFfyPiT
z?||+_@Pzvo<|bQ!pn-Nt0d}V4CZ)+$!QzTKviaL#{!aiG8ff7mIlx}|QGa1sHPtkR
z_{i<S^8XXSg$7!9ND7derSz!v7OHkP<Gu1h(;E|@ffgR{iaCHnQ$f|PCY*Ns&U+*Q
zT6n-K<^Ux|k(}o*^5N3GB)|h+F$XwRS&zT&xBy-f0ywaQaRIzy4sg<J$MVGm@QOKr
z&Say8a~Bp+f3}nCfp#3jywBUn5$r$@K#d+|;Gnli%U%)!7)5G;5gx)15ZT<~2z(g2
zc_+v}XU^CIvld4%0@U1liy1iJLKD@)OVTcgemWSMMc>EAPoEojwv{1gsQ!W+GjPC#
zCb~+Jc7ax~!XUD&LY?RH=%Y!2`|B`E%~b5?|Nq=kF4qC{P=hlzF(p6)Ej-{AbAW=A
zW-{CSR95Ajy*oNy#l7{>nOs?XIa{fD`TKXxG<v83aG`+~9`KU#U2x(Tjxmz|oE4Q;
zjwm$cvnjH?wJ8~S8<d*zuSNRGk-zlG&_;dYdM~K3IQk0tjL%i+t}=#-3{`|)!Y(Gg
zgVz+rr)%d=@%{$5rnat21&O>HCR^;jaii5sz!{r&f_s}2dO4kbGm|0Ix?TaVXWnNf
j`gRPgV#om0Qhj~`RGd2H&5smU00000NkvXXu0mjf*O16)
index 01d340aaa9095a54d19071516cf9e0ca75b1f72e..3467cf4d4701c6623125a8ecf80a833c6a0afca3
GIT binary patch
literal 4025
zc$@*b4@U5bP)<h;3K|Lk000e1NJLTq004jh004jp0{{R3^x%>C0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUyIZ#YgMF0Q*ARr($H8n{|Nm*H0XJ==1
zb#;V<gprYvo}Qkns;aiOw!y){&CSi(+1cac<L>V6`1tt$|Nm_HVu%0$026dlPE!a7
z2nYxW2nYxW2nYxW2nYxW2yC4}O#lE6_en%SRCwCOTgi6YJhLpI=WYxX-~VCnBD`Ph
z#Fi;#@$YkTWTH`B6Of&c>6Jt~F!WI?ya~>PBv;n<&OS#pUd{$+3_fF$N7N}NOrY7u
z3^5CYQd+mhnbBhDY5<ZBlo|;zErUmO;iVGdV}P6lIFh7|0Uq7TP9S@DsR;Gaf?Rh{
z9GjJ8DOzjJ$Y{`Z^rJ;?Gv^T!W9szH3JMC~r2Wv9BO~3^$V#XwMX)l;hbf?#rE(@k
zOgJ3sR#c$uB*-ZU2$OmjK{H!i+J^@sgOF;lp`;x=L--WutyO}`;1ji5O(_pG&*?RI
z!}DCJDU@(V)1{9p>g`b36|r#~(kW^5Sxm!LCD7s3oAp{#vs9*<pBAWaX}q)f0U?LF
z^3;d-mTK6Nqw)v~?+-a~*6?~1X%emQ!CR3%$%PYQqg6jmX=)Y`;!%{-mNQ8qj2kiX
zfi20&Y=pC0#W;sMaU<5uL=v%Nc)F=oSb=<QH?`q1wx1rDF?X!70=dz4+SHI3&RnMv
z8d^3Q!z6PCW5L{OEGJGmBm*O=8Q95%=%kzx4(_Xn_92r%cDCs{$8p$<LL;dGwHTGo
z8X=;HVXOi3V%2E2b)2&hE=8>%4)hL|=wP*Q5tgBe>8JaImoy)t<coQoJ-iMX95H0a
z5in2Eq?M9W4jD6AO0uYPa4d-D2H>c><KDT<Jfnt?_2J^J9QJhF=QZv!O!51=wd=aA
z69cJTjj&cideu%C%aINm&BJ{a0!lSaT1NQDz;11pMd!)Iv^_@JgUe&=35*rtnnrC@
zQbUs<RPQYj6_ZAJx}uQ75D1sXAP9UB1X!J?A8n`vYMc_rOO%z;CJUKLHP7b7dw?@l
zRFrnvBziz|s@P~f4lZ_|>||lG;F+DnOk$kIbn0y4Lm=jIxIz@UXtq%fa>|NC7vbIf
zSmzv`CLShXag2-y;@A9#Z_`7AMx4$9B|2t_NgL4`?+OTKYuaUsx<rGs*j{rWfq>Yl
z&IdaZ*prOfShFocqtmUSkt_~P!?G%o+AyCA(K_;^`}akSbA*dmQ$iDJ4ZKm`U2qJc
z*qpg%;8+f+BvmEpIV@bca-93q1wXC}-jTJw2N=EpW{?P2&_p6xoK2fM*LDiG$==#S
zLVKTf2$5n>#p>>gDZ^7Jf(BNPlo=7iYc>TclZjEYFf84<84+{R5egL*$ykT%!32ls
zTuMC(QYqS_9+U{7khX=6sR6i-urU|OkTTEJS5NaOHG>ywmU)b$mZh>aLJ31xc0U$E
zx~#PX&DA=Phs+VaQhXR5M5d5Is?%nXI$GbMjGZt!B7_KwJd6j~ris0bR>FAbS^<!^
zb1@iUn`v&@v)TiYt%~&+nS$U*JS<_7e8jSIc;5!VNj4%QSUcygm5nyrtl4sKrdhAy
zjSxJht`?%KKFUuWtJdTJvaQKe-9sAcP!@<cjHuM9rG1c6W^WE(l9m!qiPd5$+}#Q4
zq1m|_gn4ksxz&nppo|#<gLhOJb|eXkS>PHOa;O!T96d)MSf<$+v^OMH!Fmg<Rs(~2
zK;%I}gi}^{W(z~wX)QuPsZ|;UZWKO;QW7#&_>V&}&Sld&gSTWGB3!3yv^Xqu1>}vv
z`}lv}9lUuBp88nx8hnK)<~u9!0}Hyn0>`xi36S|~1*`3W{XQ8I63B~WNHvKveDH2U
zODFO<<+GBQ5woPJu_-j9hei%CGLFX=lus|p7x0t5qMUY7&O{2@VizAAP<4dA%JG^s
zCUNP!z<~3Ni4ZjJHe<|oNJzHg%91(RMx@pp<1r1#Oo(}#1ATOYdoB=#NlLfg^6@j@
zK{u@!blMa}kV(-#6EcbgsU6(hT`A9SS@7LXmtN^%9SFn?8vX2>{>uQnFaRCRSM0;)
zI>!=I1)YFr9|JAP(HabK5@0>ckk(T|v7!V8Z(%7!Oo*JNV#ja>K@QCJP&aZLV*PO}
zp8;J7YU{+&eFISg)H6oZ^Z-g;TQ3wFG_)n369lskOo2u<ER7mN;Z22wd(70Xa+bT<
zG_!06<m1JBgB#zSm5;#S7cdY+ARov@S&&s`h8;Zu(3}FDHjf$I5$X+bv{JB)$Z5>C
z)XN{_W?tkbNDgG~)~zE1!$YHZ)QO@z#9N?c=3_i6QN_YI+r+t1Q6TbAe!|wcAfvlG
zSm3!ft%5VqT+Db4@eb@aX!W{i^)!69@aS52*;~k;3zx2iOI8DZlYD;n=R6~ya*<C3
zr+*;7dXe8f8w20MMf(jGLf^ubz|}$0W3scNrO}X>NcHd`G%`V-;mR+#Y7mEiB1?La
zr7{TJB5U4DAW(-WjtE$#rnu+NWQ{TzDZxG<?>aS|RyCEEoSOXQ)NB`a(2p$s`9=FA
zlWy7sbg76rcLTi(0E)8N=p_KS)Xj0J8@LYGt88LjY~r$Zo~_;ETDy77;a{x%+!@H1
zJ+9B9zuV|0#gvgWwMPx<y3a&|4GqTQJTp3_gk+}}5f6l9z_E@A16rR1)&S*02u@_9
zo9LX{kHGUue}_^Z7p2ysK)fac{zAnYGT<*%To)?t2EhJfcU6h*0iBP?!~2}pxvk<n
z8)nb=a`WCc6hE-bcCpLZqk+B{tXF9AJACrE2D|D3RI|s3J_~4vQ=yJoF+zD-jmc>`
zKnfA>&0NRPJtum&k5jte^s<_*@abX$U?#Zu$oZ&_^>I(~wI|8DwtIW}9ap7ai!H$i
z@V$bvJJx~OG?Q%f0=Lr-+z#z4+XJwfB2#+kRHxRtVo=-W+~7v!8wokb{Ll8F%l1%0
z#B<vve%mep|BM@Y;fAj-y!ms?CE`;YV3}qn+F;;8N=iW)8XI1@5v_L{-QvQn(4Lro
z8<{WV22Xz5x0sq2rdC8CUX45U6?a@q{6DKknpt3$#q3ClrA>EoAgT}2hHxyKV#0X*
zTH<QbAvezX**AX2Uc)tKlwz3Q$=;j5_-@i-B~cNH$Y!G{xDEJvoXkz8cyWrDON4Xo
zio%3wOrE46%;i{G0cmhOd#RLcuFz$9WGf9-M_Ol>AnLVPADP76XojP~)<fo2=sz7m
z&^!L-d0q4^Q$a6N$<MyuAD&ea^N$OjuLaNQ1M9_4&bDngbqb-e#=P^%aeeZd+bx^%
zb>vu&jd_#*e<wko@&E7a3cB=%!%yTN?)R(w^me@VfuG{yr$*`+ck)>e;X@<MOc$6F
z<m03n?Ys+EA5}+Osv{DB{$;#Hxz{S`ZpG29jgxuI10#)_BFs^BLdAQRFRAhmj3zEd
z)7K0TI3&W{ct&*bU(4*a;CrgwAH!Xmby+qo+c1p6Luc1f+fQ^j^bG|2XdKELCYN0%
zSBDD%fqzNv-XYU|SqzSJ_!4g!zP$|(13yfak!>}lMwv`-L1`vXkFu__oR?^7vdTi)
zgH>5mwF$7PP)B#bG^PtE+(YooQw?XG=}gpvo45jB{fo!-FGxJ-`7iu0K!n3RNnM5b
zaI{Dpr1;_&`t=LD#si?OhgozEiwM@3XmdiEB}p8W&ohyCnDo&*rmwK&z^*lyS2whr
zWpTLia5Y4v3d-u_ZtkiOO|Fy-WU;!ob7k#VbG;b*)D`>0sR_S}pWpa5wf*cJ^vZRX
z>pFu5@YXlP^$pkZ+iD~)H4=~V@k<R+L4dbz|8M^Ej>V0OKWV`bKLtEL$P<;*F6;NU
zJQ<hu>?;d$arGBHhX1s}J2c8Jt#IZh^c%k3v$^~O=Iw&{r*mo7To$V!-;uW;2I^T=
z<2!{jE`>8T1N_E4{utl>3{`)}w<&2`!Y#4zb-^ZBoo*F;{&4N0Gk~r_kM9dUdKG-A
zF#h*08GlW7=|J~8!Sn~Rdt2Y&BHNuy(Ee>1<{Qhf;#$`c(?I`p3D0=_5<28s4g)O_
z9~dsrNz)~5C==Xt!`PO3l6rE-VI#&`ni0#_cF)%vkRD<e!}f)R^-VwMZa?m0KS-~B
zkO5dv`bl~9liE28cq1kGsFLocBp(lQTn9<bJJvVdkh>)1V>e`9-H@M1N?zbr-T-+&
zHg>4nJF&4|?a#sc#Ei9^<85a6j>p<AR?{#Q{8KRagKGFP82q7$gG)8kC_r9UW1j}=
zrW*T%5c4-e6#P@m>jk^>a$zK06C<^_jnKXkTHVsu_boHIT4uq`5Z~K*^th49z1sYe
zX0|Rnky8SCvx4`X3Gohw(NzJg(*^W1a6K(nvZ#dEOU25%fD^U_`};)hR&er7BKI^n
zkt-1-ISKa0xqozJ?w<Qc8+rboyN2~5^!}+2??CULyfS}7KO^oGN1s?{??ldgS!bgV
zIDW1HkE;d@AM{rZ`Oltnxn@G=!6TjaFz&=G(uv5lQbonC8gfD#=;fsFb4TYLLAftO
zzE=v?jmF$F<L+k0{pF21nL5_L1t!NEfeGbx)0RLWH{H$exZgYYUDsdN=>YI*gYl2^
zc&Bra*Ln1ff`8Ssc_9vc<57mTtLH<ahB?$yCb|v{<(agsOYz;7+^gR5fG;th9??8c
zVBBaxKC5Ds$8tZ;rcu<!k)9E|VR&+ld}wPS(g&|GMZ}vl=Bt630As&6!GF%!?ZVNA
zUD2;y!N!F8Wp=$yOW%q9ahYwicLuu3JD>6Yi>$vb%j&Rdrha5k!ZaU{j6qOegO52O
z<a2E0H91wN=@j^T{^W1v^hVs^7s2gXiMahj>}!qk&hsR@G>T{s$iF2v;~gs1FQD_O
z2EFG=e|x|$JVp4A^XSESLal@UO_}*S?H9ZJ<~iMge`*znz1}K5;BB2a(nkz~yll>X
zE=%0ZxIYy+<g(V1azTFV%|2IqU-xF8_krT-1C=)ez4El~3%~Zqr*&WWwc~1}*pB(X
z?~=*Oq1zuW;;lD%pIt=!b`c+lFW!W{qF3*|$@{EV>(Z;Eg1|3SvcDRwA3Drmaw}Zi
z%CQ#aQ|>|+ci}uGzT{5t&`G;cevGpt{*8~s8+>GrOS=Y-1^Mee<Xyk>I(y4@_Nk-i
z>IokbqTHX_26ov7wu>;oMoYTTa>sc72IPkm`jXx53$4!sipSfE;MbylO%eQB)OIcE
fqLlx6o9_PrXME4{*=FyU00000NkvXXu0mjf=sUwq
--- a/browser/base/content/browser-appmenu.inc
+++ b/browser/base/content/browser-appmenu.inc
@@ -189,16 +189,24 @@
                     type="checkbox"
                     command="Tools:Inspect"
                     key="key_inspect"/>
           <menuitem id="appmenu_debugger"
                     hidden="true"
                     label="&debuggerMenu.label;"
                     key="key_debugger"
                     command="Tools:Debugger"/>
+          <menuitem id="appmenu_remoteDebugger"
+                    hidden="true"
+                    label="&remoteDebuggerMenu.label;"
+                    command="Tools:RemoteDebugger"/>
+          <menuitem id="appmenu_chromeDebugger"
+                    hidden="true"
+                    label="&chromeDebuggerMenu.label;"
+                    command="Tools:ChromeDebugger"/>
           <menuitem id="appmenu_scratchpad"
                     hidden="true"
                     label="&scratchpad.label;"
                     key="key_scratchpad"
                     command="Tools:Scratchpad"/>
           <menuitem id="appmenu_styleeditor"
                     hidden="true"
                     label="&styleeditor.label;"
--- a/browser/base/content/browser-fullZoom.js
+++ b/browser/base/content/browser-fullZoom.js
@@ -220,17 +220,17 @@ var FullZoom = {
    * @param aBrowser
    *        (optional) browser object displaying the document
    */
   onLocationChange: function FullZoom_onLocationChange(aURI, aIsTabSwitch, aBrowser) {
     if (!aURI || (aIsTabSwitch && !this.siteSpecific))
       return;
 
     // Avoid the cps roundtrip and apply the default/global pref.
-    if (isBlankPageURL(aURI.spec)) {
+    if (aURI.spec == "about:blank") {
       this._applyPrefToSetting(undefined, aBrowser);
       return;
     }
 
     let browser = aBrowser || gBrowser.selectedBrowser;
 
     // Media documents should always start at 1, and are not affected by prefs.
     if (!aIsTabSwitch && browser.contentDocument.mozSyntheticDocument) {
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -546,16 +546,24 @@
                             accesskey="&inspectMenu.accesskey;"
                             key="key_inspect"
                             command="Tools:Inspect"/>
                   <menuitem id="menu_debugger"
                             hidden="true"
                             label="&debuggerMenu.label;"
                             key="key_debugger"
                             command="Tools:Debugger"/>
+                  <menuitem id="menu_remoteDebugger"
+                            hidden="true"
+                            label="&remoteDebuggerMenu.label;"
+                            command="Tools:RemoteDebugger"/>
+                  <menuitem id="menu_chromeDebugger"
+                            hidden="true"
+                            label="&chromeDebuggerMenu.label;"
+                            command="Tools:ChromeDebugger"/>
                   <menuitem id="menu_scratchpad"
                             hidden="true"
                             label="&scratchpad.label;"
                             accesskey="&scratchpad.accesskey;"
                             key="key_scratchpad"
                             command="Tools:Scratchpad"/>
                   <menuitem id="menu_styleeditor"
                             hidden="true"
--- a/browser/base/content/browser-sets.inc
+++ b/browser/base/content/browser-sets.inc
@@ -124,16 +124,18 @@
     <command id="cmd_fullZoomToggle"  oncommand="ZoomManager.toggleZoom();"/>
     <command id="Browser:OpenLocation" oncommand="openLocation();"/>
 
     <command id="Tools:Search" oncommand="BrowserSearch.webSearch();"/>
     <command id="Tools:Downloads" oncommand="BrowserDownloadsUI();"/>
     <command id="Tools:WebConsole" oncommand="HUDConsoleUI.toggleHUD();"/>
     <command id="Tools:Inspect" oncommand="InspectorUI.toggleInspectorUI();" disabled="true"/>
     <command id="Tools:Debugger" oncommand="DebuggerUI.toggleDebugger();" disabled="true"/>
+    <command id="Tools:RemoteDebugger" oncommand="DebuggerUI.toggleRemoteDebugger();" disabled="true"/>
+    <command id="Tools:ChromeDebugger" oncommand="DebuggerUI.toggleChromeDebugger();" disabled="true"/>
     <command id="Tools:Scratchpad" oncommand="Scratchpad.openScratchpad();" disabled="true"/>
     <command id="Tools:StyleEditor" oncommand="StyleEditor.openChrome();" disabled="true"/>
     <command id="Tools:Addons" oncommand="BrowserOpenAddonsMgr();"/>
     <command id="Tools:Sanitize"
      oncommand="Cc['@mozilla.org/browser/browserglue;1'].getService(Ci.nsIBrowserGlue).sanitize(window);"/>
     <command id="Tools:PrivateBrowsing" oncommand="gPrivateBrowsingUI.toggleMode();"/>
     <command id="History:UndoCloseTab" oncommand="undoCloseTab();"/>
     <command id="History:UndoCloseWindow" oncommand="undoCloseWindow();"/>
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -425,30 +425,21 @@ window[chromehidden~="toolbar"] toolbar:
   -moz-binding: url("chrome://global/content/bindings/toolbarbutton.xml#toolbarbutton-image");
   margin: 0;
 }
 
 
 /* notification anchors should only be visible when their associated
    notifications are */
 .notification-anchor-icon {
-  display: none;
   -moz-user-focus: normal;
 }
 
-/* We use the iconBox as the notification anchor when a popup notification is
-   created with a null anchorID, so in that case use a default anchor icon. */
-#notification-popup-box[anchorid="notification-popup-box"] > #default-notification-icon,
-#notification-popup-box[anchorid="geo-notification-icon"] > #geo-notification-icon,
-#notification-popup-box[anchorid="indexedDB-notification-icon"] > #indexedDB-notification-icon,
-#notification-popup-box[anchorid="addons-notification-icon"] > #addons-notification-icon,
-#notification-popup-box[anchorid="password-notification-icon"] > #password-notification-icon,
-#notification-popup-box[anchorid="webapps-notification-icon"] > #webapps-notification-icon,
-#notification-popup-box[anchorid="plugins-notification-icon"] > #plugins-notification-icon {
-  display: -moz-box;
+.notification-anchor-icon:not([showing]) {
+  display: none;
 }
 
 #invalid-form-popup > description {
   max-width: 280px;
 }
 
 #geolocation-notification {
   -moz-binding: url("chrome://browser/content/urlbarBindings.xml#geolocation-notification");
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1711,16 +1711,36 @@ function delayedStartup(isLoadingBlank, 
   if (enabled) {
     document.getElementById("menu_debugger").hidden = false;
     document.getElementById("Tools:Debugger").removeAttribute("disabled");
 #ifdef MENUBAR_CAN_AUTOHIDE
     document.getElementById("appmenu_debugger").hidden = false;
 #endif
   }
 
+  // Enable Remote Debugger?
+  let enabled = gPrefService.getBoolPref("devtools.debugger.remote-enabled");
+  if (enabled) {
+    document.getElementById("menu_remoteDebugger").hidden = false;
+    document.getElementById("Tools:RemoteDebugger").removeAttribute("disabled");
+#ifdef MENUBAR_CAN_AUTOHIDE
+    document.getElementById("appmenu_remoteDebugger").hidden = false;
+#endif
+  }
+
+  // Enable Chrome Debugger?
+  let enabled = gPrefService.getBoolPref("devtools.chrome.enabled");
+  if (enabled) {
+    document.getElementById("menu_chromeDebugger").hidden = false;
+    document.getElementById("Tools:ChromeDebugger").removeAttribute("disabled");
+#ifdef MENUBAR_CAN_AUTOHIDE
+    document.getElementById("appmenu_chromeDebugger").hidden = false;
+#endif
+  }
+
   // Enable Error Console?
   // XXX Temporarily always-enabled, see bug 601201
   let consoleEnabled = true || gPrefService.getBoolPref("devtools.errorconsole.enabled");
   if (consoleEnabled) {
     document.getElementById("javascriptConsole").hidden = false;
     document.getElementById("key_errorConsole").removeAttribute("disabled");
 #ifdef MENUBAR_CAN_AUTOHIDE
     document.getElementById("appmenu_errorConsole").hidden = false;
@@ -4428,20 +4448,20 @@ var FullScreen = {
     var controls = document.getElementsByAttribute("fullscreencontrol", "true");
     for (var i = 0; i < controls.length; ++i)
       controls[i].hidden = aShow;
   }
 };
 XPCOMUtils.defineLazyGetter(FullScreen, "useLionFullScreen", function() {
   // We'll only use OS X Lion full screen if we're
   // * on OS X
-  // * on Lion (Darwin 11.x) -- this will need to be updated for OS X 10.8
+  // * on Lion or higher (Darwin 11+)
   // * have fullscreenbutton="true"
 #ifdef XP_MACOSX
-  return /^11\./.test(Services.sysinfo.getProperty("version")) &&
+  return parseFloat(Services.sysinfo.getProperty("version")) >= 11 &&
          document.documentElement.getAttribute("fullscreenbutton") == "true";
 #else
   return false;
 #endif
 });
 
 /**
  * Returns true if |aMimeType| is text-based, false otherwise.
--- a/browser/base/content/test/browser_popupNotification.js
+++ b/browser/base/content/test/browser_popupNotification.js
@@ -637,16 +637,94 @@ var tests = [
       checkPopup(popup, this.notifyObj);
       dismissNotification(popup);
     },
     onHidden: function (popup) {
       ok(!this.notifyObj.dismissalCallbackTriggered, "dismissal callback wasn't triggered");
       ok(this.notifyObj.removedCallbackTriggered, "removed callback triggered");
     }
   },
+  // Test multiple notification icons are shown
+  { // Test #21
+    run: function () {
+      this.notifyObj1 = new basicNotification();
+      this.notifyObj1.id += "_1";
+      this.notifyObj1.anchorID = "default-notification-icon";
+      this.notification1 = showNotification(this.notifyObj1);
+
+      this.notifyObj2 = new basicNotification();
+      this.notifyObj2.id += "_2";
+      this.notifyObj2.anchorID = "geo-notification-icon";
+      this.notification2 = showNotification(this.notifyObj2);
+    },
+    onShown: function (popup) {
+      checkPopup(popup, this.notifyObj2);
+
+      // check notifyObj1 anchor icon is showing
+      isnot(document.getElementById("default-notification-icon").boxObject.width, 0,
+            "default anchor should be visible");
+      // check notifyObj2 anchor icon is showing
+      isnot(document.getElementById("geo-notification-icon").boxObject.width, 0,
+            "geo anchor should be visible");
+
+      dismissNotification(popup);
+    },
+    onHidden: [
+      function (popup) {
+      },
+      function (popup) {
+        this.notification1.remove();
+        ok(this.notifyObj1.removedCallbackTriggered, "removed callback triggered");
+
+        this.notification2.remove();
+        ok(this.notifyObj2.removedCallbackTriggered, "removed callback triggered");
+      }
+    ],
+  },
+  // Test that multiple notification icons are removed when switching tabs
+  { // Test #22
+    run: function () {
+      // show the notification on old tab.
+      this.notifyObjOld = new basicNotification();
+      this.notifyObjOld.anchorID = "default-notification-icon";
+      this.notificationOld = showNotification(this.notifyObjOld);
+
+      // switch tab
+      this.oldSelectedTab = gBrowser.selectedTab;
+      gBrowser.selectedTab = gBrowser.addTab("about:blank");
+
+      // show the notification on new tab.
+      this.notifyObjNew = new basicNotification();
+      this.notifyObjNew.anchorID = "geo-notification-icon";
+      this.notificationNew = showNotification(this.notifyObjNew);
+    },
+    onShown: function (popup) {
+      checkPopup(popup, this.notifyObjNew);
+
+      // check notifyObjOld anchor icon is removed
+      is(document.getElementById("default-notification-icon").boxObject.width, 0,
+         "default anchor shouldn't be visible");
+      // check notifyObjNew anchor icon is showing
+      isnot(document.getElementById("geo-notification-icon").boxObject.width, 0,
+            "geo anchor should be visible");
+
+      dismissNotification(popup);
+    },
+    onHidden: [
+      function (popup) {
+      },
+      function (popup) {
+        this.notificationNew.remove();
+        gBrowser.removeTab(gBrowser.selectedTab);
+
+        gBrowser.selectedTab = this.oldSelectedTab;
+        this.notificationOld.remove();
+      }
+    ],
+  }
 ];
 
 function showNotification(notifyObj) {
   return PopupNotifications.show(notifyObj.browser,
                                  notifyObj.id,
                                  notifyObj.message,
                                  notifyObj.anchorID,
                                  notifyObj.mainAction,
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -806,17 +806,17 @@ BrowserGlue.prototype = {
       let win = self.getMostRecentBrowserWindow();
       let browser = win.gBrowser;
       browser.selectedTab = browser.addTab(data);
     }
 
     try {
       // This will throw NS_ERROR_NOT_AVAILABLE if the notification cannot
       // be displayed per the idl.
-      notifier.showAlertNotification("post-update-notification", title, text,
+      notifier.showAlertNotification(null, title, text,
                                      true, url, clickCallback);
     }
     catch (e) {
     }
   },
 
 #ifdef MOZ_TELEMETRY_REPORTING
   _showTelemetryNotification: function BG__showTelemetryNotification() {
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -236,26 +236,23 @@ var PlacesOrganizer = {
     // and update the back/forward buttons by setting location.
     if (this._content.place != placeURI || !resetSearchBox) {
       this._content.place = placeURI;
       PlacesSearchBox.hideSearchUI();
       this.location = node.uri;
     }
 
     // Update the selected folder title where it appears in the UI: the folder
-    // scope button, "Find in <current collection>" command, and the search box
-    // emptytext.  They must be updated even if the selection hasn't changed --
+    // scope button, and the search box emptytext.
+    // They must be updated even if the selection hasn't changed --
     // specifically when node's title changes.  In that case a selection event
     // is generated, this method is called, but the selection does not change.
     var folderButton = document.getElementById("scopeBarFolder");
     var folderTitle = node.title || folderButton.getAttribute("emptytitle");
     folderButton.setAttribute("label", folderTitle);
-    var cmd = document.getElementById("OrganizerCommand_find:current");
-    var label = PlacesUIUtils.getFormattedString("findInPrefix", [folderTitle]);
-    cmd.setAttribute("label", label);
     if (PlacesSearchBox.filterCollection == "collection")
       PlacesSearchBox.updateCollectionTitle(folderTitle);
 
     // When we invalidate a container we use suppressSelectionEvent, when it is
     // unset a select event is fired, in many cases the selection did not really
     // change, so we should check for it, and return early in such a case. Note
     // that we cannot return any earlier than this point, because when
     // !resetSearchBox, we need to update location and hide the UI as above,
@@ -920,44 +917,49 @@ var PlacesSearchBox = {
 
     PlacesSearchBox.showSearchUI();
 
     // Update the details panel
     PlacesOrganizer.onContentTreeSelect();
   },
 
   /**
-   * Finds across all bookmarks
+   * Finds across all history, downloads or all bookmarks.
    */
   findAll: function PSB_findAll() {
-    PlacesQueryBuilder.setScope("bookmarks");
-    this.focus();
-  },
-
-  /**
-   * Finds in the currently selected Place.
-   */
-  findCurrent: function PSB_findCurrent() {
-    PlacesQueryBuilder.setScope("collection");
+    switch (this.filterCollection) {
+      case "history":
+        PlacesQueryBuilder.setScope("history");
+        break;
+      case "downloads":
+        PlacesQueryBuilder.setScope("downloads");
+        break;
+      default:
+        PlacesQueryBuilder.setScope("bookmarks");
+        break;
+    }
     this.focus();
   },
 
   /**
    * Updates the display with the title of the current collection.
    * @param   aTitle
    *          The title of the current collection.
    */
   updateCollectionTitle: function PSB_updateCollectionTitle(aTitle) {
     let title = "";
+    // This is needed when a user performs a folder-specific search
+    // using the scope bar, removes the search-string, and unfocuses
+    // the search box, at least until the removal of the scope bar.
     if (aTitle) {
       title = PlacesUIUtils.getFormattedString("searchCurrentDefault",
                                                [aTitle]);
     }
     else {
-      switch(this.filterCollection) {
+      switch (this.filterCollection) {
         case "history":
           title = PlacesUIUtils.getString("searchHistory");
           break;
         case "downloads":
           title = PlacesUIUtils.getString("searchDownloads");
           break;
         default:
           title = PlacesUIUtils.getString("searchBookmarks");                                    
--- a/browser/components/places/content/places.xul
+++ b/browser/components/places/content/places.xul
@@ -94,23 +94,17 @@
 #include ../../../base/content/browserMountPoints.inc
 #else
   <commandset id="editMenuCommands"/>
   <commandset id="placesCommands"/>
 #endif
 
   <commandset id="organizerCommandSet">
     <command id="OrganizerCommand_find:all"
-             label="&cmd.findInBookmarks.label;"
-             accesskey="&cmd.findInBookmarks.accesskey;"
              oncommand="PlacesSearchBox.findAll();"/>
-    <command id="OrganizerCommand_find:current"
-             label="&cmd.findCurrent.label;"
-             accesskey="&cmd.findCurrent.accesskey;"
-             oncommand="PlacesSearchBox.findCurrent();"/>
     <command id="OrganizerCommand_export"
              oncommand="PlacesOrganizer.exportBookmarks();"/>
     <command id="OrganizerCommand_import"
              oncommand="PlacesOrganizer.importFromFile();"/>
     <command id="OrganizerCommand_browserImport"
              oncommand="PlacesOrganizer.importFromBrowser();"/>
     <command id="OrganizerCommand_backup"
              oncommand="PlacesOrganizer.backupBookmarks();"/>
@@ -132,20 +126,16 @@
     <key id="placesKey_close" key="&cmd.close.key;" modifiers="accel" 
          oncommand="close();"/>
          
     <!-- Command Keys -->
     <key id="placesKey_find:all"
          command="OrganizerCommand_find:all" 
          key="&cmd.find.key;"
          modifiers="accel"/>
-    <key id="placesKey_find:current"
-         command="OrganizerCommand_find:current" 
-         key="&cmd.find.key;"
-         modifiers="accel,shift"/>
 
     <!-- Back/Forward Keys Support -->
 #ifndef XP_MACOSX
     <key id="placesKey_goBackKb"
          keycode="VK_LEFT"
          command="OrganizerCommand:Back"
          modifiers="alt"/>
     <key id="placesKey_goForwardKb"
--- a/browser/components/tabview/test/browser_tabview_apptabs.js
+++ b/browser/components/tabview/test/browser_tabview_apptabs.js
@@ -29,41 +29,41 @@ function onTabViewWindowLoaded() {
   let xulTab = gBrowser.loadOneTab("about:blank");
   is(gBrowser.tabs.length, 2, "we now have two tabs");
   is(groupItemOne._children.length, 1, "the new tab was added to the group");
 
   // make sure the group has no app tabs
   is(appTabCount(groupItemOne), 0, "there are no app tab icons");
 
   // pin the tab, make sure the TabItem goes away and the icon comes on
-  whenAppTabIconAdded(function() {
+  whenAppTabIconAdded(groupItemOne, function () {
     is(groupItemOne._children.length, 0,
        "the app tab's TabItem was removed from the group");
     is(appTabCount(groupItemOne), 1, "there's now one app tab icon");
 
     // create a second group and make sure it gets the icon too
     box.offset(box.width + 20, 0);
     let groupItemTwo = new contentWindow.GroupItem([],
         { bounds: box, title: "test2" });
-    whenAppTabIconAdded(function() {
+    whenAppTabIconAdded(groupItemTwo, function() {
       is(contentWindow.GroupItems.groupItems.length, 3, "we now have three groups");
       is(appTabCount(groupItemTwo), 1,
          "there's an app tab icon in the second group");
 
       // When the tab was pinned, the last active group with an item got the focus.
       // Therefore, switching the focus back to group item one.
       contentWindow.UI.setActive(groupItemOne);
 
       // unpin the tab, make sure the icon goes away and the TabItem comes on
       gBrowser.unpinTab(xulTab);
       is(groupItemOne._children.length, 1, "the app tab's TabItem is back");
       is(appTabCount(groupItemOne), 0, "the icon is gone from group one");
       is(appTabCount(groupItemTwo), 0, "the icon is gone from group two");
 
-      whenAppTabIconAdded(function() {
+      whenAppTabIconAdded(groupItemOne, function() {
         // close the second group
         groupItemTwo.close();
 
         // find app tab in group and hit it
         whenTabViewIsHidden(function() {
           ok(!TabView.isVisible(),
              "Tab View is hidden because we clicked on the app tab");
 
--- a/browser/components/tabview/test/browser_tabview_bug595965.js
+++ b/browser/components/tabview/test/browser_tabview_bug595965.js
@@ -48,17 +48,17 @@ function onTabViewShown(win) {
 
   let tray = groupItem.$appTabTray;
   let trayContainer = iQ(tray[0].parentNode);
 
   is(parseInt(trayContainer.css("width")), 0,
      "$appTabTray container is not visible");
 
   // pin the tab, make sure the TabItem goes away and the icon comes on
-  whenAppTabIconAdded(function() {
+  whenAppTabIconAdded(groupItem, function () {
     is(groupItem._children.length, 0,
        "the app tab's TabItem was removed from the group");
     is(appTabCount(groupItem), 1, "there's now one app tab icon");
 
     is(tray.css("-moz-column-count"), 1,
        "$appTabTray column count is 1");
     isnot(parseInt(trayContainer.css("width")), 0,
        "$appTabTray container is visible");
@@ -75,17 +75,17 @@ function onTabViewShown(win) {
       is(tray.css("-moz-column-count"), 2,
          "$appTabTray column count is 2");
 
       ok(!trayContainer.hasClass("appTabTrayContainerTruncated"),
          "$appTabTray container does not have .appTabTrayContainerTruncated");
 
       // add one more tab
       xulTabs.push(gBrowser.loadOneTab("about:blank"));
-      whenAppTabIconAdded(function() {
+      whenAppTabIconAdded(groupItem, function () {
         is(tray.css("-moz-column-count"), 3,
            "$appTabTray column count is 3");
 
         ok(trayContainer.hasClass("appTabTrayContainerTruncated"),
            "$appTabTray container hasClass .appTabTrayContainerTruncated");
 
         // remove all but one app tabs
         for (let i = 1; i < xulTabs.length; i++)
@@ -124,30 +124,30 @@ function onTabViewShown(win) {
           is(contentWindow.GroupItems.groupItems.length, 1,
              "we finish with one group");
           is(gBrowser.tabs.length, 1, "we finish with one tab");
 
           win.close();
 
           executeSoon(finish);
         }, win);
-      }, win);
+      });
       win.gBrowser.pinTab(xulTabs[xulTabs.length-1]);
     };
 
     // add enough tabs to have two columns
     let returnCount = 0;
     for (let i = 1; i < icons; i++) {
       xulTabs.push(gBrowser.loadOneTab("about:blank"));
-      whenAppTabIconAdded(function() {
+      whenAppTabIconAdded(groupItem, function () {
         if (++returnCount == (icons - 1))
           executeSoon(pinnedSomeTabs);
-      }, win);
+      });
       win.gBrowser.pinTab(xulTabs[i]);
     }
-  }, win);
+  });
   win.gBrowser.pinTab(xulTabs[0]);
 }
 
 function appTabCount(groupItem) {
   return groupItem.container.getElementsByClassName("appTabIcon").length;
 }
 
--- a/browser/components/tabview/test/browser_tabview_bug600645.js
+++ b/browser/components/tabview/test/browser_tabview_bug600645.js
@@ -13,23 +13,24 @@ const fi = Cc["@mozilla.org/browser/favi
 let newTab;
 
 function test() {
   waitForExplicitFinish();
 
   newTab = gBrowser.addTab();
 
   showTabView(function() {
-    whenAppTabIconAdded(onTabPinned);
+    let cw = TabView.getContentWindow();
+    whenAppTabIconAdded(cw.GroupItems.groupItems[0], onTabPinned);
     gBrowser.pinTab(newTab);
   })
 }
 
 function onTabPinned() {
-  let contentWindow = document.getElementById("tab-view").contentWindow;
+  let contentWindow = TabView.getContentWindow();
   is(contentWindow.GroupItems.groupItems.length, 1, 
      "There is one group item on startup");
 
   let groupItem = contentWindow.GroupItems.groupItems[0];
   let icon = contentWindow.iQ(".appTabIcon", groupItem.$appTabTray)[0];
   let $icon = contentWindow.iQ(icon);
 
   is($icon.data("xulTab"), newTab, 
--- a/browser/components/tabview/test/browser_tabview_bug640765.js
+++ b/browser/components/tabview/test/browser_tabview_bug640765.js
@@ -18,19 +18,19 @@ function test() {
   });
 
   showTabView(function() {
     contentWindow = document.getElementById("tab-view").contentWindow;
     is(contentWindow.GroupItems.groupItems.length, 1, "Has only one group");
 
     groupItem = contentWindow.GroupItems.groupItems[0];
 
-    whenAppTabIconAdded(function() {
-      whenAppTabIconAdded(function() {
-        whenAppTabIconAdded(function() {
+    whenAppTabIconAdded(groupItem, function () {
+      whenAppTabIconAdded(groupItem, function () {
+        whenAppTabIconAdded(groupItem, function () {
 
           is(xulTabForAppTabIcon(0), newTabOne,
             "New tab one matches the first app tab icon in tabview");
           is(xulTabForAppTabIcon(1), newTabTwo,
             "New tab two matches the second app tab icon in tabview");
           is(xulTabForAppTabIcon(2), newTabThree,
             "New tab three matches the third app tab icon in tabview");
 
--- a/browser/components/tabview/test/browser_tabview_bug678374.js
+++ b/browser/components/tabview/test/browser_tabview_bug678374.js
@@ -20,22 +20,22 @@ function test() {
     // test tab item
     let newTabItemOne = newTabOne._tabViewTabItem;
 
     newTabItemOne.addSubscriber("iconUpdated", function onIconUpdated() {
       newTabItemOne.removeSubscriber("iconUpdated", onIconUpdated);
       is(newTabItemOne.$favImage[0].src, ICON_URL, "The tab item is showing the right icon.");
 
       // test pin tab
-      whenAppTabIconAdded(function() {
+      whenAppTabIconAdded(groupItem, function() {
         let icon = cw.iQ(".appTabIcon", groupItem.$appTabTray)[0];
         is(icon.src, ICON_URL, "The app tab is showing the right icon");
 
         finish();
-      }, win);
+      });
       win.gBrowser.pinTab(newTabTwo);
     });
   }, function(win) {
     registerCleanupFunction(function() { 
       Services.prefs.clearUserPref("browser.chrome.favicons");
       win.close(); 
    });
 
--- a/browser/components/tabview/test/browser_tabview_bug685476.js
+++ b/browser/components/tabview/test/browser_tabview_bug685476.js
@@ -3,18 +3,18 @@
 
 function test() {
   waitForExplicitFinish();
 
   showTabView(function () {
     let tab = gBrowser.addTab();
     registerCleanupFunction(function () gBrowser.removeTab(tab));
 
-    whenAppTabIconAdded(function() {
-      let cw = TabView.getContentWindow();
+    let cw = TabView.getContentWindow();
+    whenAppTabIconAdded(cw.GroupItems.groupItems[0], function() {
       let body = cw.document.body;
       let [appTabIcon] = cw.iQ(".appTabTray .appTabIcon");
 
       EventUtils.synthesizeMouseAtCenter(appTabIcon, {type: "mousedown"}, cw);
       EventUtils.synthesizeMouse(body, 500, 100, {type: "mousemove"}, cw);
       EventUtils.synthesizeMouse(body, 500, 100, {type: "mouseup"}, cw);
 
       ok(TabView.isVisible(), "tabview is still visible");
--- a/browser/components/tabview/test/head.js
+++ b/browser/components/tabview/test/head.js
@@ -406,20 +406,14 @@ function goToNextGroup(win) {
   const masks = Ci.nsIDOMNSEvent;
   let mval = 0;
   mval |= masks.CONTROL_MASK;
 
   utils.sendKeyEvent("keypress", 0, 96, mval);
 }
 
 // ----------
-function whenAppTabIconAdded(callback, win) {
-  win = win || window;
-
-  let contentWindow = win.TabView.getContentWindow();
-  let groupItems = contentWindow.GroupItems.groupItems;
-  let groupItem = groupItems[(groupItems.length - 1)];
-
+function whenAppTabIconAdded(groupItem, callback) {
   groupItem.addSubscriber("appTabIconAdded", function onAppTabIconAdded() {
     groupItem.removeSubscriber("appTabIconAdded", onAppTabIconAdded);
-    callback();
+    executeSoon(callback);
   });
 }
--- a/browser/devtools/debugger/DebuggerUI.jsm
+++ b/browser/devtools/debugger/DebuggerUI.jsm
@@ -40,17 +40,23 @@
  *
  * ***** END LICENSE BLOCK ***** */
 "use strict";
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
+const DBG_XUL = "chrome://browser/content/debugger.xul";
+const REMOTE_PROFILE_NAME = "_remote-debug";
+
+Cu.import("resource://gre/modules/devtools/dbg-server.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/FileUtils.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 let EXPORTED_SYMBOLS = ["DebuggerUI"];
 
 /**
  * Provides a simple mechanism of managing debugger instances per tab.
  *
  * @param nsIDOMWindow aWindow
  *        The chrome window for which the DebuggerUI instance is created.
@@ -71,59 +77,101 @@ DebuggerUI.prototype = {
     if (tab._scriptDebugger) {
       tab._scriptDebugger.close();
       return null;
     }
     return new DebuggerPane(tab);
   },
 
   /**
+   * Starts a remote debugger in a new process, or stops it if already started.
+   * @see DebuggerProcess.constructor
+   * @return DebuggerProcess if the debugger is started, null if it's stopped.
+   */
+  toggleRemoteDebugger: function DUI_toggleRemoteDebugger(aOnClose, aOnRun) {
+    let win = this.chromeWindow;
+
+    if (win._remoteDebugger) {
+      win._remoteDebugger.close();
+      return null;
+    }
+    return new DebuggerProcess(win, aOnClose, aOnRun);
+  },
+
+  /**
+   * Starts a chrome debugger in a new process, or stops it if already started.
+   * @see DebuggerProcess.constructor
+   * @return DebuggerProcess if the debugger is started, null if it's stopped.
+   */
+  toggleChromeDebugger: function DUI_toggleChromeDebugger(aOnClose, aOnRun) {
+    let win = this.chromeWindow;
+
+    if (win._chromeDebugger) {
+      win._chromeDebugger.close();
+      return null;
+    }
+    return new DebuggerProcess(win, aOnClose, aOnRun, true);
+  },
+
+  /**
    * Get the debugger for a specified tab.
    * @return DebuggerPane if a debugger exists for the tab, null otherwise
    */
   getDebugger: function DUI_getDebugger(aTab) {
     return aTab._scriptDebugger;
   },
 
   /**
    * Get the preferences associated with the debugger frontend.
    * @return object
    */
   get preferences() {
-    return DebuggerUIPreferences;
+    return DebuggerPreferences;
   }
 };
 
 /**
  * Creates a pane that will host the debugger.
  *
  * @param XULElement aTab
  *        The tab in which to create the debugger.
  */
 function DebuggerPane(aTab) {
   this._tab = aTab;
+  
+  this._initServer();
   this._create();
 }
 
 DebuggerPane.prototype = {
 
   /**
+   * Initializes the debugger server.
+   */
+  _initServer: function DP__initServer() {
+    if (!DebuggerServer.initialized) {
+      DebuggerServer.init();
+      DebuggerServer.addBrowserActors();
+    }
+  },
+
+  /**
    * Creates and initializes the widgets containing the debugger UI.
    */
   _create: function DP__create() {
     this._tab._scriptDebugger = this;
 
     let gBrowser = this._tab.linkedBrowser.getTabBrowser();
     let ownerDocument = gBrowser.parentNode.ownerDocument;
 
     this._splitter = ownerDocument.createElement("splitter");
     this._splitter.setAttribute("class", "hud-splitter");
 
     this._frame = ownerDocument.createElement("iframe");
-    this._frame.height = DebuggerUIPreferences.height;
+    this._frame.height = DebuggerPreferences.height;
 
     this._nbox = gBrowser.getNotificationBox(this._tab.linkedBrowser);
     this._nbox.appendChild(this._splitter);
     this._nbox.appendChild(this._frame);
 
     this.close = this.close.bind(this);
     let self = this;
 
@@ -134,30 +182,30 @@ DebuggerPane.prototype = {
 
       // Bind shortcuts for accessing the breakpoint methods in the debugger.
       let bkp = self.debuggerWindow.DebuggerController.Breakpoints;
       self.addBreakpoint = bkp.addBreakpoint;
       self.removeBreakpoint = bkp.removeBreakpoint;
       self.getBreakpoint = bkp.getBreakpoint;
     }, true);
 
-    this._frame.setAttribute("src", "chrome://browser/content/debugger.xul");
+    this._frame.setAttribute("src", DBG_XUL);
   },
 
   /**
    * Closes the debugger, removing child nodes and event listeners.
    */
   close: function DP_close() {
     if (!this._tab) {
       return;
     }
-    this._tab._scriptDebugger = null;
+    delete this._tab._scriptDebugger;
     this._tab = null;
 
-    DebuggerUIPreferences.height = this._frame.height;
+    DebuggerPreferences.height = this._frame.height;
     this._frame.removeEventListener("Debugger:Close", this.close, true);
     this._frame.removeEventListener("unload", this.close, true);
 
     this._nbox.removeChild(this._splitter);
     this._nbox.removeChild(this._frame);
 
     this._splitter = null;
     this._frame = null;
@@ -181,19 +229,127 @@ DebuggerPane.prototype = {
     if (debuggerWindow) {
       return debuggerWindow.DebuggerController.Breakpoints.store;
     }
     return null;
   }
 };
 
 /**
- * Various debugger UI preferences (currently just the pane height).
+ * Creates a process that will hold the remote debugger.
+ *
+ * @param function aOnClose
+ *        Optional, a function called when the process exits.
+ * @param function aOnRun
+ *        Optional, a function called when the process starts running.
+ * @param boolean aInitServerFlag
+ *        True to initialize the server. This should happen only in the chrome
+ *        debugging case. This should also be true by default after bug #747429.
+ * @param nsIDOMWindow aWindow
+ *        The chrome window for which the remote debugger instance is created.
  */
-let DebuggerUIPreferences = {
+function DebuggerProcess(aWindow, aOnClose, aOnRun, aInitServerFlag) {
+  this._win = aWindow;
+  this._closeCallback = aOnClose;
+  this._runCallback = aOnRun;
+
+  aInitServerFlag && this._initServer();
+  this._initProfile();
+  this._create();
+}
+
+DebuggerProcess.prototype = {
+
+  /**
+   * Initializes the debugger server.
+   */
+  _initServer: function RDP__initServer() {
+    if (!DebuggerServer.initialized) {
+      DebuggerServer.init();
+      DebuggerServer.addBrowserActors();
+    }
+    DebuggerServer.closeListener();
+    DebuggerServer.openListener(DebuggerPreferences.remotePort, false);
+  },
+
+  /**
+   * Initializes a profile for the remote debugger process.
+   */
+  _initProfile: function RDP__initProfile() {
+    let profileService = Cc["@mozilla.org/toolkit/profile-service;1"]
+      .createInstance(Ci.nsIToolkitProfileService);
+
+    let dbgProfileName;
+    try {
+      dbgProfileName = profileService.selectedProfile.name + REMOTE_PROFILE_NAME;
+    } catch(e) {
+      dbgProfileName = REMOTE_PROFILE_NAME;
+      Cu.reportError(e);
+    }
+
+    this._dbgProfile = profileService.createProfile(null, null, dbgProfileName);
+    profileService.flush();
+  },
+
+  /**
+   * Creates and initializes the profile & process for the remote debugger.
+   */
+  _create: function RDP__create() {
+    this._win._remoteDebugger = this;
+
+    let file = FileUtils.getFile("CurProcD",
+      [Services.appinfo.OS == "WINNT" ? "firefox.exe"
+                                      : "firefox-bin"]);
+
+    let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
+    process.init(file);
+
+    let args = [
+      "-no-remote", "-P", this._dbgProfile.name,
+      "-chrome", DBG_XUL,
+      "-width", DebuggerPreferences.remoteWinWidth,
+      "-height", DebuggerPreferences.remoteWinHeight];
+
+    process.runwAsync(args, args.length, { observe: this.close.bind(this) });
+    this._dbgProcess = process;
+
+    if (typeof this._runCallback === "function") {
+      this._runCallback.call({}, this);
+    }
+  },
+
+  /**
+   * Closes the remote debugger, removing the profile and killing the process.
+   */
+  close: function RDP_close() {
+    if (!this._win) {
+      return;
+    }
+    delete this._win._remoteDebugger;
+    this._win = null;
+
+    if (this._dbgProcess.isRunning) {
+      this._dbgProcess.kill();
+    }
+    if (this._dbgProfile) {
+      this._dbgProfile.remove(false);
+    }
+    if (typeof this._closeCallback === "function") {
+      this._closeCallback.call({}, this);
+    }
+
+    this._dbgProcess = null;
+    this._dbgProfile = null;
+  }
+};
+
+/**
+ * Various debugger preferences.
+ */
+let DebuggerPreferences = {
 
   /**
    * Gets the preferred height of the debugger pane.
    * @return number
    */
   get height() {
     if (this._height === undefined) {
       this._height = Services.prefs.getIntPref("devtools.debugger.ui.height");
@@ -205,8 +361,40 @@ let DebuggerUIPreferences = {
    * Sets the preferred height of the debugger pane.
    * @param number value
    */
   set height(value) {
     Services.prefs.setIntPref("devtools.debugger.ui.height", value);
     this._height = value;
   }
 };
+
+/**
+ * Gets the preferred width of the remote debugger window.
+ * @return number
+ */
+XPCOMUtils.defineLazyGetter(DebuggerPreferences, "remoteWinWidth", function() {
+  return Services.prefs.getIntPref("devtools.debugger.ui.remote-win.width");
+});
+
+/**
+ * Gets the preferred height of the remote debugger window.
+ * @return number
+ */
+XPCOMUtils.defineLazyGetter(DebuggerPreferences, "remoteWinHeight", function() {
+  return Services.prefs.getIntPref("devtools.debugger.ui.remote-win.height");
+});
+
+/**
+ * Gets the preferred default remote debugging host.
+ * @return string
+ */
+XPCOMUtils.defineLazyGetter(DebuggerPreferences, "remoteHost", function() {
+  return Services.prefs.getCharPref("devtools.debugger.remote-host");
+});
+
+/**
+ * Gets the preferred default remote debugging port.
+ * @return number
+ */
+XPCOMUtils.defineLazyGetter(DebuggerPreferences, "remotePort", function() {
+  return Services.prefs.getIntPref("devtools.debugger.remote-port");
+});
--- a/browser/devtools/debugger/debugger-controller.js
+++ b/browser/devtools/debugger/debugger-controller.js
@@ -109,29 +109,28 @@ let DebuggerController = {
     DebuggerView.Properties.destroy();
 
     DebuggerController.SourceScripts.disconnect();
     DebuggerController.StackFrames.disconnect();
     DebuggerController.ThreadState.disconnect();
 
     this.dispatchEvent("Debugger:Unloaded");
     this._disconnect();
+    this._isRemote && this._quitApp();
   },
 
   /**
    * Initializes a debugger client and connects it to the debugger server,
    * wiring event handlers as necessary.
    */
   _connect: function DC__connect() {
-    if (!DebuggerServer.initialized) {
-      DebuggerServer.init();
-      DebuggerServer.addBrowserActors();
-    }
+    let transport =
+      this._isRemote ? debuggerSocketConnect(Prefs.remoteHost, Prefs.remotePort)
+                     : DebuggerServer.connectPipe();
 
-    let transport = DebuggerServer.connectPipe();
     let client = this.client = new DebuggerClient(transport);
 
     client.addListener("tabNavigated", this._onTabNavigated);
     client.addListener("tabDetached", this._onTabDetached);
 
     client.connect(function(aType, aTraits) {
       client.listTabs(function(aResponse) {
         let tab = aResponse.tabs[aResponse.selected];
@@ -216,16 +215,41 @@ let DebuggerController = {
           });
         });
 
       }.bind(this));
     }.bind(this));
   },
 
   /**
+   * Returns true if this is a remote debugger instance.
+   * @return boolean
+   */
+  get _isRemote() {
+    return !window.parent.content;
+  },
+
+  /**
+   * Attempts to quit the current process if allowed.
+   */
+  _quitApp: function DC__quitApp() {
+    let canceled = Cc["@mozilla.org/supports-PRBool;1"]
+      .createInstance(Ci.nsISupportsPRBool);
+
+    Services.obs.notifyObservers(canceled, "quit-application-requested", null);
+
+    // Somebody canceled our quit request.
+    if (canceled.data) {
+      return;
+    }
+
+    Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit);
+  },
+
+  /**
    * Convenience method, dispatching a custom event.
    *
    * @param string aType
    *        The name of the event.
    * @param string aDetail
    *        The data passed when initializing the event.
    */
   dispatchEvent: function DC_dispatchEvent(aType, aDetail) {
@@ -465,52 +489,71 @@ StackFrames.prototype = {
       let thisVar = localScope.addVar("this");
       thisVar.setGrip({
         type: frame.this.type,
         class: frame.this.class
       });
       this._addExpander(thisVar, frame.this);
     }
 
+    if (frame.environment) {
+      // Add nodes for every argument.
+      let variables = frame.environment.bindings.arguments;
+      for each (let variable in variables) {
+        let name = Object.getOwnPropertyNames(variable)[0];
+        let paramVar = localScope.addVar(name);
+        let paramVal = variable[name].value;
+        paramVar.setGrip(paramVal);
+        this._addExpander(paramVar, paramVal);
+      }
+
+      // Add nodes for every other variable in scope.
+      variables = frame.environment.bindings.variables;
+      for (let variable in variables) {
+        let paramVar = localScope.addVar(variable);
+        let paramVal = variables[variable].value;
+        paramVar.setGrip(paramVal);
+        this._addExpander(paramVar, paramVal);
+      }
+
+      // If we already found 'arguments', we are done here.
+      if ("arguments" in frame.environment.bindings.variables) {
+        // Signal that variables have been fetched.
+        DebuggerController.dispatchEvent("Debugger:FetchedVariables");
+        return;
+      }
+    }
+
+    // Sometimes in call frames with arguments we don't get 'arguments' in the
+    // environment (bug 746601) and we have to construct it manually. Note, that
+    // in this case arguments.callee will be absent, even in the cases where it
+    // shouldn't be.
     if (frame.arguments && frame.arguments.length > 0) {
       // Add "arguments".
       let argsVar = localScope.addVar("arguments");
       argsVar.setGrip({
         type: "object",
         class: "Arguments"
       });
       this._addExpander(argsVar, frame.arguments);
 
-      // Add variables for every argument.
-      let objClient = this.activeThread.pauseGrip(frame.callee);
-      objClient.getSignature(function SF_getSignature(aResponse) {
-        for (let i = 0, l = aResponse.parameters.length; i < l; i++) {
-          let param = aResponse.parameters[i];
-          let paramVar = localScope.addVar(param);
-          let paramVal = frame.arguments[i];
+      // Signal that variables have been fetched.
+      DebuggerController.dispatchEvent("Debugger:FetchedVariables");
+    }
 
-          paramVar.setGrip(paramVal);
-          this._addExpander(paramVar, paramVal);
-        }
-
-        // Signal that call parameters have been fetched.
-        DebuggerController.dispatchEvent("Debugger:FetchedParameters");
-
-      }.bind(this));
-    }
   },
 
   /**
-   * Adds a onexpand callback for a variable, lazily handling the addition of
+   * Adds an 'onexpand' callback for a variable, lazily handling the addition of
    * new properties.
    */
   _addExpander: function SF__addExpander(aVar, aObject) {
     // No need for expansion for null and undefined values, but we do need them
     // for frame.arguments which is a regular array.
-    if (!aObject || typeof aObject !== "object" ||
+    if (!aVar || !aObject || typeof aObject !== "object" ||
         (aObject.type !== "object" && !Array.isArray(aObject))) {
       return;
     }
 
     // Force the twisty to show up.
     aVar.forceShowArrow();
     aVar.onexpand = this._addVarProperties.bind(this, aVar, aObject);
   },
@@ -681,26 +724,27 @@ SourceScripts.prototype = {
     this.activeThread.removeListener("scriptsadded", this._onScriptsAdded);
     this.activeThread.removeListener("scriptscleared", this._onScriptsCleared);
   },
 
   /**
    * Handler for the debugger client's unsolicited newScript notification.
    */
   _onNewScript: function SS__onNewScript(aNotification, aPacket) {
-    this._addScript({ url: aPacket.url, startLine: aPacket.startLine });
+    this._addScript({ url: aPacket.url, startLine: aPacket.startLine }, true);
   },
 
   /**
    * Handler for the thread client's scriptsadded notification.
    */
   _onScriptsAdded: function SS__onScriptsAdded() {
     for each (let script in this.activeThread.cachedScripts) {
-      this._addScript(script);
+      this._addScript(script, false);
     }
+    DebuggerView.Scripts.commitScripts();
   },
 
   /**
    * Handler for the thread client's scriptscleared notification.
    */
   _onScriptsCleared: function SS__onScriptsCleared() {
     DebuggerView.Scripts.empty();
   },
@@ -743,51 +787,70 @@ SourceScripts.prototype = {
     let q = aUrl.indexOf('?');
     if (q > -1) {
       return aUrl.slice(0, q);
     }
     return aUrl;
   },
 
   /**
+   * Gets the prePath for a script URL.
+   *
+   * @param string aUrl
+   *        The script url.
+   * @return string
+   *         The script prePath if the url is valid, null otherwise.
+   */
+  _getScriptPrePath: function SS__getScriptDomain(aUrl) {
+    try {
+      return Services.io.newURI(aUrl, null, null).prePath + "/";
+    } catch (e) {
+    }
+    return null;
+  },
+
+  /**
    * Gets a unique, simplified label from a script url.
    * ex: a). ici://some.address.com/random/subrandom/
    *     b). ni://another.address.org/random/subrandom/page.html
    *     c). san://interesting.address.gro/random/script.js
    *     d). si://interesting.address.moc/random/another/script.js
    * =>
    *     a). subrandom/
    *     b). page.html
    *     c). script.js
    *     d). another/script.js
    *
    * @param string aUrl
    *        The script url.
    * @param string aHref
    *        The content location href to be used. If unspecified, it will
-   *        defalult to debugged panrent window location.
+   *        default to the script url prepath.
    * @return string
    *         The simplified label.
    */
   _getScriptLabel: function SS__getScriptLabel(aUrl, aHref) {
     let url = this._trimUrlQuery(aUrl);
 
     if (this._labelsCache[url]) {
       return this._labelsCache[url];
     }
 
-    let href = aHref || window.parent.content.location.href;
+    let content = window.parent.content;
+    let domain = content ? content.location.href : this._getScriptPrePath(aUrl);
+
+    let href = aHref || domain;
     let pathElements = url.split("/");
     let label = pathElements.pop() || (pathElements.pop() + "/");
 
-    // if the label as a leaf name is alreay present in the scripts list
+    // If the label as a leaf name is already present in the scripts list.
     if (DebuggerView.Scripts.containsLabel(label)) {
       label = url.replace(href.substring(0, href.lastIndexOf("/") + 1), "");
 
-      // if the path/to/script is exactly the same, we're in different domains
+      // If the path/to/script is exactly the same, we're in different domains.
       if (DebuggerView.Scripts.containsLabel(label)) {
         label = url;
       }
     }
 
     return this._labelsCache[url] = label;
   },
 
@@ -795,25 +858,26 @@ SourceScripts.prototype = {
    * Clears the labels cache, populated by SS_getScriptLabel.
    * This should be done every time the content location changes.
    */
   _clearLabelsCache: function SS__clearLabelsCache() {
     this._labelsCache = {};
   },
 
   /**
-   * Add the specified script to the list and display it in the editor if the
-   * editor is empty.
+   * Add the specified script to the list.
+   *
+   * @param object aScript
+   *        The script object coming from the active thread.
+   * @param boolean aForceFlag
+   *        True to force the script to be immediately added.
    */
-  _addScript: function SS__addScript(aScript) {
-    DebuggerView.Scripts.addScript(this._getScriptLabel(aScript.url), aScript);
-
-    if (DebuggerView.editor.getCharCount() == 0) {
-      this.showScript(aScript);
-    }
+  _addScript: function SS__addScript(aScript, aForceFlag) {
+    DebuggerView.Scripts.addScript(
+      this._getScriptLabel(aScript.url), aScript, aForceFlag);
   },
 
   /**
    * Load the editor with the script text if available, otherwise fire an event
    * to load and display the script text.
    *
    * @param object aScript
    *        The script object coming from the active thread.
@@ -871,17 +935,17 @@ SourceScripts.prototype = {
       url: aScript.url
     });
   },
 
   /**
    * Handles notifications to load a source script from the cache or from a
    * local file.
    *
-   * XXX: Tt may be better to use nsITraceableChannel to get to the sources
+   * XXX: It may be better to use nsITraceableChannel to get to the sources
    * without relying on caching when we can (not for eval, etc.):
    * http://www.softwareishard.com/blog/firebug/nsitraceablechannel-intercept-http-traffic/
    */
   _onLoadSource: function SS__onLoadSource(aEvent) {
     let url = aEvent.detail.url;
     let options = aEvent.detail.options;
     let self = this;
 
@@ -962,17 +1026,17 @@ SourceScripts.prototype = {
    * Log an error message in the error console when a script fails to load.
    *
    * @param string aUrl
    *        The URL of the source script.
    * @param string aStatus
    *        The failure status code.
    */
   _logError: function SS__logError(aUrl, aStatus) {
-    Components.utils.reportError(L10N.getFormatStr("loadingError", [aUrl, aStatus]));
+    Cu.reportError(L10N.getFormatStr("loadingError", [aUrl, aStatus]));
   },
 };
 
 /**
  * Handles all the breakpoints in the current debugger.
  */
 function Breakpoints() {
   this._onEditorBreakpointChange = this._onEditorBreakpointChange.bind(this);
@@ -1254,16 +1318,37 @@ let L10N = {
   }
 };
 
 XPCOMUtils.defineLazyGetter(L10N, "stringBundle", function() {
   return Services.strings.createBundle(DBG_STRINGS_URI);
 });
 
 /**
+ * Shortcuts for accessing various debugger preferences.
+ */
+let Prefs = {};
+
+/**
+ * Gets the preferred default remote debugging host.
+ * @return string
+ */
+XPCOMUtils.defineLazyGetter(Prefs, "remoteHost", function() {
+  return Services.prefs.getCharPref("devtools.debugger.remote-host");
+});
+
+/**
+ * Gets the preferred default remote debugging port.
+ * @return number
+ */
+XPCOMUtils.defineLazyGetter(Prefs, "remotePort", function() {
+  return Services.prefs.getIntPref("devtools.debugger.remote-port");
+});
+
+/**
  * Preliminary setup for the DebuggerController object.
  */
 DebuggerController.init();
 DebuggerController.ThreadState = new ThreadState();
 DebuggerController.StackFrames = new StackFrames();
 DebuggerController.SourceScripts = new SourceScripts();
 DebuggerController.Breakpoints = new Breakpoints();
 
--- a/browser/devtools/debugger/debugger-view.js
+++ b/browser/devtools/debugger/debugger-view.js
@@ -85,53 +85,72 @@ let DebuggerView = {
   }
 };
 
 /**
  * Functions handling the scripts UI.
  */
 function ScriptsView() {
   this._onScriptsChange = this._onScriptsChange.bind(this);
+  this._onScriptsSearch = this._onScriptsSearch.bind(this);
 }
 
 ScriptsView.prototype = {
 
   /**
    * Removes all elements from the scripts container, leaving it empty.
    */
   empty: function DVS_empty() {
     while (this._scripts.firstChild) {
       this._scripts.removeChild(this._scripts.firstChild);
     }
   },
 
   /**
+   * Removes the input in the searchbox and unhides all the scripts.
+   */
+  clearSearch: function DVS_clearSearch() {
+    this._searchbox.value = "";
+    this._onScriptsSearch({});
+  },
+
+  /**
    * Checks whether the script with the specified URL is among the scripts
    * known to the debugger and shown in the list.
    *
    * @param string aUrl
    *        The script URL.
    * @return boolean
    */
   contains: function DVS_contains(aUrl) {
+    if (this._tmpScripts.some(function(element) {
+      return element.script.url == aUrl;
+    })) {
+      return true;
+    }
     if (this._scripts.getElementsByAttribute("value", aUrl).length > 0) {
       return true;
     }
     return false;
   },
 
   /**
    * Checks whether the script with the specified label is among the scripts
    * known to the debugger and shown in the list.
    *
    * @param string aLabel
    *        The script label.
    * @return boolean
    */
   containsLabel: function DVS_containsLabel(aLabel) {
+    if (this._tmpScripts.some(function(element) {
+      return element.label == aLabel;
+    })) {
+      return true;
+    }
     if (this._scripts.getElementsByAttribute("label", aLabel).length > 0) {
       return true;
     }
     return false;
   },
 
   /**
    * Selects the script with the specified URL from the list.
@@ -167,80 +186,258 @@ ScriptsView.prototype = {
    * @return string | null
    */
   get selected() {
     return this._scripts.selectedItem ?
            this._scripts.selectedItem.value : null;
   },
 
   /**
+   * Returns the list of labels in the scripts container.
+   * @return array
+   */
+  get scriptLabels() {
+    let labels = [];
+    for (let i = 0, l = this._scripts.itemCount; i < l; i++) {
+      labels.push(this._scripts.getItemAtIndex(i).label);
+    }
+    return labels;
+  },
+
+  /**
    * Returns the list of URIs for scripts in the page.
    * @return array
    */
   get scriptLocations() {
     let locations = [];
     for (let i = 0, l = this._scripts.itemCount; i < l; i++) {
       locations.push(this._scripts.getItemAtIndex(i).value);
     }
     return locations;
   },
 
   /**
-   * Adds a script to the scripts container.
-   * If the script already exists (was previously added), null is returned.
-   * Otherwise, the newly created element is returned.
+   * Gets the number of visible (hidden=false) scripts in the container.
+   * @return number
+   */
+  get visibleItemsCount() {
+    let count = 0;
+    for (let i = 0, l = this._scripts.itemCount; i < l; i++) {
+      count += this._scripts.getItemAtIndex(i).hidden ? 0 : 1;
+    }
+    return count;
+  },
+
+  /**
+   * Prepares a script to be added to the scripts container. This allows
+   * for a large number of scripts to be batched up before being
+   * alphabetically sorted and added in the container.
+   * @see ScriptsView.commitScripts
+   *
+   * If aForceFlag is true, the script will be immediately inserted at the
+   * necessary position in the container so that all the scripts remain sorted.
+   * This can be much slower than batching up multiple scripts.
+   *
+   * @param string aLabel
+   *        The simplified script location to be shown.
+   * @param string aScript
+   *        The source script.
+   * @param boolean aForceFlag
+   *        True to force the script to be immediately added.
+   */
+  addScript: function DVS_addScript(aLabel, aScript, aForceFlag) {
+    // Batch the script to be added later.
+    if (!aForceFlag) {
+      this._tmpScripts.push({ label: aLabel, script: aScript });
+      return;
+    }
+
+    // Find the target position in the menulist and insert the script there.
+    for (let i = 0, l = this._scripts.itemCount; i < l; i++) {
+      if (this._scripts.getItemAtIndex(i).label > aLabel) {
+        this._createScriptElement(aLabel, aScript, i);
+        return;
+      }
+    }
+    // The script is alphabetically the last one.
+    this._createScriptElement(aLabel, aScript, -1, true);
+  },
+
+  /**
+   * Adds all the prepared scripts to the scripts container.
+   * If a script already exists (was previously added), nothing happens.
+   */
+  commitScripts: function DVS_commitScripts() {
+    let newScripts = this._tmpScripts;
+    this._tmpScripts = [];
+
+    if (!newScripts || !newScripts.length) {
+      return;
+    }
+    newScripts.sort(function(a, b) {
+      return a.label.toLowerCase() > b.label.toLowerCase();
+    });
+
+    for (let i = 0, l = newScripts.length; i < l; i++) {
+      let item = newScripts[i];
+      this._createScriptElement(item.label, item.script, -1, true);
+    }
+  },
+
+  /**
+   * Creates a custom script element and adds it to the scripts container.
+   * If the script with the specified label already exists, nothing happens.
    *
    * @param string aLabel
    *        The simplified script location to be shown.
    * @param string aScript
    *        The source script.
-   * @return object
-   *         The newly created html node representing the added script.
+   * @param number aIndex
+   *        The index where to insert to new script in the container.
+   *        Pass -1 to append the script at the end.
+   * @param boolean aSelectIfEmptyFlag
+   *        True to set the newly created script as the currently selected item
+   *        if there are no other existing scripts in the container.
    */
-  addScript: function DVS_addScript(aLabel, aScript) {
+  _createScriptElement: function DVS__createScriptElement(
+    aLabel, aScript, aIndex, aSelectIfEmptyFlag)
+  {
     // Make sure we don't duplicate anything.
-    if (this.containsLabel(aLabel)) {
-      return null;
+    if (aLabel == "null" || this.containsLabel(aLabel)) {
+      return;
     }
 
-    let script = this._scripts.appendItem(aLabel, aScript.url);
-    script.setAttribute("tooltiptext", aScript.url);
-    script.setUserData("sourceScript", aScript, null);
+    let scriptItem =
+      aIndex == -1 ? this._scripts.appendItem(aLabel, aScript.url)
+                   : this._scripts.insertItemAt(aIndex, aLabel, aScript.url);
 
-    this._scripts.selectedItem = script;
-    return script;
+    scriptItem.setAttribute("tooltiptext", aScript.url);
+    scriptItem.setUserData("sourceScript", aScript, null);
+
+    if (this._scripts.itemCount == 1 && aSelectIfEmptyFlag) {
+      this._scripts.selectedItem = scriptItem;
+    }
   },
 
   /**
-   * The cached click listener for the scripts container.
+   * The click listener for the scripts container.
    */
   _onScriptsChange: function DVS__onScriptsChange() {
     let script = this._scripts.selectedItem.getUserData("sourceScript");
+    this._preferredScript = script;
     DebuggerController.SourceScripts.showScript(script);
   },
 
   /**
-   * The cached scripts container.
+   * The search listener for the scripts search box.
+   */
+  _onScriptsSearch: function DVS__onScriptsSearch(e) {
+    let editor = DebuggerView.editor;
+    let scripts = this._scripts;
+    let rawValue = this._searchbox.value.toLowerCase();
+
+    let rawLength = rawValue.length;
+    let lastColon = rawValue.lastIndexOf(":");
+    let lastAt = rawValue.lastIndexOf("@");
+
+    let fileEnd = lastColon != -1 ? lastColon : lastAt != -1 ? lastAt : rawLength;
+    let lineEnd = lastAt != -1 ? lastAt : rawLength;
+
+    let file = rawValue.slice(0, fileEnd);
+    let line = window.parseInt(rawValue.slice(fileEnd + 1, lineEnd)) || -1;
+    let token = rawValue.slice(lineEnd + 1);
+
+    // Presume we won't find anything.
+    scripts.selectedItem = this._preferredScript;
+
+    // If we're not searching for a file anymore, unhide all the scripts.
+    if (!file) {
+      for (let i = 0, l = scripts.itemCount; i < l; i++) {
+        scripts.getItemAtIndex(i).hidden = false;
+      }
+    } else {
+      for (let i = 0, l = scripts.itemCount, found = false; i < l; i++) {
+        let item = scripts.getItemAtIndex(i);
+        let target = item.value.toLowerCase();
+
+        // Search is not case sensitive, and is tied to the url not the label.
+        if (target.match(file)) {
+          item.hidden = false;
+
+          if (!found) {
+            found = true;
+            scripts.selectedItem = item;
+          }
+        }
+        // Hide what doesn't match our search.
+        else {
+          item.hidden = true;
+        }
+      }
+    }
+    if (line > -1) {
+      editor.setCaretPosition(line - 1);
+    }
+    if (token) {
+      let offset = editor.find(token, { ignoreCase: true });
+      if (offset > -1) {
+        editor.setCaretPosition(0);
+        editor.setCaretOffset(offset);
+      }
+    }
+  },
+
+  /**
+   * The keyup listener for the scripts search box.
+   */
+  _onScriptsKeyUp: function DVS__onScriptsKeyUp(e) {
+    if (e.keyCode === e.DOM_VK_ESCAPE) {
+      DebuggerView.editor.focus();
+      return;
+    }
+
+    if (e.keyCode === e.DOM_VK_RETURN || e.keyCode === e.DOM_VK_ENTER) {
+      let editor = DebuggerView.editor;
+      let offset = editor.findNext(true);
+      if (offset > -1) {
+        editor.setCaretPosition(0);
+        editor.setCaretOffset(offset);
+      }
+    }
+  },
+
+  /**
+   * The cached scripts container and search box.
    */
   _scripts: null,
+  _searchbox: null,
 
   /**
    * Initialization function, called when the debugger is initialized.
    */
   initialize: function DVS_initialize() {
     this._scripts = document.getElementById("scripts");
+    this._searchbox = document.getElementById("scripts-search");
     this._scripts.addEventListener("select", this._onScriptsChange, false);
+    this._searchbox.addEventListener("select", this._onScriptsSearch, false);
+    this._searchbox.addEventListener("input", this._onScriptsSearch, false);
+    this._searchbox.addEventListener("keyup", this._onScriptsKeyUp, false);
+    this.commitScripts();
   },
 
   /**
    * Destruction function, called when the debugger is shut down.
    */
   destroy: function DVS_destroy() {
     this._scripts.removeEventListener("select", this._onScriptsChange, false);
+    this._searchbox.removeEventListener("select", this._onScriptsSearch, false);
+    this._searchbox.removeEventListener("input", this._onScriptsSearch, false);
+    this._searchbox.removeEventListener("keyup", this._onScriptsKeyUp, false);
     this._scripts = null;
+    this._searchbox = null;
   }
 };
 
 /**
  * Functions handling the html stackframes UI.
  */
 function StackFramesView() {
   this._onFramesScroll = this._onFramesScroll.bind(this);
@@ -272,16 +469,18 @@ StackFramesView.prototype = {
     else if (aState == "attached") {
       status.textContent = L10N.getStr("runningState");
       resume.label = L10N.getStr("pauseLabel");
     }
     // No valid state parameter.
     else {
       status.textContent = "";
     }
+
+    DebuggerView.Scripts.clearSearch();
   },
 
   /**
    * Removes all elements from the stackframes container, leaving it empty.
    */
   empty: function DVF_empty() {
     while (this._frames.firstChild) {
       this._frames.removeChild(this._frames.firstChild);
@@ -295,17 +494,17 @@ StackFramesView.prototype = {
   emptyText: function DVF_emptyText() {
     // Make sure the container is empty first.
     this.empty();
 
     let item = document.createElement("div");
 
     // The empty node should look grayed out to avoid confusion.
     item.className = "empty list-item";
-    item.appendChild(document.createTextNode(L10N.getStr("emptyText")));
+    item.appendChild(document.createTextNode(L10N.getStr("emptyStackText")));
 
     this._frames.appendChild(item);
   },
 
   /**
    * Adds a frame to the stackframes container.
    * If the frame already exists (was previously added), null is returned.
    * Otherwise, the newly created element is returned.
@@ -376,17 +575,17 @@ StackFramesView.prototype = {
 
   /**
    * Deselects a frame from the stackframe container.
    *
    * @param number aDepth
    *        The frame depth specified by the debugger.
    */
   unhighlightFrame: function DVF_unhighlightFrame(aDepth) {
-    this.highlightFrame(aDepth, true)
+    this.highlightFrame(aDepth, true);
   },
 
   /**
    * Gets the current dirty state.
    *
    * @return boolean value
    *         True if should load more frames.
    */
--- a/browser/devtools/debugger/debugger.xul
+++ b/browser/devtools/debugger/debugger.xul
@@ -76,16 +76,18 @@
   <div id="body" class="vbox flex">
     <xul:toolbar id="dbg-toolbar">
       <xul:button id="close">&debuggerUI.closeButton;</xul:button>
       <xul:button id="resume"/>
       <xul:button id="step-over">&debuggerUI.stepOverButton;</xul:button>
       <xul:button id="step-in">&debuggerUI.stepInButton;</xul:button>
       <xul:button id="step-out">&debuggerUI.stepOutButton;</xul:button>
       <xul:menulist id="scripts"/>
+      <xul:textbox id="scripts-search" type="search"
+                   emptytext="&debuggerUI.emptyFilterText;"/>
     </xul:toolbar>
     <div id="dbg-content" class="hbox flex">
       <div id="stack" class="vbox">
         <div class="title unselectable">&debuggerUI.stackTitle;</div>
         <div id="stackframes" class="vbox flex"></div>
       </div>
       <div id="script" class="vbox flex">
         <div class="title unselectable">&debuggerUI.scriptTitle;</div>
--- a/browser/devtools/debugger/test/Makefile.in
+++ b/browser/devtools/debugger/test/Makefile.in
@@ -41,16 +41,17 @@ topsrcdir       = @top_srcdir@
 srcdir          = @srcdir@
 VPATH           = @srcdir@
 relativesrcdir  = browser/devtools/debugger/test
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _BROWSER_TEST_FILES = \
+	browser_dbg_createRemote.js \
 	browser_dbg_debuggerstatement.js \
 	browser_dbg_listtabs.js \
 	browser_dbg_tabactor-01.js \
 	browser_dbg_tabactor-02.js \
 	browser_dbg_contextactor-01.js \
 	browser_dbg_contextactor-02.js \
 	testactors.js \
 	browser_dbg_nav-01.js \
@@ -65,16 +66,19 @@ include $(topsrcdir)/config/rules.mk
 	browser_dbg_panesize.js \
 	browser_dbg_stack-01.js \
 	browser_dbg_stack-02.js \
 	browser_dbg_stack-03.js \
 	browser_dbg_stack-04.js \
 	browser_dbg_stack-05.js \
 	browser_dbg_location-changes.js \
 	browser_dbg_script-switching.js \
+	browser_dbg_scripts-sorting.js \
+	browser_dbg_scripts-searching-01.js \
+	browser_dbg_scripts-searching-02.js \
 	browser_dbg_pause-resume.js \
 	browser_dbg_update-editor-mode.js \
 	$(warning browser_dbg_select-line.js temporarily disabled due to oranges, see bug 726609) \
 	browser_dbg_clean-exit.js \
 	browser_dbg_bug723069_editor-breakpoints.js \
 	browser_dbg_bug731394_editor-contextmenu.js \
 	browser_dbg_displayName.js \
 	browser_dbg_iframes.js \
--- a/browser/devtools/debugger/test/browser_dbg_bug723069_editor-breakpoints.js
+++ b/browser/devtools/debugger/test/browser_dbg_bug723069_editor-breakpoints.js
@@ -18,47 +18,54 @@ let gBreakpoints = null;
 
 function test()
 {
   let tempScope = {};
   Cu.import("resource:///modules/source-editor.jsm", tempScope);
   let SourceEditor = tempScope.SourceEditor;
   let scriptShown = false;
   let framesAdded = false;
+  let resumed = false;
+  let testStarted = false;
 
   debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
     gTab = aTab;
     gDebuggee = aDebuggee;
     gPane = aPane;
     gDebugger = gPane.debuggerWindow;
+    resumed = true;
+
     gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
       framesAdded = true;
-      runTest();
+      executeSoon(startTest);
     });
 
-    gDebuggee.firstCall();
+    executeSoon(function() {
+      gDebuggee.firstCall();
+    });
   });
 
-  window.addEventListener("Debugger:ScriptShown", function _onEvent(aEvent) {
-    let url = aEvent.detail.url;
-    if (url.indexOf("-02.js") != -1) {
-      scriptShown = true;
-      window.removeEventListener(aEvent.type, _onEvent);
-      runTest();
-    }
-  });
+  function onScriptShown(aEvent)
+  {
+    scriptShown = aEvent.detail.url.indexOf("-02.js") != -1;
+    executeSoon(startTest);
+  }
 
-  function runTest()
+  window.addEventListener("Debugger:ScriptShown", onScriptShown);
+
+  function startTest()
   {
-    if (scriptShown && framesAdded) {
-      Services.tm.currentThread.dispatch({ run: onScriptShown }, 0);
+    if (scriptShown && framesAdded && resumed && !testStarted) {
+      window.removeEventListener("Debugger:ScriptShown", onScriptShown);
+      testStarted = true;
+      Services.tm.currentThread.dispatch({ run: performTest }, 0);
     }
   }
 
-  function onScriptShown()
+  function performTest()
   {
     gScripts = gDebugger.DebuggerView.Scripts;
 
     is(gDebugger.DebuggerController.activeThread.state, "paused",
       "Should only be getting stack frames while paused.");
 
     is(gScripts._scripts.itemCount, 2, "Found the expected number of scripts.");
 
--- a/browser/devtools/debugger/test/browser_dbg_bug731394_editor-contextmenu.js
+++ b/browser/devtools/debugger/test/browser_dbg_bug731394_editor-contextmenu.js
@@ -16,47 +16,53 @@ function test()
 {
   let tempScope = {};
   Cu.import("resource:///modules/source-editor.jsm", tempScope);
   let SourceEditor = tempScope.SourceEditor;
 
   let contextMenu = null;
   let scriptShown = false;
   let framesAdded = false;
+  let resumed = false;
+  let testStarted = false;
 
   debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
     gTab = aTab;
     gDebuggee = aDebuggee;
     gPane = aPane;
     gDebugger = gPane.debuggerWindow;
+    resumed = true;
 
     gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
       framesAdded = true;
-      runTest();
+      executeSoon(startTest);
     });
-    gDebuggee.firstCall();
+
+    executeSoon(function() {
+      gDebuggee.firstCall();
+    });
   });
 
-  window.addEventListener("Debugger:ScriptShown", function _onEvent(aEvent) {
-    let url = aEvent.detail.url;
-    if (url.indexOf("-02.js") != -1) {
-      scriptShown = true;
-      window.removeEventListener(aEvent.type, _onEvent);
-      runTest();
-    }
-  });
+  function onScriptShown(aEvent) {
+    scriptShown = aEvent.detail.url.indexOf("-02.js") != -1;
+    executeSoon(startTest);
+  }
+
+  window.addEventListener("Debugger:ScriptShown", onScriptShown);
 
-  function runTest()
+  function startTest()
   {
-    if (scriptShown && framesAdded) {
-      Services.tm.currentThread.dispatch({ run: onScriptShown }, 0);
+    if (scriptShown && framesAdded && resumed && !testStarted) {
+      testStarted = true;
+      window.removeEventListener("Debugger:ScriptShown", onScriptShown);
+      Services.tm.currentThread.dispatch({ run: performTest }, 0);
     }
   }
 
-  function onScriptShown()
+  function performTest()
   {
     let scripts = gDebugger.DebuggerView.Scripts._scripts;
 
     is(gDebugger.DebuggerController.activeThread.state, "paused",
       "Should only be getting stack frames while paused.");
 
     is(scripts.itemCount, 2, "Found the expected number of scripts.");
 
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/test/browser_dbg_createRemote.js
@@ -0,0 +1,86 @@
+/* vim:set ts=2 sw=2 sts=2 et: */
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+var gProcess = null;
+var gTab = null;
+var gDebuggee = null;
+
+function test() {
+  remote_debug_tab_pane(STACK_URL, aOnClosing, function(aTab, aDebuggee, aProcess) {
+    gTab = aTab;
+    gDebuggee = aDebuggee;
+    gProcess = aProcess;
+
+    testSimpleCall();
+  });
+}
+
+function testSimpleCall() {
+  Services.tm.currentThread.dispatch({ run: function() {
+
+    ok(gProcess._dbgProcess,
+      "The remote debugger process wasn't created properly!");
+    ok(gProcess._dbgProcess.isRunning,
+      "The remote debugger process isn't running!");
+    is(typeof gProcess._dbgProcess.pid, "number",
+      "The remote debugger process doesn't have a pid (?!)");
+
+    info("process location: " + gProcess._dbgProcess.location);
+    info("process pid: " + gProcess._dbgProcess.pid);
+    info("process name: " + gProcess._dbgProcess.processName);
+    info("process sig: " + gProcess._dbgProcess.processSignature);
+
+    ok(gProcess._dbgProfile,
+      "The remote debugger profile wasn't created properly!");
+    ok(gProcess._dbgProfile.localDir,
+      "The remote debugger profile doesn't have a localDir...");
+    ok(gProcess._dbgProfile.rootDir,
+      "The remote debugger profile doesn't have a rootDir...");
+    ok(gProcess._dbgProfile.name,
+      "The remote debugger profile doesn't have a name...");
+
+    info("profile localDir: " + gProcess._dbgProfile.localDir);
+    info("profile rootDir: " + gProcess._dbgProfile.rootDir);
+    info("profile name: " + gProcess._dbgProfile.name);
+
+    let profileService = Cc["@mozilla.org/toolkit/profile-service;1"]
+      .createInstance(Ci.nsIToolkitProfileService);
+
+    let profile = profileService.getProfileByName(gProcess._dbgProfile.name);
+
+    ok(profile,
+      "The remote debugger profile wasn't *actually* created properly!");
+    is(profile.localDir.path, gProcess._dbgProfile.localDir.path,
+      "The remote debugger profile doesn't have the correct localDir!");
+    is(profile.rootDir.path, gProcess._dbgProfile.rootDir.path,
+      "The remote debugger profile doesn't have the correct rootDir!");
+
+    DebuggerUI.toggleRemoteDebugger();
+  }}, 0);
+}
+
+function aOnClosing() {
+  ok(!gProcess._dbgProcess.isRunning,
+    "The remote debugger process isn't closed as it should be!");
+  is(gProcess._dbgProcess.exitValue, (Services.appinfo.OS == "WINNT" ? 0 : 256),
+    "The remote debugger process didn't die cleanly.");
+
+  info("process exit value: " + gProcess._dbgProcess.exitValue);
+
+  info("profile localDir: " + gProcess._dbgProfile.localDir.path);
+  info("profile rootDir: " + gProcess._dbgProfile.rootDir.path);
+  info("profile name: " + gProcess._dbgProfile.name);
+
+  executeSoon(function() {
+    finish();
+  });
+}
+
+registerCleanupFunction(function() {
+  removeTab(gTab);
+  gProcess = null;
+  gTab = null;
+  gDebuggee = null;
+});
--- a/browser/devtools/debugger/test/browser_dbg_propertyview-01.js
+++ b/browser/devtools/debugger/test/browser_dbg_propertyview-01.js
@@ -80,38 +80,38 @@ function testSimpleCall() {
 
   gDebuggee.simpleCall();
 }
 
 function resumeAndFinish() {
   gDebugger.DebuggerController.activeThread.resume(function() {
     let vs = gDebugger.DebuggerView.Scripts;
     let ss = gDebugger.DebuggerController.SourceScripts;
-    ss._onScriptsCleared();
+    vs.empty();
+    vs._scripts.removeEventListener("select", vs._onScriptsChange, false);
 
     is(ss._trimUrlQuery("a/b/c.d?test=1&random=4"), "a/b/c.d",
       "Trimming the url query isn't done properly.");
 
     let urls = [
       { href: "ici://some.address.com/random/", leaf: "subrandom/" },
       { href: "ni://another.address.org/random/subrandom/", leaf: "page.html" },
       { href: "san://interesting.address.gro/random/", leaf: "script.js" },
       { href: "si://interesting.address.moc/random/", leaf: "script.js" },
       { href: "si://interesting.address.moc/random/", leaf: "x/script.js" },
       { href: "si://interesting.address.moc/random/", leaf: "x/y/script.js?a=1" },
       { href: "si://interesting.address.moc/random/x/", leaf: "y/script.js?a=1&b=2" },
       { href: "si://interesting.address.moc/random/x/y/", leaf: "script.js?a=1&b=2&c=3" }
     ];
 
-    vs._scripts.removeEventListener("select", vs._onScriptsChange, false);
-
     urls.forEach(function(url) {
       executeSoon(function() {
         let loc = url.href + url.leaf;
         vs.addScript(ss._getScriptLabel(loc, url.href), { url: loc });
+        vs.commitScripts();
       });
     });
 
     executeSoon(function() {
       for (let i = 0; i < vs._scripts.itemCount; i++) {
         let lab = vs._scripts.getItemAtIndex(i).getAttribute("label");
         let loc = urls[i].href + urls[i].leaf;
 
--- a/browser/devtools/debugger/test/browser_dbg_propertyview-07.js
+++ b/browser/devtools/debugger/test/browser_dbg_propertyview-07.js
@@ -22,20 +22,20 @@ function test()
     testFrameParameters();
   });
 }
 
 function testFrameParameters()
 {
   dump("Started testFrameParameters!\n");
 
-  gDebugger.addEventListener("Debugger:FetchedParameters", function test() {
-    dump("Entered Debugger:FetchedParameters!\n");
+  gDebugger.addEventListener("Debugger:FetchedVariables", function test() {
+    dump("Entered Debugger:FetchedVariables!\n");
 
-    gDebugger.removeEventListener("Debugger:FetchedParameters", test, false);
+    gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
     Services.tm.currentThread.dispatch({ run: function() {
 
       dump("After currentThread.dispatch!\n");
 
       var frames = gDebugger.DebuggerView.StackFrames._frames,
           childNodes = frames.childNodes,
           localScope = gDebugger.DebuggerView.Properties.localScope,
           localNodes = localScope.querySelector(".details").childNodes;
@@ -47,43 +47,52 @@ function testFrameParameters()
       dump("localNodes - " + localNodes.constructor + "\n");
 
       is(gDebugger.DebuggerController.activeThread.state, "paused",
         "Should only be getting stack frames while paused.");
 
       is(frames.querySelectorAll(".dbg-stackframe").length, 3,
         "Should have three frames.");
 
-      is(localNodes.length, 8,
+      is(localNodes.length, 11,
         "The localScope should contain all the created variable elements.");
 
       is(localNodes[0].querySelector(".info").textContent, "[object Proxy]",
         "Should have the right property value for 'this'.");
 
-      is(localNodes[1].querySelector(".info").textContent, "[object Arguments]",
-        "Should have the right property value for 'arguments'.");
-
-      is(localNodes[2].querySelector(".info").textContent, "[object Object]",
+      is(localNodes[1].querySelector(".info").textContent, "[object Object]",
         "Should have the right property value for 'aArg'.");
 
-      is(localNodes[3].querySelector(".info").textContent, '"beta"',
+      is(localNodes[2].querySelector(".info").textContent, '"beta"',
         "Should have the right property value for 'bArg'.");
 
-      is(localNodes[4].querySelector(".info").textContent, "3",
+      is(localNodes[3].querySelector(".info").textContent, "3",
         "Should have the right property value for 'cArg'.");
 
-      is(localNodes[5].querySelector(".info").textContent, "false",
+      is(localNodes[4].querySelector(".info").textContent, "false",
         "Should have the right property value for 'dArg'.");
 
-      is(localNodes[6].querySelector(".info").textContent, "null",
+      is(localNodes[5].querySelector(".info").textContent, "null",
         "Should have the right property value for 'eArg'.");
 
-      is(localNodes[7].querySelector(".info").textContent, "undefined",
+      is(localNodes[6].querySelector(".info").textContent, "undefined",
         "Should have the right property value for 'fArg'.");
 
+      is(localNodes[7].querySelector(".info").textContent, "1",
+        "Should have the right property value for 'a'.");
+
+      is(localNodes[8].querySelector(".info").textContent, "[object Object]",
+        "Should have the right property value for 'b'.");
+
+      is(localNodes[9].querySelector(".info").textContent, "[object Object]",
+        "Should have the right property value for 'c'.");
+
+      is(localNodes[10].querySelector(".info").textContent, "[object Arguments]",
+        "Should have the right property value for 'arguments'.");
+
       resumeAndFinish();
     }}, 0);
   }, false);
 
   EventUtils.sendMouseEvent({ type: "click" },
     content.document.querySelector("button"),
     content.window);
 }
--- a/browser/devtools/debugger/test/browser_dbg_propertyview-08.js
+++ b/browser/devtools/debugger/test/browser_dbg_propertyview-08.js
@@ -22,20 +22,20 @@ function test()
     testFrameParameters();
   });
 }
 
 function testFrameParameters()
 {
   dump("Started testFrameParameters!\n");
 
-  gDebugger.addEventListener("Debugger:FetchedParameters", function test() {
-    dump("Entered Debugger:FetchedParameters!\n");
+  gDebugger.addEventListener("Debugger:FetchedVariables", function test() {
+    dump("Entered Debugger:FetchedVariables!\n");
 
-    gDebugger.removeEventListener("Debugger:FetchedParameters", test, false);
+    gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
     Services.tm.currentThread.dispatch({ run: function() {
 
       dump("After currentThread.dispatch!\n");
 
       var frames = gDebugger.DebuggerView.StackFrames._frames,
           localScope = gDebugger.DebuggerView.Properties.localScope,
           localNodes = localScope.querySelector(".details").childNodes;
 
@@ -45,82 +45,98 @@ function testFrameParameters()
       dump("localNodes - " + localNodes.constructor + "\n");
 
       is(gDebugger.DebuggerController.activeThread.state, "paused",
         "Should only be getting stack frames while paused.");
 
       is(frames.querySelectorAll(".dbg-stackframe").length, 3,
         "Should have three frames.");
 
-      is(localNodes.length, 8,
+      is(localNodes.length, 11,
         "The localScope should contain all the created variable elements.");
 
       is(localNodes[0].querySelector(".info").textContent, "[object Proxy]",
         "Should have the right property value for 'this'.");
 
-      // Expand the __proto__ and arguments tree nodes. This causes their
-      // properties to be retrieved and displayed.
+      // Expand the '__proto__', 'arguments' and 'a' tree nodes. This causes
+      // their properties to be retrieved and displayed.
       localNodes[0].expand();
-      localNodes[1].expand();
+      localNodes[9].expand();
+      localNodes[10].expand();
 
       // Poll every few milliseconds until the properties are retrieved.
       // It's important to set the timer in the chrome window, because the
       // content window timers are disabled while the debuggee is paused.
       let count = 0;
       let intervalID = window.setInterval(function(){
         if (++count > 50) {
           ok(false, "Timed out while polling for the properties.");
           resumeAndFinish();
         }
-        if (!localNodes[0].fetched || !localNodes[1].fetched) {
+        if (!localNodes[0].fetched ||
+            !localNodes[9].fetched ||
+            !localNodes[10].fetched) {
           return;
         }
         window.clearInterval(intervalID);
         is(localNodes[0].querySelector(".property > .title > .key")
                         .textContent, "__proto__ ",
           "Should have the right property name for __proto__.");
 
         ok(localNodes[0].querySelector(".property > .title > .value")
                         .textContent.search(/object/) != -1,
           "__proto__ should be an object.");
 
-        is(localNodes[1].querySelector(".info").textContent, "[object Arguments]",
+        is(localNodes[9].querySelector(".info").textContent, "[object Object]",
+          "Should have the right property value for 'c'.");
+
+        is(localNodes[9].querySelectorAll(".property > .title > .key")[1]
+                        .textContent, "a",
+          "Should have the right property name for 'a'.");
+
+        is(localNodes[9].querySelectorAll(".property > .title > .value")[1]
+                        .textContent, 1,
+          "Should have the right value for 'c.a'.");
+
+        is(localNodes[10].querySelector(".info").textContent,
+          "[object Arguments]",
           "Should have the right property value for 'arguments'.");
 
-        is(localNodes[1].querySelector(".property > .title > .key")
+        is(localNodes[10].querySelector(".property > .title > .key")
                         .textContent, "length",
-          "Should have the right property name for length.");
+          "Should have the right property name for 'length'.");
 
-        is(localNodes[1].querySelector(".property > .title > .value")
+        is(localNodes[10].querySelector(".property > .title > .value")
                         .textContent, 5,
           "Should have the right argument length.");
 
         resumeAndFinish();
       }, 100);
     }}, 0);
   }, false);
 
   EventUtils.sendMouseEvent({ type: "click" },
     content.document.querySelector("button"),
     content.window);
 }
 
 function resumeAndFinish() {
-  gDebugger.DebuggerController.activeThread.addOneTimeListener("framescleared", function() {
+  let thread = gDebugger.DebuggerController.activeThread;
+  thread.addOneTimeListener("framescleared", function() {
     Services.tm.currentThread.dispatch({ run: function() {
       var frames = gDebugger.DebuggerView.StackFrames._frames;
 
       is(frames.querySelectorAll(".dbg-stackframe").length, 0,
         "Should have no frames.");
 
       closeDebuggerAndFinish(gTab);
     }}, 0);
   });
 
-  gDebugger.DebuggerController.activeThread.resume();
+  thread.resume();
 }
 
 registerCleanupFunction(function() {
   removeTab(gTab);
   gPane = null;
   gTab = null;
   gDebugger = null;
 });
--- a/browser/devtools/debugger/test/browser_dbg_script-switching.js
+++ b/browser/devtools/debugger/test/browser_dbg_script-switching.js
@@ -3,57 +3,59 @@
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /**
  * Make sure that switching the displayed script in the UI works as advertised.
  */
 
 const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
 
-let tempScope = {};
-Cu.import("resource:///modules/source-editor.jsm", tempScope);
-let SourceEditor = tempScope.SourceEditor;
-
 var gPane = null;
 var gTab = null;
 var gDebuggee = null;
 var gDebugger = null;
 var gScripts = null;
 
 function test()
 {
   let scriptShown = false;
   let framesAdded = false;
+  let resumed = false;
+  let testStarted = false;
 
   debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
     gTab = aTab;
     gDebuggee = aDebuggee;
     gPane = aPane;
     gDebugger = gPane.debuggerWindow;
+    resumed = true;
 
     gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
       framesAdded = true;
-      runTest();
+      executeSoon(startTest);
     });
 
-    gDebuggee.firstCall();
+    executeSoon(function() {
+      gDebuggee.firstCall();
+    });
   });
 
-  window.addEventListener("Debugger:ScriptShown", function _onEvent(aEvent) {
-    let url = aEvent.detail.url;
-    if (url.indexOf("-02.js") != -1) {
-      scriptShown = true;
-      window.removeEventListener(aEvent.type, _onEvent);
-      runTest();
-    }
-  });
+  function onScriptShown(aEvent)
+  {
+    scriptShown = aEvent.detail.url.indexOf("-02.js") != -1;
+    executeSoon(startTest);
+  }
 
-  function runTest()
+  window.addEventListener("Debugger:ScriptShown", onScriptShown);
+
+  function startTest()
   {
-    if (scriptShown && framesAdded) {
+    if (scriptShown && framesAdded && resumed && !testStarted) {
+      window.removeEventListener("Debugger:ScriptShown", onScriptShown);
+      testStarted = true;
       Services.tm.currentThread.dispatch({ run: testScriptsDisplay }, 0);
     }
   }
 }
 
 function testScriptsDisplay() {
   gScripts = gDebugger.DebuggerView.Scripts._scripts;
 
@@ -74,18 +76,16 @@ function testScriptsDisplay() {
   ok(gDebugger.DebuggerView.Scripts.contains(EXAMPLE_URL +
     label2), "Second script url is incorrect.");
 
   ok(gDebugger.DebuggerView.Scripts.containsLabel(
     label1), "First script label is incorrect.");
   ok(gDebugger.DebuggerView.Scripts.containsLabel(
     label2), "Second script label is incorrect.");
 
-  dump("Debugger editor text:\n" + gDebugger.editor.getText() + "\n");
-
   ok(gDebugger.editor.getText().search(/debugger/) != -1,
     "The correct script was loaded initially.");
 
   is(gDebugger.editor.getDebugLocation(), 5,
      "editor debugger location is correct.");
 
   window.addEventListener("Debugger:ScriptShown", function _onEvent(aEvent) {
     let url = aEvent.detail.url;
@@ -95,18 +95,16 @@ function testScriptsDisplay() {
     }
   });
 
   gDebugger.DebuggerView.Scripts.selectScript(EXAMPLE_URL + label1);
 }
 
 function testSwitchPaused()
 {
-  dump("Debugger editor text:\n" + gDebugger.editor.getText() + "\n");
-
   ok(gDebugger.editor.getText().search(/debugger/) == -1,
     "The second script is no longer displayed.");
 
   ok(gDebugger.editor.getText().search(/firstCall/) != -1,
     "The first script is displayed.");
 
   is(gDebugger.editor.getDebugLocation(), -1,
      "editor debugger location has been cleared.");
@@ -122,16 +120,18 @@ function testSwitchPaused()
 
     gDebugger.DebuggerView.Scripts.selectScript(EXAMPLE_URL +
                                                 "test-script-switching-02.js");
   });
 }
 
 function testSwitchRunning()
 {
+  dump("Debugger editor text:\n" + gDebugger.editor.getText() + "\n");
+
   ok(gDebugger.editor.getText().search(/debugger/) != -1,
     "The second script is displayed again.");
 
   ok(gDebugger.editor.getText().search(/firstCall/) == -1,
     "The first script is no longer displayed.");
 
   is(gDebugger.editor.getDebugLocation(), -1,
      "editor debugger location is still -1.");
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/test/browser_dbg_scripts-searching-01.js
@@ -0,0 +1,188 @@
+/* vim:set ts=2 sw=2 sts=2 et: */
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+var gPane = null;
+var gTab = null;
+var gDebuggee = null;
+var gDebugger = null;
+var gEditor = null;
+var gScripts = null;
+var gSearchBox = null;
+var gMenulist = null;
+
+function test()
+{
+  let scriptShown = false;
+  let framesAdded = false;
+
+  debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
+    gTab = aTab;
+    gDebuggee = aDebuggee;
+    gPane = aPane;
+    gDebugger = gPane.debuggerWindow;
+
+    gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
+      framesAdded = true;
+      runTest();
+    });
+
+    gDebuggee.simpleCall();
+  });
+
+  window.addEventListener("Debugger:ScriptShown", function _onEvent(aEvent) {
+    window.removeEventListener(aEvent.type, _onEvent);
+    scriptShown = true;
+    runTest();
+  });
+
+  function runTest()
+  {
+    if (scriptShown && framesAdded) {
+      Services.tm.currentThread.dispatch({ run: testScriptSearching }, 0);
+    }
+  }
+}
+
+function testScriptSearching() {
+  gDebugger.DebuggerController.activeThread.resume(function() {
+    gEditor = gDebugger.DebuggerView.editor;
+    gScripts = gDebugger.DebuggerView.Scripts;
+    gSearchBox = gScripts._searchbox;
+    gMenulist = gScripts._scripts;
+
+    write(":12");
+    ok(gEditor.getCaretPosition().line == 11 &&
+       gEditor.getCaretPosition().col == 0,
+      "The editor didn't jump to the correct line.");
+
+    write("@debugger");
+    ok(gEditor.getCaretPosition().line == 2 &&
+       gEditor.getCaretPosition().col == 44,
+      "The editor didn't jump to the correct token. (1)");
+
+    EventUtils.sendKey("RETURN");
+    ok(gEditor.getCaretPosition().line == 8 &&
+       gEditor.getCaretPosition().col == 2,
+      "The editor didn't jump to the correct token. (2)");
+
+    EventUtils.sendKey("ENTER");
+    ok(gEditor.getCaretPosition().line == 12 &&
+       gEditor.getCaretPosition().col == 8,
+      "The editor didn't jump to the correct token. (3)");
+
+    EventUtils.sendKey("ENTER");
+    ok(gEditor.getCaretPosition().line == 19 &&
+       gEditor.getCaretPosition().col == 4,
+      "The editor didn't jump to the correct token. (4)");
+
+    EventUtils.sendKey("RETURN");
+    ok(gEditor.getCaretPosition().line == 2 &&
+       gEditor.getCaretPosition().col == 44,
+      "The editor didn't jump to the correct token. (5)");
+
+
+    write(":bogus@debugger;");
+    ok(gEditor.getCaretPosition().line == 8 &&
+       gEditor.getCaretPosition().col == 2,
+      "The editor didn't jump to the correct token. (7)");
+
+    write(":13@debugger;");
+    ok(gEditor.getCaretPosition().line == 8 &&
+       gEditor.getCaretPosition().col == 2,
+      "The editor didn't jump to the correct token. (7)");
+
+    write(":@debugger;");
+    ok(gEditor.getCaretPosition().line == 8 &&
+       gEditor.getCaretPosition().col == 2,
+      "The editor didn't jump to the correct token. (8)");
+
+    write("::@debugger;");
+    ok(gEditor.getCaretPosition().line == 8 &&
+       gEditor.getCaretPosition().col == 2,
+      "The editor didn't jump to the correct token. (9)");
+
+    write(":::@debugger;");
+    ok(gEditor.getCaretPosition().line == 8 &&
+       gEditor.getCaretPosition().col == 2,
+      "The editor didn't jump to the correct token. (10)");
+
+
+    write(":i am not a number");
+    ok(gEditor.getCaretPosition().line == 8 &&
+       gEditor.getCaretPosition().col == 2,
+      "The editor didn't remain at the correct token. (11)");
+
+    write("@__i do not exist__");
+    ok(gEditor.getCaretPosition().line == 8 &&
+       gEditor.getCaretPosition().col == 2,
+      "The editor didn't remain at the correct token. (12)");
+
+
+    write(":1:2:3:a:b:c:::12");
+    ok(gEditor.getCaretPosition().line == 11 &&
+       gEditor.getCaretPosition().col == 0,
+      "The editor didn't jump to the correct line. (13)");
+
+    write("@don't@find@me@instead@find@debugger");
+    ok(gEditor.getCaretPosition().line == 2 &&
+       gEditor.getCaretPosition().col == 44,
+      "The editor didn't jump to the correct token. (14)");
+
+    EventUtils.sendKey("RETURN");
+    ok(gEditor.getCaretPosition().line == 8 &&
+       gEditor.getCaretPosition().col == 2,
+      "The editor didn't jump to the correct token. (15)");
+
+    EventUtils.sendKey("ENTER");
+    ok(gEditor.getCaretPosition().line == 12 &&
+       gEditor.getCaretPosition().col == 8,
+      "The editor didn't jump to the correct token. (16)");
+
+    EventUtils.sendKey("RETURN");
+    ok(gEditor.getCaretPosition().line == 19 &&
+       gEditor.getCaretPosition().col == 4,
+      "The editor didn't jump to the correct token. (17)");
+
+    EventUtils.sendKey("ENTER");
+    ok(gEditor.getCaretPosition().line == 2 &&
+       gEditor.getCaretPosition().col == 44,
+      "The editor didn't jump to the correct token. (18)");
+
+
+    clear();
+    ok(gEditor.getCaretPosition().line == 2 &&
+       gEditor.getCaretPosition().col == 44,
+      "The editor didn't remain at the correct token. (19)");
+    is(gScripts.visibleItemsCount, 1,
+      "Not all the scripts are shown after the search. (20)");
+
+    closeDebuggerAndFinish(gTab);
+  });
+}
+
+function clear() {
+  gSearchBox.focus();
+  gSearchBox.value = "";
+}
+
+function write(text) {
+  clear();
+
+  for (let i = 0; i < text.length; i++) {
+    EventUtils.sendChar(text[i]);
+  }
+  dump("editor caret position: " + gEditor.getCaretPosition().toSource() + "\n");
+}
+
+registerCleanupFunction(function() {
+  removeTab(gTab);
+  gPane = null;
+  gTab = null;
+  gDebuggee = null;
+  gDebugger = null;
+  gEditor = null;
+  gScripts = null;
+  gSearchBox = null;
+  gMenulist = null;
+});
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/test/browser_dbg_scripts-searching-02.js
@@ -0,0 +1,146 @@
+/* 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 TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
+
+var gPane = null;
+var gTab = null;
+var gDebuggee = null;
+var gDebugger = null;
+var gEditor = null;
+var gScripts = null;
+var gSearchBox = null;
+var gMenulist = null;
+
+function test()
+{
+  let scriptShown = false;
+  let framesAdded = false;
+
+  debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
+    gTab = aTab;
+    gDebuggee = aDebuggee;
+    gPane = aPane;
+    gDebugger = gPane.debuggerWindow;
+
+    gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
+      framesAdded = true;
+      runTest();
+    });
+
+    gDebuggee.firstCall();
+  });
+
+  window.addEventListener("Debugger:ScriptShown", function _onEvent(aEvent) {
+    let url = aEvent.detail.url;
+    if (url.indexOf("-02.js") != -1) {
+      scriptShown = true;
+      window.removeEventListener(aEvent.type, _onEvent);
+      runTest();
+    }
+  });
+
+  function runTest()
+  {
+    if (scriptShown && framesAdded) {
+      Services.tm.currentThread.dispatch({ run: testScriptSearching }, 0);
+    }
+  }
+}
+
+function testScriptSearching() {
+  gDebugger.DebuggerController.activeThread.resume(function() {
+    gEditor = gDebugger.DebuggerView.editor;
+    gScripts = gDebugger.DebuggerView.Scripts;
+    gSearchBox = gScripts._searchbox;
+    gMenulist = gScripts._scripts;
+
+    firstSearch();
+  });
+}
+
+function firstSearch() {
+  window.addEventListener("Debugger:ScriptShown", function _onEvent(aEvent) {
+    dump("Current script url:\n" + aEvent.detail.url + "\n");
+    dump("Debugger editor text:\n" + gEditor.getText() + "\n");
+
+    let url = aEvent.detail.url;
+    if (url.indexOf("-01.js") != -1) {
+      window.removeEventListener(aEvent.type, _onEvent);
+
+      executeSoon(function() {
+        dump("Editor caret position: " + gEditor.getCaretPosition().toSource() + "\n");
+        ok(gEditor.getCaretPosition().line == 4 &&
+           gEditor.getCaretPosition().col == 0,
+          "The editor didn't jump to the correct line. (1)");
+        is(gScripts.visibleItemsCount, 1,
+          "Not all the correct scripts are shown after the search. (1)");
+
+        secondSearch();
+      });
+    }
+  });
+  write(".*-01\.js:5");
+}
+
+function secondSearch() {
+  window.addEventListener("Debugger:ScriptShown", function _onEvent(aEvent) {
+    dump("Current script url:\n" + aEvent.detail.url + "\n");
+    dump("Debugger editor text:\n" + gEditor.getText() + "\n");
+
+    let url = aEvent.detail.url;
+    if (url.indexOf("-02.js") != -1) {
+      window.removeEventListener(aEvent.type, _onEvent);
+
+      executeSoon(function() {
+        dump("Editor caret position: " + gEditor.getCaretPosition().toSource() + "\n");
+        ok(gEditor.getCaretPosition().line == 5 &&
+           gEditor.getCaretPosition().col == 8,
+          "The editor didn't jump to the correct line. (2)");
+        is(gScripts.visibleItemsCount, 1,
+          "Not all the correct scripts are shown after the search. (2)");
+
+        finalCheck();
+      });
+    }
+  });
+  write(".*-02\.js@debugger;");
+}
+
+function finalCheck() {
+  clear();
+  ok(gEditor.getCaretPosition().line == 5 &&
+     gEditor.getCaretPosition().col == 8,
+    "The editor didn't remain at the correct token. (3)");
+  is(gScripts.visibleItemsCount, 2,
+    "Not all the scripts are shown after the search. (3)");
+
+  closeDebuggerAndFinish(gTab);
+}
+
+function clear() {
+  gSearchBox.focus();
+  gSearchBox.value = "";
+}
+
+function write(text) {
+  clear();
+
+  for (let i = 0; i < text.length; i++) {
+    EventUtils.sendChar(text[i]);
+  }
+  dump("editor caret position: " + gEditor.getCaretPosition().toSource() + "\n");
+}
+
+registerCleanupFunction(function() {
+  removeTab(gTab);
+  gPane = null;
+  gTab = null;
+  gDebuggee = null;
+  gDebugger = null;
+  gEditor = null;
+  gScripts = null;
+  gSearchBox = null;
+  gMenulist = null;
+});
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/test/browser_dbg_scripts-sorting.js
@@ -0,0 +1,124 @@
+/* vim:set ts=2 sw=2 sts=2 et: */
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+var gPane = null;
+var gTab = null;
+var gDebuggee = null;
+var gDebugger = null;
+
+function test() {
+  debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
+    gTab = aTab;
+    gDebuggee = aDebuggee;
+    gPane = aPane;
+    gDebugger = gPane.debuggerWindow;
+
+    testSimpleCall();
+  });
+}
+
+function testSimpleCall() {
+  gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
+    Services.tm.currentThread.dispatch({ run: function() {
+      resumeAndFinish();
+    }}, 0);
+  });
+
+  gDebuggee.simpleCall();
+}
+
+function resumeAndFinish() {
+  gDebugger.DebuggerController.activeThread.resume(function() {
+    checkScriptsOrder();
+    addScriptsAndCheckOrder(1, function() {
+      addScriptsAndCheckOrder(2, function() {
+        addScriptsAndCheckOrder(3, function() {
+          closeDebuggerAndFinish(gTab);
+        });
+      });
+    });
+  });
+}
+
+function addScriptsAndCheckOrder(method, callback) {
+  let vs = gDebugger.DebuggerView.Scripts;
+  let ss = gDebugger.DebuggerController.SourceScripts;
+  vs.empty();
+  vs._scripts.removeEventListener("select", vs._onScriptsChange, false);
+
+  let urls = [
+    { href: "ici://some.address.com/random/", leaf: "subrandom/" },
+    { href: "ni://another.address.org/random/subrandom/", leaf: "page.html" },
+    { href: "san://interesting.address.gro/random/", leaf: "script.js" },
+    { href: "si://interesting.address.moc/random/", leaf: "script.js" },
+    { href: "si://interesting.address.moc/random/", leaf: "x/script.js" },
+    { href: "si://interesting.address.moc/random/", leaf: "x/y/script.js?a=1" },
+    { href: "si://interesting.address.moc/random/x/", leaf: "y/script.js?a=1&b=2" },
+    { href: "si://interesting.address.moc/random/x/y/", leaf: "script.js?a=1&b=2&c=3" }
+  ];
+
+  urls.sort(function(a, b) {
+    return Math.random() - 0.5;
+  });
+
+  switch (method) {
+    case 1:
+      urls.forEach(function(url) {
+        let loc = url.href + url.leaf;
+        vs.addScript(ss._getScriptLabel(loc, url.href), { url: loc });
+      });
+      vs.commitScripts();
+      break;
+
+    case 2:
+      urls.forEach(function(url) {
+        let loc = url.href + url.leaf;
+        vs.addScript(ss._getScriptLabel(loc, url.href), { url: loc }, true);
+      });
+      break;
+
+    case 3:
+      let i = 0
+      for (; i < urls.length / 2; i++) {
+        let url = urls[i];
+        let loc = url.href + url.leaf;
+        vs.addScript(ss._getScriptLabel(loc, url.href), { url: loc });
+      }
+      vs.commitScripts();
+
+      for (; i < urls.length; i++) {
+        let url = urls[i];
+        let loc = url.href + url.leaf;
+        vs.addScript(ss._getScriptLabel(loc, url.href), { url: loc }, true);
+      }
+      break;
+  }
+
+  executeSoon(function() {
+    checkScriptsOrder(method);
+    callback();
+  });
+}
+
+function checkScriptsOrder(method) {
+  let labels = gDebugger.DebuggerView.Scripts.scriptLabels;
+  let sorted = labels.reduce(function(prev, curr, index, array) {
+    return array[index - 1] < array[index];
+  });
+
+  ok(sorted,
+    "Using method " + method + ", " +
+    "the scripts weren't in the correct order: " + labels.toSource());
+
+  return sorted;
+}
+
+registerCleanupFunction(function() {
+  removeTab(gTab);
+  gPane = null;
+  gTab = null;
+  gDebuggee = null;
+  gDebugger = null;
+});
--- a/browser/devtools/debugger/test/browser_dbg_update-editor-mode.js
+++ b/browser/devtools/debugger/test/browser_dbg_update-editor-mode.js
@@ -17,42 +17,48 @@ var gTab = null;
 var gDebuggee = null;
 var gDebugger = null;
 var gScripts = null;
 
 function test()
 {
   let scriptShown = false;
   let framesAdded = false;
+  let testStarted = false;
+  let resumed = false;
 
   debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
     gTab = aTab;
     gDebuggee = aDebuggee;
     gPane = aPane;
     gDebugger = gPane.debuggerWindow;
+    resumed = true;
 
     gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
       framesAdded = true;
-      runTest();
+      executeSoon(startTest);
     });
-    gDebuggee.firstCall();
+
+    executeSoon(function() {
+      gDebuggee.firstCall();
+    });
   });
 
-  window.addEventListener("Debugger:ScriptShown", function _onEvent(aEvent) {
-    let url = aEvent.detail.url;
-    if (url.indexOf("editor-mode") != -1) {
-      scriptShown = true;
-      window.removeEventListener(aEvent.type, _onEvent);
-      runTest();
-    }
-  });
+  function onScriptShown(aEvent) {
+    scriptShown = aEvent.detail.url.indexOf("test-editor-mode") != -1;
+    executeSoon(startTest);
+  }
 
-  function runTest()
+  window.addEventListener("Debugger:ScriptShown", onScriptShown);
+
+  function startTest()
   {
-    if (scriptShown && framesAdded) {
+    if (scriptShown && framesAdded && resumed && !testStarted) {
+      window.removeEventListener("Debugger:ScriptShown", onScriptShown);
+      testStarted = true;
       Services.tm.currentThread.dispatch({ run: testScriptsDisplay }, 0);
     }
   }
 }
 
 function testScriptsDisplay() {
   gScripts = gDebugger.DebuggerView.Scripts._scripts;
 
--- a/browser/devtools/debugger/test/head.js
+++ b/browser/devtools/debugger/test/head.js
@@ -87,22 +87,35 @@ function attach_thread_actor_for_url(aCl
     });
   });
 }
 
 function debug_tab_pane(aURL, aOnDebugging)
 {
   let tab = addTab(aURL, function() {
     gBrowser.selectedTab = gTab;
-
     let debuggee = tab.linkedBrowser.contentWindow.wrappedJSObject;
 
     let pane = DebuggerUI.toggleDebugger();
     pane._frame.addEventListener("Debugger:Connecting", function dbgConnected() {
       pane._frame.removeEventListener("Debugger:Connecting", dbgConnected, true);
 
       // Wait for the initial resume...
       pane.debuggerWindow.gClient.addOneTimeListener("resumed", function() {
         aOnDebugging(tab, debuggee, pane);
       });
     }, true);
   });
 }
+
+function remote_debug_tab_pane(aURL, aOnClosing, aOnDebugging)
+{
+  let tab = addTab(aURL, function() {
+    gBrowser.selectedTab = gTab;
+    let debuggee = tab.linkedBrowser.contentWindow.wrappedJSObject;
+
+    DebuggerUI.toggleRemoteDebugger(aOnClosing, function dbgRan(process) {
+
+      // Wait for the remote debugging process to start...
+      aOnDebugging(tab, debuggee, process);
+    });
+  });
+}
--- a/browser/devtools/highlighter/inspector.jsm
+++ b/browser/devtools/highlighter/inspector.jsm
@@ -288,59 +288,64 @@ InspectorUI.prototype = {
 
   /**
    * Add a tooltip to the Inspect and Markup buttons.
    * The tooltips include the related keyboard shortcut.
    */
   buildButtonsTooltip: function IUI_buildButtonsTooltip()
   {
     let keysbundle = Services.strings.createBundle("chrome://global-platform/locale/platformKeys.properties");
+    let separator = keysbundle.GetStringFromName("MODIFIER_SEPARATOR");
+
+    let button, tooltip;
 
     // Inspect Button - the shortcut string is built from the <key> element
 
     let key = this.chromeDoc.getElementById("key_inspect");
 
-    let modifiersAttr = key.getAttribute("modifiers");
+    if (key) {
+      let modifiersAttr = key.getAttribute("modifiers");
 
-    let combo = [];
+      let combo = [];
 
-    if (modifiersAttr.match("accel"))
+      if (modifiersAttr.match("accel"))
 #ifdef XP_MACOSX
-      combo.push(keysbundle.GetStringFromName("VK_META"));
+        combo.push(keysbundle.GetStringFromName("VK_META"));
 #else
-      combo.push(keysbundle.GetStringFromName("VK_CONTROL"));
+        combo.push(keysbundle.GetStringFromName("VK_CONTROL"));
 #endif
-    if (modifiersAttr.match("shift"))
-      combo.push(keysbundle.GetStringFromName("VK_SHIFT"));
-    if (modifiersAttr.match("alt"))
-      combo.push(keysbundle.GetStringFromName("VK_ALT"));
-    if (modifiersAttr.match("ctrl"))
-      combo.push(keysbundle.GetStringFromName("VK_CONTROL"));
-    if (modifiersAttr.match("meta"))
-      combo.push(keysbundle.GetStringFromName("VK_META"));
+      if (modifiersAttr.match("shift"))
+        combo.push(keysbundle.GetStringFromName("VK_SHIFT"));
+      if (modifiersAttr.match("alt"))
+        combo.push(keysbundle.GetStringFromName("VK_ALT"));
+      if (modifiersAttr.match("ctrl"))
+        combo.push(keysbundle.GetStringFromName("VK_CONTROL"));
+      if (modifiersAttr.match("meta"))
+        combo.push(keysbundle.GetStringFromName("VK_META"));
 
-    combo.push(key.getAttribute("key"));
-
-    let separator = keysbundle.GetStringFromName("MODIFIER_SEPARATOR");
+      combo.push(key.getAttribute("key"));
 
-    let tooltip = this.strings.formatStringFromName("inspectButton.tooltiptext",
-      [combo.join(separator)], 1);
-    let button = this.chromeDoc.getElementById("inspector-inspect-toolbutton");
+      tooltip = this.strings.formatStringFromName("inspectButtonWithShortcutKey.tooltip",
+        [combo.join(separator)], 1);
+    } else {
+      tooltip = this.strings.GetStringFromName("inspectButton.tooltip");
+    }
+
+    button = this.chromeDoc.getElementById("inspector-inspect-toolbutton");
     button.setAttribute("tooltiptext", tooltip);
 
     // Markup Button - the shortcut string is built from the accesskey attribute
 
     button = this.chromeDoc.getElementById("inspector-treepanel-toolbutton");
 #ifdef XP_MACOSX
     // On Mac, no accesskey
     tooltip = this.strings.GetStringFromName("markupButton.tooltip");
 #else
     let altString = keysbundle.GetStringFromName("VK_ALT");
     let accesskey = button.getAttribute("accesskey");
-    let separator = keysbundle.GetStringFromName("MODIFIER_SEPARATOR");
     let shortcut = altString + separator + accesskey;
     tooltip = this.strings.formatStringFromName("markupButton.tooltipWithAccesskey",
       [shortcut], 1);
 #endif
     button.setAttribute("tooltiptext", tooltip);
 
   },
 
--- a/browser/devtools/shared/Templater.jsm
+++ b/browser/devtools/shared/Templater.jsm
@@ -37,43 +37,64 @@
  * ***** END LICENSE BLOCK ***** */
 
 
 var EXPORTED_SYMBOLS = [ "Templater", "template" ];
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 const Node = Components.interfaces.nsIDOMNode;
 
+/**
+ * For full documentation, see:
+ * https://github.com/mozilla/domtemplate/blob/master/README.md
+ */
+
 // WARNING: do not 'use_strict' without reading the notes in _envEval();
 
 /**
  * Begin a new templating process.
  * @param node A DOM element or string referring to an element's id
  * @param data Data to use in filling out the template
  * @param options Options to customize the template processing. One of:
  * - allowEval: boolean (default false) Basic template interpolations are
- * either property paths (e.g. ${a.b.c.d}), however if allowEval=true then we
- * allow arbitrary JavaScript
+ *   either property paths (e.g. ${a.b.c.d}), or if allowEval=true then we
+ *   allow arbitrary JavaScript
+ * - stack: string or array of strings (default empty array) The template
+ *   engine maintains a stack of tasks to help debug where it is. This allows
+ *   this stack to be prefixed with a template name
+ * - blankNullUndefined: By default DOMTemplate exports null and undefined
+ *   values using the strings 'null' and 'undefined', which can be helpful for
+ *   debugging, but can introduce unnecessary extra logic in a template to
+ *   convert null/undefined to ''. By setting blankNullUndefined:true, this
+ *   conversion is handled by DOMTemplate
  */
 function template(node, data, options) {
   var template = new Templater(options || {});
   template.processNode(node, data);
   return template;
 }
 
 /**
  * Construct a Templater object. Use template() in preference to this ctor.
  * @deprecated Use template(node, data, options);
  */
 function Templater(options) {
   if (options == null) {
     options = { allowEval: true };
   }
   this.options = options;
-  this.stack = [];
+  if (options.stack && Array.isArray(options.stack)) {
+    this.stack = options.stack;
+  }
+  else if (typeof options.stack === 'string') {
+    this.stack = [ options.stack ];
+  }
+  else {
+    this.stack = [];
+  }
 }
 
 /**
  * Cached regex used to find ${...} sections in some text.
  * Performance note: This regex uses ( and ) to capture the 'script' for
  * further processing. Not all of the uses of this regex use this feature so
  * if use of the capturing group is a performance drain then we should split
  * this regex in two.
@@ -85,17 +106,17 @@ Templater.prototype._templateRegion = /\
  * See Templater._processTextNode() for details.
  */
 Templater.prototype._splitSpecial = /\uF001|\uF002/;
 
 /**
  * Cached regex used to detect if a script is capable of being interpreted
  * using Template._property() or if we need to use Template._envEval()
  */
-Templater.prototype._isPropertyScript = /^[a-zA-Z0-9.]*$/;
+Templater.prototype._isPropertyScript = /^[_a-zA-Z0-9.]*$/;
 
 /**
  * Recursive function to walk the tree processing the attributes as it goes.
  * @param node the node to process. If you pass a string in instead of a DOM
  * element, it is assumed to be an id for use with document.getElementById()
  * @param data the data to use for node processing.
  */
 Templater.prototype.processNode = function(node, data) {
@@ -148,17 +169,21 @@ Templater.prototype.processNode = functi
             var capture = node.hasAttribute('capture' + name.substring(2));
             node.addEventListener(name.substring(2), func, capture);
             if (capture) {
               node.removeAttribute('capture' + name.substring(2));
             }
           } else {
             // Replace references in all other attributes
             var newValue = value.replace(this._templateRegion, function(path) {
-              return this._envEval(path.slice(2, -1), data, value);
+              var insert = this._envEval(path.slice(2, -1), data, value);
+              if (this.options.blankNullUndefined && insert == null) {
+                insert = '';
+              }
+              return insert;
             }.bind(this));
             // Remove '_' prefix of attribute names so the DOM won't try
             // to use them before we've processed the template
             if (name.charAt(0) === '_') {
               node.removeAttribute(name);
               node.setAttribute(name.substring(1), newValue);
             } else if (value !== newValue) {
               attrs[i].value = newValue;
@@ -172,17 +197,17 @@ Templater.prototype.processNode = functi
 
     // Loop through our children calling processNode. First clone them, so the
     // set of nodes that we visit will be unaffected by additions or removals.
     var childNodes = Array.prototype.slice.call(node.childNodes);
     for (var j = 0; j < childNodes.length; j++) {
       this.processNode(childNodes[j], data);
     }
 
-    if (node.nodeType === Node.TEXT_NODE) {
+    if (node.nodeType === 3 /*Node.TEXT_NODE*/) {
       this._processTextNode(node, data);
     }
   } finally {
     delete data.__element;
     this.stack.pop();
   }
 };
 
@@ -342,40 +367,51 @@ Templater.prototype._processTextNode = f
     parts.forEach(function(part) {
       if (part === null || part === undefined || part === '') {
         return;
       }
       if (part.charAt(0) === '$') {
         part = this._envEval(part.slice(1), data, node.data);
       }
       this._handleAsync(part, node, function(reply, siblingNode) {
-        reply = this._toNode(reply, siblingNode.ownerDocument);
-        siblingNode.parentNode.insertBefore(reply, siblingNode);
+        var doc = siblingNode.ownerDocument;
+        if (reply == null) {
+          reply = this.options.blankNullUndefined ? '' : '' + reply;
+        }
+        if (typeof reply.cloneNode === 'function') {
+          // i.e. if (reply instanceof Element) { ...
+          reply = this._maybeImportNode(reply, doc);
+          siblingNode.parentNode.insertBefore(reply, siblingNode);
+        } else if (typeof reply.item === 'function' && reply.length) {
+          // if thing is a NodeList, then import the children
+          for (var i = 0; i < reply.length; i++) {
+            var child = this._maybeImportNode(reply.item(i), doc);
+            siblingNode.parentNode.insertBefore(child, siblingNode);
+          }
+        }
+        else {
+          // if thing isn't a DOM element then wrap its string value in one
+          reply = doc.createTextNode(reply.toString());
+          siblingNode.parentNode.insertBefore(reply, siblingNode);
+        }
+
       }.bind(this));
     }, this);
     node.parentNode.removeChild(node);
   }
 };
 
 /**
- * Helper to convert a 'thing' to a DOM Node.
- * This is (obviously) a no-op for DOM Elements (which are detected using
- * 'typeof thing.cloneNode !== "function"' (is there a better way that will
- * work in all environments, including a .jsm?)
- * Non DOM elements are converted to a string and wrapped in a TextNode.
+ * Return node or a import of node, if it's not in the given document
+ * @param node The node that we want to be properly owned
+ * @param doc The document that the given node should belong to
+ * @return A node that belongs to the given document
  */
-Templater.prototype._toNode = function(thing, document) {
-  if (thing == null) {
-    thing = '' + thing;
-  }
-  // if thing isn't a DOM element then wrap its string value in one
-  if (typeof thing.cloneNode !== 'function') {
-    thing = document.createTextNode(thing.toString());
-  }
-  return thing;
+Templater.prototype._maybeImportNode = function(node, doc) {
+  return node.ownerDocument === doc ? node : doc.importNode(node, true);
 };
 
 /**
  * A function to handle the fact that some nodes can be promises, so we check
  * and resolve if needed using a marker node to keep our place before calling
  * an inserter function.
  * @param thing The object which could be real data or a promise of real data
  * we use it directly if it's not a promise, or resolve it if it is.
@@ -424,38 +460,38 @@ Templater.prototype._stripBraces = funct
  * a string to be cut into an array using <tt>split('.')</tt>
  * @param data the data to use for node processing
  * @param newValue (optional) If defined, this value will replace the
  * original value for the data at the path specified.
  * @return The value pointed to by <tt>path</tt> before any
  * <tt>newValue</tt> is applied.
  */
 Templater.prototype._property = function(path, data, newValue) {
-  this.stack.push(path);
   try {
     if (typeof path === 'string') {
       path = path.split('.');
     }
     var value = data[path[0]];
     if (path.length === 1) {
       if (newValue !== undefined) {
         data[path[0]] = newValue;
       }
       if (typeof value === 'function') {
         return value.bind(data);
       }
       return value;
     }
     if (!value) {
-      this._handleError('Can\'t find path=' + path);
+      this._handleError('"' + path[0] + '" is undefined');
       return null;
     }
     return this._property(path.slice(1), value, newValue);
-  } finally {
-    this.stack.pop();
+  } catch (ex) {
+    this._handleError('Path error with \'' + path + '\'', ex);
+    return '${' + path + '}';
   }
 };
 
 /**
  * Like eval, but that creates a context of the variables in <tt>env</tt> in
  * which the script is evaluated.
  * WARNING: This script uses 'with' which is generally regarded to be evil.
  * The alternative is to create a Function at runtime that takes X parameters
@@ -464,47 +500,45 @@ Templater.prototype._property = function
  * @param script The string to be evaluated.
  * @param data The environment in which to eval the script.
  * @param frame Optional debugging string in case of failure.
  * @return The return value of the script, or the error message if the script
  * execution failed.
  */
 Templater.prototype._envEval = function(script, data, frame) {
   try {
-    this.stack.push(frame);
+    this.stack.push(frame.replace(/\s+/g, ' '));
     if (this._isPropertyScript.test(script)) {
       return this._property(script, data);
     } else {
       if (!this.options.allowEval) {
         this._handleError('allowEval is not set, however \'' + script + '\'' +
             ' can not be resolved using a simple property path.');
         return '${' + script + '}';
       }
       with (data) {
         return eval(script);
       }
     }
   } catch (ex) {
-    this._handleError('Template error evaluating \'' + script + '\'' +
-        ' environment=' + Object.keys(data).join(', '), ex);
+    this._handleError('Template error evaluating \'' + script + '\'', ex);
     return '${' + script + '}';
   } finally {
     this.stack.pop();
   }
 };
 
 /**
  * A generic way of reporting errors, for easy overloading in different
  * environments.
  * @param message the error message to report.
  * @param ex optional associated exception.
  */
 Templater.prototype._handleError = function(message, ex) {
-  this._logError(message);
-  this._logError('In: ' + this.stack.join(' > '));
+  this._logError(message + ' (In: ' + this.stack.join(' > ') + ')');
   if (ex) {
     this._logError(ex);
   }
 };
 
 
 /**
  * A generic way of reporting errors, for easy overloading in different
--- a/browser/devtools/shared/test/browser_templater_basic.js
+++ b/browser/devtools/shared/test/browser_templater_basic.js
@@ -1,18 +1,22 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 // Tests that the DOM Template engine works properly
 
-let tempScope = {};
-Cu.import("resource:///modules/devtools/Templater.jsm", tempScope);
-Cu.import("resource:///modules/devtools/Promise.jsm", tempScope);
-let template = tempScope.template;
-let Promise = tempScope.Promise;
+/*
+ * These tests run both in Mozilla/Mochitest and plain browsers (as does
+ * domtemplate)
+ * We should endevour to keep the source in sync.
+ */
+
+var imports = {};
+Cu.import("resource:///modules/devtools/Templater.jsm", imports);
+Cu.import("resource:///modules/devtools/Promise.jsm", imports);
 
 function test() {
   addTab("http://example.com/browser/browser/devtools/shared/test/browser_templater_basic.html", function() {
     info("Starting DOM Templater Tests");
     runTest(0);
   });
 }
 
@@ -20,17 +24,17 @@ function runTest(index) {
   var options = tests[index] = tests[index]();
   var holder = content.document.createElement('div');
   holder.id = options.name;
   var body = content.document.body;
   body.appendChild(holder);
   holder.innerHTML = options.template;
 
   info('Running ' + options.name);
-  template(holder, options.data, options.options);
+  imports.template(holder, options.data, options.options);
 
   if (typeof options.result == 'string') {
     is(holder.innerHTML, options.result, options.name);
   }
   else {
     ok(holder.innerHTML.match(options.result), options.name);
   }
 
@@ -233,18 +237,50 @@ var tests = [
     options: { allowEval: true },
     result: '<p>2</p>'
   };},
 
   function() { return {
     name: 'propertyFail',
     template: '<p>${Math.max(1, 2)}</p>',
     result: '<p>${Math.max(1, 2)}</p>'
+  };},
+
+  // Bug 723431: DOMTemplate should allow customisation of display of
+  // null/undefined values
+  function() { return {
+    name: 'propertyUndefAttrFull',