Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Wed, 08 Feb 2012 19:13:56 -0800
changeset 112101 ed637f826ef6c4c5e32cce51d6477203dd2b9d50
parent 112100 63d066d8186beffe54bbb76d6f7e093854795733 (current diff)
parent 89299 7c0ba1c98ff7f87127602ef33c0736acb0dce1e8 (diff)
child 112102 151228e4adeb28caecb40a2aa09b3bd3b9b517cc
push id1708
push userakeybl@mozilla.com
push dateMon, 19 Nov 2012 21:10:21 +0000
treeherdermozilla-beta@27b14fe50103 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone13.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge from mozilla-central.
accessible/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()