Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Wed, 08 Feb 2012 19:13:56 -0800
changeset 105816 ed637f826ef6c4c5e32cce51d6477203dd2b9d50
parent 105815 63d066d8186beffe54bbb76d6f7e093854795733 (current diff)
parent 86425 7c0ba1c98ff7f87127602ef33c0736acb0dce1e8 (diff)
child 105817 151228e4adeb28caecb40a2aa09b3bd3b9b517cc
push id1075
push uservporof@mozilla.com
push dateThu, 13 Sep 2012 10:46:49 +0000
treeherderfx-team@f39786e8364d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone13.0a1
Merge from mozilla-central.
accessible/public/nsIAccessNode.idl
accessible/src/atk/nsAccessibleWrap.cpp
accessible/src/atk/nsAccessibleWrap.h
accessible/src/base/NotificationController.cpp
accessible/src/base/Statistics.h
accessible/src/base/nsARIAGridAccessible.cpp
accessible/src/base/nsARIAGridAccessible.h
accessible/src/base/nsAccUtils.cpp
accessible/src/base/nsAccUtils.h
accessible/src/base/nsAccessNode.cpp
accessible/src/base/nsAccessNode.h
accessible/src/base/nsAccessibilityService.cpp
accessible/src/base/nsAccessibilityService.h
accessible/src/base/nsAccessible.cpp
accessible/src/base/nsAccessible.h
accessible/src/base/nsApplicationAccessible.cpp
accessible/src/base/nsApplicationAccessible.h
accessible/src/base/nsBaseWidgetAccessible.h
accessible/src/base/nsCaretAccessible.cpp
accessible/src/base/nsCoreUtils.h
accessible/src/base/nsDocAccessible.cpp
accessible/src/base/nsDocAccessible.h
accessible/src/base/nsFormControlAccessible.cpp
accessible/src/base/nsFormControlAccessible.h
accessible/src/base/nsOuterDocAccessible.cpp
accessible/src/base/nsOuterDocAccessible.h
accessible/src/base/nsRootAccessible.cpp
accessible/src/base/nsTextAttrs.cpp
accessible/src/html/nsHTMLFormControlAccessible.cpp
accessible/src/html/nsHTMLFormControlAccessible.h
accessible/src/html/nsHTMLImageAccessible.cpp
accessible/src/html/nsHTMLImageAccessible.h
accessible/src/html/nsHTMLImageMapAccessible.cpp
accessible/src/html/nsHTMLLinkAccessible.cpp
accessible/src/html/nsHTMLLinkAccessible.h
accessible/src/html/nsHTMLSelectAccessible.cpp
accessible/src/html/nsHTMLSelectAccessible.h
accessible/src/html/nsHTMLTableAccessible.cpp
accessible/src/html/nsHTMLTableAccessible.h
accessible/src/html/nsHyperTextAccessible.cpp
accessible/src/html/nsHyperTextAccessible.h
accessible/src/mac/nsAccessibleWrap.h
accessible/src/mac/nsAccessibleWrap.mm
accessible/src/msaa/nsAccessNodeWrap.cpp
accessible/src/msaa/nsAccessNodeWrap.h
accessible/src/msaa/nsAccessibleWrap.cpp
accessible/src/msaa/nsHyperTextAccessibleWrap.h
accessible/src/msaa/nsTextAccessibleWrap.cpp
accessible/src/msaa/nsTextAccessibleWrap.h
accessible/src/xforms/nsXFormsAccessible.cpp
accessible/src/xforms/nsXFormsAccessible.h
accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
accessible/src/xforms/nsXFormsFormControlsAccessible.h
accessible/src/xforms/nsXFormsWidgetsAccessible.cpp
accessible/src/xul/nsXULAlertAccessible.cpp
accessible/src/xul/nsXULAlertAccessible.h
accessible/src/xul/nsXULColorPickerAccessible.cpp
accessible/src/xul/nsXULColorPickerAccessible.h
accessible/src/xul/nsXULComboboxAccessible.cpp
accessible/src/xul/nsXULComboboxAccessible.h
accessible/src/xul/nsXULFormControlAccessible.cpp
accessible/src/xul/nsXULFormControlAccessible.h
accessible/src/xul/nsXULListboxAccessible.cpp
accessible/src/xul/nsXULListboxAccessible.h
accessible/src/xul/nsXULMenuAccessible.cpp
accessible/src/xul/nsXULMenuAccessible.h
accessible/src/xul/nsXULSliderAccessible.cpp
accessible/src/xul/nsXULSliderAccessible.h
accessible/src/xul/nsXULTabAccessible.cpp
accessible/src/xul/nsXULTreeAccessible.cpp
accessible/src/xul/nsXULTreeAccessible.h
accessible/src/xul/nsXULTreeGridAccessible.cpp
accessible/src/xul/nsXULTreeGridAccessible.h
accessible/tests/mochitest/Makefile.in
accessible/tests/mochitest/common.js
accessible/tests/mochitest/events.js
accessible/tests/mochitest/events/Makefile.in
accessible/tests/mochitest/test_text_caret.html
accessible/tests/mochitest/tree/Makefile.in
b2g/installer/package-manifest.in
browser/app/profile/firefox.js
browser/base/content/browser.js
browser/base/content/browser.xul
browser/base/content/highlighter.css
browser/base/content/nsContextMenu.js
browser/base/content/test/test_contextmenu.html
browser/components/nsBrowserGlue.js
browser/components/sessionstore/src/nsSessionStore.js
browser/components/tabview/tabitems.js
browser/devtools/highlighter/Makefile.in
browser/devtools/jar.mn
browser/devtools/sourceeditor/orion/mozilla.css
browser/devtools/webconsole/HUDService.jsm
browser/devtools/webconsole/test/Makefile.in
browser/devtools/webconsole/test/browser_gcli_web.js
build/mobile/devicemanagerADB.py
build/mobile/robocop/Actions.java.in
caps/src/nsSecurityManagerFactory.cpp
configure.in
content/base/public/nsDOMEventTargetWrapperCache.h
content/base/src/Makefile.in
content/base/src/nsAttrValue.cpp
content/base/src/nsAttrValue.h
content/base/src/nsContentUtils.cpp
content/base/src/nsDOMFileReader.cpp
content/base/src/nsEventSource.cpp
content/base/src/nsEventSource.h
content/base/src/nsGenericElement.cpp
content/base/src/nsGenericElement.h
content/base/src/nsGkAtomList.h
content/base/src/nsInProcessTabChildGlobal.cpp
content/base/src/nsInProcessTabChildGlobal.h
content/base/src/nsLineBreaker.cpp
content/base/src/nsObjectLoadingContent.cpp
content/base/src/nsStyledElement.cpp
content/base/src/nsStyledElement.h
content/base/src/nsWebSocket.cpp
content/base/src/nsWebSocket.h
content/base/src/nsXMLHttpRequest.cpp
content/base/src/nsXMLHttpRequest.h
content/base/test/Makefile.in
content/base/test/test_XHR.html
content/canvas/src/CanvasImageCache.cpp
content/canvas/src/CustomQS_Canvas2D.h
content/canvas/src/CustomQS_WebGL.h
content/canvas/src/nsCanvasRenderingContext2D.cpp
content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
content/canvas/test/webgl/test_webgl_conformance_test_suite.html
content/events/src/nsContentEventHandler.cpp
content/events/src/nsDOMDataTransfer.cpp
content/events/src/nsDOMDataTransfer.h
content/events/src/nsDOMEventTargetHelper.cpp
content/events/src/nsDOMEventTargetHelper.h
content/events/src/nsEventStateManager.cpp
content/html/content/src/nsGenericHTMLElement.cpp
content/html/content/src/nsGenericHTMLElement.h
content/html/content/src/nsHTMLButtonElement.cpp
content/html/content/src/nsHTMLCanvasElement.cpp
content/html/content/src/nsHTMLFieldSetElement.cpp
content/html/content/src/nsHTMLFieldSetElement.h
content/html/content/src/nsHTMLFormElement.cpp
content/html/content/src/nsHTMLFormElement.h
content/html/content/src/nsHTMLInputElement.cpp
content/html/content/src/nsHTMLInputElement.h
content/html/content/src/nsHTMLMenuItemElement.cpp
content/html/content/src/nsHTMLMenuItemElement.h
content/html/content/src/nsHTMLObjectElement.cpp
content/html/content/src/nsHTMLOptionElement.cpp
content/html/content/src/nsHTMLOptionElement.h
content/html/content/src/nsHTMLScriptElement.cpp
content/html/content/src/nsHTMLSelectElement.cpp
content/html/content/src/nsHTMLSelectElement.h
content/html/content/src/nsHTMLTableElement.cpp
content/html/content/src/nsHTMLTableElement.h
content/html/content/src/nsHTMLTextAreaElement.cpp
content/smil/nsISMILAnimationElement.h
content/smil/nsSMILAnimationController.cpp
content/svg/content/src/SVGLengthList.h
content/svg/content/src/nsSVGAnimationElement.cpp
content/svg/content/src/nsSVGAnimationElement.h
content/svg/content/src/nsSVGElement.cpp
content/svg/content/src/nsSVGElement.h
content/svg/content/src/nsSVGFilters.cpp
content/svg/content/src/nsSVGFilters.h
content/svg/content/src/nsSVGImageElement.cpp
content/svg/content/src/nsSVGImageElement.h
content/svg/content/src/nsSVGScriptElement.cpp
content/svg/content/src/nsSVGSwitchElement.cpp
content/xbl/src/nsXBLBinding.cpp
content/xbl/src/nsXBLDocumentInfo.cpp
content/xbl/src/nsXBLPrototypeBinding.cpp
content/xslt/src/xpath/txMozillaXPathTreeWalker.cpp
content/xslt/src/xpath/txXPathTreeWalker.h
content/xul/content/src/nsXULElement.cpp
content/xul/content/src/nsXULElement.h
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
dom/Makefile.in
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMWindowUtils.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsJSEnvironment.cpp
dom/base/nsJSEnvironment.h
dom/base/nsJSTimeoutHandler.cpp
dom/indexedDB/IDBDatabase.cpp
dom/indexedDB/IDBObjectStore.cpp
dom/ipc/ContentChild.cpp
dom/ipc/Makefile.in
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/plugins/base/nsJSNPRuntime.cpp
dom/plugins/base/nsPluginInstanceOwner.cpp
dom/plugins/base/nsPluginsDirUnix.cpp
dom/plugins/ipc/PluginInstanceParent.cpp
dom/src/Makefile.in
dom/system/NetworkGeolocationProvider.js
dom/workers/Events.cpp
dom/workers/Exceptions.cpp
dom/workers/File.cpp
dom/workers/Location.cpp
dom/workers/Navigator.cpp
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerScope.cpp
dom/workers/XMLHttpRequest.cpp
editor/libeditor/base/nsEditor.cpp
editor/libeditor/base/nsEditorEventListener.cpp
embedding/android/AndroidManifest.xml.in
embedding/android/GeckoAppShell.java
embedding/browser/webBrowser/nsDocShellTreeOwner.cpp
embedding/components/windowwatcher/src/nsWindowWatcher.cpp
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
gfx/gl/GLContextProviderEGL.cpp
gfx/gl/GLContextProviderGLX.cpp
gfx/layers/basic/BasicLayers.cpp
gfx/layers/d3d10/ImageLayerD3D10.cpp
gfx/layers/d3d9/ImageLayerD3D9.cpp
gfx/src/nsFontMetrics.cpp
gfx/thebes/gfxFont.cpp
gfx/thebes/gfxFont.h
gfx/thebes/gfxPattern.cpp
gfx/thebes/gfxPlatform.cpp
gfx/thebes/gfxWindowsPlatform.cpp
intl/unicharutil/util/nsBidiUtils.h
js/jsd/jsd_val.c
js/src/Makefile.in
js/src/MemoryMetrics.cpp
js/src/ctypes/Library.cpp
js/src/frontend/BytecodeEmitter.h
js/src/frontend/Parser.cpp
js/src/frontend/Parser.h
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsarray.cpp
js/src/jsatom.cpp
js/src/jsatom.h
js/src/jsatominlines.h
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jscompartment.cpp
js/src/jsdbgapi.cpp
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
js/src/jsfun.cpp
js/src/jsfun.h
js/src/jsgc.cpp
js/src/jsgc.h
js/src/jsgcmark.h
js/src/jsinfer.cpp
js/src/jsiter.cpp
js/src/jsiter.h
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/jsopcode.cpp
js/src/jsproxy.cpp
js/src/jsproxy.h
js/src/jstypedarray.cpp
js/src/jsweakmap.cpp
js/src/jswrapper.cpp
js/src/jswrapper.h
js/src/methodjit/PolyIC.cpp
js/src/shell/js.cpp
js/src/shell/jsworkers.cpp
js/src/vm/Debugger.cpp
js/src/vm/String.cpp
js/xpconnect/shell/xpcshell.cpp
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCQuickStubs.cpp
js/xpconnect/src/XPCQuickStubs.h
js/xpconnect/src/XPCWrappedNative.cpp
js/xpconnect/src/XPCWrappedNativeScope.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/qsgen.py
js/xpconnect/src/xpcprivate.h
js/xpconnect/src/xpcpublic.h
js/xpconnect/wrappers/WrapperFactory.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsChangeHint.h
layout/base/nsFrameManager.cpp
layout/base/nsPresShell.cpp
layout/generic/crashtests/crashtests.list
layout/generic/nsColumnSetFrame.cpp
layout/generic/nsObjectFrame.cpp
layout/generic/nsTextFrame.h
layout/generic/nsTextFrameThebes.cpp
layout/printing/nsPrintEngine.cpp
layout/reftests/bugs/reftest.list
layout/reftests/svg/reftest.list
layout/reftests/svg/smil/reftest.list
layout/style/crashtests/722117.html
layout/style/crashtests/crashtests.list
layout/style/nsCSSParser.cpp
layout/style/nsCSSValue.cpp
layout/style/nsCSSValue.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsFontFaceLoader.cpp
layout/style/nsRuleNode.cpp
layout/style/nsStyleContext.cpp
layout/style/nsStyleCoord.cpp
layout/style/nsStyleCoord.h
layout/style/nsStyleStruct.cpp
layout/style/test/property_database.js
layout/svg/base/src/nsISVGChildFrame.h
layout/svg/base/src/nsSVGContainerFrame.cpp
layout/svg/base/src/nsSVGContainerFrame.h
layout/svg/base/src/nsSVGForeignObjectFrame.cpp
layout/svg/base/src/nsSVGForeignObjectFrame.h
layout/svg/base/src/nsSVGGeometryFrame.cpp
layout/svg/base/src/nsSVGGeometryFrame.h
layout/svg/base/src/nsSVGGlyphFrame.cpp
layout/svg/base/src/nsSVGGlyphFrame.h
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/nsSVGPathGeometryFrame.cpp
layout/svg/base/src/nsSVGPathGeometryFrame.h
layout/svg/base/src/nsSVGSwitchFrame.cpp
layout/svg/base/src/nsSVGTextFrame.cpp
layout/svg/base/src/nsSVGTextFrame.h
layout/svg/base/src/nsSVGUtils.cpp
layout/svg/base/src/nsSVGUtils.h
layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
layout/xul/base/src/tree/src/nsTreeBodyFrame.h
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoAppShell.java
mobile/xul/app/mobile.js
modules/libpref/public/Preferences.h
modules/libpref/src/Preferences.cpp
modules/libpref/src/init/all.js
netwerk/base/src/nsIOService.cpp
netwerk/base/src/nsProtocolProxyService.cpp
netwerk/protocol/device/Makefile.in
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/protocol/http/HttpBaseChannel.h
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpChannel.h
parser/html/nsHtml5TreeBuilderCppSupplement.h
profile/dirserviceprovider/src/nsProfileLock.cpp
profile/dirserviceprovider/src/nsProfileLock.h
testing/mochitest/tests/test_sanitySimpletest.html
testing/xpcshell/xpcshell.ini
toolkit/components/aboutmemory/content/aboutMemory.js
toolkit/components/places/SQLFunctions.cpp
toolkit/components/places/nsNavHistory.cpp
toolkit/components/startup/nsAppStartup.cpp
toolkit/components/startup/nsAppStartup.h
toolkit/components/startup/tests/Makefile.in
toolkit/components/startup/tests/beforeunload.html
toolkit/components/startup/tests/browser_bug511456.js
toolkit/components/startup/tests/browser_bug537449.js
toolkit/components/telemetry/TelemetryHistograms.h
toolkit/profile/nsToolkitProfileService.cpp
toolkit/themes/pinstripe/global/icons/commandline.png
toolkit/themes/winstripe/global/icons/commandline.png
toolkit/xre/nsAppRunner.cpp
toolkit/xre/nsXREDirProvider.cpp
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
widget/android/nsAppShell.cpp
widget/android/nsWindow.cpp
widget/cocoa/nsChildView.mm
widget/cocoa/nsCocoaWindow.h
widget/cocoa/nsCocoaWindow.mm
widget/gtk2/nsDragService.cpp
widget/gtk2/nsWindow.cpp
widget/gtk2/nsWindow.h
widget/nsIWidget.h
widget/nsWidgetInitData.h
widget/windows/nsDragService.cpp
widget/windows/nsIMM32Handler.cpp
widget/windows/nsNativeDragSource.h
widget/windows/nsWindow.cpp
widget/xpwidgets/nsBaseWidget.h
xpcom/base/nsCycleCollector.cpp
xpcom/build/nsXPCOM.h
xpcom/io/nsBinaryStream.cpp
xpcom/io/nsLocalFileCommon.cpp
xpcom/io/nsLocalFileUnicode.h
xpcom/io/nsLocalFileWin.cpp
xpcom/io/nsMultiplexInputStream.cpp
xpcom/string/public/nsTSubstring.h
xpfe/appshell/src/nsAppShellService.cpp
xpfe/appshell/src/nsWebShellWindow.cpp
xpfe/appshell/src/nsXULWindow.cpp
--- a/accessible/public/Makefile.in
+++ b/accessible/public/Makefile.in
@@ -56,17 +56,16 @@ XPIDLSRCS = \
       nsIAccessible.idl \
       nsIAccessibleApplication.idl \
       nsIAccessibleRelation.idl \
       nsIAccessibleRole.idl \
       nsIAccessibleStates.idl \
       nsIAccessibleDocument.idl \
       nsIAccessibleProvider.idl \
       nsIAccessibleSelectable.idl \
-      nsIAccessNode.idl \
       nsIAccessibleCursorable.idl \
       nsIAccessibleEvent.idl \
       nsIAccessibleEditableText.idl \
       nsIAccessibleHyperLink.idl \
       nsIAccessibleHyperText.idl \
       nsIAccessiblePivot.idl \
       nsIAccessibleTable.idl \
       nsIAccessibleText.idl \
--- a/accessible/public/msaa/ISimpleDOMNode.idl
+++ b/accessible/public/msaa/ISimpleDOMNode.idl
@@ -112,17 +112,17 @@ cpp_quote("// DOM navigation - get a dif
 cpp_quote("//")
 cpp_quote("// get_innerHTML(/* [out] */ BSTR *htmlText);")
 cpp_quote("// ---------------------------------------------------------------------------------------------------=")
 cpp_quote("// Returns HTML of this DOM node's subtree. Does not include the start and end tag for this node/element.")
 cpp_quote("//")
 cpp_quote("//")
 cpp_quote("// get_localInterface(/* [out] */ void **localInterface);")
 cpp_quote("// ---------------------------------------------------------------------------------------------------=")
-cpp_quote("// Only available in Gecko's process - casts to an XPCOM nsIAccessNode interface pointer")
+cpp_quote("// Only available in Gecko's process - casts to an XPCOM nsAccessNode object pointer")
 cpp_quote("//")
 cpp_quote("//")
 cpp_quote("// get_language(/* [out] */ BSTR *htmlText);")
 cpp_quote("// ---------------------------------------------------------------------------------------------------=")
 cpp_quote("// Returns the computed language for this node, or empty string if unknown.")
 cpp_quote("//")
 cpp_quote("//")
 cpp_quote("///////////////////////////////////////////////////////////////////////////////////////////////////////")
deleted file mode 100644
--- a/accessible/public/nsIAccessNode.idl
+++ /dev/null
@@ -1,126 +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.
- *
- * Original Author: Aaron Leventhal (aaronl@netscape.com)
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "nsISupports.idl"
-
-interface nsIDOMNode;
-interface nsIAccessibleDocument;
-interface nsIDOMCSSPrimitiveValue;
-
-/**
- * An interface used by in-process accessibility clients
- * to get style, window, markup and other information about
- * a DOM node. When accessibility is active in Gecko,
- * every DOM node can have one nsIAccessNode for each
- * pres shell the DOM node is rendered in.
- * The nsIAccessNode implementations are instantiated lazily.
- * The nsIAccessNode tree for a given dom window
- * has a one to one relationship to the DOM tree.
- * If the DOM node for this access node is "accessible",
- * then a QueryInterface to nsIAccessible will succeed.
- */
-[scriptable, uuid(08bb2c50-1b30-11e1-bddb-0800200c9a66)]
-interface nsIAccessNode : nsISupports
-{
-  /**
-   * The DOM node this nsIAccessNode is associated with.
-   */
-  readonly attribute nsIDOMNode DOMNode;
-
-  /**
-   * The document accessible that this access node resides in.
-   */
-  readonly attribute nsIAccessibleDocument document;
-
-  /**
-   * The root document accessible that this access node resides in.
-   */
-  readonly attribute nsIAccessibleDocument rootDocument;
-
-  /**
-   * The innerHTML for the DOM node
-   * This is a text string of all the markup inside the DOM
-   * node, not including the start and end tag for the node.
-   */
-  readonly attribute DOMString innerHTML;
-
-  /**
-   * Makes an object visible on screen.
-   *
-   * @param scrollType - defines where the object should be placed on
-   *                     the screen (see nsIAccessibleScrollType for
-   *                     available constants).
-   */
-  void scrollTo(in unsigned long aScrollType);
-
-  /**
-   * Moves the top left of an object to a specified location.
-   *
-   * @param coordinateType - specifies whether the coordinates are relative to
-   *                         the screen or the parent object (for available
-   *                         constants refer to nsIAccessibleCoordinateType)
-   * @param aX - defines the x coordinate
-   * @param aY - defines the y coordinate
-  */
-  void scrollToPoint(in unsigned long aCoordinateType, in long aX, in long aY);
-
-  /**
-   * Retrieve the computed style value for this DOM node, if it is a DOM element.
-   * Note: the meanings of width, height and other size measurements depend
-   * on the version of CSS being used. Therefore, for bounds information, 
-   * it is better to use nsIAccessible::accGetBounds.
-   * @param pseudoElt The pseudo element to retrieve style for, or NULL
-   *                  for general computed style information for this node.
-   * @param propertyName Retrieve the computed style value for this property name,
-   *                     for example "border-bottom".
-   */
-  DOMString getComputedStyleValue(in DOMString pseudoElt, in DOMString propertyName);
-
-  /**
-   * The method is similar to getComputedStyleValue() excepting that this one
-   * returns nsIDOMCSSPrimitiveValue.
-   */
-  nsIDOMCSSPrimitiveValue getComputedStyleCSSValue(in DOMString pseudoElt,
-                                                   in DOMString propertyName);
-
-  /**
-   * The language for the current DOM node, e.g. en, de, etc.
-   */
-  readonly attribute DOMString language;
-};
-
--- a/accessible/public/nsIAccessible.idl
+++ b/accessible/public/nsIAccessible.idl
@@ -38,17 +38,20 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsISupports.idl"
 #include "nsIArray.idl"
 
 interface nsIPersistentProperties;
+interface nsIDOMCSSPrimitiveValue;
 interface nsIDOMDOMStringList;
+interface nsIDOMNode;
+interface nsIAccessibleDocument;
 interface nsIAccessibleRelation;
 
 /**
  * A cross-platform interface that supports platform-specific 
  * accessibility APIs like MSAA and ATK. Contains the sum of what's needed
  * to support IAccessible as well as ATK's generic accessibility objects.
  * Can also be used by in-process accessibility clients to get information
  * about objects in the accessible tree. The accessible tree is a subset of 
@@ -96,16 +99,63 @@ interface nsIAccessible : nsISupports
 
   /**
    * The 0-based index of this accessible in its parent's list of children,
    * or -1 if this accessible does not have a parent.
    */
   readonly attribute long indexInParent;
 
   /**
+   * The innerHTML for the HTML element associated with this accessible if applicable.
+   * This is a text string of all the markup inside the DOM
+   * node, not including the start and end tag for the node.
+   */
+  readonly attribute DOMString innerHTML;
+
+  /**
+   * Retrieve the computed style value for this DOM node, if it is a DOM element.
+   * Note: the meanings of width, height and other size measurements depend
+   * on the version of CSS being used. Therefore, for bounds information, 
+   * it is better to use nsIAccessible::accGetBounds.
+   *
+   * @param pseudoElt [in] The pseudo element to retrieve style for, or NULL
+   *                  for general computed style information for this node.
+   * @param propertyName [in] Retrieve the computed style value for this property name,
+   *                     for example "border-bottom".
+   */
+  DOMString getComputedStyleValue(in DOMString pseudoElt, in DOMString propertyName);
+
+  /**
+   * The method is similar to getComputedStyleValue() excepting that this one
+   * returns nsIDOMCSSPrimitiveValue.
+   */
+  nsIDOMCSSPrimitiveValue getComputedStyleCSSValue(in DOMString pseudoElt,
+                                                   in DOMString propertyName);
+
+  /**
+   * The DOM node this nsIAccessible is associated with.
+   */
+  readonly attribute nsIDOMNode DOMNode;
+
+  /**
+   * The document accessible that this access node resides in.
+   */
+  readonly attribute nsIAccessibleDocument document;
+
+  /**
+   * The root document accessible that this access node resides in.
+   */
+  readonly attribute nsIAccessibleDocument rootDocument;
+
+  /**
+   * The language for the current DOM node, e.g. en, de, etc.
+   */
+  readonly attribute DOMString language;
+
+  /**
    * Accessible name -- the main text equivalent for this node. The name is
    * specified by ARIA or by native markup. Example of ARIA markup is
    * aria-labelledby attribute placed on element of this accessible. Example
    * of native markup is HTML label linked with HTML element of this accessible.
    *
    * Value can be string or null. A null value indicates that AT may attempt to
    * compute the name. Any string value, including the empty string, should be
    * considered author-intentional, and respected.
@@ -281,14 +331,34 @@ interface nsIAccessible : nsISupports
 
   /**
    * Perform the accessible action at the given zero-based index
    * Action number 0 is the default action
    */
   void doAction(in PRUint8 index);   
 
   /**
+   * Makes an object visible on screen.
+   *
+   * @param scrollType - defines where the object should be placed on
+   *                     the screen (see nsIAccessibleScrollType for
+   *                     available constants).
+   */
+  void scrollTo(in unsigned long aScrollType);
+
+  /**
+   * Moves the top left of an object to a specified location.
+   *
+   * @param coordinateType [in] - specifies whether the coordinates are relative to
+   *                         the screen or the parent object (for available
+   *                         constants refer to nsIAccessibleCoordinateType)
+   * @param x [in] - defines the x coordinate
+   * @param y [in] - defines the y coordinate
+  */
+  void scrollToPoint(in unsigned long coordinateType, in long x, in long y);
+
+  /**
    * Get a pointer to accessibility interface for this node, which is specific 
    * to the OS/accessibility toolkit we're running on.
    */
   [noscript] void getNativeInterface(out voidPtr aOutAccessible);
 };
 
--- a/accessible/public/nsIAccessibleDocument.idl
+++ b/accessible/public/nsIAccessibleDocument.idl
@@ -34,31 +34,29 @@
  * 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 "nsISupports.idl"
 
 interface nsIAccessible;
-interface nsIAccessNode;
 interface nsIDOMDocument;
 interface nsIDOMNode;
 interface nsIDOMWindow;
 
 /**
  * An interface for in-process accessibility clients
  * that wish to retrieve information about a document.
  * When accessibility is turned on in Gecko,
  * there is an nsIAccessibleDocument for each document
  * whether it is XUL, HTML or whatever.
- * You can QueryInterface to nsIAccessibleDocument from
- * the nsIAccessible or nsIAccessNode for the root node
- * of a document. You can also get one from 
- * nsIAccessNode::GetAccessibleDocument() or 
+ * You can QueryInterface to nsIAccessibleDocument from the nsIAccessible for
+ * the root node of a document. You can also get one from 
+ * nsIAccessible::GetAccessibleDocument() or 
  * nsIAccessibleEvent::GetAccessibleDocument()
  */
 [scriptable, uuid(451242bd-8a0c-4198-ae88-c053609a4e5d)]
 interface nsIAccessibleDocument : nsISupports
 {
   /**
    * The URL of the document
    */
--- a/accessible/public/nsIAccessibleRetrieval.idl
+++ b/accessible/public/nsIAccessibleRetrieval.idl
@@ -38,25 +38,22 @@
 
 #include "nsISupports.idl"
 
 interface nsIDOMNode;
 interface nsIAccessible;
 interface nsIWeakReference;
 interface nsIPresShell;
 interface nsIDOMWindow;
-interface nsIAccessNode;
 interface nsIDOMDOMStringList;
 interface nsIAccessiblePivot;
 
 /**
- * An interface for in-process accessibility clients
- * wishing to get an nsIAccessible or nsIAccessNode for
- * a given DOM node.
- * More documentation at:
+ * An interface for in-process accessibility clients wishing to get an
+ * nsIAccessible for a given DOM node.  More documentation at:
  *   http://www.mozilla.org/projects/ui/accessibility
  */
 [scriptable, uuid(310ce77d-c92b-4761-82e8-77e1a728e8d4)]
 interface nsIAccessibleRetrieval : nsISupports
 {
   /**
    * Return application accessible.
    */
--- a/accessible/src/atk/nsMaiInterfaceDocument.cpp
+++ b/accessible/src/atk/nsMaiInterfaceDocument.cpp
@@ -74,17 +74,17 @@ documentInterfaceInitCB(AtkDocumentIface
 const gchar *
 getDocumentLocaleCB(AtkDocument *aDocument)
 {
   nsAccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aDocument));
   if (!accWrap)
     return nsnull;
 
   nsAutoString locale;
-  accWrap->GetLanguage(locale);
+  accWrap->Language(locale);
   return locale.IsEmpty() ? nsnull : nsAccessibleWrap::ReturnString(locale);
 }
 
 static inline GSList *
 prependToList(GSList *aList, const char *const aName, const nsAutoString &aValue)
 {
   if (aValue.IsEmpty())
     return aList;
--- a/accessible/src/base/Statistics.h
+++ b/accessible/src/base/Statistics.h
@@ -17,16 +17,17 @@
  *
  * The Initial Developer of the Original Code is
  * Mozilla Foundation.
  * Portions created by the Initial Developer are Copyright (C) 2011
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Trevor Saunders <trev.saunders@gmail.com> (original author)
+ *   Andrzej Skalski <askalski@mozilla.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -42,17 +43,17 @@
 
 #include "mozilla/Telemetry.h"
 
 namespace mozilla {
 namespace a11y {
 namespace statistics {
 
   inline void A11yInitialized()
-    { Telemetry::Accumulate(Telemetry::A11Y_INSTANTIATED, true); }
+    { Telemetry::Accumulate(Telemetry::A11Y_INSTANTIATED, 1); }
 
   inline void A11yConsumers(PRUint32 aConsumer)
     { Telemetry::Accumulate(Telemetry::A11Y_CONSUMERS, aConsumer); }
 
   /**
    * Report that ISimpleDOM* has been used.
    */
   inline void ISimpleDOMUsed()
@@ -65,14 +66,20 @@ namespace statistics {
   }
 
   /**
    * Report that IAccessibleTable has been used.
    */
   inline void IAccessibleTableUsed()
     { Telemetry::Accumulate(Telemetry::IACCESSIBLE_TABLE_USAGE, 1); }
 
+  /**
+   * Report that XForms accessibility has been instantiated.
+   */
+  inline void XFormsAccessibleUsed()
+    { Telemetry::Accumulate(Telemetry::XFORMS_ACCESSIBLE_USED, 1); }
+
 } // namespace statistics
 } // namespace a11y
 } // namespace mozilla
 
 #endif
 
--- a/accessible/src/base/nsAccUtils.h
+++ b/accessible/src/base/nsAccUtils.h
@@ -35,17 +35,16 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsAccUtils_h_
 #define nsAccUtils_h_
 
 #include "nsIAccessible.h"
-#include "nsIAccessNode.h"
 #include "nsIAccessibleRole.h"
 #include "nsIAccessibleText.h"
 #include "nsIAccessibleTable.h"
 
 #include "nsARIAMap.h"
 #include "nsAccessibilityService.h"
 #include "nsCoreUtils.h"
 
--- a/accessible/src/base/nsAccessNode.cpp
+++ b/accessible/src/base/nsAccessNode.cpp
@@ -31,47 +31,37 @@
  * 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 "nsDocAccessible.h"
+#include "nsAccessNode.h"
 
-#include "nsIAccessible.h"
-
-#include "nsAccCache.h"
+#include "nsAccessibilityService.h"
 #include "nsAccUtils.h"
+#include "nsApplicationAccessibleWrap.h"
 #include "nsCoreUtils.h"
+#include "nsRootAccessible.h"
 
-#include "nsHashtable.h"
-#include "nsAccessibilityService.h"
-#include "nsApplicationAccessibleWrap.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
-#include "nsIDocument.h"
-#include "nsIDOMCSSPrimitiveValue.h"
-#include "nsIDOMDocument.h"
-#include "nsIDOMElement.h"
-#include "nsIDOMHTMLElement.h"
 #include "nsIDOMWindow.h"
-#include "nsPIDOMWindow.h"
+#include "nsIFrame.h"
 #include "nsIInterfaceRequestorUtils.h"
-#include "nsIFrame.h"
+#include "nsIObserverService.h"
+#include "nsIPrefBranch.h"
 #include "nsIPrefService.h"
-#include "nsIPrefBranch.h"
-#include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsIServiceManager.h"
 #include "nsIStringBundle.h"
-#include "nsRootAccessible.h"
 #include "nsFocusManager.h"
-#include "nsIObserverService.h"
+#include "nsPresContext.h"
 #include "mozilla/Services.h"
 
 /* For documentation of the accessibility architecture, 
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
 nsIStringBundle *nsAccessNode::gStringBundle = 0;
 
@@ -84,19 +74,17 @@ nsApplicationAccessible *nsAccessNode::g
  */
  
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessible. nsISupports
 
 NS_IMPL_CYCLE_COLLECTION_1(nsAccessNode, mContent)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsAccessNode)
-  NS_INTERFACE_MAP_ENTRY(nsIAccessNode)
   NS_INTERFACE_MAP_ENTRY(nsAccessNode)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAccessNode)
 NS_INTERFACE_MAP_END
  
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsAccessNode)
 NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DESTROY(nsAccessNode, LastRelease())
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessNode construction/desctruction
 
@@ -282,136 +270,38 @@ nsAccessNode::GetFrame() const
 
 bool
 nsAccessNode::IsPrimaryForNode() const
 {
   return true;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsIAccessNode
-
-NS_IMETHODIMP
-nsAccessNode::GetDOMNode(nsIDOMNode **aDOMNode)
-{
-  NS_ENSURE_ARG_POINTER(aDOMNode);
-  *aDOMNode = nsnull;
-
-  nsINode *node = GetNode();
-  if (node)
-    CallQueryInterface(node, aDOMNode);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccessNode::GetDocument(nsIAccessibleDocument **aDocument)
-{
-  NS_ENSURE_ARG_POINTER(aDocument);
-
-  NS_IF_ADDREF(*aDocument = GetDocAccessible());
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccessNode::GetRootDocument(nsIAccessibleDocument **aRootDocument)
-{
-  NS_ENSURE_ARG_POINTER(aRootDocument);
-
-  nsRootAccessible* rootDocument = RootAccessible();
-  NS_IF_ADDREF(*aRootDocument = rootDocument);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccessNode::GetInnerHTML(nsAString& aInnerHTML)
-{
-  aInnerHTML.Truncate();
-
-  nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(mContent);
-  NS_ENSURE_TRUE(htmlElement, NS_ERROR_NULL_POINTER);
-
-  return htmlElement->GetInnerHTML(aInnerHTML);
-}
-
-NS_IMETHODIMP
+void
 nsAccessNode::ScrollTo(PRUint32 aScrollType)
 {
   if (IsDefunct())
-    return NS_ERROR_FAILURE;
+    return;
 
   nsCOMPtr<nsIPresShell> shell(GetPresShell());
-  NS_ENSURE_TRUE(shell, NS_ERROR_FAILURE);
+  if (!shell)
+    return;
 
   nsIFrame *frame = GetFrame();
-  NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
+  if (!frame)
+    return;
 
-  nsCOMPtr<nsIContent> content = frame->GetContent();
-  NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
+  nsIContent* content = frame->GetContent();
+  if (!content)
+    return;
 
   PRInt16 vPercent, hPercent;
   nsCoreUtils::ConvertScrollTypeToPercents(aScrollType, &vPercent, &hPercent);
-  return shell->ScrollContentIntoView(content, vPercent, hPercent,
-                                      nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
-}
-
-NS_IMETHODIMP
-nsAccessNode::ScrollToPoint(PRUint32 aCoordinateType, PRInt32 aX, PRInt32 aY)
-{
-  nsIFrame *frame = GetFrame();
-  if (!frame)
-    return NS_ERROR_FAILURE;
-
-  nsIntPoint coords;
-  nsresult rv = nsAccUtils::ConvertToScreenCoords(aX, aY, aCoordinateType,
-                                                  this, &coords);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsIFrame *parentFrame = frame;
-  while ((parentFrame = parentFrame->GetParent()))
-    nsCoreUtils::ScrollFrameToPoint(parentFrame, frame, coords);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccessNode::GetComputedStyleValue(const nsAString& aPseudoElt,
-                                    const nsAString& aPropertyName,
-                                    nsAString& aValue)
-{
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  nsCOMPtr<nsIDOMCSSStyleDeclaration> styleDecl =
-    nsCoreUtils::GetComputedStyleDeclaration(aPseudoElt, mContent);
-  NS_ENSURE_TRUE(styleDecl, NS_ERROR_FAILURE);
-
-  return styleDecl->GetPropertyValue(aPropertyName, aValue);
-}
-
-NS_IMETHODIMP
-nsAccessNode::GetComputedStyleCSSValue(const nsAString& aPseudoElt,
-                                       const nsAString& aPropertyName,
-                                       nsIDOMCSSPrimitiveValue **aCSSValue)
-{
-  NS_ENSURE_ARG_POINTER(aCSSValue);
-  *aCSSValue = nsnull;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  nsCOMPtr<nsIDOMCSSStyleDeclaration> styleDecl =
-    nsCoreUtils::GetComputedStyleDeclaration(aPseudoElt, mContent);
-  NS_ENSURE_STATE(styleDecl);
-
-  nsCOMPtr<nsIDOMCSSValue> cssValue;
-  styleDecl->GetPropertyCSSValue(aPropertyName, getter_AddRefs(cssValue));
-  NS_ENSURE_TRUE(cssValue, NS_ERROR_FAILURE);
-
-  return CallQueryInterface(cssValue, aCSSValue);
+  shell->ScrollContentIntoView(content, vPercent, hPercent,
+                               nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
 }
 
 // nsAccessNode public
 already_AddRefed<nsINode>
 nsAccessNode::GetCurrentFocus()
 {
   // XXX: consider to use nsFocusManager directly, it allows us to avoid
   // unnecessary query interface calls.
@@ -438,25 +328,23 @@ nsAccessNode::GetCurrentFocus()
     focusedWindow->GetDocument(getter_AddRefs(doc));
     if (doc)
       CallQueryInterface(doc, &focusedNode);
   }
 
   return focusedNode;
 }
 
-NS_IMETHODIMP
-nsAccessNode::GetLanguage(nsAString& aLanguage)
+void
+nsAccessNode::Language(nsAString& aLanguage)
 {
   aLanguage.Truncate();
 
   if (IsDefunct())
-    return NS_ERROR_FAILURE;
+    return;
 
   nsCoreUtils::GetLanguageFor(mContent, nsnull, aLanguage);
-
   if (aLanguage.IsEmpty()) { // Nothing found, so use document's language
     mContent->OwnerDoc()->GetHeaderData(nsGkAtoms::headerContentLanguage,
                                         aLanguage);
   }
- 
-  return NS_OK;
 }
+
--- a/accessible/src/base/nsAccessNode.h
+++ b/accessible/src/base/nsAccessNode.h
@@ -38,17 +38,16 @@
 
 /* For documentation of the accessibility architecture, 
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
 #ifndef _nsAccessNode_H_
 #define _nsAccessNode_H_
 
-#include "nsIAccessNode.h"
 #include "nsIAccessibleTypes.h"
 
 #include "a11yGeneric.h"
 
 #include "nsIContent.h"
 #include "nsIDOMNode.h"
 #include "nsINameSpaceManager.h"
 #include "nsIStringBundle.h"
@@ -63,36 +62,25 @@ class nsRootAccessible;
 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"
 
-#define NS_ACCESSNODE_IMPL_CID                          \
-{  /* 2b07e3d7-00b3-4379-aa0b-ea22e2c8ffda */           \
-  0x2b07e3d7,                                           \
-  0x00b3,                                               \
-  0x4379,                                               \
-  { 0xaa, 0x0b, 0xea, 0x22, 0xe2, 0xc8, 0xff, 0xda }    \
-}
-
-class nsAccessNode: public nsIAccessNode
+class nsAccessNode: public nsISupports
 {
 public:
 
   nsAccessNode(nsIContent *aContent, nsIWeakReference *aShell);
   virtual ~nsAccessNode();
 
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-    NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsAccessNode, nsIAccessNode)
-
-    NS_DECL_NSIACCESSNODE
-    NS_DECLARE_STATIC_IID_ACCESSOR(NS_ACCESSNODE_IMPL_CID)
+    NS_DECL_CYCLE_COLLECTION_CLASS(nsAccessNode)
 
     static void InitXPAccessibility();
     static void ShutdownXPAccessibility();
 
   /**
    * Return an application accessible.
    */
   static nsApplicationAccessible* GetApplicationAccessible();
@@ -129,28 +117,16 @@ public:
    * Returns true when the accessible is defunct.
    */
   virtual bool IsDefunct() const;
 
   /**
    * Return frame for the given access node object.
    */
   virtual nsIFrame* GetFrame() const;
-
-  /**
-   * Return DOM node associated with this accessible.
-   */
-  already_AddRefed<nsIDOMNode> GetDOMNode() const
-  {
-    nsIDOMNode *DOMNode = nsnull;
-    if (GetNode())
-      CallQueryInterface(GetNode(), &DOMNode);
-    return DOMNode;
-  }
-
   /**
    * Return DOM node associated with the accessible.
    */
   virtual nsINode* GetNode() const { return mContent; }
   nsIContent* GetContent() const { return mContent; }
   virtual nsIDocument* GetDocumentNode() const
     { return mContent ? mContent->OwnerDoc() : nsnull; }
 
@@ -190,16 +166,28 @@ public:
    * Return true if the accessible is primary accessible for the given DOM node.
    *
    * Accessible hierarchy may be complex for single DOM node, in this case
    * these accessibles share the same DOM node. The primary accessible "owns"
    * that DOM node in terms it gets stored in the accessible to node map.
    */
   virtual bool IsPrimaryForNode() const;
 
+  /**
+   * Return the string bundle
+   */
+  static nsIStringBundle* GetStringBundle()
+    { return gStringBundle; }
+
+  /**
+   * Interface methods on nsIAccessible shared with ISimpleDOM.
+   */
+  void Language(nsAString& aLocale);
+  void ScrollTo(PRUint32 aType);
+
 protected:
     nsPresContext* GetPresContext();
 
     void LastRelease();
 
   nsCOMPtr<nsIContent> mContent;
   nsCOMPtr<nsIWeakReference> mWeakShell;
 
@@ -216,13 +204,10 @@ protected:
 private:
   nsAccessNode();
   nsAccessNode(const nsAccessNode&);
   nsAccessNode& operator =(const nsAccessNode&);
   
   static nsApplicationAccessible *gApplicationAccessible;
 };
 
-NS_DEFINE_STATIC_IID_ACCESSOR(nsAccessNode,
-                              NS_ACCESSNODE_IMPL_CID)
-
 #endif
 
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -47,21 +47,24 @@
 #include "nsDocAccessible.h"
 #include "nsEventShell.h"
 
 #include "nsAccEvent.h"
 #include "nsAccessibleRelation.h"
 #include "nsAccessibilityService.h"
 #include "nsAccTreeWalker.h"
 #include "nsIAccessibleRelation.h"
+#include "nsRootAccessible.h"
 #include "nsTextEquivUtils.h"
 #include "Relation.h"
 #include "Role.h"
 #include "States.h"
 
+#include "nsIDOMCSSValue.h"
+#include "nsIDOMCSSPrimitiveValue.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMDocumentXBL.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIDOMNodeFilter.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDOMTreeWalker.h"
@@ -225,16 +228,102 @@ nsAccessible::~nsAccessible()
 
 void
 nsAccessible::SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry)
 {
   mRoleMapEntry = aRoleMapEntry;
 }
 
 NS_IMETHODIMP
+nsAccessible::GetComputedStyleValue(const nsAString& aPseudoElt,
+                                    const nsAString& aPropertyName,
+                                    nsAString& aValue)
+{
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsCOMPtr<nsIDOMCSSStyleDeclaration> styleDecl =
+    nsCoreUtils::GetComputedStyleDeclaration(aPseudoElt, mContent);
+  NS_ENSURE_TRUE(styleDecl, NS_ERROR_FAILURE);
+
+  return styleDecl->GetPropertyValue(aPropertyName, aValue);
+}
+
+NS_IMETHODIMP
+nsAccessible::GetComputedStyleCSSValue(const nsAString& aPseudoElt,
+                                       const nsAString& aPropertyName,
+                                       nsIDOMCSSPrimitiveValue **aCSSValue) {
+  NS_ENSURE_ARG_POINTER(aCSSValue);
+  *aCSSValue = nsnull;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsCOMPtr<nsIDOMCSSStyleDeclaration> styleDecl =
+    nsCoreUtils::GetComputedStyleDeclaration(aPseudoElt, mContent);
+  NS_ENSURE_STATE(styleDecl);
+
+  nsCOMPtr<nsIDOMCSSValue> cssValue;
+  styleDecl->GetPropertyCSSValue(aPropertyName, getter_AddRefs(cssValue));
+  NS_ENSURE_TRUE(cssValue, NS_ERROR_FAILURE);
+
+  return CallQueryInterface(cssValue, aCSSValue);
+}
+
+NS_IMETHODIMP
+nsAccessible::GetDocument(nsIAccessibleDocument **aDocument)
+{
+  NS_ENSURE_ARG_POINTER(aDocument);
+
+  NS_IF_ADDREF(*aDocument = GetDocAccessible());
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAccessible::GetDOMNode(nsIDOMNode **aDOMNode)
+{
+  NS_ENSURE_ARG_POINTER(aDOMNode);
+  *aDOMNode = nsnull;
+
+  nsINode *node = GetNode();
+  if (node)
+    CallQueryInterface(node, aDOMNode);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAccessible::GetRootDocument(nsIAccessibleDocument **aRootDocument)
+{
+  NS_ENSURE_ARG_POINTER(aRootDocument);
+
+  nsRootAccessible* rootDocument = RootAccessible();
+  NS_IF_ADDREF(*aRootDocument = rootDocument);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAccessible::GetInnerHTML(nsAString& aInnerHTML)
+{
+  aInnerHTML.Truncate();
+
+  nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(mContent);
+  NS_ENSURE_TRUE(htmlElement, NS_ERROR_NULL_POINTER);
+
+  return htmlElement->GetInnerHTML(aInnerHTML);
+}
+
+NS_IMETHODIMP
+nsAccessible::GetLanguage(nsAString& aLanguage)
+{
+  Language(aLanguage);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsAccessible::GetName(nsAString& aName)
 {
   aName.Truncate();
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   GetARIAName(aName);
@@ -546,17 +635,17 @@ nsAccessible::GetChildren(nsIArray **aOu
     children->AppendElement(child, false);
   }
 
   NS_ADDREF(*aOutChildren = children);
   return NS_OK;
 }
 
 bool
-nsAccessible::GetAllowsAnonChildAccessibles()
+nsAccessible::CanHaveAnonChildren()
 {
   return true;
 }
 
 /* readonly attribute long childCount; */
 NS_IMETHODIMP
 nsAccessible::GetChildCount(PRInt32 *aChildCount) 
 {
@@ -1369,16 +1458,40 @@ nsAccessible::GetAttributesInternal(nsIP
     nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textAlign, value);
 
   // Expose 'text-indent' attribute.
   rv = GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("text-indent"),
                              value);
   if (NS_SUCCEEDED(rv))
     nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textIndent, value);
 
+  // Expose 'margin-left' attribute.
+  rv = GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("margin-left"),
+                             value);
+  if (NS_SUCCEEDED(rv))
+    nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginLeft, value);
+
+  // Expose 'margin-right' attribute.
+  rv = GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("margin-right"),
+                             value);
+  if (NS_SUCCEEDED(rv))
+    nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginRight, value);
+
+  // Expose 'margin-top' attribute.
+  rv = GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("margin-top"),
+                             value);
+  if (NS_SUCCEEDED(rv))
+    nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginTop, value);
+
+  // Expose 'margin-bottom' attribute.
+  rv = GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("margin-bottom"),
+                             value);
+  if (NS_SUCCEEDED(rv))
+    nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginBottom, value);
+
   // Expose draggable object attribute?
   nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(mContent);
   if (htmlElement) {
     bool draggable = false;
     htmlElement->GetDraggable(&draggable);
     if (draggable) {
       nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::draggable,
                              NS_LITERAL_STRING("true"));
@@ -2171,16 +2284,42 @@ nsAccessible::DispatchClickEvent(nsICont
   bool res = nsCoreUtils::DispatchMouseEvent(NS_MOUSE_BUTTON_DOWN, presShell,
                                                aContent);
   if (!res)
     return;
 
   nsCoreUtils::DispatchMouseEvent(NS_MOUSE_BUTTON_UP, presShell, aContent);
 }
 
+NS_IMETHODIMP
+nsAccessible::ScrollTo(PRUint32 aHow)
+{
+  nsAccessNode::ScrollTo(aHow);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAccessible::ScrollToPoint(PRUint32 aCoordinateType, PRInt32 aX, PRInt32 aY)
+{
+  nsIFrame *frame = GetFrame();
+  if (!frame)
+    return NS_ERROR_FAILURE;
+
+  nsIntPoint coords;
+  nsresult rv = nsAccUtils::ConvertToScreenCoords(aX, aY, aCoordinateType,
+                                                  this, &coords);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsIFrame *parentFrame = frame;
+  while ((parentFrame = parentFrame->GetParent()))
+    nsCoreUtils::ScrollFrameToPoint(parentFrame, frame, coords);
+
+  return NS_OK;
+}
+
 // nsIAccessibleSelectable
 NS_IMETHODIMP nsAccessible::GetSelectedChildren(nsIArray **aSelectedAccessibles)
 {
   NS_ENSURE_ARG_POINTER(aSelectedAccessibles);
   *aSelectedAccessibles = nsnull;
 
   if (IsDefunct() || !IsSelect())
     return NS_ERROR_FAILURE;
@@ -2935,17 +3074,17 @@ nsAccessible::ContainerWidget() const
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessible protected methods
 
 void
 nsAccessible::CacheChildren()
 {
-  nsAccTreeWalker walker(mWeakShell, mContent, GetAllowsAnonChildAccessibles());
+  nsAccTreeWalker walker(mWeakShell, mContent, CanHaveAnonChildren());
 
   nsAccessible* child = nsnull;
   while ((child = walker.NextChild()) && AppendChild(child));
 }
 
 void
 nsAccessible::TestChildCache(nsAccessible* aCachedChild) const
 {
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -125,16 +125,27 @@ public:
   // Public methods
 
   /**
    * get the description of this accessible
    */
   virtual void Description(nsString& aDescription);
 
   /**
+   * Return DOM node associated with this accessible.
+   */
+  inline already_AddRefed<nsIDOMNode> DOMNode() const
+  {
+    nsIDOMNode *DOMNode = nsnull;
+    if (GetNode())
+      CallQueryInterface(GetNode(), &DOMNode);
+    return DOMNode;
+  }
+
+  /**
    * Returns the accessible name specified by ARIA.
    */
   nsresult GetARIAName(nsAString& aName);
 
   /**
    * Maps ARIA state attributes to state of accessible. Note the given state
    * argument should hold states for accessible before you pass it into this
    * method.
@@ -383,19 +394,19 @@ public:
 
   /**
    * Handle accessible event, i.e. process it, notifies observers and fires
    * platform specific event.
    */
   virtual nsresult HandleAccEvent(AccEvent* aAccEvent);
 
   /**
-   * Return true if there are accessible children in anonymous content
+   * Return true if this accessible allows accessible children from anonymous subtree.
    */
-  virtual bool GetAllowsAnonChildAccessibles();
+  virtual bool CanHaveAnonChildren();
 
   /**
    * Returns text of accessible if accessible has text role otherwise empty
    * string.
    *
    * @param aText         [in] returned text of the accessible
    * @param aStartOffset  [in, optional] start offset inside of the accessible,
    *                        if missed entire text is appended
--- a/accessible/src/base/nsApplicationAccessible.cpp
+++ b/accessible/src/base/nsApplicationAccessible.cpp
@@ -416,17 +416,17 @@ nsApplicationAccessible::GetSiblingAtOff
 {
   if (aError)
     *aError = NS_OK; // fail peacefully
 
   return nsnull;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsIAccessNode and nsAccessNode
+// nsIAccessible
 
 NS_IMETHODIMP
 nsApplicationAccessible::GetDOMNode(nsIDOMNode **aDOMNode)
 {
   NS_ENSURE_ARG_POINTER(aDOMNode);
   *aDOMNode = nsnull;
   return NS_OK;
 }
--- a/accessible/src/base/nsApplicationAccessible.h
+++ b/accessible/src/base/nsApplicationAccessible.h
@@ -64,32 +64,30 @@ class nsApplicationAccessible: public ns
 {
 public:
 
   nsApplicationAccessible();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIAccessNode
+  // nsIAccessible
   NS_SCRIPTABLE NS_IMETHOD GetDOMNode(nsIDOMNode** aDOMNode);
   NS_SCRIPTABLE NS_IMETHOD GetDocument(nsIAccessibleDocument** aDocument);
   NS_SCRIPTABLE NS_IMETHOD GetRootDocument(nsIAccessibleDocument** aRootDocument);
   NS_SCRIPTABLE NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML);
   NS_SCRIPTABLE NS_IMETHOD ScrollTo(PRUint32 aScrollType);
   NS_SCRIPTABLE NS_IMETHOD ScrollToPoint(PRUint32 aCoordinateType, PRInt32 aX, PRInt32 aY);
   NS_SCRIPTABLE NS_IMETHOD GetComputedStyleValue(const nsAString& aPseudoElt,
                                                  const nsAString& aPropertyName,
                                                  nsAString& aValue NS_OUTPARAM);
   NS_SCRIPTABLE NS_IMETHOD GetComputedStyleCSSValue(const nsAString& aPseudoElt,
                                                     const nsAString& aPropertyName,
                                                     nsIDOMCSSPrimitiveValue** aValue NS_OUTPARAM);
   NS_SCRIPTABLE NS_IMETHOD GetLanguage(nsAString& aLanguage);
-
-  // nsIAccessible
   NS_IMETHOD GetParent(nsIAccessible **aParent);
   NS_IMETHOD GetNextSibling(nsIAccessible **aNextSibling);
   NS_IMETHOD GetPreviousSibling(nsIAccessible **aPreviousSibling);
   NS_IMETHOD GetName(nsAString &aName);
   NS_IMETHOD GetValue(nsAString &aValue);
   NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
   NS_IMETHOD GroupPosition(PRInt32 *aGroupLevel, PRInt32 *aSimilarItemsInGroup,
                            PRInt32 *aPositionInGroup);
--- a/accessible/src/base/nsCoreUtils.h
+++ b/accessible/src/base/nsCoreUtils.h
@@ -186,17 +186,17 @@ public:
    */
   static nsresult ScrollSubstringTo(nsIFrame *aFrame,
                                     nsIDOMNode *aStartNode, PRInt32 aStartIndex,
                                     nsIDOMNode *aEndNode, PRInt32 aEndIndex,
                                     PRInt16 aVPercent, PRInt16 aHPercent);
 
   /**
    * Scrolls the given frame to the point, used for implememntation of
-   * nsIAccessNode::scrollToPoint and nsIAccessibleText::scrollSubstringToPoint.
+   * nsIAccessible::scrollToPoint and nsIAccessibleText::scrollSubstringToPoint.
    *
    * @param aScrollableFrame  the scrollable frame
    * @param aFrame            the frame to scroll
    * @param aPoint            the point scroll to
    */
   static void ScrollFrameToPoint(nsIFrame *aScrollableFrame,
                                  nsIFrame *aFrame, const nsIntPoint& aPoint);
 
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -1520,17 +1520,17 @@ nsDocAccessible::ProcessInvalidationList
 // nsAccessible protected
 
 void
 nsDocAccessible::CacheChildren()
 {
   // Search for accessible children starting from the document element since
   // some web pages tend to insert elements under it rather than document body.
   nsAccTreeWalker walker(mWeakShell, mDocument->GetRootElement(),
-                         GetAllowsAnonChildAccessibles());
+                         CanHaveAnonChildren());
 
   nsAccessible* child = nsnull;
   while ((child = walker.NextChild()) && AppendChild(child));
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Protected members
 
@@ -1876,17 +1876,17 @@ nsDocAccessible::UpdateTree(nsAccessible
 
   // If child node is not accessible then look for its accessible children.
   nsAccessible* child = GetAccessible(aChildNode);
   if (child) {
     updateFlags |= UpdateTreeInternal(child, aIsInsert);
 
   } else {
     nsAccTreeWalker walker(mWeakShell, aChildNode,
-                           aContainer->GetAllowsAnonChildAccessibles(), true);
+                           aContainer->CanHaveAnonChildren(), true);
 
     while ((child = walker.NextChild()))
       updateFlags |= UpdateTreeInternal(child, aIsInsert);
   }
 
   // Content insertion/removal is not cause of accessible tree change.
   if (updateFlags == eNoAccessible)
     return;
--- a/accessible/src/base/nsTextAttrs.cpp
+++ b/accessible/src/base/nsTextAttrs.cpp
@@ -278,18 +278,18 @@ nsTextAttrsMgr::GetRange(const nsTArray<
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsLangTextAttr
 
 nsLangTextAttr::nsLangTextAttr(nsHyperTextAccessible *aRootAcc, 
                                nsIContent *aRootContent, nsIContent *aContent) :
   nsTextAttr<nsAutoString>(aContent == nsnull), mRootContent(aRootContent)
 {
-  nsresult rv = aRootAcc->GetLanguage(mRootNativeValue);
-  mIsRootDefined = NS_SUCCEEDED(rv) && !mRootNativeValue.IsEmpty();
+  aRootAcc->Language(mRootNativeValue);
+  mIsRootDefined =  !mRootNativeValue.IsEmpty();
 
   if (aContent)
     mIsDefined = GetLang(aContent, mNativeValue);
 }
 
 bool
 nsLangTextAttr::GetValueFor(nsIContent *aElm, nsAutoString *aValue)
 {
--- a/accessible/src/html/nsHTMLTableAccessible.cpp
+++ b/accessible/src/html/nsHTMLTableAccessible.cpp
@@ -453,17 +453,17 @@ NS_IMPL_ISUPPORTS_INHERITED2(nsHTMLTable
 
 void
 nsHTMLTableAccessible::CacheChildren()
 {
   // Move caption accessible so that it's the first child. Check for the first
   // caption only, because nsAccessibilityService ensures we don't create
   // accessibles for the other captions, since only the first is actually
   // visible.
-  nsAccTreeWalker walker(mWeakShell, mContent, GetAllowsAnonChildAccessibles());
+  nsAccTreeWalker walker(mWeakShell, mContent, CanHaveAnonChildren());
 
   nsAccessible* child = nsnull;
   while ((child = walker.NextChild())) {
     if (child->Role() == roles::CAPTION) {
       InsertChildAt(0, child);
       while ((child = walker.NextChild()) && AppendChild(child));
       break;
     }
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -1143,17 +1143,17 @@ nsHyperTextAccessible::GetTextAttributes
                               accAtOffsetIdx);
   nsresult rv = textAttrsMgr.GetAttributes(*aAttributes, &startOffset,
                                            &endOffset);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Compute spelling attributes on text accessible only.
   nsIFrame *offsetFrame = accAtOffset->GetFrame();
   if (offsetFrame && offsetFrame->GetType() == nsGkAtoms::textFrame) {
-    nsCOMPtr<nsIDOMNode> node = accAtOffset->GetDOMNode();
+    nsCOMPtr<nsIDOMNode> node = accAtOffset->DOMNode();
 
     PRInt32 nodeOffset = 0;
     nsresult rv = RenderedToContentOffset(offsetFrame, offsetInAcc,
                                           &nodeOffset);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Set 'misspelled' text attribute.
     rv = GetSpellTextAttribute(node, nodeOffset, &startOffset, &endOffset,
@@ -1555,22 +1555,27 @@ nsHyperTextAccessible::GetAssociatedEdit
 
 /**
   * =================== Caret & Selection ======================
   */
 
 nsresult
 nsHyperTextAccessible::SetSelectionRange(PRInt32 aStartPos, PRInt32 aEndPos)
 {
-  nsresult rv = TakeFocus();
-  NS_ENSURE_SUCCESS(rv, rv);
+  bool isFocusable = State() & states::FOCUSABLE;
+
+  // If accessible is focusable then focus it before setting the selection to
+  // neglect control's selection changes on focus if any (for example, inputs
+  // that do select all on focus).
+  // some input controls
+  if (isFocusable)
+    TakeFocus();
 
   // Set the selection
   SetSelectionBounds(0, aStartPos, aEndPos);
-  NS_ENSURE_SUCCESS(rv, rv);
 
   // If range 0 was successfully set, clear any additional selection 
   // ranges remaining from previous selection
   nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
   NS_ENSURE_STATE(frameSelection);
 
   nsCOMPtr<nsISelection> domSel =
     frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL);
@@ -1580,17 +1585,22 @@ nsHyperTextAccessible::SetSelectionRange
   domSel->GetRangeCount(&numRanges);
 
   for (PRInt32 count = 0; count < numRanges - 1; count ++) {
     nsCOMPtr<nsIDOMRange> range;
     domSel->GetRangeAt(1, getter_AddRefs(range));
     domSel->RemoveRange(range);
   }
 
-  // Now that selection is done, move the focus to the selection.
+  // When selection is done, move the focus to the selection if accessible is
+  // not focusable. That happens when selection is set within hypertext
+  // accessible.
+  if (isFocusable)
+    return NS_OK;
+
   nsFocusManager* DOMFocusManager = nsFocusManager::GetFocusManager();
   if (DOMFocusManager) {
     nsCOMPtr<nsIPresShell> shell = GetPresShell();
     NS_ENSURE_TRUE(shell, NS_ERROR_FAILURE);
     nsCOMPtr<nsIDocument> doc = shell->GetDocument();
     NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
     nsCOMPtr<nsPIDOMWindow> window = doc->GetWindow();
     nsCOMPtr<nsIDOMElement> result;
@@ -2250,20 +2260,18 @@ nsHyperTextAccessible::GetDOMPointByFram
 {
   NS_ENSURE_ARG(aAccessible);
 
   nsCOMPtr<nsIDOMNode> node;
 
   if (!aFrame) {
     // If the given frame is null then set offset after the DOM node of the
     // given accessible.
-    nsCOMPtr<nsIAccessNode> accessNode(do_QueryInterface(aAccessible));
-
     nsCOMPtr<nsIDOMNode> DOMNode;
-    accessNode->GetDOMNode(getter_AddRefs(DOMNode));
+    aAccessible->GetDOMNode(getter_AddRefs(DOMNode));
     nsCOMPtr<nsIContent> content(do_QueryInterface(DOMNode));
     NS_ENSURE_STATE(content);
 
     nsCOMPtr<nsIContent> parent(content->GetParent());
     NS_ENSURE_STATE(parent);
 
     *aNodeOffset = parent->IndexOf(content) + 1;
     node = do_QueryInterface(parent);
--- a/accessible/src/msaa/CAccessibleComponent.cpp
+++ b/accessible/src/msaa/CAccessibleComponent.cpp
@@ -150,17 +150,17 @@ CAccessibleComponent::get_background(IA2
 
 HRESULT
 CAccessibleComponent::GetARGBValueFromCSSProperty(const nsAString& aPropName,
                                                   IA2Color *aColorValue)
 {
 __try {
   *aColorValue = 0;
 
-  nsCOMPtr<nsIAccessNode> acc(do_QueryObject(this));
+  nsRefPtr<nsAccessible> acc(do_QueryObject(this));
   if (!acc)
     return E_FAIL;
 
   nsCOMPtr<nsIDOMCSSPrimitiveValue> cssValue;
   nsresult rv = acc->GetComputedStyleCSSValue(EmptyString(), aPropName,
                                               getter_AddRefs(cssValue));
   if (NS_FAILED(rv) || !cssValue)
     return GetHRESULT(rv);
--- a/accessible/src/msaa/nsAccessNodeWrap.cpp
+++ b/accessible/src/msaa/nsAccessNodeWrap.cpp
@@ -391,19 +391,18 @@ STDMETHODIMP nsAccessNodeWrap::get_compu
 
 STDMETHODIMP nsAccessNodeWrap::scrollTo(/* [in] */ boolean aScrollTopLeft)
 {
 __try {
   PRUint32 scrollType =
     aScrollTopLeft ? nsIAccessibleScrollType::SCROLL_TYPE_TOP_LEFT :
                      nsIAccessibleScrollType::SCROLL_TYPE_BOTTOM_RIGHT;
 
-  nsresult rv = ScrollTo(scrollType);
-  if (NS_SUCCEEDED(rv))
-    return S_OK;
+  ScrollTo(scrollType);
+  return S_OK;
 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
 
   return E_FAIL;
 }
 
 ISimpleDOMNode*
 nsAccessNodeWrap::MakeAccessNode(nsINode *aNode)
 {
@@ -549,20 +548,17 @@ nsAccessNodeWrap::get_innerHTML(BSTR __R
 
 STDMETHODIMP 
 nsAccessNodeWrap::get_language(BSTR __RPC_FAR *aLanguage)
 {
 __try {
   *aLanguage = NULL;
 
   nsAutoString language;
-  if (NS_FAILED(GetLanguage(language))) {
-    return E_FAIL;
-  }
-
+  Language(language);
   if (language.IsEmpty())
     return S_FALSE;
 
   *aLanguage = ::SysAllocStringLen(language.get(), language.Length());
   if (!*aLanguage)
     return E_OUTOFMEMORY;
 
 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
@@ -570,17 +566,17 @@ nsAccessNodeWrap::get_language(BSTR __RP
   return S_OK;
 }
 
 STDMETHODIMP 
 nsAccessNodeWrap::get_localInterface( 
     /* [out] */ void __RPC_FAR *__RPC_FAR *localInterface)
 {
 __try {
-  *localInterface = static_cast<nsIAccessNode*>(this);
+  *localInterface = static_cast<nsAccessNode*>(this);
   NS_ADDREF_THIS();
 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
  
 void nsAccessNodeWrap::InitAccessibility()
 {
   Compatibility::Init();
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -1140,18 +1140,18 @@ nsAccessibleWrap::role(long *aRole)
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
 nsAccessibleWrap::scrollTo(enum IA2ScrollType aScrollType)
 {
 __try {
-  nsresult rv = ScrollTo(aScrollType);
-  return GetHRESULT(rv);
+  nsAccessNode::ScrollTo(aScrollType);
+  return S_OK;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
 nsAccessibleWrap::scrollToPoint(enum IA2CoordinateType aCoordType,
                                 long aX, long aY)
@@ -1361,19 +1361,17 @@ nsAccessibleWrap::get_locale(IA2Locale *
 {
 __try {
   // Language codes consist of a primary code and a possibly empty series of
   // subcodes: language-code = primary-code ( "-" subcode )*
   // Two-letter primary codes are reserved for [ISO639] language abbreviations.
   // Any two-letter subcode is understood to be a [ISO3166] country code.
 
   nsAutoString lang;
-  nsresult rv = GetLanguage(lang);
-  if (NS_FAILED(rv))
-    return GetHRESULT(rv);
+  Language(lang);
 
   // If primary code consists from two letters then expose it as language.
   PRInt32 offset = lang.FindChar('-', 0);
   if (offset == -1) {
     if (lang.Length() == 2) {
       aLocale->language = ::SysAllocString(lang.get());
       return S_OK;
     }
--- a/accessible/src/xforms/nsXFormsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsAccessible.cpp
@@ -38,16 +38,17 @@
 
 #include "nsXFormsAccessible.h"
 
 #include "nsAccessibilityService.h"
 #include "nsAccUtils.h"
 #include "nsTextEquivUtils.h"
 #include "Role.h"
 #include "States.h"
+#include "Statistics.h"
 
 #include "nscore.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMNodeList.h"
 #include "nsIEditor.h"
 #include "nsIMutableArray.h"
 #include "nsIXFormsUtilityService.h"
@@ -65,16 +66,17 @@ nsIXFormsUtilityService *nsXFormsAccessi
 nsXFormsAccessibleBase::nsXFormsAccessibleBase()
 {
   if (!sXFormsService) {
     nsresult rv = CallGetService("@mozilla.org/xforms-utility-service;1",
                                  &sXFormsService);
     if (NS_FAILED(rv))
       NS_WARNING("No XForms utility service.");
   }
+  statistics::XFormsAccessibleUsed();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXFormsAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsXFormsAccessible::
 nsXFormsAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
@@ -208,17 +210,17 @@ nsXFormsAccessible::Description(nsString
     GetTextEquivFromIDRefs(this, nsGkAtoms::aria_describedby,
                            aDescription);
 
   if (aDescription.IsEmpty())
     GetBoundChildElementValue(NS_LITERAL_STRING("hint"), aDescription);
 }
 
 bool
-nsXFormsAccessible::GetAllowsAnonChildAccessibles()
+nsXFormsAccessible::CanHaveAnonChildren()
 {
   return false;
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXFormsContainerAccessible
 ////////////////////////////////////////////////////////////////////////////////
@@ -231,17 +233,17 @@ nsXFormsContainerAccessible::
 
 role
 nsXFormsContainerAccessible::NativeRole()
 {
   return roles::GROUPING;
 }
 
 bool
-nsXFormsContainerAccessible::GetAllowsAnonChildAccessibles()
+nsXFormsContainerAccessible::CanHaveAnonChildren()
 {
   return true;
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXFormsEditableAccessible
 ////////////////////////////////////////////////////////////////////////////////
--- a/accessible/src/xforms/nsXFormsAccessible.h
+++ b/accessible/src/xforms/nsXFormsAccessible.h
@@ -85,17 +85,17 @@ public:
   virtual nsresult GetNameInternal(nsAString& aName);
 
   // Returns state of xforms element taking into account state of instance node
   // that it is bound to.
   virtual PRUint64 NativeState();
 
   // Denies accessible nodes in anonymous content of xforms element by
   // always returning false value.
-  virtual bool GetAllowsAnonChildAccessibles();
+  virtual bool CanHaveAnonChildren();
 
 protected:
   // Returns value of first child xforms element by tagname that is bound to
   // instance node.
   nsresult GetBoundChildElementValue(const nsAString& aTagName,
                                      nsAString& aValue);
 
   // Cache accessible child item/choices elements. For example, the method is
@@ -126,17 +126,17 @@ class nsXFormsContainerAccessible : publ
 public:
   nsXFormsContainerAccessible(nsIContent *aContent, nsIWeakReference *aShell);
 
   // nsAccessible
   virtual mozilla::a11y::role NativeRole();
 
   // Allows accessible nodes in anonymous content of xforms element by
   // always returning true value.
-  virtual bool GetAllowsAnonChildAccessibles();
+  virtual bool CanHaveAnonChildren();
 };
 
 
 /**
  * The class is base for accessible objects for XForms elements that have
  * editable area.
  */
 class nsXFormsEditableAccessible : public nsXFormsAccessible
--- a/accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
@@ -585,17 +585,17 @@ nsXFormsSelectComboboxAccessible::Native
     state |= states::EXPANDED;
   else
     state |= states::COLLAPSED;
 
   return state | states::HASPOPUP | states::FOCUSABLE;
 }
 
 bool
-nsXFormsSelectComboboxAccessible::GetAllowsAnonChildAccessibles()
+nsXFormsSelectComboboxAccessible::CanHaveAnonChildren()
 {
   return true;
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXFormsItemComboboxAccessible
 ////////////////////////////////////////////////////////////////////////////////
--- a/accessible/src/xforms/nsXFormsFormControlsAccessible.h
+++ b/accessible/src/xforms/nsXFormsFormControlsAccessible.h
@@ -292,17 +292,17 @@ class nsXFormsSelectComboboxAccessible :
 {
 public:
   nsXFormsSelectComboboxAccessible(nsIContent *aContent,
                                    nsIWeakReference *aShell);
 
   // nsAccessible
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 NativeState();
-  virtual bool GetAllowsAnonChildAccessibles();
+  virtual bool CanHaveAnonChildren();
 };
 
 
 /**
  * Accessible object for xforms:item element when it is represented by a
  * listitem. This occurs when the item is contained in a xforms:select with
  * minimal appearance. Such a xforms:select is represented by a combobox.
  */
--- a/accessible/src/xul/nsXULComboboxAccessible.cpp
+++ b/accessible/src/xul/nsXULComboboxAccessible.cpp
@@ -135,17 +135,17 @@ nsXULComboboxAccessible::Description(nsS
     nsAccessible* focusedOptionAcc = GetAccService()->
       GetAccessibleInWeakShell(focusedOptionContent, mWeakShell);
     if (focusedOptionAcc)
       focusedOptionAcc->Description(aDescription);
   }
 }
 
 bool
-nsXULComboboxAccessible::GetAllowsAnonChildAccessibles()
+nsXULComboboxAccessible::CanHaveAnonChildren()
 {
   if (mContent->NodeInfo()->Equals(nsGkAtoms::textbox, kNameSpaceID_XUL) ||
       mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::editable,
                             nsGkAtoms::_true, eIgnoreCase)) {
     // Both the XUL <textbox type="autocomplete"> and <menulist editable="true"> widgets
     // use nsXULComboboxAccessible. We need to walk the anonymous children for these
     // so that the entry field is a child
     return true;
--- a/accessible/src/xul/nsXULComboboxAccessible.h
+++ b/accessible/src/xul/nsXULComboboxAccessible.h
@@ -56,17 +56,17 @@ public:
   NS_IMETHOD GetValue(nsAString& aValue);
   NS_IMETHOD DoAction(PRUint8 aIndex);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
 
   // nsAccessible
   virtual void Description(nsString& aDescription);
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 NativeState();
-  virtual bool GetAllowsAnonChildAccessibles();
+  virtual bool CanHaveAnonChildren();
 
   // ActionAccessible
   virtual PRUint8 ActionCount();
 
   // Widgets
   virtual bool IsActiveWidget() const;
   virtual bool AreItemsOperable() const;
 };
--- a/accessible/src/xul/nsXULFormControlAccessible.cpp
+++ b/accessible/src/xul/nsXULFormControlAccessible.cpp
@@ -657,27 +657,20 @@ nsXULToolbarButtonAccessible::GetPositio
 
   *aPosInSet = posInSet;
   *aSetSize = setSize;
 }
 
 bool
 nsXULToolbarButtonAccessible::IsSeparator(nsAccessible *aAccessible)
 {
-  nsCOMPtr<nsIDOMNode> domNode;
-  aAccessible->GetDOMNode(getter_AddRefs(domNode));
-  nsCOMPtr<nsIContent> contentDomNode(do_QueryInterface(domNode));
-
-  if (!contentDomNode)
-    return false;
-
-  return (contentDomNode->Tag() == nsGkAtoms::toolbarseparator) ||
-         (contentDomNode->Tag() == nsGkAtoms::toolbarspacer) ||
-         (contentDomNode->Tag() == nsGkAtoms::toolbarspring);
-}
+  nsIContent* content = aAccessible->GetContent();
+  return content && ((content->Tag() == nsGkAtoms::toolbarseparator) ||
+                     (content->Tag() == nsGkAtoms::toolbarspacer) ||
+                     (content->Tag() == nsGkAtoms::toolbarspring)); }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULToolbarAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsXULToolbarAccessible::
   nsXULToolbarAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
@@ -846,17 +839,17 @@ NS_IMETHODIMP nsXULTextFieldAccessible::
       return NS_OK;
     }
     return NS_ERROR_FAILURE;
   }
   return NS_ERROR_INVALID_ARG;
 }
 
 bool
-nsXULTextFieldAccessible::GetAllowsAnonChildAccessibles()
+nsXULTextFieldAccessible::CanHaveAnonChildren()
 {
   return false;
 }
 
 NS_IMETHODIMP nsXULTextFieldAccessible::GetAssociatedEditor(nsIEditor **aEditor)
 {
   *aEditor = nsnull;
 
--- a/accessible/src/xul/nsXULFormControlAccessible.h
+++ b/accessible/src/xul/nsXULFormControlAccessible.h
@@ -262,17 +262,17 @@ public:
 
   // nsIAccessibleEditableText
   NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
 
   // nsAccessible
   virtual void ApplyARIAState(PRUint64* aState);
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 NativeState();
-  virtual bool GetAllowsAnonChildAccessibles();
+  virtual bool CanHaveAnonChildren();
 
   // ActionAccessible
   virtual PRUint8 ActionCount();
 
 protected:
   // nsAccessible
   virtual void CacheChildren();
 
--- a/accessible/src/xul/nsXULListboxAccessible.cpp
+++ b/accessible/src/xul/nsXULListboxAccessible.cpp
@@ -1019,17 +1019,17 @@ NS_IMETHODIMP nsXULListitemAccessible::G
       aName.AssignLiteral("check");
 
     return NS_OK;
   }
   return NS_ERROR_INVALID_ARG;
 }
 
 bool
-nsXULListitemAccessible::GetAllowsAnonChildAccessibles()
+nsXULListitemAccessible::CanHaveAnonChildren()
 {
   // That indicates we should walk anonymous children for listitems
   return true;
 }
 
 void
 nsXULListitemAccessible::GetPositionAndSizeInternal(PRInt32 *aPosInSet,
                                                     PRInt32 *aSetSize)
--- a/accessible/src/xul/nsXULListboxAccessible.h
+++ b/accessible/src/xul/nsXULListboxAccessible.h
@@ -136,17 +136,17 @@ public:
 
   // nsAccessible
   virtual void Description(nsString& aDesc);
   virtual nsresult GetNameInternal(nsAString& aName);
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 NativeState();
   virtual void GetPositionAndSizeInternal(PRInt32 *aPosInSet,
                                           PRInt32 *aSetSize);
-  virtual bool GetAllowsAnonChildAccessibles();
+  virtual bool CanHaveAnonChildren();
 
   // Widgets
   virtual nsAccessible* ContainerWidget() const;
 
 protected:
   /**
    * Return listbox accessible for the listitem.
    */
--- a/accessible/src/xul/nsXULMenuAccessible.cpp
+++ b/accessible/src/xul/nsXULMenuAccessible.cpp
@@ -315,17 +315,17 @@ void
 nsXULMenuitemAccessible::GetPositionAndSizeInternal(PRInt32 *aPosInSet,
                                                     PRInt32 *aSetSize)
 {
   nsAccUtils::GetPositionAndSizeForXULContainerItem(mContent, aPosInSet,
                                                     aSetSize);
 }
 
 bool
-nsXULMenuitemAccessible::GetAllowsAnonChildAccessibles()
+nsXULMenuitemAccessible::CanHaveAnonChildren()
 {
   // That indicates we don't walk anonymous children for menuitems
   return false;
 }
 
 NS_IMETHODIMP nsXULMenuitemAccessible::DoAction(PRUint8 index)
 {
   if (index == eAction_Click) {   // default action
--- a/accessible/src/xul/nsXULMenuAccessible.h
+++ b/accessible/src/xul/nsXULMenuAccessible.h
@@ -61,17 +61,17 @@ public:
   virtual void Description(nsString& aDescription);
   virtual nsresult GetNameInternal(nsAString& aName);
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 NativeState();
   virtual PRInt32 GetLevelInternal();
   virtual void GetPositionAndSizeInternal(PRInt32 *aPosInSet,
                                           PRInt32 *aSetSize);
 
-  virtual bool GetAllowsAnonChildAccessibles();
+  virtual bool CanHaveAnonChildren();
 
   // ActionAccessible
   virtual PRUint8 ActionCount();
   virtual KeyBinding AccessKey() const;
   virtual KeyBinding KeyboardShortcut() const;
 
   // Widgets
   virtual bool IsActiveWidget() const;
--- a/accessible/src/xul/nsXULSliderAccessible.cpp
+++ b/accessible/src/xul/nsXULSliderAccessible.cpp
@@ -185,17 +185,17 @@ nsXULSliderAccessible::SetCurrentValue(d
   // ARIA redefined current value.
   if (rv != NS_OK_NO_ARIA_VALUE)
     return rv;
 
   return SetSliderAttr(nsGkAtoms::curpos, aValue);
 }
 
 bool
-nsXULSliderAccessible::GetAllowsAnonChildAccessibles()
+nsXULSliderAccessible::CanHaveAnonChildren()
 {
   // Do not allow anonymous xul:slider be accessible.
   return false;
 }
 
 // Utils
 
 already_AddRefed<nsIContent>
--- a/accessible/src/xul/nsXULSliderAccessible.h
+++ b/accessible/src/xul/nsXULSliderAccessible.h
@@ -60,17 +60,17 @@ public:
   NS_IMETHOD DoAction(PRUint8 aIndex);
 
   // nsIAccessibleValue
   NS_DECL_NSIACCESSIBLEVALUE
 
   // nsAccessible
   virtual mozilla::a11y::role NativeRole();
   virtual PRUint64 NativeState();
-  virtual bool GetAllowsAnonChildAccessibles();
+  virtual bool CanHaveAnonChildren();
 
   // ActionAccessible
   virtual PRUint8 ActionCount();
 
 protected:
   already_AddRefed<nsIContent> GetSliderNode();
 
   nsresult GetSliderAttr(nsIAtom *aName, nsAString& aValue);
--- a/accessible/src/xul/nsXULTabAccessible.cpp
+++ b/accessible/src/xul/nsXULTabAccessible.cpp
@@ -148,19 +148,19 @@ nsXULTabAccessible::RelationByType(PRUin
     return rel;
 
   // Expose 'LABEL_FOR' relation on tab accessible for tabpanel accessible.
   nsCOMPtr<nsIDOMXULRelatedElement> tabsElm =
     do_QueryInterface(mContent->GetParent());
   if (!tabsElm)
     return rel;
 
-  nsCOMPtr<nsIDOMNode> DOMNode(GetDOMNode());
+  nsCOMPtr<nsIDOMNode> domNode(DOMNode());
   nsCOMPtr<nsIDOMNode> tabpanelNode;
-  tabsElm->GetRelatedElement(DOMNode, getter_AddRefs(tabpanelNode));
+  tabsElm->GetRelatedElement(domNode, getter_AddRefs(tabpanelNode));
   if (!tabpanelNode)
     return rel;
 
   nsCOMPtr<nsIContent> tabpanelContent(do_QueryInterface(tabpanelNode));
   rel.AppendTarget(tabpanelContent);
   return rel;
 }
 
@@ -250,18 +250,18 @@ nsXULTabpanelAccessible::RelationByType(
     return rel;
 
   // Expose 'LABELLED_BY' relation on tabpanel accessible for tab accessible.
   nsCOMPtr<nsIDOMXULRelatedElement> tabpanelsElm =
     do_QueryInterface(mContent->GetParent());
   if (!tabpanelsElm)
     return rel;
 
-  nsCOMPtr<nsIDOMNode> DOMNode(GetDOMNode());
+  nsCOMPtr<nsIDOMNode> domNode(DOMNode());
   nsCOMPtr<nsIDOMNode> tabNode;
-  tabpanelsElm->GetRelatedElement(DOMNode, getter_AddRefs(tabNode));
+  tabpanelsElm->GetRelatedElement(domNode, getter_AddRefs(tabNode));
   if (!tabNode)
     return rel;
 
   nsCOMPtr<nsIContent> tabContent(do_QueryInterface(tabNode));
   rel.AppendTarget(tabContent);
   return rel;
 }
--- a/accessible/tests/mochitest/Makefile.in
+++ b/accessible/tests/mochitest/Makefile.in
@@ -53,16 +53,17 @@ DIRS	= \
   hypertext \
   name \
   pivot \
   relations \
   selectable \
   states \
   table \
   text \
+  textcaret \
   textselection \
   tree \
   treeupdate \
   value \
   $(null)
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
@@ -98,17 +99,16 @@ include $(topsrcdir)/config/rules.mk
 		test_childAtPoint.html \
 		test_childAtPoint.xul \
 		test_descr.html \
 		test_nsIAccessibleDocument.html \
 		test_nsIAccessibleImage.html \
 		test_nsIAccessNode_utils.html \
 		test_nsOuterDocAccessible.html \
 		test_role_nsHyperTextAcc.html \
-		test_text_caret.html \
 		test_textboxes.html \
 		test_textboxes.xul \
 		testTextboxes.js \
 		text.js \
 		treeview.css \
 		treeview.js \
 		$(NULL)
 
--- a/accessible/tests/mochitest/attributes/test_obj_css.html
+++ b/accessible/tests/mochitest/attributes/test_obj_css.html
@@ -1,12 +1,13 @@
 <html>
 <!--
 https://bugzilla.mozilla.org/show_bug.cgi?id=439566
 https://bugzilla.mozilla.org/show_bug.cgi?id=460932
+https://bugzilla.mozilla.org/show_bug.cgi?id=689540
 -->
 <head>
   <title>CSS-like attributes tests</title>
   <link rel="stylesheet" type="text/css"
         href="chrome://mochikit/content/tests/SimpleTest/test.css" />
 
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
@@ -20,26 +21,38 @@ https://bugzilla.mozilla.org/show_bug.cg
     function testCSSAttrs(aID)
     {
       var node = document.getElementById(aID);
       var computedStyle = document.defaultView.getComputedStyle(node, "");
 
       var attrs = {
         "display": computedStyle.display,
         "text-align": computedStyle.textAlign,
-        "text-indent": computedStyle.textIndent
+        "text-indent": computedStyle.textIndent,
+        "margin-left": computedStyle.marginLeft,
+        "margin-right": computedStyle.marginRight,
+        "margin-top": computedStyle.marginTop,
+        "margin-bottom": computedStyle.marginBottom
       };
       testAttrs(aID, attrs, true);
     }
 
     function doTest()
     {
       testCSSAttrs("span");
       testCSSAttrs("div");
+
       testCSSAttrs("p");
+      testCSSAttrs("p2");
+
+      testCSSAttrs("pml");
+      testCSSAttrs("pmr");
+      testCSSAttrs("pmt");
+      testCSSAttrs("pmb");
+
       testCSSAttrs("input");
       testCSSAttrs("table");
       testCSSAttrs("tr");
       testCSSAttrs("td");
 
       SimpleTest.finish();
     }
 
@@ -54,25 +67,38 @@ https://bugzilla.mozilla.org/show_bug.cg
      title="Include the css display property as an IAccessible2 object attribute">
     Mozilla Bug 439566
   </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=460932"
      title="text-indent and text-align should really be object attribute">
     Mozilla Bug 460932
   </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=689540"
+     title="Expose IA2 margin- object attributes">
+    Mozilla Bug 689540
+  </a>
 
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <span id="span" role="group">It's span</span>
   <div id="div">It's div</div>
+
   <p id="p">It's paragraph"</p>
+  <p id="p2"  style="text-indent: 5px">It's another paragraph</p>
+
+  <p id="pml" style="margin-left : 11px;">It's a paragraph with left margin</p>
+  <p id="pmr" style="margin-right : 21px;">It's a paragraph with right margin</p>
+  <p id="pmt" style="margin-top : 31px;">It's a paragraph with top margin</p>
+  <p id="pmb" style="margin-bottom : 41px;">It's a paragraph with bottom margin</p>
+
   <input id="input"/>
   <table id="table">
     <tr id="tr" role="group">
       <td id="td">td</td>
     </tr>
   </table>
 </body>
 </html>
--- a/accessible/tests/mochitest/common.js
+++ b/accessible/tests/mochitest/common.js
@@ -13,17 +13,16 @@ const nsIAccessibleTextChangeEvent =
 
 const nsIAccessibleStates = Components.interfaces.nsIAccessibleStates;
 const nsIAccessibleRole = Components.interfaces.nsIAccessibleRole;
 const nsIAccessibleScrollType = Components.interfaces.nsIAccessibleScrollType;
 const nsIAccessibleCoordinateType = Components.interfaces.nsIAccessibleCoordinateType;
 
 const nsIAccessibleRelation = Components.interfaces.nsIAccessibleRelation;
 
-const nsIAccessNode = Components.interfaces.nsIAccessNode;
 const nsIAccessible = Components.interfaces.nsIAccessible;
 
 const nsIAccessibleDocument = Components.interfaces.nsIAccessibleDocument;
 const nsIAccessibleApplication = Components.interfaces.nsIAccessibleApplication;
 
 const nsIAccessibleText = Components.interfaces.nsIAccessibleText;
 const nsIAccessibleEditableText = Components.interfaces.nsIAccessibleEditableText;
 
@@ -116,20 +115,18 @@ function addA11yLoadEvent(aFunc, aWindow
 function getNode(aAccOrNodeOrID)
 {
   if (!aAccOrNodeOrID)
     return null;
 
   if (aAccOrNodeOrID instanceof nsIDOMNode)
     return aAccOrNodeOrID;
 
-  if (aAccOrNodeOrID instanceof nsIAccessible) {
-    aAccOrNodeOrID.QueryInterface(nsIAccessNode);
+  if (aAccOrNodeOrID instanceof nsIAccessible)
     return aAccOrNodeOrID.DOMNode;
-  }
 
   node = document.getElementById(aAccOrNodeOrID);
   if (!node) {
     ok(false, "Can't get DOM element for " + aAccOrNodeOrID);
     return null;
   }
 
   return node;
@@ -162,17 +159,16 @@ const DONOTFAIL_IF_NO_INTERFACE = 2;
 function getAccessible(aAccOrElmOrID, aInterfaces, aElmObj, aDoNotFailIf)
 {
   if (!aAccOrElmOrID)
     return null;
 
   var elm = null;
 
   if (aAccOrElmOrID instanceof nsIAccessible) {
-    aAccOrElmOrID.QueryInterface(nsIAccessNode);
     elm = aAccOrElmOrID.DOMNode;
 
   } else if (aAccOrElmOrID instanceof nsIDOMNode) {
     elm = aAccOrElmOrID;
 
   } else {
     elm = document.getElementById(aAccOrElmOrID);
     if (!elm) {
@@ -194,18 +190,16 @@ function getAccessible(aAccOrElmOrID, aI
     if (!acc) {
       if (!(aDoNotFailIf & DONOTFAIL_IF_NO_ACC))
         ok(false, "Can't get accessible for " + aAccOrElmOrID);
 
       return null;
     }
   }
 
-  acc.QueryInterface(nsIAccessNode);
-
   if (!aInterfaces)
     return acc;
 
   if (aInterfaces instanceof Array) {
     for (var index = 0; index < aInterfaces.length; index++) {
       try {
         acc.QueryInterface(aInterfaces[index]);
       } catch (e) {
@@ -252,31 +246,29 @@ function getContainerAccessible(aAccOrEl
   return node ? getAccessible(node) : null;
 }
 
 /**
  * Return root accessible for the given identifier.
  */
 function getRootAccessible(aAccOrElmOrID)
 {
-  var acc = getAccessible(aAccOrElmOrID ? aAccOrElmOrID : document,
-                          [nsIAccessNode]);
+  var acc = getAccessible(aAccOrElmOrID ? aAccOrElmOrID : document);
   return acc ? acc.rootDocument.QueryInterface(nsIAccessible) : null;
 }
 
 /**
  * Return tab document accessible the given accessible is contained by.
  */
 function getTabDocAccessible(aAccOrElmOrID)
 {
-  var acc = getAccessible(aAccOrElmOrID ? aAccOrElmOrID : document,
-                          [nsIAccessNode]);
+  var acc = getAccessible(aAccOrElmOrID ? aAccOrElmOrID : document);
 
   var docAcc = acc.document.QueryInterface(nsIAccessible);
-  var containerDocAcc = docAcc.parent.QueryInterface(nsIAccessNode).document;
+  var containerDocAcc = docAcc.parent.document;
 
   // Test is running is stand-alone mode.
   if (acc.rootDocument == containerDocAcc)
     return docAcc;
 
   // In the case of running all tests together.
   return containerDocAcc.QueryInterface(nsIAccessible);
 }
@@ -579,17 +571,17 @@ function getTextFromClipboard()
 }
 
 /**
  * Return pretty name for identifier, it may be ID, DOM node or accessible.
  */
 function prettyName(aIdentifier)
 {
   if (aIdentifier instanceof nsIAccessible) {
-    var acc = getAccessible(aIdentifier, [nsIAccessNode]);
+    var acc = getAccessible(aIdentifier);
     var msg = "[" + getNodePrettyName(acc.DOMNode);
     try {
       msg += ", role: " + roleToString(acc.role);
       if (acc.name)
         msg += ", name: '" + acc.name + "'";
     } catch (e) {
       msg += "defunct";
     }
--- a/accessible/tests/mochitest/events.js
+++ b/accessible/tests/mochitest/events.js
@@ -1216,16 +1216,43 @@ function synthSelectAll(aNodeOrID, aChec
   }
 
   this.getID = function synthSelectAll_getID()
   {
     return aNodeOrID + " selectall";
   }
 }
 
+/**
+ * Set caret offset in text accessible.
+ */
+function setCaretOffset(aID, aOffset, aFocusTargetID)
+{
+  this.target = getAccessible(aID, [nsIAccessibleText]);
+  this.offset = aOffset == -1 ? this.target.characterCount: aOffset;
+  this.focus = aFocusTargetID ? getAccessible(aFocusTargetID) : null;
+
+  this.invoke = function setCaretOffset_invoke()
+  {
+    this.target.caretOffset = this.offset;
+  }
+
+  this.getID = function setCaretOffset_getID()
+  {
+   return "Set caretOffset on " + prettyName(aID) + " at " + this.offset;
+  }
+
+  this.eventSeq = [
+    new caretMoveChecker(this.offset, this.target)
+  ];
+
+  if (this.focus)
+    this.eventSeq.push(new asyncInvokerChecker(EVENT_FOCUS, this.focus));
+}
+
 
 ////////////////////////////////////////////////////////////////////////////////
 // Event queue checkers
 
 /**
  * Common invoker checker (see eventSeq of eventQueue).
  */
 function invokerChecker(aEventType, aTargetOrFunc, aTargetFuncArg, aIsAsync)
--- a/accessible/tests/mochitest/events/test_contextmenu.html
+++ b/accessible/tests/mochitest/events/test_contextmenu.html
@@ -86,17 +86,17 @@
 
     function getFocusedMenuItem()
     {
       var menu = getAccessible(getAccessible(getContextMenuNode()));
       for (var idx = 0; idx < menu.childCount; idx++) {
         var item = menu.getChildAt(idx);
 
         if (hasState(item, STATE_FOCUSED))
-          return getAccessible(item, [nsIAccessNode]);
+          return getAccessible(item);
       }
       return null;
     }
 
     ////////////////////////////////////////////////////////////////////////////
     // Do tests
 
     var gQueue = null;
--- a/accessible/tests/mochitest/hypertext/test_update.html
+++ b/accessible/tests/mochitest/hypertext/test_update.html
@@ -55,17 +55,17 @@
         return "Add links for '" + aContainerID + "'";
       }
     }
 
     function updateText(aContainerID)
     {
       this.containerNode = getNode(aContainerID);
       this.container = getAccessible(this.containerNode, nsIAccessibleHyperText);
-      this.text = this.container.firstChild.QueryInterface(nsIAccessNode);
+      this.text = this.container.firstChild;
       this.textNode = this.text.DOMNode;
       this.textLen = this.textNode.data.length;
 
       this.eventSeq = [
         new invokerChecker(EVENT_TEXT_INSERTED, this.containerNode)
       ];
 
       this.invoke = function updateText_invoke()
--- a/accessible/tests/mochitest/pivot.js
+++ b/accessible/tests/mochitest/pivot.js
@@ -70,17 +70,16 @@ var ObjectTraversalRule =
  */
 function virtualCursorChangedChecker(aDocAcc, aIdOrNameOrAcc, aTextOffsets)
 {
   this.__proto__ = new invokerChecker(EVENT_VIRTUALCURSOR_CHANGED, aDocAcc);
 
   this.check = function virtualCursorChangedChecker_check(aEvent)
   {
     var position = aDocAcc.virtualCursor.position;
-    position.QueryInterface(nsIAccessNode);
 
     var idMatches = position.DOMNode.id == aIdOrNameOrAcc;
     var nameMatches = position.name == aIdOrNameOrAcc;
     var accMatches = position == aIdOrNameOrAcc;
 
     SimpleTest.ok(idMatches || nameMatches || accMatches, "id or name matches",
                   "expecting " + aIdOrNameOrAcc + ", got '" +
                   prettyName(position));
@@ -209,9 +208,9 @@ function dumpTraversalSequence(aPivot, a
 {
   var sequence = []
   if (aPivot.moveFirst(aRule)) {
     do {
       sequence.push("'" + prettyName(aPivot.position) + "'");
     } while (aPivot.moveNext(aRule))
   }
   SimpleTest.info("\n[" + sequence.join(", ") + "]\n");
-}
\ No newline at end of file
+}
--- a/accessible/tests/mochitest/relations/Makefile.in
+++ b/accessible/tests/mochitest/relations/Makefile.in
@@ -40,20 +40,19 @@ DEPTH		= ../../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = accessible/relations
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
-# test_tabbrowser.xul disabled for misusing <tabbrowser> (bug 715857)
-
 _TEST_FILES =\
 		test_embeds.xul \
 		test_general.html \
 		test_general.xul \
+		test_tabbrowser.xul \
 		test_tree.xul \
 		test_update.html \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/a11y/$(relativesrcdir)
--- a/accessible/tests/mochitest/relations/test_tabbrowser.xul
+++ b/accessible/tests/mochitest/relations/test_tabbrowser.xul
@@ -1,105 +1,86 @@
 <?xml version="1.0"?>
 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
 <?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
                  type="text/css"?>
 
-<!-- Firefox tabbrowser -->
-<?xml-stylesheet href="chrome://browser/content/browser.css"
-                 type="text/css"?>
-<!-- SeaMonkey tabbrowser -->
-<?xml-stylesheet href="chrome://navigator/content/navigator.css"
-                 type="text/css"?>
-
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         title="Accessible XUL tabbrowser relation tests">
 
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
   <script type="application/javascript"
-          src="chrome://browser/content/utilityOverlay.js"/>
+          src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
 
   <script type="application/javascript"
           src="../common.js" />
   <script type="application/javascript"
           src="../role.js" />
   <script type="application/javascript"
           src="../relations.js" />
   <script type="application/javascript"
           src="../events.js" />
+  <script type="application/javascript"
+          src="../browser.js"></script>
 
-  <script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
   <script type="application/javascript">
   <![CDATA[
     ////////////////////////////////////////////////////////////////////////////
-    // Test
+    // Invoker
+    function testTabRelations()
+    {
+      this.eventSeq = [
+        new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, tabDocumentAt, 0),
+        new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, tabDocumentAt, 1)
+     ];
 
-    const Ci = Components.interfaces;
+      this.invoke = function testTabRelations_invoke()
+      {
+        var docURIs = ["about:", "about:mozilla"];
+        tabBrowser().loadTabs(docURIs, false, true);
+      }
+
+      this.finalCheck = function testTabRelations_finalCheck(aEvent)
+      {
+        ////////////////////////////////////////////////////////////////////////
+        // 'labelled by'/'label for' relations for xul:tab and xul:tabpanel
 
-    // Hack to make xul:tabbrowser work.
-    var handleDroppedLink  = null;
-    Components.utils.import("resource://gre/modules/Services.jsm");
-    var XULBrowserWindow = {
-      isBusy: false,
-      setOverLink: function (link, b) {
+        var tabs = tabBrowser().tabContainer.childNodes;
+        var panels = tabBrowser().mTabBox.tabpanels.childNodes;
+
+        testRelation(panels[0], RELATION_LABELLED_BY, tabs[0]);
+        testRelation(tabs[0], RELATION_LABEL_FOR, panels[0]);
+        testRelation(panels[1], RELATION_LABELLED_BY, tabs[1]);
+        testRelation(tabs[1], RELATION_LABEL_FOR, panels[1]);
       }
-    };
-    var gFindBar = {
-      hidden: true
-    };
 
+      this.getID = function testTabRelations_getID()
+      {
+        return "relations of tabs";
+      }
+    }
+    
+    ////////////////////////////////////////////////////////////////////////////
+    // Test
+    var gQueue = null;
     function doTest()
     {
-      var tabBrowser = document.getElementById("tabbrowser");
-
-      // Load documents into tabs and wait for reorder events caused by these
-      // documents load before we start the test.
-      var docURIs = ["about:", "about:mozilla"];
-
-      var handler = {
-        handleEvent: function handleEvent(aEvent) {
-          var target = aEvent.accessible;
-          if (target.role == ROLE_INTERNAL_FRAME &&
-              target.parent.parent == getAccessible(this.tabBrowser.mTabBox.tabpanels)) {
-            this.reorderCnt++;
-          }
-
-          if (this.reorderCnt == docURIs.length) {
-            unregisterA11yEventListener(EVENT_REORDER, this);
-            testRelations();
-          }
-        },
+      // Load documents into tabs and wait for DocLoadComplete events caused by
+      // these documents load before we start the test.
 
-        tabBrowser: tabBrowser,
-        reorderCnt: 0
-      };
-      registerA11yEventListener(EVENT_REORDER, handler);
-
-      tabBrowser.loadTabs(docURIs, false, true);
-    }
+      gQueue = new eventQueue();
 
-    function testRelations()
-    {
-      //////////////////////////////////////////////////////////////////////////
-      // 'labelled by'/'label for' relations for xul:tab and xul:tabpanel
-
-      var tabs = getNode("tabbrowser").tabContainer.childNodes;
-      var panels = getNode("tabbrowser").mTabBox.tabpanels.childNodes;
-
-      testRelation(panels[0], RELATION_LABELLED_BY, tabs[0]);
-      testRelation(tabs[0], RELATION_LABEL_FOR, panels[0]);
-      testRelation(panels[1], RELATION_LABELLED_BY, tabs[1]);
-      testRelation(tabs[1], RELATION_LABEL_FOR, panels[1]);
-
-      SimpleTest.finish();
+      gQueue.push(new testTabRelations());
+      gQueue.onFinish = function() { closeBrowserWindow(); }
+      gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTest);
+    openBrowserWindow(doTest);
   ]]>
   </script>
 
   <vbox flex="1" style="overflow: auto;">
     <body xmlns="http://www.w3.org/1999/xhtml">
       <a target="_blank"
          href="https://bugzilla.mozilla.org/show_bug.cgi?id=552944"
          title="No relationship between tabs and associated property page in new tabbrowser construct">
@@ -107,32 +88,13 @@
       </a><br/>
       <p id="display"></p>
       <div id="content" style="display: none">
       </div>
       <pre id="test">
       </pre>
     </body>
 
-    <!-- Hack to make xul:tabbrowser work -->
-    <menubar>
-      <menu label="menu">
-        <menupopup>
-          <menuitem label="close window hook" id="menu_closeWindow"/>
-          <menuitem label="close hook" id="menu_close"/>
-        </menupopup>
-      </menu>
-    </menubar>
-
-    <tabs id="tabbrowser-tabs" class="tabbrowser-tabs"
-          tabbrowser="tabbrowser"
-          setfocus="false">
-      <tab class="tabbrowser-tab" selected="true"/>
-    </tabs>
-    <tabbrowser id="tabbrowser"
-                type="content-primary"
-                tabcontainer="tabbrowser-tabs"
-                flex="1"/>
-    <toolbar id="addon-bar"/>
+    <vbox id="eventdump"></vbox>
   </vbox>
 
 </window>
 
--- a/accessible/tests/mochitest/test_nsIAccessNode_utils.html
+++ b/accessible/tests/mochitest/test_nsIAccessNode_utils.html
@@ -10,25 +10,25 @@
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript"
           src="common.js"></script>
 
   <script type="application/javascript">
     function doTest()
     {
       var elmObj = {};
-      var acc = getAccessible("span", [nsIAccessNode], elmObj);
+      var acc = getAccessible("span", null, elmObj);
       computedStyle = document.defaultView.getComputedStyle(elmObj.value, "");
 
       // html:span element
       is(acc.getComputedStyleValue("", "color"), computedStyle.color,
          "Wrong color for element with ID 'span'");
 
       // text child of html:span element
-      acc = getAccessible(acc.firstChild, [nsIAccessNode]);
+      acc = getAccessible(acc.firstChild);
       is(acc.getComputedStyleValue("", "color"), computedStyle.color,
          "Wrong color for text child of element with ID 'span'");
 
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/textcaret/Makefile.in
@@ -0,0 +1,54 @@
+#
+# ***** 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
+# Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2012
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Alexander Surkov <surkov.alexander@gmail.com> (original author)
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH		= ../../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+relativesrcdir  = accessible/textcaret
+
+include $(DEPTH)/config/autoconf.mk
+include $(topsrcdir)/config/rules.mk
+
+_TEST_FILES = \
+		test_browserui.xul \
+		test_general.html \
+		$(NULL)
+
+libs:: $(_TEST_FILES)
+	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/a11y/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/textcaret/test_browserui.xul
@@ -0,0 +1,69 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+                 type="text/css"?>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        title="Accessibility Caret Offset Test.">
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+
+  <script type="application/javascript"
+          src="../common.js"></script>
+  <script type="application/javascript"
+          src="../role.js"></script>
+  <script type="application/javascript"
+          src="../states.js"></script>
+  <script type="application/javascript"
+          src="../events.js"></script>
+  <script type="application/javascript"
+          src="../browser.js"></script>
+
+  <script type="application/javascript">
+  <![CDATA[
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Tests
+
+    //gA11yEventDumpID = "eventdump"; // debug stuff
+    //gA11yEventDumpToConsole = true; // debug
+
+    var gQueue = null;
+    function doTests()
+    {
+      gQueue = new eventQueue();
+      gQueue.push(new setCaretOffset(urlbarInput(), -1, urlbarInput()));
+      gQueue.push(new setCaretOffset(urlbarInput(), 0));
+      gQueue.onFinish = function()
+      {
+        closeBrowserWindow();
+      }
+
+      gQueue.invoke();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    openBrowserWindow(doTests, "about:");
+  ]]>
+  </script>
+
+  <vbox flex="1" style="overflow: auto;">
+  <body xmlns="http://www.w3.org/1999/xhtml">
+    <a target="_blank"
+       href="https://bugzilla.mozilla.org/show_bug.cgi?id=723833"
+       title="IAccessibleText::setCaretOffset on location or search bar causes focus to jump">
+      Mozilla Bug 723833
+    </a>
+    <p id="display"></p>
+    <div id="content" style="display: none">
+    </div>
+    <pre id="test">
+    </pre>
+  </body>
+
+  <vbox id="eventdump"></vbox>
+  </vbox>
+</window>
rename from accessible/tests/mochitest/test_text_caret.html
rename to accessible/tests/mochitest/textcaret/test_general.html
--- a/accessible/tests/mochitest/test_text_caret.html
+++ b/accessible/tests/mochitest/textcaret/test_general.html
@@ -5,62 +5,21 @@
 
   <link rel="stylesheet" type="text/css"
         href="chrome://mochikit/content/tests/SimpleTest/test.css" />
 
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
 
   <script type="application/javascript"
-          src="common.js"></script>
+          src="../common.js"></script>
   <script type="application/javascript"
-          src="events.js"></script>
+          src="../events.js"></script>
 
   <script type="application/javascript">
-
-    /**
-     * Checkers.
-     */
-    function caretMovedChecker(aID, aOffset)
-    {
-      this.__proto__ = new invokerChecker(EVENT_TEXT_CARET_MOVED, aID);
-
-      this.check = function caretMovedChecker_check(aEvent)
-      {
-        is(aEvent.QueryInterface(nsIAccessibleCaretMoveEvent).caretOffset,
-           aOffset,
-           "Wrong caret offset for " + prettyName(aEvent.target));
-      }
-    }
-
-    /**
-     * Invokers.
-     */
-    function setCaretOffsetInvoker(aID, aOffset, aFocusableContainerID)
-    {
-      this.target = getAccessible(aID, [nsIAccessibleText]);
-      this.focus = aFocusableContainerID ?
-        getAccessible(aFocusableContainerID) : this.target;
-
-      this.invoke = function setCaretOffsetInvoker_invoke()
-      {
-        this.target.caretOffset = aOffset;
-      }
-
-      this.getID = function setCaretOffsetInvoker_getID()
-      {
-        return "Set caretOffset on " + prettyName(aID) + " at " + aOffset;
-      }
-
-      this.eventSeq = [
-        new caretMovedChecker(this.target, aOffset),
-        new asyncInvokerChecker(EVENT_FOCUS, this.focus)
-      ];
-    }
-
     /**
      * Turn on/off the caret browsing mode.
      */
     function turnCaretBrowsing(aIsOn)
     {
       var prefs = Components.classes["@mozilla.org/preferences-service;1"].
         getService(Components.interfaces.nsIPrefBranch);
       prefs.setBoolPref("accessibility.browsewithcaret", aIsOn);
@@ -76,19 +35,19 @@
 
     function doTests()
     {
       turnCaretBrowsing(true);
 
       // test caret move events and caret offsets
       gQueue = new eventQueue();
 
-      gQueue.push(new setCaretOffsetInvoker("textbox", 1));
-      gQueue.push(new setCaretOffsetInvoker("link", 1));
-      gQueue.push(new setCaretOffsetInvoker("heading", 1, document));
+      gQueue.push(new setCaretOffset("textbox", 1, "textbox"));
+      gQueue.push(new setCaretOffset("link", 1, "link"));
+      gQueue.push(new setCaretOffset("heading", 1, document));
       gQueue.onFinish = function()
       {
         turnCaretBrowsing(false);
       }
 
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
--- a/accessible/tests/mochitest/tree/Makefile.in
+++ b/accessible/tests/mochitest/tree/Makefile.in
@@ -40,18 +40,16 @@ DEPTH		= ../../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = accessible/tree
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
-# test_tabbrowser.xul disabled for misusing <tabbrowser> (bug 715857)
-
 _TEST_FILES =\
 		dockids.html \
 	$(warning test_applicationacc.xul temporarily disabled, see bug 561508) \
 		test_aria_globals.html \
 		test_aria_imgmap.html \
 		test_aria_presentation.html \
 		test_button.xul \
 		test_canvas.html \
@@ -67,16 +65,17 @@ include $(topsrcdir)/config/rules.mk
 		test_iframe.html \
 		test_img.html \
 		test_invalidationlist.html \
 		test_list.html \
 		test_map.html \
 		test_media.html \
 		test_select.html \
 		test_tabbox.xul \
+		test_tabbrowser.xul \
 		test_table.html \
 		test_tree.xul \
 		test_txtcntr.html \
 		test_txtctrl.html \
 		test_txtctrl.xul \
 		wnd.xul \
 		$(NULL)
 
--- a/accessible/tests/mochitest/tree/test_tabbrowser.xul
+++ b/accessible/tests/mochitest/tree/test_tabbrowser.xul
@@ -1,230 +1,208 @@
 <?xml version="1.0"?>
 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
 
-<!-- Firefox tabbrowser -->
-<?xml-stylesheet href="chrome://browser/content/browser.css"
-                 type="text/css"?>
-<!-- SeaMonkey tabbrowser -->
-<?xml-stylesheet href="chrome://navigator/content/navigator.css"
-                 type="text/css"?>
-
 <?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
                  type="text/css"?>
 
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         title="Accessible XUL tabbrowser hierarchy tests">
 
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
   <script type="application/javascript"
-          src="chrome://browser/content/utilityOverlay.js"/>
+          src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
 
   <script type="application/javascript"
           src="../common.js" />
   <script type="application/javascript"
           src="../role.js" />
   <script type="application/javascript"
           src="../events.js" />
+  <script type="application/javascript"
+          src="../browser.js"></script>
 
-  <script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
   <script type="application/javascript">
   <![CDATA[
     ////////////////////////////////////////////////////////////////////////////
-    // Test
+    // invoker
+    function testTabHierarchy()
+    {
+      this.eventSeq = [
+        new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, tabDocumentAt, 0),
+        new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, tabDocumentAt, 1)
+      ];
+
+      this.invoke = function testTabHierarchy_invoke()
+      {
+        var docURIs = ["about:", "about:mozilla"];
+        tabBrowser().loadTabs(docURIs, false, true);
+      }
 
-    const Ci = Components.interfaces;
+      this.finalCheck = function testTabHierarchy_finalCheck(aEvent)
+      {
+        ////////////////////
+        // Tab bar
+        ////////////////////
+        var tabsAccTree = {
+          // xul:tabs
+          role: ROLE_PAGETABLIST,
+          children: [
+            // Children depend on application (UI): see below.
+          ]
+        };
+
+        // SeaMonkey and Firefox tabbrowser UIs differ.
+        if ("restoreTab" in tabBrowser) {
+          SimpleTest.ok(true, "Testing SeaMonkey tabbrowser UI.");
 
-    // Hack to make xul:tabbrowser work.
-    Components.utils.import("resource://gre/modules/Services.jsm");
-    var handleDroppedLink = null;
-    var XULBrowserWindow = {
-      isBusy: false,
-      setOverLink: function (link, b) {}
-    };
-    var gFindBar = {
-      hidden: true
-    };
-
-    function doTest()
-    {
-      var tabBrowser = document.getElementById("tabbrowser");
+          tabsAccTree.children.splice(0, 0,
+            {
+              // xul:toolbarbutton ("Open a new tab")
+              role: ROLE_PUSHBUTTON,
+              children: []
+            },
+            {
+              // xul:tab ("about:")
+              role: ROLE_PAGETAB,
+              children: []
+            },
+            {
+              // tab ("about:mozilla")
+              role: ROLE_PAGETAB,
+              children: []
+            },
+            {
+              // xul:toolbarbutton ("List all tabs")
+              role: ROLE_PUSHBUTTON,
+              children: [
+                {
+                  // xul:menupopup
+                  role: ROLE_MENUPOPUP,
+                  children: []
+                }
+              ]
+            },
+            {
+              // xul:toolbarbutton ("Close current tab")
+              role: ROLE_PUSHBUTTON,
+              children: []
+            }
+            );
+        } else {
+          SimpleTest.ok(true, "Testing Firefox tabbrowser UI.");
 
-      // Load documents into tabs and wait for reorder events caused by these
-      // documents load before we start the test.
-      var docURIs = ["about:", "about:mozilla"];
+          // NB: The (3) buttons are not visible, unless manually hovered,
+          //     probably due to size reduction in this test.
+          tabsAccTree.children.splice(0, 0,
+            {
+              // xul:tab ("about:")
+              role: ROLE_PAGETAB,
+              children: [
+                {
+                  // xul:toolbarbutton ("Close Tab")
+                  role: ROLE_PUSHBUTTON,
+                  children: []
+                }
+              ]
+            },
+            {
+              // tab ("about:mozilla")
+              role: ROLE_PAGETAB,
+              children: [
+                {
+                  // xul:toolbarbutton ("Close Tab")
+                  role: ROLE_PUSHBUTTON,
+                  children: []
+                }
+              ]
+            },
+            {
+              // xul:toolbarbutton ("Open a new tab")
+              role: ROLE_PUSHBUTTON,
+              children: []
+            }
+            // "List all tabs" dropdown
+            // XXX: This child(?) is not present in this test.
+            //      I'm not sure why (though probably expected).
+            );
+        }
 
-      var handler = {
-        handleEvent: function handleEvent(aEvent) {
-          var target = aEvent.accessible;
-          if (target.role == ROLE_INTERNAL_FRAME &&
-              target.parent.parent == getAccessible(this.tabBrowser.mTabBox.tabpanels)) {
-            this.reorderCnt++;
-          }
+        testAccessibleTree(tabBrowser().tabContainer, tabsAccTree);
 
-          if (this.reorderCnt == docURIs.length) {
-            unregisterA11yEventListener(EVENT_REORDER, this);
-            testAccTree();
-          }
-        },
+        ////////////////////
+        // Tab contents
+        ////////////////////
+        var tabboxAccTree = {
+          // xul:tabpanels
+          role: ROLE_PANE,
+          children: [
+            {
+              // xul:notificationbox
+              role: ROLE_PROPERTYPAGE,
+              children: [
+                {
+                  // xul:browser
+                  role: ROLE_INTERNAL_FRAME,
+                  children: [
+                    {
+                      // #document ("about:")
+                      role: ROLE_DOCUMENT
+                      // children: [ ... ] // Ignore document content.
+                    }
+                  ]
+                }
+              ]
+            },
+            {
+              // notificationbox
+              role: ROLE_PROPERTYPAGE,
+              children: [
+                {
+                  // browser
+                  role: ROLE_INTERNAL_FRAME,
+                  children: [
+                    {
+                      // #document ("about:mozilla")
+                      role: ROLE_DOCUMENT
+                      // children: [ ... ] // Ignore document content.
+                    }
+                  ]
+                }
+              ]
+            }
+          ]
+        };
 
-        tabBrowser: tabBrowser,
-        reorderCnt: 0
-      };
-      registerA11yEventListener(EVENT_REORDER, handler);
+        testAccessibleTree(tabBrowser().mTabBox.tabpanels, tabboxAccTree);
+      }
 
-      // Test XUL and HTML documents.
-      tabBrowser.loadTabs(docURIs, false, true);
+      this.getID = function testTabHierarchy_getID()
+      {
+        return "hierarchy of tabs";
+      }
     }
 
-    function testAccTree()
+    ////////////////////////////////////////////////////////////////////////////
+    // Test
+    var gQueue = null;
+    function doTest()
     {
-      var tabBrowser = document.getElementById("tabbrowser");
-
-      ////////////////////
-      // Tab bar
-      ////////////////////
-      var tabsAccTree = {
-        // xul:tabs
-        role: ROLE_PAGETABLIST,
-        children: [
-          // Children depend on application (UI): see below.
-        ]
-      };
-
-      // SeaMonkey and Firefox tabbrowser UIs differ.
-      if ("restoreTab" in tabBrowser) {
-        SimpleTest.ok(true, "Testing SeaMonkey tabbrowser UI.");
-
-        tabsAccTree.children.splice(0, 0,
-          {
-            // xul:toolbarbutton ("Open a new tab")
-            role: ROLE_PUSHBUTTON,
-            children: []
-          },
-          {
-            // xul:tab ("about:")
-            role: ROLE_PAGETAB,
-            children: []
-          },
-          {
-            // tab ("about:mozilla")
-            role: ROLE_PAGETAB,
-            children: []
-          },
-          {
-            // xul:toolbarbutton ("List all tabs")
-            role: ROLE_PUSHBUTTON,
-            children: [
-              {
-                // xul:menupopup
-                role: ROLE_MENUPOPUP,
-                children: []
-              }
-            ]
-          },
-          {
-            // xul:toolbarbutton ("Close current tab")
-            role: ROLE_PUSHBUTTON,
-            children: []
-          }
-          );
-      } else {
-        SimpleTest.ok(true, "Testing Firefox tabbrowser UI.");
+      // Load documents into tabs and wait for docLoadComplete events caused by these
+      // documents load before we start the test.
+      gQueue = new eventQueue();
 
-        // NB: The (3) buttons are not visible, unless manually hovered,
-        //     probably due to size reduction in this test.
-        tabsAccTree.children.splice(0, 0,
-          {
-            // xul:tab ("about:")
-            role: ROLE_PAGETAB,
-            children: [
-              {
-                // xul:toolbarbutton ("Close Tab")
-                role: ROLE_PUSHBUTTON,
-                children: []
-              }
-            ]
-          },
-          {
-            // tab ("about:mozilla")
-            role: ROLE_PAGETAB,
-            children: [
-              {
-                // xul:toolbarbutton ("Close Tab")
-                role: ROLE_PUSHBUTTON,
-                children: []
-              }
-            ]
-          },
-          {
-            // xul:toolbarbutton ("Open a new tab")
-            role: ROLE_PUSHBUTTON,
-            children: []
-          }
-          // "List all tabs" dropdown
-          // XXX: This child(?) is not present in this test.
-          //      I'm not sure why (though probably expected).
-          );
-      }
-
-      testAccessibleTree(tabBrowser.tabContainer, tabsAccTree);
-
-      ////////////////////
-      // Tab contents
-      ////////////////////
-      var tabboxAccTree = {
-        // xul:tabpanels
-        role: ROLE_PANE,
-        children: [
-          {
-            // xul:notificationbox
-            role: ROLE_PROPERTYPAGE,
-            children: [
-              {
-                // xul:browser
-                role: ROLE_INTERNAL_FRAME,
-                children: [
-                  {
-                    // #document ("about:")
-                    role: ROLE_DOCUMENT
-                    // children: [ ... ] // Ignore document content.
-                  }
-                ]
-              }
-            ]
-          },
-          {
-            // notificationbox
-            role: ROLE_PROPERTYPAGE,
-            children: [
-              {
-                // browser
-                role: ROLE_INTERNAL_FRAME,
-                children: [
-                  {
-                    // #document ("about:mozilla")
-                    role: ROLE_DOCUMENT
-                    // children: [ ... ] // Ignore document content.
-                  }
-                ]
-              }
-            ]
-          }
-        ]
-      };
-
-      testAccessibleTree(tabBrowser.mTabBox.tabpanels, tabboxAccTree);
-
-      SimpleTest.finish();
+      gQueue.push(new testTabHierarchy());
+      gQueue.onFinish = function() { closeBrowserWindow(); }
+      gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTest);
+    openBrowserWindow(doTest);
   ]]>
   </script>
 
   <vbox flex="1" style="overflow: auto;">
     <body xmlns="http://www.w3.org/1999/xhtml">
       <a target="_blank"
          href="https://bugzilla.mozilla.org/show_bug.cgi?id=540389"
          title=" WARNING: Bad accessible tree!: [tabbrowser tab] ">
@@ -237,31 +215,12 @@
       </a><br/>
       <p id="display"></p>
       <div id="content" style="display: none">
       </div>
       <pre id="test">
       </pre>
     </body>
 
-    <!-- Hack to make xul:tabbrowser work -->
-    <menubar>
-      <menu label="menu">
-        <menupopup>
-          <menuitem label="close window hook" id="menu_closeWindow"/>
-          <menuitem label="close hook" id="menu_close"/>
-        </menupopup>
-      </menu>
-    </menubar>
-
-    <tabs id="tabbrowser-tabs" class="tabbrowser-tabs"
-          tabbrowser="tabbrowser"
-          setfocus="false">
-      <tab class="tabbrowser-tab" selected="true" fadein="true"/>
-    </tabs>
-    <tabbrowser id="tabbrowser"
-                type="content-primary"
-                tabcontainer="tabbrowser-tabs"
-                flex="1"/>
-    <toolbar id="addon-bar"/>
+    <vbox id="eventdump"></vbox>
   </vbox>
 
 </window>
--- a/accessible/tests/mochitest/treeupdate/test_doc.html
+++ b/accessible/tests/mochitest/treeupdate/test_doc.html
@@ -59,18 +59,18 @@
       this.eventSeq = [
         new invokerChecker(EVENT_HIDE, null),
         new invokerChecker(EVENT_REORDER, getDocNode, aID)
       ];
 
       this.preinvoke = function rootContentRemoved_preinvoke()
       {
         // Set up target for hide event before we invoke.
-        var text = getAccessible(getAccessible(getDocNode(aID)).firstChild,
-                                               [nsIAccessNode]).DOMNode;
+        var text =
+          getAccessible(getAccessible(getDocNode(aID)).firstChild).DOMNode;
         this.eventSeq[0].target = text;
       }
 
       this.finalCheck = function rootContentRemoved_finalCheck()
       {
         var tree = {
           role: ROLE_DOCUMENT,
           states: {
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -408,16 +408,20 @@ pref("dom.mozBrowserFramesWhitelist", "h
 
 // Temporary permission hack for WebSMS
 pref("dom.sms.enabled", true);
 pref("dom.sms.whitelist", "file://,http://localhost:6666");
 
 // Ignore X-Frame-Options headers.
 pref("b2g.ignoreXFrameOptions", true);
 
+// controls if we want camera support
+pref("device.camera.enabled", true);
+pref("media.realtime_decoder.enabled", true);
+
 // "Preview" landing of bug 710563, which is bogged down in analysis
 // of talos regression.  This is a needed change for higher-framerate
 // CSS animations, and incidentally works around an apparent bug in
 // our handling of requestAnimationFrame() listeners, which are
 // supposed to enable this REPEATING_PRECISE_CAN_SKIP behavior.  The
 // secondary bug isn't really worth investigating since it's obseleted
 // by bug 710563.
 pref("layout.frame_rate.precise", true);
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -74,19 +74,20 @@ function startupHttpd(baseDir, port) {
   server.registerDirectory('/', new LocalFile(baseDir));
   server.registerContentType('appcache', 'text/cache-manifest');
   server.start(port);
 }
 
 // FIXME Bug 707625
 // until we have a proper security model, add some rights to
 // the pre-installed web applications
+// XXX never grant 'content-camera' to non-gaia apps
 function addPermissions(urls) {
   let permissions = [
-    'indexedDB', 'indexedDB-unlimited', 'webapps-manage', 'offline-app'
+    'indexedDB', 'indexedDB-unlimited', 'webapps-manage', 'offline-app', 'content-camera'
   ];
   urls.forEach(function(url) {
     let uri = Services.io.newURI(url, null, null);
     let allow = Ci.nsIPermissionManager.ALLOW_ACTION;
 
     permissions.forEach(function(permission) {
       Services.perms.add(uri, permission, allow);
     });
@@ -128,16 +129,17 @@ var shell = {
     if (!homeURL) {
       let msg = 'Fatal error during startup: [No homescreen found]';
       return alert(msg);
     }
 
     window.controllers.appendController(this);
     window.addEventListener('keypress', this);
     window.addEventListener('MozApplicationManifest', this);
+    window.addEventListener("AppCommand", this);
     this.contentBrowser.addEventListener('load', this, true);
 
     try {
       Services.io.offline = false;
 
       let fileScheme = 'file://';
       if (homeURL.substring(0, fileScheme.length) == fileScheme) {
         homeURL = homeURL.replace(fileScheme, '');
@@ -219,16 +221,23 @@ var shell = {
             break;
           case evt.DOM_VK_ESCAPE:
             if (evt.defaultPrevented)
               return;
             this.doCommand('cmd_close');
             break;
         }
         break;
+      case 'AppCommand':
+        switch (evt.command) {
+          case 'Menu':
+            this.sendEvent(content, 'menu');
+            break;
+        }
+        break;
       case 'load':
         this.contentBrowser.removeEventListener('load', this, true);
         this.turnScreenOn();
 
         let chromeWindow = window.QueryInterface(Ci.nsIDOMChromeWindow);
         chromeWindow.browserDOMWindow = new nsBrowserAccess();
 
         this.sendEvent(window, 'ContentStart');
--- a/b2g/chrome/content/webapi.js
+++ b/b2g/chrome/content/webapi.js
@@ -51,19 +51,16 @@ XPCOMUtils.defineLazyGetter(Services, 'f
 
     onProgressChange: function onProgressChange(progress, request,
                                                 curSelf, maxSelf,
                                                 curTotal, maxTotal) {
     },
 
     onLocationChange: function onLocationChange(progress, request,
                                                 locationURI, flags) {
-      if (locationURI.spec.indexOf('/apps/') == -1)
-        return;
-
       content.addEventListener('appwillopen', function(evt) {
         let appManager = content.wrappedJSObject.Gaia.AppManager;
         let topWindow = appManager.foregroundWindow.contentWindow;
         generateAPI(topWindow);
       });
 
       generateAPI(content.wrappedJSObject);
     },
--- a/b2g/components/B2GComponents.manifest
+++ b/b2g/components/B2GComponents.manifest
@@ -1,2 +1,7 @@
 # Scrollbars
 category agent-style-sheets browser-content-stylesheet chrome://browser/content/content.css
+
+# CameraContent.js
+component {eff4231b-abce-4f7f-a40a-d646e8fde3ce} CameraContent.js
+contract @mozilla.org/b2g-camera-content;1 {eff4231b-abce-4f7f-a40a-d646e8fde3ce}
+category JavaScript-navigator-property mozCamera @mozilla.org/b2g-camera-content;1
new file mode 100644
--- /dev/null
+++ b/b2g/components/CameraContent.js
@@ -0,0 +1,83 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+const kProtocolName = "b2g-camera:";
+
+let CameraContent = function() {
+  this.hasPrivileges = false;
+  this.mapping = [];
+}
+ 
+CameraContent.prototype = {
+  getCameraURI: function(aOptions) {
+    if (!this.hasPrivileges)
+      return null;
+
+    let options = aOptions || { };
+    if (!options.camera)
+      options.camera = 0;
+    if (!options.width)
+      options.width = 320;
+    if (!options.height)
+      options.height = 240;
+
+    let uuid = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID().toString();
+    uuid = uuid.substring(1, uuid.length - 2); // remove the brackets
+    this.mapping.push(uuid);
+    let uri = kProtocolName + "?camera=" + options.camera + 
+                              "&width=" + options.width +
+                              "&height=" + options.height +
+                              "&type=video/x-raw-yuv";
+    // XXX that's no e10s ready, but the camera inputstream itself is not...
+    Services.prefs.setCharPref("b2g.camera." + kProtocolName + "?" + uuid, uri);
+    return kProtocolName + "?" + uuid;
+  },
+  
+  observe: function(aSubject, aTopic, aData) {
+    if (aTopic == "inner-window-destroyed") {
+      let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
+      if (wId == this.innerWindowID) {
+        Services.obs.removeObserver(this, "inner-window-destroyed");
+        for (let aId in this.mapping)
+          Services.prefs.clearUserPref("b2g.camera." + kProtocolName + "?" + aId);
+        this.mapping = null;
+      }
+    }
+  },
+
+  init: function(aWindow) {
+    let principal = aWindow.document.nodePrincipal;
+    let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
+
+    let perm = principal == secMan.getSystemPrincipal() ? Ci.nsIPermissionManager.ALLOW_ACTION : Services.perms.testExactPermission(principal.URI, "content-camera");
+
+    //only pages with perm set and chrome pages can use the camera in content
+    this.hasPrivileges = perm == Ci.nsIPermissionManager.ALLOW_ACTION || from.schemeIs("chrome");
+
+    Services.obs.addObserver(this, "inner-window-destroyed", false);
+    let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
+    this.innerWindowID = util.currentInnerWindowID;
+  },
+ 
+  classID: Components.ID("{eff4231b-abce-4f7f-a40a-d646e8fde3ce}"),
+
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIB2GCameraContent, Ci.nsIDOMGlobalPropertyInitializer, Ci.nsIObserver]),
+  
+  classInfo: XPCOMUtils.generateCI({classID: Components.ID("{eff4231b-abce-4f7f-a40a-d646e8fde3ce}"),
+                                    contractID: "@mozilla.org/b2g-camera-content;1",
+                                    interfaces: [Ci.nsIB2GCameraContent],
+                                    flags: Ci.nsIClassInfo.DOM_OBJECT,
+                                    classDescription: "B2G Camera Content Helper"})
+}
+ 
+const NSGetFactory = XPCOMUtils.generateNSGetFactory([CameraContent]);
--- a/b2g/components/Makefile.in
+++ b/b2g/components/Makefile.in
@@ -39,13 +39,18 @@ topsrcdir  = @top_srcdir@
 srcdir     = @srcdir@
 VPATH      = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = B2GComponents
 XPIDL_MODULE = B2GComponents
 
+XPIDLSRCS = \
+        b2g.idl \
+        $(NULL)
+
 EXTRA_PP_COMPONENTS = \
         B2GComponents.manifest \
+        CameraContent.js \
         $(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/b2g/components/b2g.idl
@@ -0,0 +1,12 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "domstubs.idl"
+
+[scriptable, uuid(3615a616-571d-4194-bf54-ccf546067b14)]
+interface nsIB2GCameraContent : nsISupports
+{
+    /* temporary solution, waiting for getUserMedia */
+	DOMString getCameraURI([optional] in jsval options);
+};
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -598,8 +598,9 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DL
 #endif
 
 [b2g]
 @BINPATH@/chrome/icons/
 @BINPATH@/chrome/chrome@JAREXT@
 @BINPATH@/chrome/chrome.manifest
 @BINPATH@/components/B2GComponents.manifest
 @BINPATH@/components/B2GComponents.xpt
+@BINPATH@/components/CameraContent.js
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1026,16 +1026,22 @@ pref("services.sync.prefs.sync.xpinstall
 
 // Disable the error console
 pref("devtools.errorconsole.enabled", false);
 
 // Enable the Inspector
 pref("devtools.inspector.enabled", true);
 pref("devtools.inspector.htmlHeight", 112);
 
+// Enable the Debugger
+pref("devtools.debugger.enabled", false);
+
+// The default Debugger UI height
+pref("devtools.debugger.ui.height", 250);
+
 // 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);
 
@@ -1114,8 +1120,13 @@ pref("browser.panorama.animate_zoom", tr
 // Defines the url to be used for new tabs.
 pref("browser.newtab.url", "about:newtab");
 
 // Toggles the content of 'about:newtab'. Shows the grid when enabled.
 pref("browser.newtabpage.enabled", true);
 
 // Enable the DOM full-screen API.
 pref("full-screen-api.enabled", true);
+
+// Startup Crash Tracking
+// number of startup crashes that can occur before starting into safe mode automatically
+// (this pref has no effect if more than 6 hours have passed since the last crash)
+pref("toolkit.startup.max_resumed_crashes", 2);
--- a/browser/base/content/aboutDialog.js
+++ b/browser/base/content/aboutDialog.js
@@ -260,27 +260,27 @@ appUpdater.prototype =
       let cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"].
                        createInstance(Components.interfaces.nsISupportsPRBool);
       Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart");
 
       // Something aborted the quit process.
       if (cancelQuit.data)
         return;
 
+      let appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"].
+                       getService(Components.interfaces.nsIAppStartup);
+
       // If already in safe mode restart in safe mode (bug 327119)
       if (Services.appinfo.inSafeMode) {
-        let env = Components.classes["@mozilla.org/process/environment;1"].
-                  getService(Components.interfaces.nsIEnvironment);
-        env.set("MOZ_SAFE_MODE_RESTART", "1");
+        appStartup.restartInSafeMode(Components.interfaces.nsIAppStartup.eAttemptQuit);
+        return;
       }
 
-      Components.classes["@mozilla.org/toolkit/app-startup;1"].
-      getService(Components.interfaces.nsIAppStartup).
-      quit(Components.interfaces.nsIAppStartup.eAttemptQuit |
-           Components.interfaces.nsIAppStartup.eRestart);
+      appStartup.quit(Components.interfaces.nsIAppStartup.eAttemptQuit |
+                      Components.interfaces.nsIAppStartup.eRestart);
       return;
     }
 
     const URI_UPDATE_PROMPT_DIALOG = "chrome://mozapps/content/update/updates.xul";
     // Firefox no longer displays a license for updates and the licenseURL check
     // is just in case a distibution does.
     if (this.update && (this.update.billboardURL || this.update.licenseURL ||
         this.addons.length != 0)) {
--- a/browser/base/content/browser-appmenu.inc
+++ b/browser/base/content/browser-appmenu.inc
@@ -184,16 +184,21 @@
                     command="Tools:WebConsole"
                     key="key_webConsole"/>
           <menuitem id="appmenu_pageInspect"
                     hidden="true"
                     label="&inspectMenu.label;"
                     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_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-doctype.inc
+++ b/browser/base/content/browser-doctype.inc
@@ -14,10 +14,12 @@
 <!ENTITY % placesDTD SYSTEM "chrome://browser/locale/places/places.dtd">
 %placesDTD;
 #ifdef MOZ_SAFE_BROWSING
 <!ENTITY % safebrowsingDTD SYSTEM "chrome://browser/locale/safebrowsing/phishing-afterload-warning-message.dtd">
 %safebrowsingDTD;
 #endif
 <!ENTITY % aboutHomeDTD SYSTEM "chrome://browser/locale/aboutHome.dtd">
 %aboutHomeDTD;
+<!ENTITY % debuggerDTD SYSTEM "chrome://browser/locale/devtools/debugger.dtd">
+%debuggerDTD;
 ]>
 
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -541,16 +541,21 @@
                             command="Tools:WebConsole"/>
                   <menuitem id="menu_pageinspect"
                             type="checkbox"
                             hidden="true"
                             label="&inspectMenu.label;"
                             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_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
@@ -122,16 +122,17 @@
     <command id="cmd_fullZoomReset"   oncommand="FullZoom.reset()"/>
     <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: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();"/>
@@ -247,16 +248,23 @@
     <key id="key_errorConsole" key="&errorConsoleCmd.commandkey;" oncommand="toJavaScriptConsole();" modifiers="accel,shift" disabled="true"/>
     <key id="key_webConsole" key="&webConsoleCmd.commandkey;" oncommand="HUDConsoleUI.toggleHUD();"
 #ifdef XP_MACOSX
         modifiers="accel,alt"
 #else
         modifiers="accel,shift"
 #endif
     />
+    <key id="key_debugger" key="&debuggerMenu.commandkey;" command="Tools:Debugger"
+#ifdef XP_MACOSX
+        modifiers="accel,alt"
+#else
+        modifiers="accel,shift"
+#endif
+    />
     <key id="key_inspect" key="&inspectMenu.commandkey;" command="Tools:Inspect"
 #ifdef XP_MACOSX
         modifiers="accel,alt"
 #else
         modifiers="accel,shift"
 #endif
     />
     <key id="key_scratchpad" keycode="&scratchpad.keycode;" modifiers="shift"
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -176,16 +176,22 @@ XPCOMUtils.defineLazyGetter(this, "Popup
 });
 
 XPCOMUtils.defineLazyGetter(this, "InspectorUI", function() {
   let tmp = {};
   Cu.import("resource:///modules/inspector.jsm", tmp);
   return new tmp.InspectorUI(window);
 });
 
+XPCOMUtils.defineLazyGetter(this, "DebuggerUI", function() {
+  let tmp = {};
+  Cu.import("resource:///modules/devtools/DebuggerUI.jsm", tmp);
+  return new tmp.DebuggerUI(window);
+});
+
 XPCOMUtils.defineLazyGetter(this, "Tilt", function() {
   let tmp = {};
   Cu.import("resource:///modules/devtools/Tilt.jsm", tmp);
   return new tmp.Tilt(window);
 });
 
 let gInitialPages = [
   "about:blank",
@@ -1724,16 +1730,26 @@ function delayedStartup(isLoadingBlank, 
   if (enabled) {
     document.getElementById("menu_pageinspect").hidden = false;
     document.getElementById("Tools:Inspect").removeAttribute("disabled");
 #ifdef MENUBAR_CAN_AUTOHIDE
     document.getElementById("appmenu_pageInspect").hidden = false;
 #endif
   }
 
+  // Enable Debugger?
+  let enabled = gPrefService.getBoolPref("devtools.debugger.enabled");
+  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 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;
@@ -1784,16 +1800,27 @@ function delayedStartup(isLoadingBlank, 
       appMenuOpening = null;
       Services.telemetry.getHistogramById("FX_APP_MENU_OPEN_MS").add(duration);
     }, false);
   }
 
   window.addEventListener("mousemove", MousePosTracker, false);
   window.addEventListener("dragover", MousePosTracker, false);
 
+  // End startup crash tracking after a delay to catch crashes while restoring
+  // tabs and to postpone saving the pref to disk.
+  try {
+    let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"].
+                     getService(Ci.nsIAppStartup);
+    const startupCrashEndDelay = 30 * 1000;
+    setTimeout(appStartup.trackStartupCrashEnd, startupCrashEndDelay);
+  } catch (ex) {
+    Cu.reportError("Could not end startup crash tracking: " + ex);
+  }
+
   Services.obs.notifyObservers(window, "browser-delayed-startup-finished", "");
   TelemetryTimestamps.add("delayedStartupFinished");
 }
 
 function BrowserShutdown() {
   // In certain scenarios it's possible for unload to be fired before onload,
   // (e.g. if the window is being closed after browser.js loads but before the
   // load completes). In that case, there's nothing to do here.
@@ -6002,17 +6029,17 @@ function MultiplexHandler(event)
         SelectDetector(event, false);
     } else if (name == 'charsetGroup') {
         var charset = node.getAttribute('id');
         charset = charset.substring('charset.'.length, charset.length)
         BrowserSetForcedCharacterSet(charset);
     } else if (name == 'charsetCustomize') {
         //do nothing - please remove this else statement, once the charset prefs moves to the pref window
     } else {
-        SetForcedCharset(node.getAttribute('id'));
+        BrowserSetForcedCharacterSet(node.getAttribute('id'));
     }
     } catch(ex) { alert(ex); }
 }
 
 function SelectDetector(event, doReload)
 {
     var uri =  event.target.getAttribute("id");
     var prefvalue = uri.substring('chardet.'.length, uri.length);
@@ -8972,20 +8999,19 @@ function safeModeRestart()
                     (Services.prompt.BUTTON_POS_1 *
                      Services.prompt.BUTTON_TITLE_CANCEL) +
                     Services.prompt.BUTTON_POS_0_DEFAULT;
 
   let rv = Services.prompt.confirmEx(window, promptTitle, promptMessage,
                                      buttonFlags, restartText, null, null,
                                      null, {});
   if (rv == 0) {
-    let environment = Components.classes["@mozilla.org/process/environment;1"].
-      getService(Components.interfaces.nsIEnvironment);
-    environment.set("MOZ_SAFE_MODE_RESTART", "1");
-    Application.restart();
+    let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"].
+                     getService(Ci.nsIAppStartup);
+    appStartup.restartInSafeMode(Ci.nsIAppStartup.eAttemptQuit);
   }
 }
 
 /* duplicateTabIn duplicates tab in a place specified by the parameter |where|.
  *
  * |where| can be:
  *  "tab"         new tab
  *  "tabshifted"  same as "tab" but in background if default is to select new
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -845,21 +845,16 @@
 
 # Update primaryToolbarButtons in browser/themes/browserShared.inc when adding
 # or removing default items with the toolbarbutton-1 class.
 
       <toolbarbutton id="print-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
                      label="&printButton.label;" command="cmd_print"
                      tooltiptext="&printButton.tooltip;"/>
 
-      <toolbaritem id="navigator-throbber" title="&throbberItem.title;" align="center" pack="center"
-                   mousethrough="always">
-        <image/>
-      </toolbaritem>
-
       <toolbarbutton id="downloads-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
                      observes="Tools:Downloads"
                      ondrop="DownloadsButtonDNDObserver.onDrop(event)"
                      ondragover="DownloadsButtonDNDObserver.onDragOver(event)"
                      ondragenter="DownloadsButtonDNDObserver.onDragOver(event)"
                      ondragexit="DownloadsButtonDNDObserver.onDragExit(event)"
                      label="&downloads.label;"
                      tooltiptext="&downloads.tooltip;"/>
@@ -880,31 +875,16 @@
                      label="&newNavigatorCmd.label;"
                      command="key_newNavigator"
                      tooltiptext="&newWindowButton.tooltip;"
                      ondrop="newWindowButtonObserver.onDrop(event)"
                      ondragover="newWindowButtonObserver.onDragOver(event)"
                      ondragenter="newWindowButtonObserver.onDragOver(event)"
                      ondragexit="newWindowButtonObserver.onDragExit(event)"/>
 
-      <toolbarbutton id="cut-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
-                     label="&cutCmd.label;"
-                     command="cmd_cut"
-                     tooltiptext="&cutButton.tooltip;"/>
-
-      <toolbarbutton id="copy-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
-                     label="&copyCmd.label;"
-                     command="cmd_copy"
-                     tooltiptext="&copyButton.tooltip;"/>
-
-      <toolbarbutton id="paste-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
-                     label="&pasteCmd.label;"
-                     command="cmd_paste"
-                     tooltiptext="&pasteButton.tooltip;"/>
-
       <toolbarbutton id="fullscreen-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
                      observes="View:FullScreen"
                      type="checkbox"
                      label="&fullScreenCmd.label;"
                      tooltiptext="&fullScreenButton.tooltip;"/>
 
       <toolbaritem id="zoom-controls" class="chromeclass-toolbar-additional"
                    title="&zoomControls.label;">
@@ -912,36 +892,58 @@
                        label="&fullZoomReduceCmd.label;"
                        command="cmd_fullZoomReduce"
                        tooltiptext="&zoomOutButton.tooltip;"/>
         <toolbarbutton id="zoom-in-button" class="toolbarbutton-1"
                        label="&fullZoomEnlargeCmd.label;"
                        command="cmd_fullZoomEnlarge"
                        tooltiptext="&zoomInButton.tooltip;"/>
       </toolbaritem>
-#ifdef MOZ_SERVICES_SYNC
-      <toolbarbutton id="sync-button"
-                     class="toolbarbutton-1 chromeclass-toolbar-additional"
-                     label="&syncToolbarButton.label;"
-                     oncommand="gSyncUI.handleToolbarButton()"/>
-#endif
+
       <toolbarbutton id="feed-button"
                      type="menu"
                      class="toolbarbutton-1 chromeclass-toolbar-additional"
                      disabled="true"
                      label="&feedButton.label;"
                      tooltiptext="&feedButton.tooltip;"
                      onclick="return FeedHandler.onFeedButtonClick(event);">
         <menupopup position="after_end"
                    id="feed-menu"
                    onpopupshowing="return FeedHandler.buildFeedList(this);"
                    oncommand="return FeedHandler.subscribeToFeed(null, event);"
                    onclick="checkForMiddleClick(this, event);"/>
       </toolbarbutton>
 
+      <toolbarbutton id="cut-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
+                     label="&cutCmd.label;"
+                     command="cmd_cut"
+                     tooltiptext="&cutButton.tooltip;"/>
+
+      <toolbarbutton id="copy-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
+                     label="&copyCmd.label;"
+                     command="cmd_copy"
+                     tooltiptext="&copyButton.tooltip;"/>
+
+      <toolbarbutton id="paste-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
+                     label="&pasteCmd.label;"
+                     command="cmd_paste"
+                     tooltiptext="&pasteButton.tooltip;"/>
+
+#ifdef MOZ_SERVICES_SYNC
+      <toolbarbutton id="sync-button"
+                     class="toolbarbutton-1 chromeclass-toolbar-additional"
+                     label="&syncToolbarButton.label;"
+                     oncommand="gSyncUI.handleToolbarButton()"/>
+#endif
+
+      <toolbaritem id="navigator-throbber" title="&throbberItem.title;" align="center" pack="center"
+                   mousethrough="always">
+        <image/>
+      </toolbaritem>
+
       <toolbarbutton id="tabview-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
                      label="&tabGroupsButton.label;"
                      command="Browser:ToggleTabView"
                      tooltiptext="&tabGroupsButton.tooltip;"
                      observes="tabviewGroupsNumber"/>
     </toolbarpalette>
   </toolbox>
 
--- a/browser/base/content/highlighter.css
+++ b/browser/base/content/highlighter.css
@@ -43,37 +43,40 @@
 }
 
 /*
  * Node Infobar
  */
 
 #highlighter-nodeinfobar-container {
   position: absolute;
+  max-width: 95%;
 }
 
 #highlighter-nodeinfobar-container:not([disable-transitions]) {
   -moz-transition-property: top, left;
   -moz-transition-duration: 0.1s;
   -moz-transition-timing-function: linear;
 }
 
 #highlighter-nodeinfobar {
   display: block;
   white-space: nowrap;
   direction: ltr;
+  overflow: hidden;
+  text-overflow: ellipsis;
 }
 
 #highlighter-nodeinfobar-container[locked] > #highlighter-nodeinfobar {
   pointer-events: auto;
 }
 
-#highlighter-nodeinfobar-id,
-.highlighter-nodeinfobar-class,
-#highlighter-nodeinfobar-tagname {
+html|*#highlighter-nodeinfobar-id,
+html|*#highlighter-nodeinfobar-classes,
+html|*#highlighter-nodeinfobar-tagname {
   -moz-user-select: text;
   cursor: text;
 }
 
 .highlighter-nodeinfobar-arrow {
   display: none;
 }
 
@@ -84,15 +87,11 @@
 #highlighter-nodeinfobar-container[position="bottom"]:not([hide-arrow]) > #highlighter-nodeinfobar-arrow-top {
   display: block;
 }
 
 #highlighter-nodeinfobar-container[disabled] {
   visibility: hidden;
 }
 
-#highlighter-nodeinfobar-id:empty {
-  display: none;
-}
-
-#highlighter-nodeinfobar-tagname {
+html|*#highlighter-nodeinfobar-tagname {
   text-transform: lowercase;
 }
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -326,26 +326,27 @@ nsContextMenu.prototype = {
                   this.onTextInput && top.gBidiUI);
     this.showItem("context-bidi-page-direction-toggle",
                   !this.onTextInput && top.gBidiUI);
   },
 
   initSpellingItems: function() {
     var canSpell = InlineSpellCheckerUI.canSpellCheck;
     var onMisspelling = InlineSpellCheckerUI.overMisspelling;
+    var showUndo = canSpell && InlineSpellCheckerUI.canUndo();
     this.showItem("spell-check-enabled", canSpell);
     this.showItem("spell-separator", canSpell || this.onEditableArea);
     document.getElementById("spell-check-enabled")
             .setAttribute("checked", canSpell && InlineSpellCheckerUI.enabled);
 
     this.showItem("spell-add-to-dictionary", onMisspelling);
-    this.showItem("spell-undo-add-to-dictionary", InlineSpellCheckerUI.canUndo());
+    this.showItem("spell-undo-add-to-dictionary", showUndo);
 
     // suggestion list
-    this.showItem("spell-suggestions-separator", onMisspelling);
+    this.showItem("spell-suggestions-separator", onMisspelling || showUndo);
     if (onMisspelling) {
       var suggestionsSeparator =
         document.getElementById("spell-add-to-dictionary");
       var numsug =
         InlineSpellCheckerUI.addSuggestionsToMenu(suggestionsSeparator.parentNode,
                                                   suggestionsSeparator, 5);
       this.showItem("spell-no-suggestions", numsug == 0);
     }
--- a/browser/base/content/safeMode.js
+++ b/browser/base/content/safeMode.js
@@ -133,16 +133,24 @@ function onOK() {
 
 function onCancel() {
   var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"]
                              .getService(Components.interfaces.nsIAppStartup);
   appStartup.quit(appStartup.eForceQuit);
 }
 
 function onLoad() {
+  var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"]
+                             .getService(Components.interfaces.nsIAppStartup);
+
+  if (appStartup.automaticSafeModeNecessary) {
+    document.getElementById("autoSafeMode").hidden = false;
+    document.getElementById("manualSafeMode").hidden = true;
+  }
+
   document.getElementById("tasks")
           .addEventListener("CheckboxStateChange", UpdateOKButtonState, false);
 }
 
 function UpdateOKButtonState() {
   document.documentElement.getButton("accept").disabled = 
     !document.getElementById("resetUserPrefs").checked &&
     !document.getElementById("deleteBookmarks").checked &&
--- a/browser/base/content/safeMode.xul
+++ b/browser/base/content/safeMode.xul
@@ -66,17 +66,22 @@
             ondialogextra1="window.close()"
             onload="onLoad();"
             buttondisabledaccept="true">
 
   <script type="application/javascript" src="chrome://browser/content/safeMode.js"/>
 
   <stringbundle id="preferencesBundle" src="chrome://browser/locale/preferences/preferences.properties"/>
 
-  <description>&safeModeDescription.label;</description>
+  <vbox id="autoSafeMode" hidden="true">
+    <label class="header plain" value="&autoSafeModeIntro.label;"/>
+    <description>&autoSafeModeDescription.label;</description>
+  </vbox>
+
+  <description id="manualSafeMode">&safeModeDescription.label;</description>
 
   <separator class="thin"/>
 
   <label value="&safeModeDescription2.label;"/>
   <vbox id="tasks">
     <checkbox id="disableAddons"  label="&disableAddons.label;"  accesskey="&disableAddons.accesskey;"/>
     <checkbox id="resetToolbars"  label="&resetToolbars.label;"  accesskey="&resetToolbars.accesskey;"/>
     <checkbox id="deleteBookmarks" label="&deleteBookmarks.label;" accesskey="&deleteBookmarks.accesskey;"/>
--- a/browser/base/content/test/test_contextmenu.html
+++ b/browser/base/content/test/test_contextmenu.html
@@ -253,31 +253,32 @@ function runTest(testNum) {
   switch (testNum) {
     case 1:
         // Invoke context menu for next test.
         openContextMenuFor(text);
         break;
 
     case 2:
         // Context menu for plain text
-        checkContextMenu(["context-back",         false,
+        plainTextItems = ["context-back",         false,
                           "context-forward",      false,
                           "context-reload",       true,
                           "context-stop",         false,
                           "---",                  null,
                           "context-bookmarkpage", true,
                           "context-savepage",     true,
                           "context-sendpage",     true,
                           "---",                  null,
                           "context-viewbgimage",  false,
                           "context-selectall",    true,
                           "---",                  null,
                           "context-viewsource",   true,
                           "context-viewinfo",     true
-                         ].concat(inspectItems));
+                         ].concat(inspectItems);
+        checkContextMenu(plainTextItems);
         closeContextMenu();
         openContextMenuFor(link); // Invoke context menu for next test.
         break;
 
     case 3:
         // Context menu for text link
         checkContextMenu(["context-openlinkintab", true,
                           "context-openlink",      true,
@@ -508,23 +509,31 @@ function runTest(testNum) {
                           "spell-check-enabled", true,
                           "spell-dictionaries",  true,
                               ["spell-check-dictionary-en-US", true,
                                "---",                          null,
                                "spell-add-dictionaries",       true], null
                          ].concat(inspectItems));
         contextMenu.ownerDocument.getElementById("spell-add-to-dictionary").doCommand(); // Add to dictionary
         closeContextMenu();
+        openContextMenuFor(text); // Invoke context menu for next test.
+        break;
+
+    case 15:
+        // Re-check context menu for plain text to make sure it hasn't changed
+        checkContextMenu(plainTextItems);
+        closeContextMenu();
         openContextMenuFor(textarea, false, true); // Invoke context menu for next test.
         break;
-    
-    case 15:    
+
+    case 16:
         // Context menu for textarea after a word has been added
         // to the dictionary
         checkContextMenu(["spell-undo-add-to-dictionary", true,
+                          "---",                 null,
                           "context-undo",        false,
                           "---",                 null,
                           "context-cut",         false,
                           "context-copy",        false,
                           "context-paste",       null, // ignore clipboard state
                           "context-delete",      false,
                           "---",                 null,
                           "context-selectall",   true,
@@ -535,17 +544,17 @@ function runTest(testNum) {
                                "---",                          null,
                                "spell-add-dictionaries",       true], null
                          ].concat(inspectItems));
         contextMenu.ownerDocument.getElementById("spell-undo-add-to-dictionary").doCommand(); // Undo add to dictionary
         closeContextMenu();
         openContextMenuFor(contenteditable);
         break;
 
-    case 16:
+    case 17:
         // Context menu for contenteditable
         checkContextMenu(["spell-no-suggestions", false,
                           "spell-add-to-dictionary", true,
                           "---",                 null,
                           "context-undo",        false,
                           "---",                 null,
                           "context-cut",         false,
                           "context-copy",        false,
@@ -560,17 +569,17 @@ function runTest(testNum) {
                                "---",                          null,
                                "spell-add-dictionaries",       true], null
                          ].concat(inspectItems));
 
         closeContextMenu();
         openContextMenuFor(inputspell); // Invoke context menu for next test.
         break;
 
-    case 17:
+    case 18:
         // Context menu for spell-check input
         checkContextMenu(["*prodigality",        true, // spelling suggestion
                           "spell-add-to-dictionary", true,
                           "---",                 null,
                           "context-undo",        false,
                           "---",                 null,
                           "context-cut",         false,
                           "context-copy",        false,
@@ -585,23 +594,23 @@ function runTest(testNum) {
                                "---",                          null,
                                "spell-add-dictionaries",       true], null
                          ].concat(inspectItems));
 
         closeContextMenu();
         openContextMenuFor(link); // Invoke context menu for next test.
         break;
 
-    case 18:
+    case 19:
         executeCopyCommand("cmd_copyLink", "http://mozilla.com/");
         closeContextMenu();
         openContextMenuFor(pagemenu); // Invoke context menu for next test.
         break;
 
-    case 19:
+    case 20:
         // Context menu for element with assigned content context menu
         checkContextMenu(["+Plain item",          {type: "", icon: "", checked: false, disabled: false},
                           "+Disabled item",       {type: "", icon: "", checked: false, disabled: true},
                           "+Item w/ textContent", {type: "", icon: "", checked: false, disabled: false},
                           "---",                  null,
                           "+Checkbox",            {type: "checkbox", icon: "", checked: true, disabled: false},
                           "---",                  null,
                           "+Radio1",              {type: "checkbox", icon: "", checked: true, disabled: false},
@@ -634,17 +643,17 @@ function runTest(testNum) {
                           "context-viewinfo",     true
                          ].concat(inspectItems));
 
         invokeItemAction("0");
         closeContextMenu();
         openContextMenuFor(pagemenu, true); // Invoke context menu for next test.
         break;
 
-    case 20:
+    case 21:
         // Context menu for element with assigned content context menu
         // The shift key should bypass content context menu processing
         checkContextMenu(["context-back",         false,
                           "context-forward",      false,
                           "context-reload",       true,
                           "context-stop",         false,
                           "---",                  null,
                           "context-bookmarkpage", true,
@@ -679,17 +688,17 @@ function runTest(testNum) {
   }
 
 }
 
 
 var testNum = 1;
 var subwindow, chromeWin, contextMenu, lastElement;
 var text, link, mailto, input, img, canvas, video_ok, video_bad, video_bad2,
-    iframe, video_in_iframe, image_in_iframe, textarea, contenteditable, inputspell, pagemenu;
+    iframe, video_in_iframe, image_in_iframe, textarea, contenteditable, inputspell, pagemenu, plainTextItems;
 
 function startTest() {
     netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
     chromeWin = subwindow
                     .QueryInterface(Ci.nsIInterfaceRequestor)
                     .getInterface(Ci.nsIWebNavigation)
                     .QueryInterface(Ci.nsIDocShellTreeItem)
                     .rootTreeItem
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -183,16 +183,23 @@ BrowserGlue.prototype = {
         break;
       case "quit-application-requested":
         this._onQuitRequest(subject, data);
         break;
       case "quit-application-granted":
         // This pref must be set here because SessionStore will use its value
         // on quit-application.
         this._setPrefToSaveSession();
+        try {
+          let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"].
+                           getService(Ci.nsIAppStartup);
+          appStartup.trackStartupCrashEnd();
+        } catch (e) {
+          Cu.reportError("Could not end startup crash tracking in quit-application-granted: " + e);
+        }
         break;
 #ifdef OBSERVE_LASTWINDOW_CLOSE_TOPICS
       case "browser-lastwindow-close-requested":
         // The application is not actually quitting, but the last full browser
         // window is about to be closed.
         this._onQuitRequest(subject, "lastwindow");
         break;
       case "browser-lastwindow-close-granted":
@@ -410,16 +417,19 @@ BrowserGlue.prototype = {
       aAddons.forEach(function(aAddon) {
         // If the add-on isn't user disabled or can't be enabled then skip it
         if (!aAddon.userDisabled || !(aAddon.permissions & AddonManager.PERM_CAN_ENABLE))
           return;
 
         browser.selectedTab = browser.addTab("about:newaddon?id=" + aAddon.id);
       })
     });
+
+    let keywordURLUserSet = Services.prefs.prefHasUserValue("keyword.URL");
+    Services.telemetry.getHistogramById("FX_KEYWORD_URL_USERSET").add(keywordURLUserSet);
   },
 
   _onQuitRequest: function BG__onQuitRequest(aCancelQuit, aQuitType) {
     // If user has already dismissed quit request, then do nothing
     if ((aCancelQuit instanceof Ci.nsISupportsPRBool) && aCancelQuit.data)
       return;
 
     // There are several cases where we won't show a dialog here:
--- a/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js
+++ b/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js
@@ -32,16 +32,17 @@
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://gre/modules/Services.jsm");
 
 #ifndef XP_WIN
 #define BROKEN_WM_Z_ORDER
 #endif
 
 ////////////////////////////////////////////////////////////////////////////////
 //// Utilities
 
@@ -171,37 +172,47 @@ PrivateBrowsingService.prototype = {
           else // no open browser windows, just restore a blank state on exit
             this._savedBrowserState = blankState;
         }
       }
 
       this._closePageInfoWindows();
 
       // save view-source windows URIs and close them
-      let viewSrcWindowsEnum = Cc["@mozilla.org/appshell/window-mediator;1"].
-                               getService(Ci.nsIWindowMediator).
-                               getEnumerator("navigator:view-source");
+      let viewSrcWindowsEnum = Services.wm.getEnumerator("navigator:view-source");
       while (viewSrcWindowsEnum.hasMoreElements()) {
         let win = viewSrcWindowsEnum.getNext();
         if (this._inPrivateBrowsing) {
           let plainURL = win.gBrowser.currentURI.spec;
           if (plainURL.indexOf("view-source:") == 0) {
             plainURL = plainURL.substr(12);
             this._viewSrcURLs.push(plainURL);
           }
         }
         win.close();
       }
+        
+      var windowsEnum = Services.wm.getEnumerator("navigator:browser");
+      while (windowsEnum.hasMoreElements()) {
+        var window = windowsEnum.getNext();
+        window.getInterface(Ci.nsIWebNavigation)
+              .QueryInterface(Ci.nsIDocShellTreeItem)
+              .treeOwner
+              .QueryInterface(Ci.nsIInterfaceRequestor)
+              .getInterface(Ci.nsIXULWindow)
+              .docShell.QueryInterface(Ci.nsILoadContext)
+              .usePrivateBrowsing = this._inPrivateBrowsing;
+      }
 
       if (!this._quitting && this._saveSession) {
         let browserWindow = this._getBrowserWindow();
 
-        // if there are open browser windows, load a dummy session to get a distinct 
+	// if there are open browser windows, load a dummy session to get a distinct 
         // separation between private and non-private sessions
-        if (browserWindow) {
+	if (browserWindow) {
           // set an empty session to transition from/to pb mode, see bug 476463
           ss.setBrowserState(blankState);
 
           // just in case the only remaining window after setBrowserState is different.
           // it probably shouldn't be with the current sessionstore impl, but we shouldn't
           // rely on behaviour the API doesn't guarantee
           browserWindow = this._getBrowserWindow();
           let browser = browserWindow.gBrowser;
--- a/browser/components/tabview/tabitems.js
+++ b/browser/components/tabview/tabitems.js
@@ -98,17 +98,17 @@ function TabItem(tab, options) {
   this.isStacked = false;
   this.url = "";
 
   // Read off the total vertical and horizontal padding on the tab container
   // and cache this value, as it must be the same for every TabItem.
   if (Utils.isEmptyObject(TabItems.tabItemPadding)) {
     TabItems.tabItemPadding.x = parseInt($div.css('padding-left'))
         + parseInt($div.css('padding-right'));
-  
+
     TabItems.tabItemPadding.y = parseInt($div.css('padding-top'))
         + parseInt($div.css('padding-bottom'));
   }
   
   this.bounds = new Rect(0,0,1,1);
 
   this._lastTabUpdateTime = Date.now();
 
--- a/browser/devtools/Makefile.in
+++ b/browser/devtools/Makefile.in
@@ -49,12 +49,13 @@ include $(topsrcdir)/config/config.mk
 DIRS = \
   highlighter \
   webconsole \
   sourceeditor \
   styleeditor \
   styleinspector \
   tilt \
   scratchpad \
+  debugger \
   shared \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/DebuggerUI.jsm
@@ -0,0 +1,377 @@
+/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Debugger UI code.
+ *
+ * The Initial Developer of the Original Code is
+ *   Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Dave Camp <dcamp@mozilla.com> (original author)
+ *   Panos Astithas <past@mozilla.com>
+ *   Victor Porof <vporof@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+"use strict";
+
+/*global Components, NetUtil, Services, XPCOMUtils */
+/*global DebuggerServer, DebuggerClient, SourceEditor */
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/NetUtil.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/devtools/dbg-server.jsm");
+Cu.import("resource://gre/modules/devtools/dbg-client.jsm");
+Cu.import("resource:///modules/XPCOMUtils.jsm");
+Cu.import("resource:///modules/source-editor.jsm");
+
+let EXPORTED_SYMBOLS = ["DebuggerUI"];
+
+/**
+ * Creates a pane that will host the debugger UI.
+ */
+function DebuggerPane(aTab) {
+  this._tab = aTab;
+  this._close = this.close.bind(this);
+  this._debugTab = this.debugTab.bind(this);
+}
+
+DebuggerPane.prototype = {
+  /**
+   * Creates and initializes the widgets contained in the debugger UI.
+   */
+  create: function DP_create(gBrowser) {
+    this._tab._scriptDebugger = this;
+
+    this._nbox = gBrowser.getNotificationBox(this._tab.linkedBrowser);
+    this._splitter = gBrowser.parentNode.ownerDocument.createElement("splitter");
+    this._splitter.setAttribute("class", "hud-splitter");
+    this.frame = gBrowser.parentNode.ownerDocument.createElement("iframe");
+    this.frame.height = DebuggerUIPreferences.height;
+
+    this._nbox.appendChild(this._splitter);
+    this._nbox.appendChild(this.frame);
+
+    let self = this;
+
+    this.frame.addEventListener("DOMContentLoaded", function initPane(aEvent) {
+      if (aEvent.target != self.frame.contentDocument) {
+        return;
+      }
+      self.frame.removeEventListener("DOMContentLoaded", initPane, true);
+      // Initialize the source editor.
+      self.frame.contentWindow.editor = self.editor = new SourceEditor();
+
+      let config = {
+        mode: SourceEditor.MODES.JAVASCRIPT,
+        showLineNumbers: true,
+        readOnly: true
+      };
+
+      let editorPlaceholder = self.frame.contentDocument.getElementById("editor");
+      self.editor.init(editorPlaceholder, config, self._onEditorLoad.bind(self));
+    }, true);
+    this.frame.addEventListener("DebuggerClose", this._close, true);
+
+    this.frame.setAttribute("src", "chrome://browser/content/debugger.xul");
+  },
+
+  /**
+   * The load event handler for the source editor. This method does post-load
+   * editor initialization.
+   */
+  _onEditorLoad: function DP__onEditorLoad() {
+    // Connect to the debugger server.
+    this.connect();
+  },
+
+  /**
+   * Closes the debugger UI removing child nodes and event listeners.
+   */
+  close: function DP_close() {
+    if (this._tab) {
+      this._tab._scriptDebugger = null;
+      this._tab = null;
+    }
+    if (this.frame) {
+      DebuggerUIPreferences.height = this.frame.height;
+
+      this.frame.removeEventListener("unload", this._close, true);
+      this.frame.removeEventListener("DebuggerClose", this._close, true);
+      if (this.frame.parentNode) {
+        this.frame.parentNode.removeChild(this.frame);
+      }
+      this.frame = null;
+    }
+    if (this._nbox) {
+      this._nbox.removeChild(this._splitter);
+      this._nbox = null;
+    }
+
+    this._splitter = null;
+
+    if (this._client) {
+      this._client.removeListener("newScript", this.onNewScript);
+      this._client.removeListener("tabDetached", this._close);
+      this._client.removeListener("tabNavigated", this._debugTab);
+      this._client.close();
+      this._client = null;
+    }
+  },
+
+  /**
+   * Initializes a debugger client and connects it to the debugger server,
+   * wiring event handlers as necessary.
+   */
+  connect: function DP_connect() {
+    this.frame.addEventListener("unload", this._close, true);
+
+    let transport = DebuggerServer.connectPipe();
+    this._client = new DebuggerClient(transport);
+    // Store the new script handler locally, so when it's time to remove it we
+    // don't need to go through the iframe, since it might be cleared.
+    this.onNewScript = this.debuggerWindow.SourceScripts.onNewScript;
+    let self = this;
+    this._client.addListener("tabNavigated", this._debugTab);
+    this._client.addListener("tabDetached", this._close);
+    this._client.addListener("newScript", this.onNewScript);
+    this._client.connect(function(aType, aTraits) {
+      self._client.listTabs(function(aResponse) {
+        let tab = aResponse.tabs[aResponse.selected];
+        self.debuggerWindow.startDebuggingTab(self._client, tab);
+        if (self.onConnected) {
+          self.onConnected(self);
+        }
+      });
+    });
+  },
+
+  /**
+   * Starts debugging the current tab. This function is called on each location
+   * change in this tab.
+   */
+  debugTab: function DP_debugTab(aNotification, aPacket) {
+    let self = this;
+    this._client.activeThread.detach(function() {
+      self._client.activeTab.detach(function() {
+        self._client.listTabs(function(aResponse) {
+          let tab = aResponse.tabs[aResponse.selected];
+          self.debuggerWindow.startDebuggingTab(self._client, tab);
+          if (self.onConnected) {
+            self.onConnected(self);
+          }
+        });
+      });
+    });
+  },
+
+  get debuggerWindow() {
+    return this.frame.contentWindow;
+  },
+
+  get debuggerClient() {
+    return this._client;
+  },
+
+  get activeThread() {
+    try {
+      return this.debuggerWindow.ThreadState.activeThread;
+    } catch(ex) {
+      return undefined;
+    }
+  }
+};
+
+function DebuggerUI(aWindow) {
+  this.aWindow = aWindow;
+
+  aWindow.addEventListener("Debugger:LoadSource", this._onLoadSource.bind(this));
+}
+
+DebuggerUI.prototype = {
+  /**
+   * Starts the debugger or stops it, if it is already started.
+   */
+  toggleDebugger: function DebuggerUI_toggleDebugger() {
+    if (!DebuggerServer.initialized) {
+      DebuggerServer.init();
+      DebuggerServer.addBrowserActors();
+    }
+
+    let gBrowser = this.aWindow.gBrowser;
+    let tab = gBrowser.selectedTab;
+
+    if (tab._scriptDebugger) {
+      // If the debugger is already open, just close it.
+      tab._scriptDebugger.close();
+      return tab._scriptDebugger;
+    }
+
+    let pane = new DebuggerPane(tab);
+    pane.create(gBrowser);
+    return pane;
+  },
+
+  getDebugger: function DebuggerUI_getDebugger(aTab) {
+    return aTab._scriptDebugger;
+  },
+
+  get preferences() {
+    return DebuggerUIPreferences;
+  },
+
+  /**
+   * Handles notifications to load a source script from the cache or from a
+   * local file.
+   * 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 DebuggerUI__onLoadSource(aEvent) {
+    let gBrowser = this.aWindow.gBrowser;
+
+    let url = aEvent.detail;
+    let scheme = Services.io.extractScheme(url);
+    switch (scheme) {
+      case "file":
+      case "chrome":
+      case "resource":
+        try {
+          NetUtil.asyncFetch(url, function onFetch(aStream, aStatus) {
+            if (!Components.isSuccessCode(aStatus)) {
+              return this.logError(url, aStatus);
+            }
+            let source = NetUtil.readInputStreamToString(aStream, aStream.available());
+            aStream.close();
+            this._onSourceLoaded(url, source);
+          }.bind(this));
+        } catch (ex) {
+          return this.logError(url, ex.name);
+        }
+        break;
+
+      default:
+        let channel = Services.io.newChannel(url, null, null);
+        let chunks = [];
+        let streamListener = { // nsIStreamListener inherits nsIRequestObserver
+          onStartRequest: function (aRequest, aContext, aStatusCode) {
+            if (!Components.isSuccessCode(aStatusCode)) {
+              return this.logError(url, aStatusCode);
+            }
+          }.bind(this),
+          onDataAvailable: function (aRequest, aContext, aStream, aOffset, aCount) {
+            chunks.push(NetUtil.readInputStreamToString(aStream, aCount));
+          },
+          onStopRequest: function (aRequest, aContext, aStatusCode) {
+            if (!Components.isSuccessCode(aStatusCode)) {
+              return this.logError(url, aStatusCode);
+            }
+
+            this._onSourceLoaded(url, chunks.join(""));
+          }.bind(this)
+        };
+
+        channel.loadFlags = channel.LOAD_FROM_CACHE;
+        channel.asyncOpen(streamListener, null);
+        break;
+    }
+  },
+
+  /**
+   * 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 DebuggerUI_logError(aUrl, aStatus) {
+    let view = this.getDebugger(gBrowser.selectedTab).DebuggerView;
+    Components.utils.reportError(view.getFormatStr("loadingError", [ aUrl, aStatus ]));
+  },
+
+  /**
+   * Called when source has been loaded.
+   *
+   * @param string aSourceUrl
+   *        The URL of the source script.
+   * @param string aSourceText
+   *        The text of the source script.
+   */
+  _onSourceLoaded: function DebuggerUI__onSourceLoaded(aSourceUrl, aSourceText) {
+    let dbg = this.getDebugger(this.aWindow.gBrowser.selectedTab);
+    if (aSourceUrl.slice(-3) == ".js") {
+      dbg.editor.setMode(SourceEditor.MODES.JAVASCRIPT);
+    } else {
+      dbg.editor.setMode(SourceEditor.MODES.HTML);
+    }
+    dbg.editor.setText(aSourceText);
+    let doc = dbg.frame.contentDocument;
+    let scripts = doc.getElementById("scripts");
+    let elt = scripts.getElementsByAttribute("value", aSourceUrl)[0];
+    let script = elt.getUserData("sourceScript");
+    script.loaded = true;
+    script.text = aSourceText;
+    elt.setUserData("sourceScript", script, null);
+  }
+};
+
+/**
+ * Various debugger UI preferences (currently just the pane height).
+ */
+let DebuggerUIPreferences = {
+
+  _height: -1,
+
+  /**
+   * Gets the preferred height of the debugger pane.
+   *
+   * @return number
+   *         The preferred height.
+   */
+  get height() {
+    if (this._height < 0) {
+      this._height = Services.prefs.getIntPref("devtools.debugger.ui.height");
+    }
+    return this._height;
+  },
+
+  /**
+   * Sets the preferred height of the debugger pane.
+   *
+   * @param number value
+   *        The new height.
+   */
+  set height(value) {
+    Services.prefs.setIntPref("devtools.debugger.ui.height", value);
+    this._height = value;
+  }
+};
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/Makefile.in
@@ -0,0 +1,53 @@
+# ***** 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 Debugger UI code.
+#
+# The Initial Developer of the Original Code is
+#   Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#  Dave Camp <dcamp@mozilla.com>
+#  Victor Porof <vporof@mozilla.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH     = ../../..
+topsrcdir = @top_srcdir@
+srcdir    = @srcdir@
+VPATH     = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+ifdef ENABLE_TESTS
+	DIRS += test
+endif
+
+include $(topsrcdir)/config/rules.mk
+
+libs::
+	$(NSINSTALL) $(srcdir)/*.jsm $(FINAL_TARGET)/modules/devtools
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/debugger-view.js
@@ -0,0 +1,1125 @@
+/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ *   Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Victor Porof <vporof@mozilla.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the LGPL or the GPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ ***** END LICENSE BLOCK *****/
+"use strict";
+
+/*global Components, XPCOMUtils, Services, StackFrames, ThreadState, dump */
+const Cu = Components.utils;
+
+const DBG_STRINGS_URI = "chrome://browser/locale/devtools/debugger.properties";
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import('resource://gre/modules/Services.jsm');
+
+/**
+ * Object mediating visual changes and event listeners between the debugger and
+ * the html view.
+ */
+let DebuggerView = {
+
+  /**
+   * L10N shortcut function
+   *
+   * @param string aName
+   * @return string
+   */
+  getStr: function DV_getStr(aName) {
+    return this.stringBundle.GetStringFromName(aName);
+  },
+
+  /**
+   * L10N shortcut function
+   *
+   * @param string aName
+   * @param array aArray
+   * @return string
+   */
+  getFormatStr: function DV_getFormatStr(aName, aArray) {
+    return this.stringBundle.formatStringFromName(aName, aArray, aArray.length);
+  }
+};
+
+XPCOMUtils.defineLazyGetter(DebuggerView, "stringBundle", function() {
+  return Services.strings.createBundle(DBG_STRINGS_URI);
+});
+
+/**
+ * Functions handling the html stackframes UI.
+ */
+DebuggerView.Stackframes = {
+
+  /**
+   * Sets the current frames state based on the debugger active thread state.
+   *
+   * @param string aState
+   *        Either "paused" or "attached".
+   */
+  updateState: function DVF_updateState(aState) {
+    let resume = document.getElementById("resume");
+    let status = document.getElementById("status");
+
+    // if we're paused, show a pause label and disable the resume button
+    if (aState === "paused") {
+      status.textContent = DebuggerView.getStr("pausedState");
+      resume.disabled = false;
+    } else if (aState === "attached") {
+      // if we're attached, do the opposite
+      status.textContent = DebuggerView.getStr("runningState");
+      resume.disabled = true;
+    } else {
+      // no valid state parameter
+      status.textContent = "";
+    }
+  },
+
+  /**
+   * Sets the onClick listener for the stackframes container.
+   *
+   * @param function aHandler
+   *        The delegate used as the event listener.
+   */
+  addClickListener: function DVF_addClickListener(aHandler) {
+    // save the handler so it can be removed on shutdown
+    this._onFramesClick = aHandler;
+    this._frames.addEventListener("click", aHandler, false);
+  },
+
+  /**
+   * Removes all elements from the stackframes container, leaving it empty.
+   */
+  empty: function DVF_empty() {
+    while (this._frames.firstChild) {
+      this._frames.removeChild(this._frames.firstChild);
+    }
+  },
+
+  /**
+   * Removes all elements from the stackframes container, and adds a child node
+   * with an empty text note attached.
+   */
+  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(DebuggerView.getStr("emptyText")));
+
+    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.
+   *
+   * @param number aDepth
+   *        The frame depth specified by the debugger.
+   * @param string aFrameIdText
+   *        The id to be displayed in the list.
+   * @param string aFrameNameText
+   *        The name to be displayed in the list.
+   * @return object
+   *         The newly created html node representing the added frame.
+   */
+  addFrame: function DVF_addFrame(aDepth, aFrameIdText, aFrameNameText) {
+    // make sure we don't duplicate anything
+    if (document.getElementById("stackframe-" + aDepth)) {
+      return null;
+    }
+
+    let frame = document.createElement("div");
+    let frameId = document.createElement("span");
+    let frameName = document.createElement("span");
+
+    // create a list item to be added to the stackframes container
+    frame.id = "stackframe-" + aDepth;
+    frame.className = "dbg-stackframe list-item";
+
+    // this list should display the id and name of the frame
+    frameId.className = "dbg-stackframe-id";
+    frameName.className = "dbg-stackframe-name";
+    frameId.appendChild(document.createTextNode(aFrameIdText));
+    frameName.appendChild(document.createTextNode(aFrameNameText));
+
+    frame.appendChild(frameId);
+    frame.appendChild(frameName);
+
+    this._frames.appendChild(frame);
+
+    // return the element for later use if necessary
+    return frame;
+  },
+
+  /**
+   * Highlights a frame from the stackframe container as selected/deselected.
+   *
+   * @param number aDepth
+   *        The frame depth specified by the debugger.
+   * @param boolean aSelect
+   *        True if the frame should be selected, false otherwise.
+   */
+  highlightFrame: function DVF_highlightFrame(aDepth, aSelect) {
+    let frame = document.getElementById("stackframe-" + aDepth);
+
+    // the list item wasn't found in the stackframe container
+    if (!frame) {
+      dump("The frame list item wasn't found in the stackframes container.");
+      return;
+    }
+
+    // add the 'selected' css class if the frame isn't already selected
+    if (aSelect && !frame.classList.contains("selected")) {
+      frame.classList.add("selected");
+
+    // remove the 'selected' css class if the frame is already selected
+    } else if (!aSelect && frame.classList.contains("selected")) {
+      frame.classList.remove("selected");
+    }
+  },
+
+  /**
+   * Gets the current dirty state.
+   *
+   * @return boolean value
+   *         True if should load more frames.
+   */
+  get dirty() {
+    return this._dirty;
+  },
+
+  /**
+   * Sets if the active thread has more frames that need to be loaded.
+   *
+   * @param boolean aValue
+   *        True if should load more frames.
+   */
+  set dirty(aValue) {
+    this._dirty = aValue;
+  },
+
+  /**
+   * The cached click listener for the stackframes container.
+   */
+  _onFramesClick: null,
+
+  /**
+   * Listener handling the stackframes container scroll event.
+   */
+  _onFramesScroll: function DVF__onFramesScroll(aEvent) {
+    // update the stackframes container only if we have to
+    if (this._dirty) {
+      let clientHeight = this._frames.clientHeight;
+      let scrollTop = this._frames.scrollTop;
+      let scrollHeight = this._frames.scrollHeight;
+
+      // if the stackframes container was scrolled past 95% of the height,
+      // load more content
+      if (scrollTop >= (scrollHeight - clientHeight) * 0.95) {
+        this._dirty = false;
+
+        StackFrames._addMoreFrames();
+      }
+    }
+  },
+
+  /**
+   * Listener handling the close button click event.
+   */
+  _onCloseButtonClick: function DVF__onCloseButtonClick() {
+    let root = document.documentElement;
+    let debuggerClose = document.createEvent("Events");
+
+    debuggerClose.initEvent("DebuggerClose", true, false);
+    root.dispatchEvent(debuggerClose);
+  },
+
+  /**
+   * Listener handling the resume button click event.
+   */
+  _onResumeButtonClick: function DVF__onResumeButtonClick() {
+    ThreadState.activeThread.resume();
+  },
+
+  /**
+   * Specifies if the active thread has more frames which need to be loaded.
+   */
+  _dirty: false,
+
+  /**
+   * The cached stackframes container.
+   */
+  _frames: null,
+
+  /**
+   * Initialization function, called when the debugger is initialized.
+   */
+  initialize: function DVF_initialize() {
+    let close = document.getElementById("close");
+    let resume = document.getElementById("resume");
+    let frames = document.getElementById("stackframes");
+
+    close.addEventListener("click", this._onCloseButtonClick, false);
+    resume.addEventListener("click", this._onResumeButtonClick, false);
+    frames.addEventListener("scroll", this._onFramesScroll, false);
+    window.addEventListener("resize", this._onFramesScroll, false);
+
+    this._frames = frames;
+  },
+
+  /**
+   * Destruction function, called when the debugger is shut down.
+   */
+  destroy: function DVF_destroy() {
+    let close = document.getElementById("close");
+    let resume = document.getElementById("resume");
+    let frames = this._frames;
+
+    close.removeEventListener("click", this._onCloseButtonClick, false);
+    resume.removeEventListener("click", this._onResumeButtonClick, false);
+    frames.removeEventListener("click", this._onFramesClick, false);
+    frames.removeEventListener("scroll", this._onFramesScroll, false);
+    window.removeEventListener("resize", this._onFramesScroll, false);
+
+    this._frames = null;
+  }
+};
+
+/**
+ * Functions handling the properties view.
+ */
+DebuggerView.Properties = {
+
+  /**
+   * Adds a scope to contain any inspected variables.
+   * If the optional id is not specified, the scope html node will have a
+   * default id set as aName-scope.
+   *
+   * @param string aName
+   *        The scope name (e.g. "Local", "Global" or "With block").
+   * @param string aId
+   *        Optional, an id for the scope html node.
+   * @return object
+   *         The newly created html node representing the added scope or null
+   *         if a node was not created.
+   */
+  _addScope: function DVP__addScope(aName, aId) {
+    // make sure the parent container exists
+    if (!this._vars) {
+      return null;
+    }
+
+    // compute the id of the element if not specified
+    aId = aId || (aName + "-scope");
+
+    // contains generic nodes and functionality
+    let element = this._createPropertyElement(aName, aId, "scope", this._vars);
+
+    // make sure the element was created successfully
+    if (!element) {
+      dump("The debugger scope container wasn't created properly: " + aId);
+      return null;
+    }
+
+    /**
+     * @see DebuggerView.Properties._addVar
+     */
+    element.addVar = this._addVar.bind(this, element);
+
+    // return the element for later use if necessary
+    return element;
+  },
+
+  /**
+   * Adds a variable to a specified scope.
+   * If the optional id is not specified, the variable html node will have a
+   * default id set as aScope.id->aName-variable.
+   *
+   * @param object aScope
+   *        The parent scope element.
+   * @param string aName
+   *        The variable name.
+   * @param string aId
+   *        Optional, an id for the variable html node.
+   * @return object
+   *         The newly created html node representing the added var.
+   */
+  _addVar: function DVP__addVar(aScope, aName, aId) {
+    // make sure the scope container exists
+    if (!aScope) {
+      return null;
+    }
+
+    // compute the id of the element if not specified
+    aId = aId || (aScope.id + "->" + aName + "-variable");
+
+    // contains generic nodes and functionality
+    let element = this._createPropertyElement(aName, aId, "variable",
+                                              aScope.querySelector(".details"));
+
+    // make sure the element was created successfully
+    if (!element) {
+      dump("The debugger variable container wasn't created properly: " + aId);
+      return null;
+    }
+
+    /**
+     * @see DebuggerView.Properties._setGrip
+     */
+    element.setGrip = this._setGrip.bind(this, element);
+
+    /**
+     * @see DebuggerView.Properties._addProperties
+     */
+    element.addProperties = this._addProperties.bind(this, element);
+
+    // setup the additional elements specific for a variable node
+    element.refresh(function() {
+      let separator = document.createElement("span");
+      let info = document.createElement("span");
+      let title = element.querySelector(".title");
+      let arrow = element.querySelector(".arrow");
+
+      // separator shouldn't be selectable
+      separator.className = "unselectable";
+      separator.appendChild(document.createTextNode(": "));
+
+      // the variable information (type, class and/or value)
+      info.className = "info";
+
+      title.appendChild(separator);
+      title.appendChild(info);
+
+    }.bind(this));
+
+    // return the element for later use if necessary
+    return element;
+  },
+
+  /**
+   * Sets the specific grip for a variable.
+   * The grip should contain the value or the type & class, as defined in the
+   * remote debugger protocol. For convenience, undefined and null are
+   * both considered types.
+   *
+   * @param object aVar
+   *        The parent variable element.
+   * @param object aGrip
+   *        The primitive or object defining the grip, specifying
+   *        the value and/or type & class of the variable (if the type
+   *        is not specified, it will be inferred from the value).
+   *        e.g. 42
+   *             true
+   *             "nasu"
+   *             { type: "undefined" } }
+   *             { type: "null" } }
+   *             { type: "object", class: "Object" } }
+   * @return object
+   *         The same variable.
+   */
+  _setGrip: function DVP__setGrip(aVar, aGrip) {
+    // make sure the variable container exists
+    if (!aVar) {
+      return null;
+    }
+
+    let info = aVar.querySelector(".info") || aVar.target.info;
+
+    // make sure the info node exists
+    if (!info) {
+      dump("Could not set the grip for the corresponding variable: " + aVar.id);
+      return null;
+    }
+
+    info.textContent = this._propertyString(aGrip);
+    info.classList.add(this._propertyColor(aGrip));
+
+    return aVar;
+  },
+
+  /**
+   * Adds multiple properties to a specified variable.
+   * This function handles two types of properties: data properties and
+   * accessor properties, as defined in the remote debugger protocol spec.
+   *
+   * @param object aVar
+   *        The parent variable element.
+   * @param object aProperties
+   *        An object containing the key: descriptor data properties,
+   *        specifying the value and/or type & class of the variable,
+   *        or 'get' & 'set' accessor properties.
+   *        e.g. { "someProp0": { value: 42 },
+   *               "someProp1": { value: true },
+   *               "someProp2": { value: "nasu" },
+   *               "someProp3": { value: { type: "undefined" } },
+   *               "someProp4": { value: { type: "null" } },
+   *               "someProp5": { value: { type: "object", class: "Object" } },
+   *               "someProp6": { get: { "type": "object", "class": "Function" },
+   *                              set: { "type": "undefined" } } }
+   * @return object
+   *         The same variable.
+   */
+  _addProperties: function DVP__addProperties(aVar, aProperties) {
+    // for each property, add it using the passed object key/grip
+    for (let i in aProperties) {
+      // Can't use aProperties.hasOwnProperty(i), because it may be overridden.
+      if (Object.getOwnPropertyDescriptor(aProperties, i)) {
+
+        // get the specified descriptor for current property
+        let desc = aProperties[i];
+
+        // as described in the remote debugger protocol, the value grip must be
+        // contained in a 'value' property
+        let value = desc["value"];
+
+        // for accessor property descriptors, the two grips need to be
+        // contained in 'get' and 'set' properties
+        let getter = desc["get"];
+        let setter = desc["set"];
+
+        // handle data property and accessor property descriptors
+        if (value !== undefined) {
+          this._addProperty(aVar, [i, value]);
+        }
+        if (getter !== undefined || setter !== undefined) {
+          let prop = this._addProperty(aVar, [i]).expand();
+          prop.getter = this._addProperty(prop, ["get", getter]);
+          prop.setter = this._addProperty(prop, ["set", setter]);
+        }
+      }
+    }
+    return aVar;
+  },
+
+  /**
+   * Adds a property to a specified variable.
+   * If the optional id is not specified, the property html node will have a
+   * default id set as aVar.id->aKey-property.
+   *
+   * @param object aVar
+   *        The parent variable element.
+   * @param {Array} aProperty
+   *        An array containing the key and grip properties, specifying
+   *        the value and/or type & class of the variable (if the type
+   *        is not specified, it will be inferred from the value).
+   *        e.g. ["someProp0": 42]
+   *             ["someProp1": true]
+   *             ["someProp2": "nasu"]
+   *             ["someProp3": { type: "undefined" }]
+   *             ["someProp4": { type: "null" }]
+   *             ["someProp5": { type: "object", class: "Object" }]
+   * @param string aName
+   *        Optional, the property name.
+   * @paarm string aId
+   *        Optional, an id for the property html node.
+   * @return object
+   *         The newly created html node representing the added prop.
+   */
+  _addProperty: function DVP__addProperty(aVar, aProperty, aName, aId) {
+    // make sure the variable container exists
+    if (!aVar) {
+      return null;
+    }
+
+    // compute the id of the element if not specified
+    aId = aId || (aVar.id + "->" + aProperty[0] + "-property");
+
+    // contains generic nodes and functionality
+    let element = this._createPropertyElement(aName, aId, "property",
+                                              aVar.querySelector(".details"));
+
+    // make sure the element was created successfully
+    if (!element) {
+      dump("The debugger property container wasn't created properly.");
+      return null;
+    }
+
+    /**
+     * @see DebuggerView.Properties._setGrip
+     */
+    element.setGrip = this._setGrip.bind(this, element);
+
+    /**
+     * @see DebuggerView.Properties._addProperties
+     */
+    element.addProperties = this._addProperties.bind(this, element);
+
+    // setup the additional elements specific for a variable node
+    element.refresh(function(pKey, pGrip) {
+      let propertyString = this._propertyString(pGrip);
+      let propertyColor = this._propertyColor(pGrip);
+      let key = document.createElement("div");
+      let value = document.createElement("div");
+      let separator = document.createElement("span");
+      let title = element.querySelector(".title");
+      let arrow = element.querySelector(".arrow");
+
+      // use a key element to specify the property name
+      key.className = "key";
+      key.appendChild(document.createTextNode(pKey));
+
+      // use a value element to specify the property value
+      value.className = "value";
+      value.appendChild(document.createTextNode(propertyString));
+      value.classList.add(propertyColor);
+
+      // separator shouldn't be selected
+      separator.className = "unselectable";
+      separator.appendChild(document.createTextNode(": "));
+
+      if (pKey) {
+        title.appendChild(key);
+      }
+      if (pGrip) {
+        title.appendChild(separator);
+        title.appendChild(value);
+      }
+
+      // make the property also behave as a variable, to allow
+      // recursively adding properties to properties
+      element.target = {
+        info: value
+      };
+
+      // save the property to the variable for easier access
+      Object.defineProperty(aVar, pKey, { value: element,
+                                          writable: false,
+                                          enumerable: true,
+                                          configurable: true });
+    }.bind(this), aProperty);
+
+    // return the element for later use if necessary
+    return element;
+  },
+
+  /**
+   * Returns a custom formatted property string for a type and a value.
+   *
+   * @param string | object aGrip
+   *        The variable grip.
+   * @return string
+   *         The formatted property string.
+   */
+  _propertyString: function DVP__propertyString(aGrip) {
+    if (aGrip && "object" === typeof aGrip) {
+      switch (aGrip["type"]) {
+        case "undefined":
+          return "undefined";
+        case "null":
+          return "null";
+        default:
+          return "[" + aGrip["type"] + " " + aGrip["class"] + "]";
+      }
+    } else {
+      switch (typeof aGrip) {
+        case "string":
+          return "\"" + aGrip + "\"";
+        case "boolean":
+          return aGrip ? "true" : "false";
+        default:
+          return aGrip + "";
+      }
+    }
+    return aGrip + "";
+  },
+
+  /**
+   * Returns a custom class style for a type and a value.
+   *
+   * @param string | object aGrip
+   *        The variable grip.
+   *
+   * @return string
+   *         The css class style.
+   */
+  _propertyColor: function DVP__propertyColor(aGrip) {
+    if (aGrip && "object" === typeof aGrip) {
+      switch (aGrip["type"]) {
+        case "undefined":
+          return "token-undefined";
+        case "null":
+          return "token-null";
+      }
+    } else {
+      switch (typeof aGrip) {
+        case "string":
+          return "token-string";
+        case "boolean":
+          return "token-boolean";
+        case "number":
+          return "token-number";
+      }
+    }
+    return "token-other";
+  },
+
+  /**
+   * Creates an element which contains generic nodes and functionality used by
+   * any scope, variable or property added to the tree.
+   *
+   * @param string aName
+   *        A generic name used in a title strip.
+   * @param string aId
+   *        id used by the created element node.
+   * @param string aClass
+   *        Recommended style class used by the created element node.
+   * @param object aParent
+   *        The parent node which will contain the element.
+   * @return object
+   *         The newly created html node representing the generic elem.
+   */
+  _createPropertyElement: function DVP__createPropertyElement(aName, aId, aClass, aParent) {
+    // make sure we don't duplicate anything and the parent exists
+    if (document.getElementById(aId)) {
+      dump("Duplicating a property element id is not allowed.");
+      return null;
+    }
+    if (!aParent) {
+      dump("A property element must have a valid parent node specified.");
+      return null;
+    }
+
+    let element = document.createElement("div");
+    let arrow = document.createElement("span");
+    let name = document.createElement("span");
+    let title = document.createElement("div");
+    let details = document.createElement("div");
+
+    // create a scope node to contain all the elements
+    element.id = aId;
+    element.className = aClass;
+
+    // the expand/collapse arrow
+    arrow.className = "arrow";
+    arrow.style.visibility = "hidden";
+
+    // the name element
+    name.className = "name unselectable";
+    name.appendChild(document.createTextNode(aName || ""));
+
+    // the title element, containing the arrow and the name
+    title.className = "title";
+    title.addEventListener("click", function() { element.toggle(); }, true);
+
+    // the node element which will contain any added scope variables
+    details.className = "details";
+
+    title.appendChild(arrow);
+    title.appendChild(name);
+
+    element.appendChild(title);
+    element.appendChild(details);
+
+    aParent.appendChild(element);
+
+    /**
+     * Shows the element, setting the display style to "block".
+     * @return object
+     *         The same element.
+     */
+    element.show = function DVP_element_show() {
+      element.style.display = "-moz-box";
+
+      if ("function" === typeof element.onshow) {
+        element.onshow(element);
+      }
+      return element;
+    };
+
+    /**
+     * Hides the element, setting the display style to "none".
+     * @return object
+     *         The same element.
+     */
+    element.hide = function DVP_element_hide() {
+      element.style.display = "none";
+
+      if ("function" === typeof element.onhide) {
+        element.onhide(element);
+      }
+      return element;
+    };
+
+    /**
+     * Expands the element, showing all the added details.
+     * @return object
+     *         The same element.
+     */
+    element.expand = function DVP_element_expand() {
+      arrow.setAttribute("open", "");
+      details.setAttribute("open", "");
+
+      if ("function" === typeof element.onexpand) {
+        element.onexpand(element);
+      }
+      return element;
+    };
+
+    /**
+     * Collapses the element, hiding all the added details.
+     * @return object
+     *         The same element.
+     */
+    element.collapse = function DVP_element_collapse() {
+      arrow.removeAttribute("open");
+      details.removeAttribute("open");
+
+      if ("function" === typeof element.oncollapse) {
+        element.oncollapse(element);
+      }
+      return element;
+    };
+
+    /**
+     * Toggles between the element collapse/expand state.
+     * @return object
+     *         The same element.
+     */
+    element.toggle = function DVP_element_toggle() {
+      element.expanded = !element.expanded;
+
+      if ("function" === typeof element.ontoggle) {
+        element.ontoggle(element);
+      }
+      return element;
+    };
+
+    /**
+     * Returns if the element is visible.
+     * @return boolean
+     *         True if the element is visible.
+     */
+    Object.defineProperty(element, "visible", {
+      get: function DVP_element_getVisible() {
+        return element.style.display !== "none";
+      },
+      set: function DVP_element_setVisible(value) {
+        if (value) {
+          element.show();
+        } else {
+          element.hide();
+        }
+      }
+    });
+
+    /**
+     * Returns if the element is expanded.
+     * @return boolean
+     *         True if the element is expanded.
+     */
+    Object.defineProperty(element, "expanded", {
+      get: function DVP_element_getExpanded() {
+        return arrow.hasAttribute("open");
+      },
+      set: function DVP_element_setExpanded(value) {
+        if (value) {
+          element.expand();
+        } else {
+          element.collapse();
+        }
+      }
+    });
+
+    /**
+     * Removes all added children in the details container tree.
+     * @return object
+     *         The same element.
+     */
+    element.empty = function DVP_element_empty() {
+      // this details node won't have any elements, so hide the arrow
+      arrow.style.visibility = "hidden";
+      while (details.firstChild) {
+        details.removeChild(details.firstChild);
+      }
+
+      if ("function" === typeof element.onempty) {
+        element.onempty(element);
+      }
+      return element;
+    };
+
+    /**
+     * Removes the element from the parent node details container tree.
+     * @return object
+     *         The same element.
+     */
+    element.remove = function DVP_element_remove() {
+      element.parentNode.removeChild(element);
+
+      if ("function" === typeof element.onremove) {
+        element.onremove(element);
+      }
+      return element;
+    };
+
+    /**
+     * Generic function refreshing the internal state of the element when
+     * it's modified (e.g. a child detail, variable, property is added).
+     *
+     * @param function aFunction
+     *        The function logic used to modify the internal state.
+     * @param array aArguments
+     *        Optional arguments array to be applied to aFunction.
+     */
+    element.refresh = function DVP_element_refresh(aFunction, aArguments) {
+      if ("function" === typeof aFunction) {
+        aFunction.apply(this, aArguments);
+      }
+
+      let node = aParent.parentNode;
+      let arrow = node.querySelector(".arrow");
+      let children = node.querySelector(".details").childNodes.length;
+
+      // if the parent details node has at least one element, set the
+      // expand/collapse arrow visible
+      if (children) {
+        arrow.style.visibility = "visible";
+      } else {
+        arrow.style.visibility = "hidden";
+      }
+    }.bind(this);
+
+    // return the element for later use and customization
+    return element;
+  },
+
+  /**
+   * Returns the global scope container.
+   */
+  get globalScope() {
+    return this._globalScope;
+  },
+
+  /**
+   * Sets the display mode for the global scope container.
+   *
+   * @param boolean value
+   *        False to hide the container, true to show.
+   */
+  set globalScope(value) {
+    if (value) {
+      this._globalScope.show();
+    } else {
+      this._globalScope.hide();
+    }
+  },
+
+  /**
+   * Returns the local scope container.
+   */
+  get localScope() {
+    return this._localScope;
+  },
+
+  /**
+   * Sets the display mode for the local scope container.
+   *
+   * @param boolean value
+   *        False to hide the container, true to show.
+   */
+  set localScope(value) {
+    if (value) {
+      this._localScope.show();
+    } else {
+      this._localScope.hide();
+    }
+  },
+
+  /**
+   * Returns the with block scope container.
+   */
+  get withScope() {
+    return this._withScope;
+  },
+
+  /**
+   * Sets the display mode for the with block scope container.
+   *
+   * @param boolean value
+   *        False to hide the container, true to show.
+   */
+  set withScope(value) {
+    if (value) {
+      this._withScope.show();
+    } else {
+      this._withScope.hide();
+    }
+  },
+
+  /**
+   * Returns the closure scope container.
+   */
+  get closureScope() {
+    return this._closureScope;
+  },
+
+  /**
+   * Sets the display mode for the with block scope container.
+   *
+   * @param boolean value
+   *        False to hide the container, true to show.
+   */
+  set closureScope(value) {
+    if (value) {
+      this._closureScope.show();
+    } else {
+      this._closureScope.hide();
+    }
+  },
+
+  /**
+   * The cached variable properties container.
+   */
+  _vars: null,
+
+  /**
+   * Auto-created global, local, with block and closure scopes containing vars.
+   */
+  _globalScope: null,
+  _localScope: null,
+  _withScope: null,
+  _closureScope: null,
+
+  /**
+   * Initialization function, called when the debugger is initialized.
+   */
+  initialize: function DVP_initialize() {
+    this._vars = document.getElementById("variables");
+    this._localScope = this._addScope(DebuggerView.getStr("localScope")).expand();
+    this._withScope = this._addScope(DebuggerView.getStr("withScope")).hide();
+    this._closureScope = this._addScope(DebuggerView.getStr("closureScope")).hide();
+    this._globalScope = this._addScope(DebuggerView.getStr("globalScope"));
+  },
+
+  /**
+   * Destruction function, called when the debugger is shut down.
+   */
+  destroy: function DVP_destroy() {
+    this._vars = null;
+    this._globalScope = null;
+    this._localScope = null;
+    this._withScope = null;
+    this._closureScope = null;
+  }
+};
+
+/**
+ * Functions handling the html scripts UI.
+ */
+DebuggerView.Scripts = {
+
+  /**
+   * Sets the change event listener for the source scripts container.
+   *
+   * @param function aHandler
+   *        The delegate used as the event listener.
+   */
+  addChangeListener: function DVS_addChangeListener(aHandler) {
+    // Save the handler so it can be removed on shutdown.
+    this._onScriptsChange = aHandler;
+    this._scripts.addEventListener("select", aHandler, false);
+  },
+
+  /**
+   * Removes all elements from the scripts container, leaving it empty.
+   */
+  empty: function DVS_empty() {
+    while (this._scripts.firstChild) {
+      this._scripts.removeChild(this._scripts.firstChild);
+    }
+  },
+
+  /**
+   * 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.
+   *
+   * @param string aUrl
+   *        The script url.
+   * @param string aScript
+   *        The source script.
+   * @param string aScriptNameText
+   *        Optional, title displayed instead of url.
+   * @return object
+   *         The newly created html node representing the added script.
+   */
+  addScript: function DVS_addScript(aUrl, aSource, aScriptNameText) {
+    // make sure we don't duplicate anything
+    if (this._scripts.getElementsByAttribute("value", aUrl).length > 0) {
+      return null;
+    }
+
+    let script = this._scripts.appendItem(aScriptNameText || aUrl, aUrl);
+    script.setUserData("sourceScript", aSource, null);
+    this._scripts.selectedItem = script;
+    return script;
+  },
+
+  /**
+   * The cached click listener for the scripts container.
+   */
+  _onScriptsChange: null,
+
+  /**
+   * The cached scripts container.
+   */
+  _scripts: null,
+
+  /**
+   * Initialization function, called when the debugger is initialized.
+   */
+  initialize: function DVS_initialize() {
+    this._scripts = document.getElementById("scripts");
+  },
+
+  /**
+   * Destruction function, called when the debugger is shut down.
+   */
+  destroy: function DVS_destroy() {
+    this._scripts.removeEventListener("select", this._onScriptsChange, false);
+    this._scripts = null;
+  }
+};
+
+
+let DVF = DebuggerView.Stackframes;
+DVF._onFramesScroll = DVF._onFramesScroll.bind(DVF);
+DVF._onCloseButtonClick = DVF._onCloseButtonClick.bind(DVF);
+DVF._onResumeButtonClick = DVF._onResumeButtonClick.bind(DVF);
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/debugger.css
@@ -0,0 +1,173 @@
+/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ *   Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Dave Camp <dcamp@mozilla.com>
+ *   Victor Porof <vporof@mozilla.com>
+ *   Panos Astithas <past@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Debugger content
+ */
+
+#dbg-content > * > .vbox {
+  cursor: default;
+}
+
+/**
+ * Debugger statusbar
+ */
+
+#dbg-statusbar {
+  -moz-appearance: statusbar;
+}
+
+/**
+ * Stack frames
+ */
+
+#stack {
+  width: 200px;
+}
+
+#stackframes {
+  overflow: auto;
+}
+
+/**
+ * Properties elements
+ */
+
+#properties {
+  width: 250px;
+}
+
+#variables {
+  overflow: auto;
+}
+
+/**
+ * Scope element
+ */
+
+.scope {
+  display: -moz-box;
+  -moz-box-orient: vertical;
+}
+
+.scope > .details {
+  display: none;
+}
+
+.scope > .details[open] {
+  display: -moz-box;
+  -moz-box-orient: vertical;
+}
+
+/**
+ * Variable element
+ */
+
+.variable {
+  display: -moz-box;
+  -moz-box-orient: vertical;
+}
+
+.variable > .title {
+  white-space: nowrap;
+}
+
+.variable > .details {
+  display: none;
+}
+
+.variable > .details[open] {
+  display: -moz-box;
+  -moz-box-orient: vertical;
+}
+
+/**
+ * Property element
+ */
+
+.property {
+  display: -moz-box;
+  -moz-box-orient: vertical;
+}
+
+.property > .title {
+  white-space: nowrap;
+}
+
+.property > .title > .key {
+  display: inline-block;
+}
+
+.property > .title > .value {
+  display: inline-block;
+}
+
+.property > .details {
+  display: none;
+}
+
+.property > .details[open] {
+  display: -moz-box;
+  -moz-box-orient: vertical;
+}
+
+/**
+ * Display helpers
+ */
+
+.hbox {
+  display: -moz-box;
+  -moz-box-orient: horizontal;
+}
+
+.vbox {
+  display: -moz-box;
+  -moz-box-orient: vertical;
+}
+
+.flex {
+  -moz-box-flex: 1;
+}
+
+.unselectable {
+  -moz-user-select: -moz-none;
+  cursor: default;
+}
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/debugger.js
@@ -0,0 +1,513 @@
+/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ *   Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Dave Camp <dcamp@mozilla.com>
+ *   Panos Astithas <past@mozilla.com>
+ *   Victor Porof <vporof@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+"use strict";
+
+var gInitialized = false;
+var gClient = null;
+var gTabClient = null;
+
+
+function initDebugger()
+{
+  window.removeEventListener("DOMContentLoaded", initDebugger, false);
+  if (gInitialized) {
+    return;
+  }
+  gInitialized = true;
+
+  DebuggerView.Stackframes.initialize();
+  DebuggerView.Properties.initialize();
+  DebuggerView.Scripts.initialize();
+}
+
+/**
+ * Called by chrome to set up a debugging session.
+ *
+ * @param DebuggerClient aClient
+ *        The debugger client.
+ * @param object aTabGrip
+ *        The remote protocol grip of the tab.
+ */
+function startDebuggingTab(aClient, aTabGrip)
+{
+  gClient = aClient;
+
+  gClient.attachTab(aTabGrip.actor, function(aResponse, aTabClient) {
+    if (aTabClient) {
+      gTabClient = aTabClient;
+      gClient.attachThread(aResponse.threadActor, function(aResponse, aThreadClient) {
+        if (!aThreadClient) {
+          dump("Couldn't attach to thread: "+aResponse.error+"\n");
+          return;
+        }
+        ThreadState.connect(aThreadClient, function() {
+          StackFrames.connect(aThreadClient, function() {
+            SourceScripts.connect(aThreadClient, function() {
+              aThreadClient.resume();
+            });
+          });
+        });
+      });
+    }
+  });
+}
+
+function shutdownDebugger()
+{
+  window.removeEventListener("unload", shutdownDebugger, false);
+
+  SourceScripts.disconnect();
+  StackFrames.disconnect();
+  ThreadState.disconnect();
+  ThreadState.activeThread = false;
+
+  DebuggerView.Stackframes.destroy();
+  DebuggerView.Properties.destroy();
+  DebuggerView.Scripts.destroy();
+}
+
+
+/**
+ * ThreadState keeps the UI up to date with the state of the
+ * thread (paused/attached/etc.).
+ */
+var ThreadState = {
+  activeThread: null,
+
+  /**
+   * Connect to a thread client.
+   * @param object aThreadClient
+   *        The thread client.
+   * @param function aCallback
+   *        The next function in the initialization sequence.
+   */
+  connect: function TS_connect(aThreadClient, aCallback) {
+    this.activeThread = aThreadClient;
+    aThreadClient.addListener("paused", ThreadState.update);
+    aThreadClient.addListener("resumed", ThreadState.update);
+    aThreadClient.addListener("detached", ThreadState.update);
+    this.update();
+    aCallback && aCallback();
+  },
+
+  /**
+   * Update the UI after a thread state change.
+   */
+  update: function TS_update(aEvent) {
+    DebuggerView.Stackframes.updateState(this.activeThread.state);
+    if (aEvent == "detached") {
+      ThreadState.activeThread = false;
+    }
+  },
+
+  /**
+   * Disconnect from the client.
+   */
+  disconnect: function TS_disconnect() {
+    this.activeThread.removeListener("paused", ThreadState.update);
+    this.activeThread.removeListener("resumed", ThreadState.update);
+    this.activeThread.removeListener("detached", ThreadState.update);
+  }
+};
+
+ThreadState.update = ThreadState.update.bind(ThreadState);
+
+/**
+ * Keeps the stack frame list up-to-date, using the thread client's
+ * stack frame cache.
+ */
+var StackFrames = {
+  pageSize: 25,
+  activeThread: null,
+  selectedFrame: null,
+
+  /**
+   * Watch a given thread client.
+   * @param object aThreadClient
+   *        The thread client.
+   * @param function aCallback
+   *        The next function in the initialization sequence.
+   */
+  connect: function SF_connect(aThreadClient, aCallback) {
+    DebuggerView.Stackframes.addClickListener(this.onClick);
+
+    this.activeThread = aThreadClient;
+    aThreadClient.addListener("paused", this.onPaused);
+    aThreadClient.addListener("framesadded", this.onFrames);
+    aThreadClient.addListener("framescleared", this.onFramesCleared);
+    this.onFramesCleared();
+    aCallback && aCallback();
+  },
+
+  /**
+   * Disconnect from the client.
+   */
+  disconnect: function TS_disconnect() {
+    this.activeThread.removeListener("paused", this.onPaused);
+    this.activeThread.removeListener("framesadded", this.onFrames);
+    this.activeThread.removeListener("framescleared", this.onFramesCleared);
+  },
+
+  /**
+   * Handler for the thread client's paused notification.
+   */
+  onPaused: function SF_onPaused() {
+    this.activeThread.fillFrames(this.pageSize);
+  },
+
+  /**
+   * Handler for the thread client's framesadded notification.
+   */
+  onFrames: function SF_onFrames() {
+    DebuggerView.Stackframes.empty();
+
+    for each (let frame in this.activeThread.cachedFrames) {
+      this._addFramePanel(frame);
+    }
+
+    if (this.activeThread.moreFrames) {
+      DebuggerView.Stackframes.dirty = true;
+    }
+
+    if (!this.selectedFrame) {
+      this.selectFrame(0);
+    }
+  },
+
+  /**
+   * Handler for the thread client's framescleared notification.
+   */
+  onFramesCleared: function SF_onFramesCleared() {
+    DebuggerView.Stackframes.emptyText();
+    this.selectedFrame = null;
+    // Clear the properties as well.
+    DebuggerView.Properties.localScope.empty();
+    DebuggerView.Properties.globalScope.empty();
+  },
+
+  /**
+   * Event handler for clicks on stack frames.
+   */
+  onClick: function SF_onClick(aEvent) {
+    let target = aEvent.target;
+    while (target) {
+      if (target.stackFrame) {
+        this.selectFrame(target.stackFrame.depth);
+        return;
+      }
+      target = target.parentNode;
+    }
+  },
+
+  /**
+   * Marks the stack frame in the specified depth as selected and updates the
+   * properties view with the stack frame's data.
+   *
+   * @param number aDepth
+   *        The depth of the frame in the stack.
+   */
+  selectFrame: function SF_selectFrame(aDepth) {
+    if (this.selectedFrame !== null) {
+      DebuggerView.Stackframes.highlightFrame(this.selectedFrame, false);
+    }
+
+    this.selectedFrame = aDepth;
+    if (aDepth !== null) {
+      DebuggerView.Stackframes.highlightFrame(this.selectedFrame, true);
+    }
+
+    // Display the local variables.
+    let frame = this.activeThread.cachedFrames[aDepth];
+    if (!frame) {
+      return;
+    }
+    let localScope = DebuggerView.Properties.localScope;
+    localScope.empty();
+    // Add "this".
+    if (frame["this"]) {
+      let thisVar = localScope.addVar("this");
+      thisVar.setGrip({ "type": frame["this"].type,
+                        "class": frame["this"].class });
+      this._addExpander(thisVar, frame["this"]);
+    }
+
+    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; i < aResponse.parameters.length; i++) {
+          let param = aResponse.parameters[i];
+          let paramVar = localScope.addVar(param);
+          let paramVal = frame.arguments[i];
+          paramVar.setGrip(paramVal);
+          this._addExpander(paramVar, paramVal);
+        }
+      }.bind(this));
+    }
+  },
+
+  _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" ||
+        (aObject.type != "object" && !Array.isArray(aObject))) {
+      return;
+    }
+    // Add a dummy property to force the twisty to show up.
+    aVar.addProperties({ " ": { value: " " }});
+    aVar.onexpand = this._addVarProperties.bind(this, aVar, aObject);
+  },
+
+  _addVarProperties: function SF_addVarProperties(aVar, aObject) {
+    // Retrieve the properties only once.
+    if (aVar.fetched) {
+      return;
+    }
+    // Clear the placeholder property put in place to display the twisty.
+    aVar.empty();
+
+    // For arrays we have to construct a grip-like object to pass into
+    // addProperties.
+    if (Array.isArray(aObject)) {
+      let properties = { length: { writable: true, value: aObject.length } };
+      for (let i = 0; i < aObject.length; i++) {
+        properties[i + ""] = { value: aObject[i] };
+      }
+      aVar.addProperties(properties);
+      // Expansion handlers must be set after the properties are added.
+      for (let i = 0; i < aObject.length; i++) {
+        this._addExpander(aVar[i + ""], aObject[i]);
+      }
+      aVar.fetched = true;
+      return;
+    }
+
+    let objClient = this.activeThread.pauseGrip(aObject);
+    objClient.getPrototypeAndProperties(function SF_onProtoAndProps(aResponse) {
+      // Add __proto__.
+      if (aResponse.prototype.type != "null") {
+        let properties = {};
+        properties["__proto__ "] = { value: aResponse.prototype };
+        aVar.addProperties(properties);
+        // Expansion handlers must be set after the properties are added.
+        this._addExpander(aVar["__proto__ "], aResponse.prototype);
+      }
+
+      // Sort the rest of the properties before adding them, for better UX.
+      let properties = {};
+      for each (let prop in Object.keys(aResponse.ownProperties).sort()) {
+        properties[prop] = aResponse.ownProperties[prop];
+      }
+      aVar.addProperties(properties);
+      // Expansion handlers must be set after the properties are added.
+      for (let prop in aResponse.ownProperties) {
+        this._addExpander(aVar[prop], aResponse.ownProperties[prop].value);
+      }
+
+      aVar.fetched = true;
+    }.bind(this));
+  },
+
+  /**
+   * Adds the specified stack frame to the list.
+   *
+   * @param Debugger.Frame aFrame
+   *        The new frame to add.
+   */
+  _addFramePanel: function SF_addFramePanel(aFrame) {
+    let depth = aFrame.depth;
+    let idText = "#" + aFrame.depth + " ";
+    let nameText = this._frameTitle(aFrame);
+
+    let panel = DebuggerView.Stackframes.addFrame(depth, idText, nameText);
+
+    if (panel) {
+      panel.stackFrame = aFrame;
+    }
+  },
+
+  /**
+   * Loads more stack frames from the debugger server cache.
+   */
+  _addMoreFrames: function SF_addMoreFrames() {
+    this.activeThread.fillFrames(
+      this.activeThread.cachedFrames.length + this.pageSize);
+  },
+
+  /**
+   * Create a textual representation for the stack frame specified, for
+   * displaying in the stack frame list.
+   *
+   * @param Debugger.Frame aFrame
+   *        The stack frame to label.
+   */
+  _frameTitle: function SF_frameTitle(aFrame) {
+    if (aFrame.type == "call") {
+      return aFrame["calleeName"] ? aFrame["calleeName"] + "()" : "(anonymous)";
+    }
+
+    return "(" + aFrame.type + ")";
+  }
+};
+
+StackFrames.onPaused = StackFrames.onPaused.bind(StackFrames);
+StackFrames.onFrames = StackFrames.onFrames.bind(StackFrames);
+StackFrames.onFramesCleared = StackFrames.onFramesCleared.bind(StackFrames);
+StackFrames.onClick = StackFrames.onClick.bind(StackFrames);
+
+/**
+ * Keeps the source script list up-to-date, using the thread client's
+ * source script cache.
+ */
+var SourceScripts = {
+  pageSize: 25,
+  activeThread: null,
+
+  /**
+   * Watch a given thread client.
+   * @param object aThreadClient
+   *        The thread client.
+   * @param function aCallback
+   *        The next function in the initialization sequence.
+   */
+  connect: function SS_connect(aThreadClient, aCallback) {
+    DebuggerView.Scripts.addChangeListener(this.onChange);
+
+    this.activeThread = aThreadClient;
+    aThreadClient.addListener("paused", this.onPaused);
+    aThreadClient.addListener("scriptsadded", this.onScripts);
+    aThreadClient.addListener("scriptscleared", this.onScriptsCleared);
+    this.onScriptsCleared();
+    aCallback && aCallback();
+  },
+
+  /**
+   * Disconnect from the client.
+   */
+  disconnect: function TS_disconnect() {
+    this.activeThread.removeListener("paused", this.onPaused);
+    this.activeThread.removeListener("scriptsadded", this.onScripts);
+    this.activeThread.removeListener("scriptscleared", this.onScriptsCleared);
+  },
+
+  /**
+   * Handler for the thread client's paused notification.
+   */
+  onPaused: function SS_onPaused() {
+    this.activeThread.fillScripts();
+  },
+
+  /**
+   * Handler for the debugger client's unsolicited newScript notification.
+   */
+  onNewScript: function SS_onNewScript(aNotification, aPacket) {
+    this._addScript({ url: aPacket.url, startLine: aPacket.startLine });
+  },
+
+  /**
+   * Handler for the thread client's scriptsadded notification.
+   */
+  onScripts: function SS_onScripts() {
+    this.onScriptsCleared();
+    for each (let script in this.activeThread.cachedScripts) {
+      this._addScript(script);
+    }
+  },
+
+  /**
+   * Handler for the thread client's scriptscleared notification.
+   */
+  onScriptsCleared: function SS_onScriptsCleared() {
+    DebuggerView.Scripts.empty();
+  },
+
+  /**
+   * Handler for changes on the selected source script.
+   */
+  onChange: function SS_onClick(aEvent) {
+    let scripts = aEvent.target;
+    let script = scripts.selectedItem.getUserData("sourceScript");
+    this._showScript(script);
+  },
+
+  /**
+   * Add the specified script to the list and display it in the editor if the
+   * editor is empty.
+   */
+  _addScript: function SS_addScript(aScript) {
+    DebuggerView.Scripts.addScript(aScript.url, aScript);
+
+    if (window.editor.getCharCount() == 0) {
+      this._showScript(aScript);
+    }
+  },
+
+  /**
+   * Load the editor with the script text if available, otherwise fire an event
+   * to load and display the script text.
+   */
+  _showScript: function SS_showScript(aScript) {
+    if (!aScript.loaded) {
+      // Notify the chrome code that we need to load a script file.
+      var evt = document.createEvent("CustomEvent");
+      evt.initCustomEvent("Debugger:LoadSource", true, false, aScript.url);
+      document.documentElement.dispatchEvent(evt);
+      window.editor.setText(DebuggerView.getStr("loadingText"));
+    } else {
+      window.editor.setText(aScript.text);
+    }
+  }
+};
+
+SourceScripts.onPaused = SourceScripts.onPaused.bind(SourceScripts);
+SourceScripts.onScripts = SourceScripts.onScripts.bind(SourceScripts);
+SourceScripts.onNewScript = SourceScripts.onNewScript.bind(SourceScripts);
+SourceScripts.onScriptsCleared = SourceScripts.onScriptsCleared.bind(SourceScripts);
+SourceScripts.onChange = SourceScripts.onChange.bind(SourceScripts);
+
+window.addEventListener("DOMContentLoaded", initDebugger, false);
+window.addEventListener("unload", shutdownDebugger, false);
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/debugger.xul
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- ***** 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
+   -   Mozilla Foundation.
+   - Portions created by the Initial Developer are Copyright (C) 2011
+   - the Initial Developer. All Rights Reserved.
+   -
+   - Contributor(s):
+   -   Dave Camp <dcamp@mozilla.com>
+   -   Panos Astithas <past@mozilla.com>
+   -   Victor Porof <vporof@mozilla.com>
+   -
+   - Alternatively, the contents of this file may be used under the terms of
+   - either the GNU General Public License Version 2 or later (the "GPL"), or
+   - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+   - in which case the provisions of the GPL or the LGPL are applicable instead
+   - of those above. If you wish to allow use of your version of this file only
+   - under the terms of either the GPL or the LGPL, and not to allow others to
+   - use your version of this file under the terms of the MPL, indicate your
+   - decision by deleting the provisions above and replace them with the notice
+   - and other provisions required by the GPL or the LGPL. If you do not delete
+   - the provisions above, a recipient may use your version of this file under
+   - the terms of any one of the MPL, the GPL or the LGPL.
+   -
+   - ***** END LICENSE BLOCK ***** -->
+<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://browser/content/orion.css" type="text/css"?>
+<?xml-stylesheet href="chrome://browser/content/debugger.css" type="text/css"?>
+<?xml-stylesheet href="chrome://browser/skin/devtools/debugger.css" type="text/css"?>
+<!DOCTYPE window [
+<!ENTITY % debuggerDTD SYSTEM "chrome://browser/locale/devtools/debugger.dtd" >
+ %debuggerDTD;
+]>
+<xul:window xmlns="http://www.w3.org/1999/xhtml"
+            xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+    <xul:script type="text/javascript" src="debugger.js"/>
+    <xul:script type="text/javascript" src="debugger-view.js"/>
+
+    <div id="body" class="vbox flex">
+        <xul:toolbar id="dbg-toolbar">
+            <xul:button id="close">&debuggerUI.closeButton;</xul:button>
+            <xul:button id="resume">&debuggerUI.resumeButton;</xul:button>
+            <xul:menulist id="scripts"/>
+        </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>
+                <div id="editor" class="vbox flex"></div>
+            </div>
+            <div id="properties" class="vbox">
+                <div class="title unselectable">&debuggerUI.propertiesTitle;</div>
+                <div id="variables" class="vbox flex"></div>
+            </div>
+        </div>
+        <div id="dbg-statusbar">
+            <span id="status"></span>
+        </div>
+    </div>
+
+</xul:window>
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/test/Makefile.in
@@ -0,0 +1,90 @@
+# ***** 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
+#   Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2011
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#  Dave Camp <dcamp@mozilla.com>
+#  Victor Porof <vporof@mozilla.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH           = ../../../..
+topsrcdir       = @top_srcdir@
+srcdir          = @srcdir@
+VPATH           = @srcdir@
+relativesrcdir  = browser/devtools/debugger/test
+
+include $(DEPTH)/config/autoconf.mk
+include $(topsrcdir)/config/rules.mk
+
+_BROWSER_TEST_FILES = \
+	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 \
+	browser_dbg_propertyview-01.js \
+	browser_dbg_propertyview-02.js \
+	browser_dbg_propertyview-03.js \
+	browser_dbg_propertyview-04.js \
+	browser_dbg_propertyview-05.js \
+	browser_dbg_propertyview-06.js \
+	browser_dbg_propertyview-07.js \
+	browser_dbg_propertyview-08.js \
+	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_location-changes.js \
+	browser_dbg_script-switching.js \
+	head.js \
+	$(NULL)
+
+_BROWSER_TEST_PAGES = \
+	browser_dbg_tab1.html \
+	browser_dbg_tab2.html \
+	browser_dbg_debuggerstatement.html \
+	browser_dbg_stack.html \
+	browser_dbg_script-switching.html \
+	test-script-switching-01.js \
+	test-script-switching-02.js \
+	browser_dbg_frame-parameters.html \
+	$(NULL)
+
+libs:: $(_BROWSER_TEST_FILES)
+	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
+
+libs:: $(_BROWSER_TEST_PAGES)
+	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/test/browser_dbg_contextactor-01.js
@@ -0,0 +1,49 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Check extension-added context actor lifetimes.
+ */
+
+var gTab1 = null;
+var gTab1Actor = null;
+
+var gClient = null;
+
+function test()
+{
+  DebuggerServer.addActors("chrome://mochitests/content/browser/browser/devtools/debugger/test/testactors.js");
+
+  let transport = DebuggerServer.connectPipe();
+  gClient = new DebuggerClient(transport);
+  gClient.connect(function(aType, aTraits) {
+    is(aType, "browser", "Root actor should identify itself as a browser.");
+    get_tab();
+  });
+}
+
+function get_tab()
+{
+  gTab1 = addTab(TAB1_URL, function() {
+    attach_tab_actor_for_url(gClient, TAB1_URL, function(aGrip) {
+      gTab1Actor = aGrip.actor;
+      gClient.request({ to: aGrip.actor, type: "testContextActor1" }, function(aResponse) {
+        ok(aResponse.actor, "testContextActor1 request should return an actor.");
+        ok(aResponse.actor.indexOf("testone") >= 0,
+           "testContextActor's actorPrefix should be used.");
+        gClient.request({ to: aResponse.actor, type: "ping" }, function(aResponse) {
+          is(aResponse.pong, "pong", "Actor should response to requests.");
+          finish_test();
+        });
+      });
+    });
+  });
+}
+
+function finish_test()
+{
+  gClient.close(function() {
+    removeTab(gTab1);
+    finish();
+  });
+};
new file mode 100644
--- /dev/null
+++ b/browser/devtools/debugger/test/browser_dbg_contextactor-02.js
@@ -0,0 +1,59 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Check extension-added context actor lifetimes.
+ */
+
+var gTab1 = null;
+var gTab1Actor = null;
+
+var gClient = null;
+
+function test()
+{
+  DebuggerServer.addActors("chrome://mochitests/content/browser/browser/devtools/debugger/test/testactors.js");
+
+  let transport = DebuggerServer.connectPipe();
+  gClient = new DebuggerClient(transport);
+  gClient.connect(function(aType, aTraits) {
+    is(aType, "browser", "Root actor should identify itself as a browser.");
+    get_tab();
+  });
+}
+
+function get_tab()
+{
+  gTab1 = addTab(TAB1_URL, function() {
+    get_tab_actor_for_url(gClient, TAB1_URL, function(aGrip) {
+      gTab1Actor = aGrip.actor;
+      gClient.request({ to: gTab1Actor, type: "attach" }, function(aResponse) {
+        gClient.request({ to: gTab1Actor, type: "testContextActor1" }, function(aResponse) {
+          navigate_tab(aResponse.actor);
+        });
+      });
+    });
+  });
+}
+
+function navigate_tab(aTestActor)
+{
+  gClient.addOneTimeListener("tabNavigated", function(aEvent, aResponse) {
+    gClient.request({ to: aTestActor, type: "ping" }, function(aResponse) {
+      // TODO: Currently the client is supposed to clean up after tabNavigated
+      // events. We should remove this check, or even better, remove the whole
+      // test.
+      todo(aResponse.error, "noSuchActor", "testContextActor1 should have gone away with the navigation.");
+      finish_test();
+    });
+  });
+  gTab1.linkedBrowser.loadURI(TAB2_URL);
+}