Merge from mozilla-central. Unfortunately, PA does not work as of this merge
authorNicholas D. Matsakis <nmatsakis@mozilla.com>
Wed, 31 Oct 2012 10:30:12 -0700
changeset 112018 6c4dcc6a6cfc
parent 110078 da1354451b1e (current diff)
parent 112017 3393586a210b (diff)
child 112019 81a8c5b7fd9f
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
milestone19.0a1
Merge from mozilla-central. Unfortunately, PA does not work as of this merge (at least in Debug mode) due to some of the GC infrastructure changes.
accessible/src/msaa/nsHTMLWin32ObjectAccessible.cpp
accessible/src/msaa/nsHTMLWin32ObjectAccessible.h
browser/components/privatebrowsing/test/browser/browser_console_clear.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_beforeunload.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_certexceptionsui.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_commandline_toggle.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_concurrent.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_concurrent_page.html
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_cookieacceptdialog.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_crh.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_downloadmonitor.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_fastswitch.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_findbar.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_forgetthissite.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_geoprompt_page.html
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_import.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_lastpbcontextexited.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_before_after.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_before_after_page.html
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_before_after_page2.html
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_page1.html
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_localStorage_page2.html
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_newwindow_stopcmd.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_openLocationLastURL.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_opendir.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_openlocation.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_pageinfo.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_placestitle.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_popupblocker.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_popupmode.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_protocolhandler.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_protocolhandler_page.html
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_searchbar.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_sslsite_transition.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_theming.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_transition.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_ui.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_urlbarfocus.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_urlbarundo.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_viewsource.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_windowtitle.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_windowtitle_page.html
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_zoom.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_zoomrestore.js
browser/components/privatebrowsing/test/browser/ctxmenu-image.png
browser/components/privatebrowsing/test/browser/ctxmenu.html
browser/components/privatebrowsing/test/browser/head.js
browser/components/privatebrowsing/test/browser/popup.html
browser/components/privatebrowsing/test/browser/staller.sjs
browser/components/privatebrowsing/test/browser/title.sjs
browser/components/safebrowsing/SafeBrowsing.jsm
browser/components/safebrowsing/content/blockedSite.xhtml
browser/components/safebrowsing/content/report-phishing-overlay.xul
browser/components/safebrowsing/jar.mn
caps/idl/nsISignatureVerifier.idl
content/base/src/nsStubImageDecoderObserver.cpp
content/base/src/nsStubImageDecoderObserver.h
content/canvas/src/CustomQS_Canvas.h
content/canvas/src/CustomQS_Canvas2D.h
content/canvas/src/nsCanvasRenderingContext2D.cpp
content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
content/canvas/src/nsCanvasRenderingContext2DAzure.h
content/events/src/nsDOMWifiEvent.cpp
content/events/src/nsDOMWifiEvent.h
dom/bluetooth/BluetoothUtils.h
dom/identity/tests/head_identity.js
dom/identity/tests/test_identity_idp_auth_basics.html
dom/identity/tests/test_identity_idp_prov_basics.html
dom/identity/tests/test_identity_rp_basics.html
dom/imptests/webapps/DOMCore/tests/submissions/Ms2ger/test_DOMImplementation-hasFeature.html
dom/interfaces/css/nsIDOMCSS2Properties.idl
dom/interfaces/events/nsIWifiEventInits.idl
dom/system/gonk/TimeSetting.cpp
dom/system/gonk/TimeSetting.h
dom/tests/mochitest/dom-level2-core/test_domimplementationhasfeature02.html
dom/tests/mochitest/dom-level2-core/test_isSupported01.html
dom/tests/mochitest/dom-level2-core/test_isSupported02.html
dom/tests/mochitest/dom-level2-core/test_nodeissupported03.html
dom/tests/mochitest/dom-level2-core/test_nodeissupported05.html
intl/uconv/tests/unit/test_decode_x_mac_roman.js
intl/uconv/tests/unit/test_encode_x_mac_roman.js
js/public/Utility.h
js/src/Makefile.in
js/src/builtin/ParallelArray.cpp
js/src/gc/Heap.h
js/src/ion/Bailouts.cpp
js/src/ion/CodeGenerator.cpp
js/src/ion/CodeGenerator.h
js/src/ion/Ion.cpp
js/src/ion/Ion.h
js/src/ion/IonBuilder.cpp
js/src/ion/IonBuilder.h
js/src/ion/IonCaches.cpp
js/src/ion/IonFrames.cpp
js/src/ion/LIR-Common.h
js/src/ion/LIR.h
js/src/ion/LOpcodes.h
js/src/ion/Lowering.cpp
js/src/ion/Lowering.h
js/src/ion/MIR.cpp
js/src/ion/MIR.h
js/src/ion/MOpcodes.h
js/src/ion/TypeOracle.h
js/src/ion/VMFunctions.cpp
js/src/ion/VMFunctions.h
js/src/ion/arm/Trampoline-arm.cpp
js/src/ion/shared/CodeGenerator-shared.cpp
js/src/ion/shared/CodeGenerator-shared.h
js/src/ion/shared/CodeGenerator-x86-shared.cpp
js/src/ion/shared/CodeGenerator-x86-shared.h
js/src/ion/x64/Trampoline-x64.cpp
js/src/ion/x86/Trampoline-x86.cpp
js/src/jit-test/tests/debug/Debugger-debuggees-07.js
js/src/js.msg
js/src/jsapi-tests/testUTF8.cpp
js/src/jsapi.cpp
js/src/jsarray.cpp
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jsdbgapi.cpp
js/src/jsfun.cpp
js/src/jsgc.cpp
js/src/jsgc.h
js/src/jsgcinlines.h
js/src/jsinfer.cpp
js/src/jsinferinlines.h
js/src/jsinterpinlines.h
js/src/jsiter.cpp
js/src/jsmemorymetrics.cpp
js/src/jsobj.cpp
js/src/jsparcompile.cpp
js/src/jsprvtd.h
js/src/jsscript.cpp
js/src/jsscript.h
js/src/jsstr.cpp
js/src/jstaskset.cpp
js/src/methodjit/Compiler.cpp
js/src/methodjit/InvokeHelpers.cpp
js/src/methodjit/MonoIC.cpp
js/src/methodjit/StubCalls.cpp
js/src/shell/Makefile.in
js/src/shell/js.cpp
js/xpconnect/src/codegen.py
js/xpconnect/src/dombindings.conf
js/xpconnect/src/dombindings.cpp
js/xpconnect/src/dombindings.h
js/xpconnect/src/dombindingsgen.py
js/xpconnect/tests/mochitest/test_bug361111.xul
js/xpconnect/tests/mochitest/test_bug760131.html
layout/base/nsFrameIterator.cpp
layout/base/nsFrameIterator.h
layout/reftests/flexbox/flexbox-align-self-horiz-1.xhtml
mfbt/double-conversion/more-architectures.patch
mobile/android/base/AboutHomeContent.java.in
mobile/android/base/android-sync-files.mk
mobile/android/base/sync/log/writers/SingleTagLogWriter.java
mobile/android/sync/README.txt
mobile/android/sync/android-drawable-hdpi-resources.mn
mobile/android/sync/android-drawable-ldpi-resources.mn
mobile/android/sync/android-drawable-mdpi-resources.mn
mobile/android/sync/android-drawable-resources.mn
mobile/android/sync/android-layout-resources.mn
mobile/android/sync/android-values-resources.mn
mobile/android/sync/java-sources.mn
mobile/android/sync/java-third-party-sources.mn
mobile/android/sync/manifests/SyncAndroidManifest_activities.xml.in
mobile/android/sync/manifests/SyncAndroidManifest_permissions.xml.in
mobile/android/sync/manifests/SyncAndroidManifest_services.xml.in
mobile/android/sync/preprocess-sources.mn
mobile/android/sync/strings.xml.in
other-licenses/nsis/Contrib/CityHash/cityhash/city.cc
other-licenses/nsis/Contrib/CityHash/cityhash/stdint.h
python/virtualenv/virtualenv_support/distribute-0.6.27.tar.gz
python/virtualenv/virtualenv_support/pip-1.1.tar.gz
security/manager/tools/getHSTSPreloadList.py
security/patches/bug-797572
testing/mozbase/mozdevice/mozdevice/sutcli.py
toolkit/components/osfile/osfileutils.cpp
toolkit/components/osfile/osfileutils.h
toolkit/components/satchel/test/unit/test_bug_248970.js
toolkit/content/tests/unit/test_privatebrowsing_downloadLastDir_c.js
toolkit/identity/tests/mochitest/head_identity.js
toolkit/identity/tests/mochitest/test_authentication.html
toolkit/identity/tests/mochitest/test_provisioning.html
toolkit/identity/tests/mochitest/test_relying_party.html
toolkit/mozapps/downloads/tests/unit/test_DownloadLastDir.js
toolkit/mozapps/downloads/tests/unit/test_DownloadLastDirWithCPS.js
toolkit/mozapps/downloads/tests/unit/test_privatebrowsing_downloadLastDir.js
xpcom/base/dmd.h
--- a/Makefile.in
+++ b/Makefile.in
@@ -43,18 +43,20 @@ ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
 tier_base_dirs += \
   other-licenses/android \
   $(NULL)
 endif
 
 ifdef MOZ_MEMORY
 tier_base_dirs += memory/mozjemalloc
 ifdef MOZ_JEMALLOC
+ifndef MOZ_NATIVE_JEMALLOC
 tier_base_dirs += memory/jemalloc
 endif
+endif
 tier_base_dirs += memory/build
 endif
 ifndef MOZ_NATIVE_ZLIB
 tier_base_dirs += modules/zlib
 endif
 tier_base_dirs += \
   mozglue \
   memory/mozalloc \
@@ -75,17 +77,17 @@ DIST_GARBAGE = config.cache config.log c
    netwerk/necko-config.h xpcom/xpcom-config.h xpcom/xpcom-private.h \
    $(topsrcdir)/.mozconfig.mk $(topsrcdir)/.mozconfig.out
 
 default alldep all:: $(topsrcdir)/configure config.status
 	$(RM) -r $(DIST)/sdk
 	$(RM) -r $(DIST)/include
 	$(RM) -r $(DIST)/private
 	$(RM) -r $(DIST)/public
-	$(RM) $(DIST)/chrome.manifest
+	$(RM) $(DIST)/bin/chrome.manifest $(DIST)/bin/components/components.manifest
 	$(RM) -r _tests
 
 $(topsrcdir)/configure: $(topsrcdir)/configure.in
 	@echo "STOP!  configure.in has changed, and your configure is out of date."
 	@echo "Please rerun autoconf and re-configure your build directory."
 	@echo "To ignore this message, touch 'configure' in the source directory,"
 	@echo "but your build might not succeed."
 	@exit 1
--- a/accessible/src/atk/AccessibleWrap.cpp
+++ b/accessible/src/atk/AccessibleWrap.cpp
@@ -737,32 +737,30 @@ ConvertToAtkAttributeSet(nsIPersistentPr
 
     //libspi will free it
     return objAttributeSet;
 }
 
 AtkAttributeSet*
 GetAttributeSet(Accessible* aAccessible)
 {
-    nsCOMPtr<nsIPersistentProperties> attributes;
-    aAccessible->GetAttributes(getter_AddRefs(attributes));
-
-    if (attributes) {
-        // Deal with attributes that we only need to expose in ATK
-        if (aAccessible->State() & states::HASPOPUP) {
-          // There is no ATK state for haspopup, must use object attribute to expose the same info
-          nsAutoString oldValueUnused;
-          attributes->SetStringProperty(NS_LITERAL_CSTRING("haspopup"), NS_LITERAL_STRING("true"),
-                                        oldValueUnused);
-        }
-
-        return ConvertToAtkAttributeSet(attributes);
+  nsCOMPtr<nsIPersistentProperties> attributes = aAccessible->Attributes();
+  if (attributes) {
+    // There is no ATK state for haspopup, must use object attribute to expose
+    // the same info.
+    if (aAccessible->State() & states::HASPOPUP) {
+      nsAutoString unused;
+      attributes->SetStringProperty(NS_LITERAL_CSTRING("haspopup"),
+                                    NS_LITERAL_STRING("true"), unused);
     }
 
-    return nullptr;
+    return ConvertToAtkAttributeSet(attributes);
+  }
+
+  return nullptr;
 }
 
 AtkAttributeSet *
 getAttributesCB(AtkObject *aAtkObj)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
   return accWrap ? GetAttributeSet(accWrap) : nullptr;
 }
--- a/accessible/src/atk/AtkSocketAccessible.cpp
+++ b/accessible/src/atk/AtkSocketAccessible.cpp
@@ -4,16 +4,17 @@
  * 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 <atk/atk.h>
 #include "AtkSocketAccessible.h"
 
 #include "InterfaceInitFuncs.h"
 #include "nsMai.h"
+#include "mozilla/Likely.h"
 
 AtkSocketEmbedType AtkSocketAccessible::g_atk_socket_embed = NULL;
 GType AtkSocketAccessible::g_atk_socket_type = G_TYPE_INVALID;
 const char* AtkSocketAccessible::sATKSocketEmbedSymbol = "atk_socket_embed";
 const char* AtkSocketAccessible::sATKSocketGetTypeSymbol = "atk_socket_get_type";
 
 bool AtkSocketAccessible::gCanEmbed = FALSE;
 
@@ -100,17 +101,17 @@ GetExtents(AtkComponent* aComponent, gin
                    aX, aY, aWidth, aHeight, aCoordType);
 }
 }
 
 void
 mai_atk_component_iface_init(AtkComponentIface* aIface)
 {
   NS_ASSERTION(aIface, "Invalid Interface");
-  if (NS_UNLIKELY(!aIface))
+  if (MOZ_UNLIKELY(!aIface))
     return;
 
   aIface->ref_accessible_at_point = RefAccessibleAtPoint;
   aIface->get_extents = GetExtents;
 }
 
 AtkSocketAccessible::AtkSocketAccessible(nsIContent* aContent,
                                          DocAccessible* aDoc,
--- a/accessible/src/atk/RootAccessibleWrap.cpp
+++ b/accessible/src/atk/RootAccessibleWrap.cpp
@@ -5,24 +5,20 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "RootAccessibleWrap.h"
 
 #include "nsMai.h"
 
 using namespace mozilla::a11y;
 
-NativeRootAccessibleWrap::NativeRootAccessibleWrap(AtkObject* aAccessible):
-  RootAccessible(nullptr, nullptr, nullptr)
+GtkWindowAccessible::GtkWindowAccessible(AtkObject* aAccessible) :
+  DummyAccessible()
 {
-  // XXX: mark the object as defunct to ensure no single internal method is
-  // running on it.
-  mFlags |= eIsDefunct;
-
   g_object_ref(aAccessible);
   mAtkObject = aAccessible;
 }
 
-NativeRootAccessibleWrap::~NativeRootAccessibleWrap()
+GtkWindowAccessible::~GtkWindowAccessible()
 {
   g_object_unref(mAtkObject);
   mAtkObject = nullptr;
 }
--- a/accessible/src/atk/RootAccessibleWrap.h
+++ b/accessible/src/atk/RootAccessibleWrap.h
@@ -2,32 +2,33 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #ifndef mozilla_a11y_RootAccessibleWrap_h__
 #define mozilla_a11y_RootAccessibleWrap_h__
 
+#include "BaseAccessibles.h"
 #include "RootAccessible.h"
 
 namespace mozilla {
 namespace a11y {
 
 typedef RootAccessible RootAccessibleWrap;
 
-/* NativeRootAccessibleWrap is the accessible class for gtk+ native window.
- * The instance of NativeRootAccessibleWrap is a child of MaiAppRoot instance.
+/* GtkWindowAccessible is the accessible class for gtk+ native window.
+ * The instance of GtkWindowAccessible is a child of MaiAppRoot instance.
  * It is added into root when the toplevel window is created, and removed
  * from root when the toplevel window is destroyed.
  */
-class NativeRootAccessibleWrap : public RootAccessible
+class GtkWindowAccessible MOZ_FINAL : public DummyAccessible
 {
 public:
-  NativeRootAccessibleWrap(AtkObject* aAccessible);
-  virtual ~NativeRootAccessibleWrap();
+  GtkWindowAccessible(AtkObject* aAccessible);
+  virtual ~GtkWindowAccessible();
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif   /* mozilla_a11y_Root_Accessible_Wrap_h__ */
 
--- a/accessible/src/atk/nsMaiInterfaceAction.cpp
+++ b/accessible/src/atk/nsMaiInterfaceAction.cpp
@@ -4,16 +4,17 @@
  * 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 "InterfaceInitFuncs.h"
 
 #include "Accessible-inl.h"
 #include "nsMai.h"
 #include "Role.h"
+#include "mozilla/Likely.h"
 
 #include "nsString.h"
 
 using namespace mozilla::a11y;
 
 extern "C" {
 
 static gboolean
@@ -111,17 +112,17 @@ getKeyBindingCB(AtkAction *aAction, gint
   return AccessibleWrap::ReturnString(keyBindingsStr);
 }
 }
 
 void
 actionInterfaceInitCB(AtkActionIface* aIface)
 {
   NS_ASSERTION(aIface, "Invalid aIface");
-  if (NS_UNLIKELY(!aIface))
+  if (MOZ_UNLIKELY(!aIface))
     return;
 
   aIface->do_action = doActionCB;
   aIface->get_n_actions = getActionCountCB;
   aIface->get_description = getActionDescriptionCB;
   aIface->get_keybinding = getKeyBindingCB;
   aIface->get_name = getActionNameCB;
 }
--- a/accessible/src/atk/nsMaiInterfaceComponent.cpp
+++ b/accessible/src/atk/nsMaiInterfaceComponent.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "InterfaceInitFuncs.h"
 
 #include "AccessibleWrap.h"
 #include "nsAccUtils.h"
 #include "nsCoreUtils.h"
 #include "nsMai.h"
+#include "mozilla/Likely.h"
 
 extern "C" {
 
 static AtkObject*
 refAccessibleAtPointCB(AtkComponent* aComponent, gint aAccX, gint aAccY,
                        AtkCoordType aCoordType)
 {
   return refAccessibleAtPointHelper(GetAccessibleWrap(ATK_OBJECT(aComponent)),
@@ -95,17 +96,17 @@ getExtentsHelper(AccessibleWrap* aAccWra
   *aWidth = width;
   *aHeight = height;
 }
 
 void
 componentInterfaceInitCB(AtkComponentIface* aIface)
 {
   NS_ASSERTION(aIface, "Invalid Interface");
-  if(NS_UNLIKELY(!aIface))
+  if(MOZ_UNLIKELY(!aIface))
     return;
 
   /*
    * Use default implementation in atk for contains, get_position,
    * and get_size
    */
   aIface->ref_accessible_at_point = refAccessibleAtPointCB;
   aIface->get_extents = getExtentsCB;
--- a/accessible/src/atk/nsMaiInterfaceDocument.cpp
+++ b/accessible/src/atk/nsMaiInterfaceDocument.cpp
@@ -4,16 +4,17 @@
  * 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 "InterfaceInitFuncs.h"
 
 #include "AccessibleWrap.h"
 #include "DocAccessible.h"
 #include "nsMai.h"
+#include "mozilla/Likely.h"
 
 static const char* const kDocTypeName = "W3C-doctype";
 static const char* const kDocUrlName = "DocURL";
 static const char* const kMimeTypeName = "MimeType";
 
 // below functions are vfuncs on an ATK  interface so they need to be C call
 extern "C" {
 
@@ -21,17 +22,17 @@ static const gchar* getDocumentLocaleCB(
 static AtkAttributeSet* getDocumentAttributesCB(AtkDocument* aDocument);
 static const gchar* getDocumentAttributeValueCB(AtkDocument* aDocument,
                                                 const gchar* aAttrName);
 
 void
 documentInterfaceInitCB(AtkDocumentIface *aIface)
 {
     NS_ASSERTION(aIface, "Invalid Interface");
-    if(NS_UNLIKELY(!aIface))
+    if(MOZ_UNLIKELY(!aIface))
         return;
 
     /*
      * We don't support get_document or set_attribute right now.
      * get_document_type is deprecated, we return DocType in
      * get_document_attribute_value and get_document_attributes instead.
      */
     aIface->get_document_attributes = getDocumentAttributesCB;
--- a/accessible/src/atk/nsMaiInterfaceEditableText.cpp
+++ b/accessible/src/atk/nsMaiInterfaceEditableText.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "InterfaceInitFuncs.h"
 
 #include "HyperTextAccessible.h"
 #include "nsMai.h"
 
 #include "nsString.h"
+#include "mozilla/Likely.h"
 
 extern "C" {
 static void
 setTextContentsCB(AtkEditableText *aText, const gchar *aString)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
   if (!accWrap)
     return;
@@ -111,17 +112,17 @@ pasteTextCB(AtkEditableText *aText, gint
   text->PasteText(aPosition);
 }
 }
 
 void
 editableTextInterfaceInitCB(AtkEditableTextIface* aIface)
 {
   NS_ASSERTION(aIface, "Invalid aIface");
-  if (NS_UNLIKELY(!aIface))
+  if (MOZ_UNLIKELY(!aIface))
     return;
 
   aIface->set_text_contents = setTextContentsCB;
   aIface->insert_text = insertTextCB;
   aIface->copy_text = copyTextCB;
   aIface->cut_text = cutTextCB;
   aIface->delete_text = deleteTextCB;
   aIface->paste_text = pasteTextCB;
--- a/accessible/src/atk/nsMaiInterfaceHyperlinkImpl.cpp
+++ b/accessible/src/atk/nsMaiInterfaceHyperlinkImpl.cpp
@@ -2,16 +2,17 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* 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 "InterfaceInitFuncs.h"
 
 #include "nsMaiHyperlink.h"
+#include "mozilla/Likely.h"
 
 extern "C" {
 static AtkHyperlink*
 getHyperlinkCB(AtkHyperlinkImpl* aImpl)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aImpl));
   if (!accWrap)
     return nullptr;
@@ -23,13 +24,13 @@ getHyperlinkCB(AtkHyperlinkImpl* aImpl)
   return maiHyperlink->GetAtkHyperlink();
 }
 }
 
 void
 hyperlinkImplInterfaceInitCB(AtkHyperlinkImplIface *aIface)
 {
   NS_ASSERTION(aIface, "no interface!");
-  if (NS_UNLIKELY(!aIface))
+  if (MOZ_UNLIKELY(!aIface))
     return;
 
   aIface->get_hyperlink = getHyperlinkCB;
 }
--- a/accessible/src/atk/nsMaiInterfaceHypertext.cpp
+++ b/accessible/src/atk/nsMaiInterfaceHypertext.cpp
@@ -4,16 +4,17 @@
  * 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 "InterfaceInitFuncs.h"
 
 #include "HyperTextAccessible.h"
 #include "nsMai.h"
 #include "nsMaiHyperlink.h"
+#include "mozilla/Likely.h"
 
 extern "C" {
 
 static AtkHyperlink*
 getLinkCB(AtkHypertext *aText, gint aLinkIndex)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
   if (!accWrap)
@@ -65,15 +66,15 @@ getLinkIndexCB(AtkHypertext *aText, gint
   return index;
 }
 }
 
 void
 hypertextInterfaceInitCB(AtkHypertextIface* aIface)
 {
   NS_ASSERTION(aIface, "no interface!");
-  if (NS_UNLIKELY(!aIface))
+  if (MOZ_UNLIKELY(!aIface))
     return;
 
   aIface->get_link = getLinkCB;
   aIface->get_n_links = getLinkCountCB;
   aIface->get_link_index = getLinkIndexCB;
 }
--- a/accessible/src/atk/nsMaiInterfaceImage.cpp
+++ b/accessible/src/atk/nsMaiInterfaceImage.cpp
@@ -3,16 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "InterfaceInitFuncs.h"
 
 #include "AccessibleWrap.h"
 #include "ImageAccessible.h"
+#include "mozilla/Likely.h"
 #include "nsMai.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 extern "C" {
 const gchar* getDescriptionCB(AtkObject* aAtkObj);
 
@@ -48,15 +49,15 @@ getImageSizeCB(AtkImage* aImage, gint* a
   accWrap->AsImage()->GetImageSize(aAccWidth, aAccHeight);
 }
 }
 
 void
 imageInterfaceInitCB(AtkImageIface* aIface)
 {
   NS_ASSERTION(aIface, "no interface!");
-  if (NS_UNLIKELY(!aIface))
+  if (MOZ_UNLIKELY(!aIface))
     return;
 
   aIface->get_image_position = getImagePositionCB;
   aIface->get_image_description = getImageDescriptionCB;
   aIface->get_image_size = getImageSizeCB;
 }
--- a/accessible/src/atk/nsMaiInterfaceSelection.cpp
+++ b/accessible/src/atk/nsMaiInterfaceSelection.cpp
@@ -3,16 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "InterfaceInitFuncs.h"
 
 #include "AccessibleWrap.h"
 #include "nsMai.h"
+#include "mozilla/Likely.h"
 
 #include <atk/atk.h>
 
 extern "C" {
 
 static gboolean
 addSelectionCB(AtkSelection *aSelection, gint i)
 {
@@ -91,17 +92,17 @@ selectAllSelectionCB(AtkSelection *aSele
   return accWrap->SelectAll();
 }
 }
 
 void
 selectionInterfaceInitCB(AtkSelectionIface* aIface)
 {
   NS_ASSERTION(aIface, "Invalid aIface");
-  if (NS_UNLIKELY(!aIface))
+  if (MOZ_UNLIKELY(!aIface))
     return;
 
   aIface->add_selection = addSelectionCB;
   aIface->clear_selection = clearSelectionCB;
   aIface->ref_selection = refSelectionCB;
   aIface->get_selection_count = getSelectionCountCB;
   aIface->is_child_selected = isChildSelectedCB;
   aIface->remove_selection = removeSelectionCB;
--- a/accessible/src/atk/nsMaiInterfaceTable.cpp
+++ b/accessible/src/atk/nsMaiInterfaceTable.cpp
@@ -10,16 +10,18 @@
 #include "AccessibleWrap.h"
 #include "nsAccUtils.h"
 #include "TableAccessible.h"
 #include "TableCellAccessible.h"
 #include "nsMai.h"
 
 #include "nsArrayUtils.h"
 
+#include "mozilla/Likely.h"
+
 using namespace mozilla::a11y;
 
 extern "C" {
 static AtkObject*
 refAtCB(AtkTable* aTable, gint aRowIdx, gint aColIdx)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
   if (!accWrap || aRowIdx < 0 || aColIdx < 0)
@@ -288,17 +290,17 @@ isCellSelectedCB(AtkTable *aTable, gint 
       IsCellSelected(aRowIdx, aColIdx));
 }
 }
 
 void
 tableInterfaceInitCB(AtkTableIface* aIface)
 {
   NS_ASSERTION(aIface, "no interface!");
-  if (NS_UNLIKELY(!aIface))
+  if (MOZ_UNLIKELY(!aIface))
     return;
 
   aIface->ref_at = refAtCB;
   aIface->get_index_at = getIndexAtCB;
   aIface->get_column_at_index = getColumnAtIndexCB;
   aIface->get_row_at_index = getRowAtIndexCB;
   aIface->get_n_columns = getColumnCountCB;
   aIface->get_n_rows = getRowCountCB;
--- a/accessible/src/atk/nsMaiInterfaceText.cpp
+++ b/accessible/src/atk/nsMaiInterfaceText.cpp
@@ -6,16 +6,18 @@
 
 #include "InterfaceInitFuncs.h"
 
 #include "HyperTextAccessible.h"
 #include "nsMai.h"
 
 #include "nsIPersistentProperties2.h"
 
+#include "mozilla/Likely.h"
+
 using namespace mozilla::a11y;
 
 AtkAttributeSet* ConvertToAtkAttributeSet(nsIPersistentProperties* aAttributes);
 
 static void
 ConvertTexttoAsterisks(AccessibleWrap* accWrap, nsAString& aString)
 {
   // convert each char to "*" when it's "password text" 
@@ -441,17 +443,17 @@ setCaretOffsetCB(AtkText *aText, gint aO
     return NS_SUCCEEDED(rv) ? TRUE : FALSE;
 }
 }
 
 void
 textInterfaceInitCB(AtkTextIface* aIface)
 {
   NS_ASSERTION(aIface, "Invalid aIface");
-  if (NS_UNLIKELY(!aIface))
+  if (MOZ_UNLIKELY(!aIface))
     return;
 
   aIface->get_text = getTextCB;
   aIface->get_text_after_offset = getTextAfterOffsetCB;
   aIface->get_text_at_offset = getTextAtOffsetCB;
   aIface->get_character_at_offset = getCharacterAtOffsetCB;
   aIface->get_text_before_offset = getTextBeforeOffsetCB;
   aIface->get_caret_offset = getCaretOffsetCB;
--- a/accessible/src/atk/nsMaiInterfaceValue.cpp
+++ b/accessible/src/atk/nsMaiInterfaceValue.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* 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 "InterfaceInitFuncs.h"
+#include "mozilla/Likely.h"
 
 #include "AccessibleWrap.h"
 #include "nsMai.h"
 
 extern "C" {
 
 static void
 getCurrentValueCB(AtkValue *obj, GValue *value)
@@ -111,17 +112,17 @@ setCurrentValueCB(AtkValue *obj, const G
     return !NS_FAILED(accValue->SetCurrentValue(accDouble));
 }
 }
 
 void
 valueInterfaceInitCB(AtkValueIface* aIface)
 {
   NS_ASSERTION(aIface, "Invalid aIface");
-  if (NS_UNLIKELY(!aIface))
+  if (MOZ_UNLIKELY(!aIface))
     return;
 
   aIface->get_current_value = getCurrentValueCB;
   aIface->get_maximum_value = getMaximumValueCB;
   aIface->get_minimum_value = getMinimumValueCB;
   aIface->get_minimum_increment = getMinimumIncrementCB;
   aIface->set_current_value = setCurrentValueCB;
 }
--- a/accessible/src/base/AccEvent.h
+++ b/accessible/src/base/AccEvent.h
@@ -57,17 +57,17 @@ public:
      // eDoNotEmit : This event is confirmed as a duplicate, do not emit it.
      eDoNotEmit
   };
 
   // Initialize with an nsIAccessible
   AccEvent(uint32_t aEventType, Accessible* aAccessible,
            EIsFromUserInput aIsFromUserInput = eAutoDetect,
            EEventRule aEventRule = eRemoveDupes);
-  // Initialize with an nsIDOMNode
+  // Initialize with an nsINode
   AccEvent(uint32_t aEventType, nsINode* aNode,
            EIsFromUserInput aIsFromUserInput = eAutoDetect,
            EEventRule aEventRule = eRemoveDupes);
   virtual ~AccEvent() {}
 
   // AccEvent
   uint32_t GetEventType() const { return mEventType; }
   EEventRule GetEventRule() const { return mEventRule; }
new file mode 100644
--- /dev/null
+++ b/accessible/src/base/AccTypes.h
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#pragma once
+
+namespace mozilla {
+namespace a11y {
+
+/**
+ * Accessible object types used when creating an accessible based on the frame.
+ */
+enum AccType {
+  eNoAccessible,
+  eHTMLBRAccessible,
+  eHTMLButtonAccessible,
+  eHTMLCanvasAccessible,
+  eHTMLCaptionAccessible,
+  eHTMLCheckboxAccessible,
+  eHTMLComboboxAccessible,
+  eHTMLFileInputAccessible,
+  eHTMLGroupboxAccessible,
+  eHTMLHRAccessible,
+  eHTMLImageMapAccessible,
+  eHTMLLabelAccessible,
+  eHTMLLiAccessible,
+  eHTMLSelectListAccessible,
+  eHTMLMediaAccessible,
+  eHTMLObjectFrameAccessible,
+  eHTMLRadioButtonAccessible,
+  eHTMLTableAccessible,
+  eHTMLTableCellAccessible,
+  eHTMLTableRowAccessible,
+  eHTMLTextFieldAccessible,
+  eHyperTextAccessible,
+  eImageAccessible,
+  eOuterDocAccessible,
+  eTextLeafAccessible
+};
+}
+}
+
--- a/accessible/src/base/Logging.cpp
+++ b/accessible/src/base/Logging.cpp
@@ -157,23 +157,27 @@ LogDocState(nsIDocument* aDocumentNode)
       break;
   }
 
   printf("doc state: %s", docState);
   printf(", %sinitial", aDocumentNode->IsInitialDocument() ? "" : "not ");
   printf(", %sshowing", aDocumentNode->IsShowing() ? "" : "not ");
   printf(", %svisible", aDocumentNode->IsVisible() ? "" : "not ");
   printf(", %sactive", aDocumentNode->IsActive() ? "" : "not ");
+  printf(", %sresource", aDocumentNode->IsResourceDoc() ? "" : "not ");
+  printf(", has %srole content",
+         nsCoreUtils::GetRoleContent(aDocumentNode) ? "" : "no ");
 }
 
 static void
 LogPresShell(nsIDocument* aDocumentNode)
 {
   nsIPresShell* ps = aDocumentNode->GetShell();
-  printf("presshell: %p", static_cast<void*>(ps));
+  printf("presshell: %p, is %s destroying", static_cast<void*>(ps),
+         (ps->IsDestroying() ? "" : "not"));
   nsIScrollableFrame *sf = ps ?
     ps->GetRootScrollFrameAsScrollableExternal() : nullptr;
   printf(", root scroll frame: %p", static_cast<void*>(sf));
 }
 
 static void
 LogDocLoadGroup(nsIDocument* aDocumentNode)
 {
@@ -421,21 +425,21 @@ logging::DocLoad(const char* aMsg, nsIDo
 }
 
 void
 logging::DocCompleteLoad(DocAccessible* aDocument, bool aIsLoadEventTarget)
 {
   MsgBegin(sDocLoadTitle, "document loaded *completely*");
 
   printf("    DOM document: %p, acc document: %p\n",
-         static_cast<void*>(aDocument->GetDocumentNode()),
+         static_cast<void*>(aDocument->DocumentNode()),
          static_cast<void*>(aDocument));
 
   printf("    ");
-  LogDocURI(aDocument->GetDocumentNode());
+  LogDocURI(aDocument->DocumentNode());
   printf("\n");
 
   printf("    ");
   LogDocAccState(aDocument);
   printf("\n");
 
   printf("    document is load event target: %s\n",
          (aIsLoadEventTarget ? "true" : "false"));
@@ -526,17 +530,17 @@ void
 logging::FocusNotificationTarget(const char* aMsg, const char* aTargetDescr,
                                  nsISupports* aTargetThing)
 {
   MsgBegin(sFocusTitle, aMsg);
 
   if (aTargetThing) {
     nsCOMPtr<nsINode> targetNode(do_QueryInterface(aTargetThing));
     if (targetNode)
-      Node(aTargetDescr, targetNode);
+      AccessibleNNode(aTargetDescr, targetNode);
     else
       printf("    %s: %p, window\n", aTargetDescr,
              static_cast<void*>(aTargetThing));
   }
 
   MsgEnd();
 }
 
@@ -651,17 +655,17 @@ void
 logging::Address(const char* aDescr, Accessible* aAcc)
 {
   if (!aAcc->IsDoc()) {
     printf("    %s accessible: %p, node: %p\n", aDescr,
            static_cast<void*>(aAcc), static_cast<void*>(aAcc->GetNode()));
   }
 
   DocAccessible* doc = aAcc->Document();
-  nsIDocument* docNode = aAcc->GetDocumentNode();
+  nsIDocument* docNode = doc->DocumentNode();
   printf("    document: %p, node: %p\n",
          static_cast<void*>(doc), static_cast<void*>(docNode));
 
   printf("    ");
   LogDocURI(docNode);
   printf("\n");
 }
 
@@ -675,17 +679,17 @@ logging::Node(const char* aDescr, nsINod
     return;
   }
 
   if (aNode->IsNodeOfType(nsINode::eDOCUMENT)) {
     printf("%s: %p, document\n", aDescr, static_cast<void*>(aNode));
     return;
   }
 
-  nsINode* parentNode = aNode->GetNodeParent();
+  nsINode* parentNode = aNode->GetParentNode();
   int32_t idxInParent = parentNode ? parentNode->IndexOf(aNode) : - 1;
 
   if (aNode->IsNodeOfType(nsINode::eTEXT)) {
     printf("%s: %p, text node, idx in parent: %d\n",
            aDescr, static_cast<void*>(aNode), idxInParent);
     return;
   }
 
@@ -705,16 +709,28 @@ logging::Node(const char* aDescr, nsINod
   if (idAtom)
     idAtom->ToUTF8String(id);
 
   printf("%s: %p, %s@id='%s', idx in parent: %d\n",
          aDescr, static_cast<void*>(elm), tag.get(), id.get(), idxInParent);
 }
 
 void
+logging::Document(DocAccessible* aDocument)
+{
+  printf("    Document: %p, document node: %p\n",
+         static_cast<void*>(aDocument),
+         static_cast<void*>(aDocument->DocumentNode()));
+
+  printf("    Document ");
+  LogDocURI(aDocument->DocumentNode());
+  printf("\n");
+}
+
+void
 logging::AccessibleNNode(const char* aDescr, Accessible* aAccessible)
 {
   printf("    %s: %p; ", aDescr, static_cast<void*>(aAccessible));
   if (!aAccessible)
     return;
 
   nsAutoString role;
   GetAccService()->GetStringRole(aAccessible->Role(), role);
@@ -723,42 +739,45 @@ logging::AccessibleNNode(const char* aDe
 
   printf("role: %s, name: '%s';\n", NS_ConvertUTF16toUTF8(role).get(),
          NS_ConvertUTF16toUTF8(name).get());
 
   nsAutoCString nodeDescr(aDescr);
   nodeDescr.AppendLiteral(" node");
   Node(nodeDescr.get(), aAccessible->GetNode());
 
-  printf("    Document: %p, document node: %p\n",
-         static_cast<void*>(aAccessible->Document()),
-         static_cast<void*>(aAccessible->GetDocumentNode()));
-
-  printf("    Document ");
-  LogDocURI(static_cast<nsIDocument*>(aAccessible->GetDocumentNode()));
-  printf("\n");
+  Document(aAccessible->Document());
 }
 
 void
 logging::AccessibleNNode(const char* aDescr, nsINode* aNode)
 {
   DocAccessible* document =
     GetAccService()->GetDocAccessible(aNode->OwnerDoc());
 
   if (document) {
     Accessible* accessible = document->GetAccessible(aNode);
     if (accessible) {
       AccessibleNNode(aDescr, accessible);
       return;
     }
   }
 
-  nsAutoCString nodeDescr("Not accessible ");
+  nsAutoCString nodeDescr("[not accessible] ");
   nodeDescr.Append(aDescr);
   Node(nodeDescr.get(), aNode);
+
+  if (document) {
+    Document(document);
+    return;
+  }
+
+  printf("    [contained by not accessible document]:\n");
+  LogDocInfo(aNode->OwnerDoc(), document);
+  printf("\n");
 }
 
 void
 logging::DOMEvent(const char* aDescr, nsINode* aOrigTarget,
                   const nsAString& aEventType)
 {
   logging::MsgBegin("DOMEvents", "event '%s' %s",
                     NS_ConvertUTF16toUTF8(aEventType).get(), aDescr);
--- a/accessible/src/base/Logging.h
+++ b/accessible/src/base/Logging.h
@@ -146,16 +146,21 @@ void Text(const char* aText);
 void Address(const char* aDescr, Accessible* aAcc);
 
 /**
  * Log the DOM node info as message entry.
  */
 void Node(const char* aDescr, nsINode* aNode);
 
 /**
+ * Log the document accessible info as message entry.
+ */
+void Document(DocAccessible* aDocument);
+
+/**
  * Log the accessible and its DOM node as a message entry.
  */
 void AccessibleNNode(const char* aDescr, Accessible* aAccessible);
 void AccessibleNNode(const char* aDescr, nsINode* aNode);
 
 /**
  * Log the DOM event.
  */
--- a/accessible/src/base/Makefile.in
+++ b/accessible/src/base/Makefile.in
@@ -53,16 +53,17 @@ EXPORTS = \
   nsAccessibilityService.h \
   nsAccessNode.h \
   $(NULL)
 
 EXPORTS_NAMESPACES = mozilla/a11y
 
 EXPORTS_mozilla/a11y = \
   FocusManager.h \
+  AccTypes.h \
   States.h \
   Role.h \
   $(NULL)
 
 ifdef MOZ_DEBUG
 EXPORTS_mozilla/a11y += \
   Logging.h \
   $(NULL)
--- a/accessible/src/base/NotificationController.cpp
+++ b/accessible/src/base/NotificationController.cpp
@@ -238,18 +238,18 @@ NotificationController::WillRefresh(mozi
 
   // Bind hanging child documents.
   uint32_t hangingDocCnt = mHangingChildDocuments.Length();
   for (uint32_t idx = 0; idx < hangingDocCnt; idx++) {
     DocAccessible* childDoc = mHangingChildDocuments[idx];
     if (childDoc->IsDefunct())
       continue;
 
-    nsIContent* ownerContent = mDocument->GetDocumentNode()->
-      FindContentForSubDocument(childDoc->GetDocumentNode());
+    nsIContent* ownerContent = mDocument->DocumentNode()->
+      FindContentForSubDocument(childDoc->DocumentNode());
     if (ownerContent) {
       Accessible* outerDocAcc = mDocument->GetAccessible(ownerContent);
       if (outerDocAcc && outerDocAcc->AppendChild(childDoc)) {
         if (mDocument->AppendChildDocument(childDoc))
           continue;
 
         outerDocAcc->RemoveChild(childDoc);
       }
@@ -419,18 +419,18 @@ NotificationController::CoalesceEvents()
         }
 
         // Ignore events unattached from DOM since we don't coalesce them.
         if (!thisEvent->mNode->IsInDoc())
           continue;
 
         // Coalesce events by sibling targets (this is a case for reorder
         // events).
-        if (thisEvent->mNode->GetNodeParent() ==
-            tailEvent->mNode->GetNodeParent()) {
+        if (thisEvent->mNode->GetParentNode() ==
+            tailEvent->mNode->GetParentNode()) {
           tailEvent->mEventRule = thisEvent->mEventRule;
           return;
         }
 
         // This and tail events can be anywhere in the tree, make assumptions
         // for mutation events.
 
         // Coalesce tail event if tail node is descendant of this node. Stop
@@ -516,17 +516,17 @@ void
 NotificationController::ApplyToSiblings(uint32_t aStart, uint32_t aEnd,
                                         uint32_t aEventType, nsINode* aNode,
                                         AccEvent::EEventRule aEventRule)
 {
   for (uint32_t index = aStart; index < aEnd; index ++) {
     AccEvent* accEvent = mEvents[index];
     if (accEvent->mEventType == aEventType &&
         accEvent->mEventRule != AccEvent::eDoNotEmit && accEvent->mNode &&
-        accEvent->mNode->GetNodeParent() == aNode->GetNodeParent()) {
+        accEvent->mNode->GetParentNode() == aNode->GetParentNode()) {
       accEvent->mEventRule = aEventRule;
     }
   }
 }
 
 void
 NotificationController::CoalesceSelChangeEvents(AccSelChangeEvent* aTailEvent,
                                                 AccSelChangeEvent* aThisEvent,
@@ -700,17 +700,17 @@ NotificationController::TextEnumerator(n
                                        void* aUserArg)
 {
   DocAccessible* document = static_cast<DocAccessible*>(aUserArg);
   nsIContent* textNode = aEntry->GetKey();
   Accessible* textAcc = document->GetAccessible(textNode);
 
   // If the text node is not in tree or doesn't have frame then this case should
   // have been handled already by content removal notifications.
-  nsINode* containerNode = textNode->GetNodeParent();
+  nsINode* containerNode = textNode->GetParentNode();
   if (!containerNode) {
     NS_ASSERTION(!textAcc,
                  "Text node was removed but accessible is kept alive!");
     return PL_DHASH_NEXT;
   }
 
   nsIFrame* textFrame = textNode->GetPrimaryFrame();
   if (!textFrame) {
--- a/accessible/src/base/nsARIAMap.h
+++ b/accessible/src/base/nsARIAMap.h
@@ -87,25 +87,25 @@ const bool kUseMapRole = true;
 const bool kUseNativeRole = false;
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // ARIA attribute characteristic masks
 
 /**
  * This mask indicates the attribute should not be exposed as an object
- * attribute via the catch-all logic in Accessible::GetAttributes.
+ * attribute via the catch-all logic in Accessible::Attributes().
  * This means it either isn't mean't to be exposed as an object attribute, or
  * that it should, but is already handled in other code.
  */
 const uint8_t ATTR_BYPASSOBJ  = 0x0001;
 
 /**
  * This mask indicates the attribute is expected to have an NMTOKEN or bool value.
- * (See for example usage in Accessible::GetAttributes)
+ * (See for example usage in Accessible::Attributes())
  */
 const uint8_t ATTR_VALTOKEN   = 0x0010;
 
 /**
  * Small footprint storage of persistent aria attribute characteristics.
  */
 struct nsAttributeCharacteristics
 {
--- a/accessible/src/base/nsAccDocManager.cpp
+++ b/accessible/src/base/nsAccDocManager.cpp
@@ -354,37 +354,32 @@ nsAccDocManager::CreateDocOrRootAccessib
       aDocument->IsResourceDoc() || !aDocument->IsActive())
     return nullptr;
 
   // Ignore documents without presshell and not having root frame.
   nsIPresShell* presShell = aDocument->GetShell();
   if (!presShell || !presShell->GetRootFrame() || presShell->IsDestroying())
     return nullptr;
 
-  // Do not create document accessible until role content is loaded, otherwise
-  // we get accessible document with wrong role.
-  nsIContent *rootElm = nsCoreUtils::GetRoleContent(aDocument);
-  if (!rootElm)
-    return nullptr;
-
   bool isRootDoc = nsCoreUtils::IsRootDocument(aDocument);
 
   DocAccessible* parentDocAcc = nullptr;
   if (!isRootDoc) {
     // XXXaaronl: ideally we would traverse the presshell chain. Since there's
     // no easy way to do that, we cheat and use the document hierarchy.
     parentDocAcc = GetDocAccessible(aDocument->GetParentDocument());
     NS_ASSERTION(parentDocAcc,
                  "Can't create an accessible for the document!");
     if (!parentDocAcc)
       return nullptr;
   }
 
   // We only create root accessibles for the true root, otherwise create a
   // doc accessible.
+  nsIContent *rootElm = nsCoreUtils::GetRoleContent(aDocument);
   nsRefPtr<DocAccessible> docAcc = isRootDoc ?
     new RootAccessibleWrap(aDocument, rootElm, presShell) :
     new DocAccessibleWrap(aDocument, rootElm, presShell);
 
   // Cache the document accessible into document cache.
   mDocAccessibleCache.Put(aDocument, docAcc);
 
   // Initialize the document accessible.
--- a/accessible/src/base/nsAccDocManager.h
+++ b/accessible/src/base/nsAccDocManager.h
@@ -35,17 +35,24 @@ public:
    */
   DocAccessible* GetDocAccessible(nsIDocument* aDocument);
 
   /**
    * Return document accessible for the given presshell.
    */
   DocAccessible* GetDocAccessible(const nsIPresShell* aPresShell)
   {
-    return aPresShell ? GetDocAccessible(aPresShell->GetDocument()) : nullptr;
+    if (!aPresShell)
+      return nullptr;
+
+    DocAccessible* doc = aPresShell->GetDocAccessible();
+    if (doc)
+      return doc;
+
+    return GetDocAccessible(aPresShell->GetDocument());
   }
 
   /**
    * Search through all document accessibles for an accessible with the given
    * unique id.
    */
   Accessible* FindAccessibleInCache(nsINode* aNode) const;
 
--- a/accessible/src/base/nsAccTreeWalker.cpp
+++ b/accessible/src/base/nsAccTreeWalker.cpp
@@ -69,17 +69,17 @@ nsAccTreeWalker::NextChildInternal(bool 
   if (!mState->childList)
     mState->childList = mState->content->GetChildren(mChildFilter);
 
   uint32_t length = 0;
   if (mState->childList)
     mState->childList->GetLength(&length);
 
   while (mState->childIdx < length) {
-    nsIContent* childNode = mState->childList->GetNodeAt(mState->childIdx);
+    nsIContent* childNode = mState->childList->Item(mState->childIdx);
     mState->childIdx++;
 
     bool isSubtreeHidden = false;
     Accessible* accessible = mWalkCache ? mDoc->GetAccessible(childNode) :
       GetAccService()->GetOrCreateAccessible(childNode, mDoc, &isSubtreeHidden);
 
     if (accessible)
       return accessible;
--- a/accessible/src/base/nsAccUtils.cpp
+++ b/accessible/src/base/nsAccUtils.cpp
@@ -376,18 +376,19 @@ nsAccUtils::GetScreenCoordsForParent(nsA
   Accessible* parent = document->GetContainerAccessible(aAccessNode->GetNode());
   if (!parent)
     return nsIntPoint(0, 0);
 
   nsIFrame *parentFrame = parent->GetFrame();
   if (!parentFrame)
     return nsIntPoint(0, 0);
 
-  nsIntRect parentRect = parentFrame->GetScreenRectExternal();
-  return nsIntPoint(parentRect.x, parentRect.y);
+  nsRect rect = parentFrame->GetScreenRectInAppUnits();
+  return nsPoint(rect.x, rect.y).
+    ToNearestPixels(parentFrame->PresContext()->AppUnitsPerDevPixel());
 }
 
 uint8_t
 nsAccUtils::GetAttributeCharacteristics(nsIAtom* aAtom)
 {
     for (uint32_t i = 0; i < nsARIAMap::gWAIUnivAttrMapLength; i++)
       if (*nsARIAMap::gWAIUnivAttrMap[i].attributeName == aAtom)
         return nsARIAMap::gWAIUnivAttrMap[i].characteristics;
--- a/accessible/src/base/nsAccUtils.h
+++ b/accessible/src/base/nsAccUtils.h
@@ -11,17 +11,16 @@
 #include "nsIAccessibleText.h"
 
 #include "nsAccessibilityService.h"
 #include "nsCoreUtils.h"
 
 #include "mozilla/dom/Element.h"
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
-#include "nsIDOMNode.h"
 #include "nsIPersistentProperties2.h"
 #include "nsIPresShell.h"
 #include "nsPoint.h"
 
 class nsAccessNode;
 class Accessible;
 class HyperTextAccessible;
 class DocAccessible;
--- a/accessible/src/base/nsAccessNode.cpp
+++ b/accessible/src/base/nsAccessNode.cpp
@@ -78,17 +78,17 @@ nsAccessNode::Shutdown()
   mContent = nullptr;
   mDoc = nullptr;
 }
 
 RootAccessible*
 nsAccessNode::RootAccessible() const
 {
   nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
-    nsCoreUtils::GetDocShellTreeItemFor(mContent);
+    nsCoreUtils::GetDocShellTreeItemFor(GetNode());
   NS_ASSERTION(docShellTreeItem, "No docshell tree item for mContent");
   if (!docShellTreeItem) {
     return nullptr;
   }
   nsCOMPtr<nsIDocShellTreeItem> root;
   docShellTreeItem->GetRootTreeItem(getter_AddRefs(root));
   NS_ASSERTION(root, "No root content tree item");
   if (!root) {
@@ -106,29 +106,23 @@ nsAccessNode::GetFrame() const
 }
 
 nsINode*
 nsAccessNode::GetNode() const
 {
   return mContent;
 }
 
-nsIDocument*
-nsAccessNode::GetDocumentNode() const
-{
-  return mContent ? mContent->OwnerDoc() : nullptr;
-}
-
 void
 nsAccessNode::Language(nsAString& aLanguage)
 {
   aLanguage.Truncate();
 
   if (!mDoc)
     return;
 
   nsCoreUtils::GetLanguageFor(mContent, nullptr, aLanguage);
   if (aLanguage.IsEmpty()) { // Nothing found, so use document's language
-    mContent->OwnerDoc()->GetHeaderData(nsGkAtoms::headerContentLanguage,
+    mDoc->DocumentNode()->GetHeaderData(nsGkAtoms::headerContentLanguage,
                                         aLanguage);
   }
 }
 
--- a/accessible/src/base/nsAccessNode.h
+++ b/accessible/src/base/nsAccessNode.h
@@ -59,17 +59,16 @@ public:
    * Return frame for the given access node object.
    */
   virtual nsIFrame* GetFrame() const;
   /**
    * Return DOM node associated with the accessible.
    */
   virtual nsINode* GetNode() const;
   nsIContent* GetContent() const { return mContent; }
-  virtual nsIDocument* GetDocumentNode() const;
 
   /**
    * Return node type information of DOM node associated with the accessible.
    */
   bool IsContent() const
   {
     return GetNode() && GetNode()->IsNodeOfType(nsINode::eCONTENT);
   }
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -4,19 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsAccessibilityService.h"
 
 // NOTE: alphabetically ordered
 #include "Accessible-inl.h"
 #include "ApplicationAccessibleWrap.h"
 #include "ARIAGridAccessibleWrap.h"
-#ifdef MOZ_ACCESSIBILITY_ATK
-#include "AtkSocketAccessible.h"
-#endif
 #include "DocAccessible-inl.h"
 #include "FocusManager.h"
 #include "HTMLCanvasAccessible.h"
 #include "HTMLElementAccessibles.h"
 #include "HTMLImageMapAccessible.h"
 #include "HTMLLinkAccessible.h"
 #include "HTMLListAccessible.h"
 #include "HTMLSelectAccessible.h"
@@ -29,20 +26,25 @@
 #include "nsIAccessibleProvider.h"
 #include "nsXFormsFormControlsAccessible.h"
 #include "nsXFormsWidgetsAccessible.h"
 #include "OuterDocAccessible.h"
 #include "Role.h"
 #include "RootAccessibleWrap.h"
 #include "States.h"
 #include "Statistics.h"
+#include "TextLeafAccessibleWrap.h"
+
+#ifdef MOZ_ACCESSIBILITY_ATK
+#include "AtkSocketAccessible.h"
+#endif
+
 #ifdef XP_WIN
-#include "nsHTMLWin32ObjectAccessible.h"
+#include "HTMLWin32ObjectAccessible.h"
 #endif
-#include "TextLeafAccessibleWrap.h"
 
 #ifdef A11Y_LOG
 #include "Logging.h"
 #endif
 
 #ifdef MOZ_CRASHREPORTER
 #include "nsExceptionHandler.h"
 #endif
@@ -161,312 +163,81 @@ nsAccessibilityService::GetRootDocumentA
       return aCanCreate ?
         GetDocAccessible(documentNode) : GetDocAccessibleFromCache(documentNode);
     }
   }
   return nullptr;
 }
 
 already_AddRefed<Accessible>
-nsAccessibilityService::CreateOuterDocAccessible(nsIContent* aContent,
-                                                 nsIPresShell* aPresShell)
-{
-  Accessible* accessible =
-    new OuterDocAccessible(aContent, GetDocAccessible(aPresShell));
-  NS_ADDREF(accessible);
-  return accessible;
-}
-
-already_AddRefed<Accessible>
-nsAccessibilityService::CreateHTMLButtonAccessible(nsIContent* aContent,
-                                                   nsIPresShell* aPresShell)
-{
-  Accessible* accessible =
-    new HTMLButtonAccessible(aContent, GetDocAccessible(aPresShell));
-  NS_ADDREF(accessible);
-  return accessible;
-}
-
-already_AddRefed<Accessible>
-nsAccessibilityService::CreateHTMLLIAccessible(nsIContent* aContent,
-                                               nsIPresShell* aPresShell)
-{
-  Accessible* accessible =
-    new HTMLLIAccessible(aContent, GetDocAccessible(aPresShell));
-  NS_ADDREF(accessible);
-  return accessible;
-}
-
-already_AddRefed<Accessible>
-nsAccessibilityService::CreateHyperTextAccessible(nsIContent* aContent,
-                                                  nsIPresShell* aPresShell)
-{
-  Accessible* accessible =
-    new HyperTextAccessibleWrap(aContent, GetDocAccessible(aPresShell));
-  NS_ADDREF(accessible);
-  return accessible;
-}
-
-already_AddRefed<Accessible>
-nsAccessibilityService::CreateHTMLCheckboxAccessible(nsIContent* aContent,
-                                                     nsIPresShell* aPresShell)
-{
-  Accessible* accessible =
-    new HTMLCheckboxAccessible(aContent, GetDocAccessible(aPresShell));
-  NS_ADDREF(accessible);
-  return accessible;
-}
-
-already_AddRefed<Accessible>
-nsAccessibilityService::CreateHTMLComboboxAccessible(nsIContent* aContent,
-                                                     nsIPresShell* aPresShell)
-{
-  Accessible* accessible =
-    new HTMLComboboxAccessible(aContent, GetDocAccessible(aPresShell));
-  NS_ADDREF(accessible);
-  return accessible;
-}
-
-already_AddRefed<Accessible>
-nsAccessibilityService::CreateHTMLCanvasAccessible(nsIContent* aContent,
-                                                   nsIPresShell* aPresShell)
-{
-  Accessible* accessible =
-    new HTMLCanvasAccessible(aContent, GetDocAccessible(aPresShell));
-  NS_ADDREF(accessible);
-  return accessible;
-}
-
-already_AddRefed<Accessible>
-nsAccessibilityService::CreateHTMLFileInputAccessible(nsIContent* aContent,
-                                                      nsIPresShell* aPresShell)
-{
-  Accessible* accessible =
-    new HTMLFileInputAccessible(aContent, GetDocAccessible(aPresShell));
-  NS_ADDREF(accessible);
-  return accessible;
-}
-
-already_AddRefed<Accessible>
-nsAccessibilityService::CreateHTMLImageAccessible(nsIContent* aContent,
-                                                  nsIPresShell* aPresShell)
-{
-  Accessible* accessible =
-    new ImageAccessibleWrap(aContent, GetDocAccessible(aPresShell));
-  NS_ADDREF(accessible);
-  return accessible;
-}
-
-already_AddRefed<Accessible>
-nsAccessibilityService::CreateHTMLImageMapAccessible(nsIContent* aContent,
-                                                     nsIPresShell* aPresShell)
-{
-  Accessible* accessible =
-    new HTMLImageMapAccessible(aContent, GetDocAccessible(aPresShell));
-  NS_ADDREF(accessible);
-  return accessible;
-}
-
-already_AddRefed<Accessible>
-nsAccessibilityService::CreateHTMLGroupboxAccessible(nsIContent* aContent,
-                                                     nsIPresShell* aPresShell)
-{
-  Accessible* accessible =
-    new HTMLGroupboxAccessible(aContent, GetDocAccessible(aPresShell));
-  NS_ADDREF(accessible);
-  return accessible;
-}
-
-already_AddRefed<Accessible>
-nsAccessibilityService::CreateHTMLListboxAccessible(nsIContent* aContent,
-                                                    nsIPresShell* aPresShell)
-{
-  Accessible* accessible =
-    new HTMLSelectListAccessible(aContent, GetDocAccessible(aPresShell));
-  NS_ADDREF(accessible);
-  return accessible;
-}
-
-already_AddRefed<Accessible>
-nsAccessibilityService::CreateHTMLMediaAccessible(nsIContent* aContent,
-                                                  nsIPresShell* aPresShell)
-{
-  Accessible* accessible =
-    new EnumRoleAccessible(aContent, GetDocAccessible(aPresShell),
-                           roles::GROUPING);
-  NS_ADDREF(accessible);
-  return accessible;
-}
-
-already_AddRefed<Accessible>
 nsAccessibilityService::CreateHTMLObjectFrameAccessible(nsObjectFrame* aFrame,
                                                         nsIContent* aContent,
-                                                        nsIPresShell* aPresShell)
+                                                        DocAccessible* aDoc)
 {
   // We can have several cases here:
   // 1) a text or html embedded document where the contentDocument variable in
   //    the object element holds the content;
   // 2) web content that uses a plugin, which means we will have to go to
   //    the plugin to get the accessible content;
   // 3) an image or imagemap, where the image frame points back to the object
   //    element DOMNode.
 
   if (aFrame->GetRect().IsEmpty())
     return nullptr;
 
-
   // 1) for object elements containing either HTML or TXT documents
   nsCOMPtr<nsIDOMHTMLObjectElement> obj(do_QueryInterface(aContent));
   if (obj) {
     nsCOMPtr<nsIDOMDocument> domDoc;
     obj->GetContentDocument(getter_AddRefs(domDoc));
-    if (domDoc)
-      return CreateOuterDocAccessible(aContent, aPresShell);
+    if (domDoc) {
+      Accessible* newAcc = new OuterDocAccessible(aContent, aDoc);
+      NS_ADDREF(newAcc);
+      return newAcc;
+    }
   }
 
 #if defined(XP_WIN) || defined(MOZ_ACCESSIBILITY_ATK)
   // 2) for plugins
   nsRefPtr<nsNPAPIPluginInstance> pluginInstance;
   if (NS_SUCCEEDED(aFrame->GetPluginInstance(getter_AddRefs(pluginInstance))) &&
       pluginInstance) {
 #ifdef XP_WIN
     // Note: pluginPort will be null if windowless.
     HWND pluginPort = nullptr;
     aFrame->GetPluginPort(&pluginPort);
 
     Accessible* accessible =
-      new nsHTMLWin32ObjectOwnerAccessible(aContent,
-                                           GetDocAccessible(aPresShell),
-                                           pluginPort);
+      new HTMLWin32ObjectOwnerAccessible(aContent, aDoc, pluginPort);
     NS_ADDREF(accessible);
     return accessible;
 
 #elif MOZ_ACCESSIBILITY_ATK
     if (!AtkSocketAccessible::gCanEmbed)
       return nullptr;
 
     nsCString plugId;
     nsresult rv = pluginInstance->GetValueFromPlugin(
       NPPVpluginNativeAccessibleAtkPlugId, &plugId);
     if (NS_SUCCEEDED(rv) && !plugId.IsEmpty()) {
       AtkSocketAccessible* socketAccessible =
-        new AtkSocketAccessible(aContent, GetDocAccessible(aPresShell),
-                                plugId);
+        new AtkSocketAccessible(aContent, aDoc, plugId);
 
       NS_ADDREF(socketAccessible);
       return socketAccessible;
     }
 #endif
   }
 #endif
 
   // 3) for images and imagemaps, or anything else with a child frame
   // we have the object frame, get the image frame
-  nsIFrame* frame = aFrame->GetFirstPrincipalChild();
-  return frame ? frame->CreateAccessible() : nullptr;
-}
-
-already_AddRefed<Accessible>
-nsAccessibilityService::CreateHTMLRadioButtonAccessible(nsIContent* aContent,
-                                                        nsIPresShell* aPresShell)
-{
-  Accessible* accessible =
-    new HTMLRadioButtonAccessible(aContent, GetDocAccessible(aPresShell));
-  NS_ADDREF(accessible);
-  return accessible;
-}
-
-already_AddRefed<Accessible>
-nsAccessibilityService::CreateHTMLTableAccessible(nsIContent* aContent,
-                                                  nsIPresShell* aPresShell)
-{
-  Accessible* accessible =
-    new HTMLTableAccessibleWrap(aContent, GetDocAccessible(aPresShell));
-  NS_ADDREF(accessible);
-  return accessible;
-}
-
-already_AddRefed<Accessible>
-nsAccessibilityService::CreateHTMLTableCellAccessible(nsIContent* aContent,
-                                                      nsIPresShell* aPresShell)
-{
-  Accessible* accessible =
-    new HTMLTableCellAccessibleWrap(aContent, GetDocAccessible(aPresShell));
-  NS_ADDREF(accessible);
-  return accessible;
-}
-
-already_AddRefed<Accessible>
-nsAccessibilityService::CreateHTMLTableRowAccessible(nsIContent* aContent,
-                                                     nsIPresShell* aPresShell)
-{
-  Accessible* accessible =
-    new EnumRoleAccessible(aContent, GetDocAccessible(aPresShell), roles::ROW);
-  NS_ADDREF(accessible);
-  return accessible;
-}
-
-already_AddRefed<Accessible>
-nsAccessibilityService::CreateTextLeafAccessible(nsIContent* aContent,
-                                                 nsIPresShell* aPresShell)
-{
-  Accessible* accessible =
-    new TextLeafAccessibleWrap(aContent, GetDocAccessible(aPresShell));
-  NS_ADDREF(accessible);
-  return accessible;
-}
-
-already_AddRefed<Accessible>
-nsAccessibilityService::CreateHTMLTextFieldAccessible(nsIContent* aContent,
-                                                      nsIPresShell* aPresShell)
-{
-  Accessible* accessible =
-    new HTMLTextFieldAccessible(aContent, GetDocAccessible(aPresShell));
-  NS_ADDREF(accessible);
-  return accessible;
-}
-
-already_AddRefed<Accessible>
-nsAccessibilityService::CreateHTMLLabelAccessible(nsIContent* aContent,
-                                                  nsIPresShell* aPresShell)
-{
-  Accessible* accessible =
-    new HTMLLabelAccessible(aContent, GetDocAccessible(aPresShell));
-  NS_ADDREF(accessible);
-  return accessible;
-}
-
-already_AddRefed<Accessible>
-nsAccessibilityService::CreateHTMLHRAccessible(nsIContent* aContent,
-                                               nsIPresShell* aPresShell)
-{
-  Accessible* accessible =
-    new HTMLHRAccessible(aContent, GetDocAccessible(aPresShell));
-  NS_ADDREF(accessible);
-  return accessible;
-}
-
-already_AddRefed<Accessible>
-nsAccessibilityService::CreateHTMLBRAccessible(nsIContent* aContent,
-                                               nsIPresShell* aPresShell)
-{
-  Accessible* accessible =
-    new HTMLBRAccessible(aContent, GetDocAccessible(aPresShell));
-  NS_ADDREF(accessible);
-  return accessible;
-}
-
-already_AddRefed<Accessible>
-nsAccessibilityService::CreateHTMLCaptionAccessible(nsIContent* aContent,
-                                                    nsIPresShell* aPresShell)
-{
-  Accessible* accessible =
-    new HTMLCaptionAccessible(aContent, GetDocAccessible(aPresShell));
-  NS_ADDREF(accessible);
-  return accessible;
+  nsIFrame* childFrame = aFrame->GetFirstPrincipalChild();
+  return childFrame ? CreateAccessibleByFrameType(childFrame, aContent, aDoc) :
+    nullptr;
 }
 
 void
 nsAccessibilityService::ContentRangeInserted(nsIPresShell* aPresShell,
                                              nsIContent* aContainer,
                                              nsIContent* aStartChild,
                                              nsIContent* aEndChild)
 {
@@ -891,17 +662,17 @@ nsAccessibilityService::GetOrCreateAcces
   }
 
   // We have a content node.
   if (!aNode->IsInDoc()) {
     NS_WARNING("Creating accessible for node with no document");
     return nullptr;
   }
 
-  if (aNode->OwnerDoc() != aDoc->GetDocumentNode()) {
+  if (aNode->OwnerDoc() != aDoc->DocumentNode()) {
     NS_ERROR("Creating accessible for wrong document");
     return nullptr;
   }
 
   if (!aNode->IsContent())
     return nullptr;
 
   nsIContent* content = aNode->AsContent();
@@ -947,17 +718,17 @@ nsAccessibilityService::GetOrCreateAcces
     frame->GetRenderedText(&text, nullptr, nullptr, 0, UINT32_MAX);
     if (text.IsEmpty()) {
       if (aIsSubtreeHidden)
         *aIsSubtreeHidden = true;
 
       return nullptr;
     }
 
-    newAcc = frame->CreateAccessible();
+    newAcc = CreateAccessibleByFrameType(frame, content, aDoc);
     if (aDoc->BindToDocument(newAcc, nullptr)) {
       newAcc->AsTextLeaf()->SetText(text);
       return newAcc;
     }
 
     return nullptr;
   }
 
@@ -1104,17 +875,17 @@ nsAccessibilityService::GetOrCreateAcces
           // is no better place:
           if (aIsSubtreeHidden)
             *aIsSubtreeHidden = true;
 
           return nullptr;
         }
 
         // Try using frame to do it.
-        newAcc = frame->CreateAccessible();
+        newAcc = CreateAccessibleByFrameType(frame, content, aDoc);
       }
     }
   }
 
   if (!newAcc) {
     // Elements may implement nsIAccessibleProvider via XBL. This allows them to
     // say what kind of accessible to create.
     newAcc = CreateAccessibleByType(content, aDoc);
@@ -1653,34 +1424,121 @@ nsAccessibilityService::CreateHTMLAccess
       new HTMLProgressMeterAccessible(aContent, aDoc);
     NS_ADDREF(accessible);
     return accessible;
   }
 
   return nullptr;
  }
 
+already_AddRefed<Accessible>
+nsAccessibilityService::CreateAccessibleByFrameType(nsIFrame* aFrame,
+                                                    nsIContent* aContent,
+                                                    DocAccessible* aDoc)
+{
+  nsRefPtr<Accessible> newAcc;
+  switch (aFrame->AccessibleType()) {
+    case eNoAccessible:
+      return nullptr;
+    case eHTMLBRAccessible:
+      newAcc = new HTMLBRAccessible(aContent, aDoc);
+      break;
+    case eHTMLButtonAccessible:
+      newAcc = new HTMLButtonAccessible(aContent, aDoc);
+      break;
+    case eHTMLCanvasAccessible:
+      newAcc = new HTMLCanvasAccessible(aContent, aDoc);
+      break;
+    case eHTMLCaptionAccessible:
+      newAcc = new HTMLCaptionAccessible(aContent, aDoc);
+      break;
+    case eHTMLCheckboxAccessible:
+      newAcc = new HTMLCheckboxAccessible(aContent, aDoc);
+      break;
+    case eHTMLComboboxAccessible:
+      newAcc = new HTMLComboboxAccessible(aContent, aDoc);
+      break;
+    case eHTMLFileInputAccessible:
+      newAcc = new HTMLFileInputAccessible(aContent, aDoc);
+      break;
+    case eHTMLGroupboxAccessible:
+      newAcc = new HTMLGroupboxAccessible(aContent, aDoc);
+      break;
+    case eHTMLHRAccessible:
+      newAcc = new HTMLHRAccessible(aContent, aDoc);
+      break;
+    case eHTMLImageMapAccessible:
+      newAcc = new HTMLImageMapAccessible(aContent, aDoc);
+      break;
+    case eHTMLLabelAccessible:
+      newAcc = new HTMLLabelAccessible(aContent, aDoc);
+      break;
+    case eHTMLLiAccessible:
+      newAcc = new HTMLLIAccessible(aContent, aDoc);
+      break;
+    case eHTMLSelectListAccessible:
+      newAcc = new HTMLSelectListAccessible(aContent, aDoc);
+      break;
+    case eHTMLMediaAccessible:
+      newAcc = new EnumRoleAccessible(aContent, aDoc, roles::GROUPING);
+      break;
+    case eHTMLObjectFrameAccessible: {
+      nsObjectFrame* objectFrame = do_QueryFrame(aFrame);
+      newAcc = CreateHTMLObjectFrameAccessible(objectFrame, aContent, aDoc);
+      break;
+    }
+
+    case eHTMLRadioButtonAccessible:
+      newAcc = new HTMLRadioButtonAccessible(aContent, aDoc);
+      break;
+    case eHTMLTableAccessible:
+      newAcc = new HTMLTableAccessibleWrap(aContent, aDoc);
+      break;
+    case eHTMLTableCellAccessible:
+      newAcc = new HTMLTableCellAccessibleWrap(aContent, aDoc);
+      break;
+    case eHTMLTableRowAccessible:
+      newAcc = new EnumRoleAccessible(aContent, aDoc, roles::ROW);
+      break;
+    case eHTMLTextFieldAccessible:
+      newAcc = new HTMLTextFieldAccessible(aContent, aDoc);
+      break;
+    case eHyperTextAccessible:
+      newAcc = new HyperTextAccessibleWrap(aContent, aDoc);
+      break;
+    case eImageAccessible:
+      newAcc = new ImageAccessibleWrap(aContent, aDoc);
+      break;
+    case eOuterDocAccessible:
+      newAcc = new OuterDocAccessible(aContent, aDoc);
+      break;
+    case eTextLeafAccessible:
+      newAcc = new TextLeafAccessibleWrap(aContent, aDoc);
+      break;
+  }
+
+  return newAcc.forget();
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessibilityService (DON'T put methods here)
 
 Accessible*
 nsAccessibilityService::AddNativeRootAccessible(void* aAtkAccessible)
 {
 #ifdef MOZ_ACCESSIBILITY_ATK
   ApplicationAccessible* applicationAcc = ApplicationAcc();
   if (!applicationAcc)
     return nullptr;
 
-  nsRefPtr<NativeRootAccessibleWrap> nativeRootAcc =
-    new NativeRootAccessibleWrap(static_cast<AtkObject*>(aAtkAccessible));
-  if (!nativeRootAcc)
-    return nullptr;
+  GtkWindowAccessible* nativeWnd =
+    new GtkWindowAccessible(static_cast<AtkObject*>(aAtkAccessible));
 
-  if (applicationAcc->AppendChild(nativeRootAcc))
-    return nativeRootAcc;
+  if (applicationAcc->AppendChild(nativeWnd))
+    return nativeWnd;
 #endif
 
   return nullptr;
 }
 
 void
 nsAccessibilityService::RemoveNativeRootAccessible(Accessible* aAccessible)
 {
--- a/accessible/src/base/nsAccessibilityService.h
+++ b/accessible/src/base/nsAccessibilityService.h
@@ -11,16 +11,17 @@
 #include "a11yGeneric.h"
 #include "nsAccDocManager.h"
 
 #include "mozilla/a11y/FocusManager.h"
 
 #include "nsIObserver.h"
 
 class nsImageFrame;
+class nsObjectFrame;
 class nsITreeView;
 
 namespace mozilla {
 namespace a11y {
 
 class ApplicationAccessible;
 
 /**
@@ -75,64 +76,18 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIACCESSIBLERETRIEVAL
   NS_DECL_NSIOBSERVER
 
   // nsIAccessibilityService
   virtual Accessible* GetRootDocumentAccessible(nsIPresShell* aPresShell,
                                                 bool aCanCreate);
   already_AddRefed<Accessible>
-    CreateHTMLButtonAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  already_AddRefed<Accessible>
-    CreateHTMLBRAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  already_AddRefed<Accessible>
-    CreateHTMLCanvasAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  already_AddRefed<Accessible>
-    CreateHTMLCaptionAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  already_AddRefed<Accessible>
-    CreateHTMLCheckboxAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  already_AddRefed<Accessible>
-    CreateHTMLComboboxAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  already_AddRefed<Accessible>
-    CreateHTMLFileInputAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  already_AddRefed<Accessible>
-    CreateHTMLGroupboxAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  already_AddRefed<Accessible>
-    CreateHTMLHRAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  already_AddRefed<Accessible>
-    CreateHTMLImageAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  already_AddRefed<Accessible>
-    CreateHTMLImageMapAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  already_AddRefed<Accessible>
-    CreateHTMLLabelAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  already_AddRefed<Accessible>
-    CreateHTMLLIAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  already_AddRefed<Accessible>
-    CreateHTMLListboxAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  already_AddRefed<Accessible>
-    CreateHTMLMediaAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  already_AddRefed<Accessible>
     CreateHTMLObjectFrameAccessible(nsObjectFrame* aFrame, nsIContent* aContent,
-                                    nsIPresShell* aPresShell);
-  already_AddRefed<Accessible>
-    CreateHTMLRadioButtonAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  already_AddRefed<Accessible>
-    CreateHTMLTableAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  already_AddRefed<Accessible>
-    CreateHTMLTableCellAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  already_AddRefed<Accessible>
-    CreateHTMLTableRowAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  already_AddRefed<Accessible>
-    CreateTextLeafAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  already_AddRefed<Accessible>
-    CreateHTMLTextFieldAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  already_AddRefed<Accessible>
-    CreateHyperTextAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
-  already_AddRefed<Accessible>
-    CreateOuterDocAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
+                                    DocAccessible* aDoc);
 
   /**
    * Adds/remove ATK root accessible for gtk+ native window to/from children
    * of the application accessible.
    */
   virtual Accessible* AddNativeRootAccessible(void* aAtkAccessible);
   virtual void RemoveNativeRootAccessible(Accessible* aRootAccessible);
 
@@ -235,16 +190,23 @@ private:
    * Create accessible for HTML node by tag name.
    */
   already_AddRefed<Accessible>
     CreateHTMLAccessibleByMarkup(nsIFrame* aFrame, nsIContent* aContent,
                                  DocAccessible* aDoc,
                                  bool aIsLegalPartOfHTMLTable);
 
   /**
+   * Create an accessible whose type depends on the given frame.
+   */
+  already_AddRefed<Accessible>
+    CreateAccessibleByFrameType(nsIFrame* aFrame, nsIContent* aContent,
+                                DocAccessible* aDoc);
+
+  /**
    * Create accessible if parent is a deck frame.
    */
   already_AddRefed<Accessible>
     CreateAccessibleForDeckChild(nsIFrame* aFrame, nsIContent* aContent,
                                  DocAccessible* aDoc);
 
 #ifdef MOZ_XUL
   /**
--- a/accessible/src/base/nsCoreUtils.cpp
+++ b/accessible/src/base/nsCoreUtils.cpp
@@ -4,16 +4,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsCoreUtils.h"
 
 #include "nsIAccessibleTypes.h"
 
 #include "nsAccessNode.h"
 
+#include "nsIBaseWindow.h"
+#include "nsIDocShellTreeOwner.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsRange.h"
 #include "nsIDOMWindow.h"
 #include "nsIDOMXULElement.h"
 #include "nsIDocShell.h"
@@ -24,16 +26,17 @@
 #include "nsIScrollableFrame.h"
 #include "nsEventStateManager.h"
 #include "nsISelectionPrivate.h"
 #include "nsISelectionController.h"
 #include "nsPIDOMWindow.h"
 #include "nsGUIEvent.h"
 #include "nsIView.h"
 #include "nsLayoutUtils.h"
+#include "nsGkAtoms.h"
 
 #include "nsComponentManagerUtils.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "mozilla/dom/Element.h"
 
 #include "nsITreeBoxObject.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsITreeColumns.h"
@@ -45,19 +48,19 @@
 bool
 nsCoreUtils::HasClickListener(nsIContent *aContent)
 {
   NS_ENSURE_TRUE(aContent, false);
   nsEventListenerManager* listenerManager =
     aContent->GetListenerManager(false);
 
   return listenerManager &&
-    (listenerManager->HasListenersFor(NS_LITERAL_STRING("click")) ||
-     listenerManager->HasListenersFor(NS_LITERAL_STRING("mousedown")) ||
-     listenerManager->HasListenersFor(NS_LITERAL_STRING("mouseup")));
+    (listenerManager->HasListenersFor(nsGkAtoms::onclick) ||
+     listenerManager->HasListenersFor(nsGkAtoms::onmousedown) ||
+     listenerManager->HasListenersFor(nsGkAtoms::onmouseup));
 }
 
 void
 nsCoreUtils::DispatchClickEvent(nsITreeBoxObject *aTreeBoxObj,
                                 int32_t aRowIndex, nsITreeColumn *aColumn,
                                 const nsCString& aPseudoElt)
 {
   nsCOMPtr<nsIDOMElement> tcElm;
@@ -159,21 +162,18 @@ nsCoreUtils::DispatchMouseEvent(uint32_t
   event.button = nsMouseEvent::eLeftButton;
   event.time = PR_IntervalNow();
 
   nsEventStatus status = nsEventStatus_eIgnore;
   aPresShell->HandleEventWithTarget(&event, aFrame, aContent, &status);
 }
 
 uint32_t
-nsCoreUtils::GetAccessKeyFor(nsIContent *aContent)
+nsCoreUtils::GetAccessKeyFor(nsIContent* aContent)
 {
-  if (!aContent)
-    return 0;
-
   // Accesskeys are registered by @accesskey attribute only. At first check
   // whether it is presented on the given element to avoid the slow
   // nsEventStateManager::GetRegisteredAccessKey() method.
   if (!aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::accesskey))
     return 0;
 
   nsIPresShell* presShell = aContent->OwnerDoc()->GetShell();
   if (!presShell)
@@ -246,17 +246,17 @@ nsCoreUtils::GetRoleContent(nsINode *aNo
 bool
 nsCoreUtils::IsAncestorOf(nsINode *aPossibleAncestorNode,
                           nsINode *aPossibleDescendantNode,
                           nsINode *aRootNode)
 {
   NS_ENSURE_TRUE(aPossibleAncestorNode && aPossibleDescendantNode, false);
 
   nsINode *parentNode = aPossibleDescendantNode;
-  while ((parentNode = parentNode->GetNodeParent()) &&
+  while ((parentNode = parentNode->GetParentNode()) &&
          parentNode != aRootNode) {
     if (parentNode == aPossibleAncestorNode)
       return true;
   }
 
   return false;
 }
 
@@ -301,29 +301,24 @@ nsCoreUtils::ScrollSubstringTo(nsIFrame*
   return NS_OK;
 }
 
 void
 nsCoreUtils::ScrollFrameToPoint(nsIFrame *aScrollableFrame,
                                 nsIFrame *aFrame,
                                 const nsIntPoint& aPoint)
 {
-  nsIScrollableFrame *scrollableFrame = do_QueryFrame(aScrollableFrame);
+  nsIScrollableFrame* scrollableFrame = do_QueryFrame(aScrollableFrame);
   if (!scrollableFrame)
     return;
 
-  nsPresContext *presContext = aFrame->PresContext();
-
-  nsIntRect frameRect = aFrame->GetScreenRectExternal();
-  int32_t devDeltaX = aPoint.x - frameRect.x;
-  int32_t devDeltaY = aPoint.y - frameRect.y;
-
-  nsPoint deltaPoint;
-  deltaPoint.x = presContext->DevPixelsToAppUnits(devDeltaX);
-  deltaPoint.y = presContext->DevPixelsToAppUnits(devDeltaY);
+  nsPoint point =
+    aPoint.ToAppUnits(aFrame->PresContext()->AppUnitsPerDevPixel());
+  nsRect frameRect = aFrame->GetScreenRectInAppUnits();
+  nsPoint deltaPoint(point.x - frameRect.x, point.y - frameRect.y);
 
   nsPoint scrollPoint = scrollableFrame->GetScrollPosition();
   scrollPoint -= deltaPoint;
 
   scrollableFrame->ScrollTo(scrollPoint, nsIScrollableFrame::INSTANT);
 }
 
 void
@@ -384,29 +379,25 @@ nsCoreUtils::ConvertScrollTypeToPercents
 nsIntPoint
 nsCoreUtils::GetScreenCoordsForWindow(nsINode *aNode)
 {
   nsIntPoint coords(0, 0);
   nsCOMPtr<nsIDocShellTreeItem> treeItem(GetDocShellTreeItemFor(aNode));
   if (!treeItem)
     return coords;
 
-  nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
-  treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
-  nsCOMPtr<nsIDOMDocument> domDoc = do_GetInterface(rootTreeItem);
-  if (!domDoc)
+  nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
+  treeItem->GetTreeOwner(getter_AddRefs(treeOwner));
+  if (!treeOwner)
     return coords;
 
-  nsCOMPtr<nsIDOMWindow> window;
-  domDoc->GetDefaultView(getter_AddRefs(window));
-  if (!window)
-    return coords;
+  nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(treeOwner);
+  if (baseWindow)
+    baseWindow->GetPosition(&coords.x, &coords.y); // in device pixels
 
-  window->GetScreenX(&coords.x);
-  window->GetScreenY(&coords.y);
   return coords;
 }
 
 already_AddRefed<nsIDocShellTreeItem>
 nsCoreUtils::GetDocShellTreeItemFor(nsINode *aNode)
 {
   if (!aNode)
     return nullptr;
@@ -479,36 +470,16 @@ nsCoreUtils::IsErrorPage(nsIDocument *aD
   uri->GetPath(path);
 
   NS_NAMED_LITERAL_CSTRING(neterror, "neterror");
   NS_NAMED_LITERAL_CSTRING(certerror, "certerror");
 
   return StringBeginsWith(path, neterror) || StringBeginsWith(path, certerror);
 }
 
-already_AddRefed<nsIDOMNode>
-nsCoreUtils::GetDOMNodeForContainer(nsIDocShellTreeItem *aContainer)
-{
-  nsCOMPtr<nsIDocShell> shell = do_QueryInterface(aContainer);
-
-  nsCOMPtr<nsIContentViewer> cv;
-  shell->GetContentViewer(getter_AddRefs(cv));
-
-  if (!cv)
-    return nullptr;
-
-  nsIDocument* doc = cv->GetDocument();
-  if (!doc)
-    return nullptr;
-
-  nsIDOMNode* node = nullptr;
-  CallQueryInterface(doc, &node);
-  return node;
-}
-
 bool
 nsCoreUtils::GetID(nsIContent *aContent, nsAString& aID)
 {
   nsIAtom *idAttribute = aContent->GetIDAttributeName();
   return idAttribute ? aContent->GetAttr(kNameSpaceID_None, idAttribute, aID) : false;
 }
 
 bool
--- a/accessible/src/base/nsCoreUtils.h
+++ b/accessible/src/base/nsCoreUtils.h
@@ -11,17 +11,16 @@
 #include "nsIBoxObject.h"
 #include "nsIPresShell.h"
 
 #include "nsIDOMDOMStringList.h"
 #include "nsPoint.h"
 #include "nsTArray.h"
 
 class nsRange;
-class nsIDOMNode;
 class nsIFrame;
 class nsIDocShellTreeItem;
 class nsITreeColumn;
 class nsITreeBoxObject;
 class nsIWidget;
 
 /**
  * Core utils.
@@ -164,17 +163,18 @@ public:
    * Converts scroll type constant defined in nsIAccessibleScrollType to
    * vertical and horizontal parameters.
    */
   static void ConvertScrollTypeToPercents(uint32_t aScrollType,
                                           nsIPresShell::ScrollAxis *aVertical,
                                           nsIPresShell::ScrollAxis *aHorizontal);
 
   /**
-   * Returns coordinates relative screen for the top level window.
+   * Returns coordinates in device pixels relative screen for the top level
+   * window.
    *
    * @param aNode  the DOM node hosted in the window.
    */
   static nsIntPoint GetScreenCoordsForWindow(nsINode *aNode);
 
   /**
    * Return document shell tree item for the given DOM node.
    */
@@ -205,22 +205,16 @@ public:
    * Return presShell for the document containing the given DOM node.
    */
   static nsIPresShell *GetPresShellFor(nsINode *aNode)
   {
     return aNode->OwnerDoc()->GetShell();
   }
 
   /**
-   * Return document node for the given document shell tree item.
-   */
-  static already_AddRefed<nsIDOMNode>
-    GetDOMNodeForContainer(nsIDocShellTreeItem *aContainer);
-
-  /**
    * Get the ID for an element, in some types of XML this may not be the ID attribute
    * @param aContent  Node to get the ID for
    * @param aID       Where to put ID string
    * @return          true if there is an ID set for this node
    */
   static bool GetID(nsIContent *aContent, nsAString& aID);
 
   /**
--- a/accessible/src/generic/ARIAGridAccessible.cpp
+++ b/accessible/src/generic/ARIAGridAccessible.cpp
@@ -609,29 +609,26 @@ ARIAGridCellAccessible::ApplyARIAState(u
   if (nsAccUtils::HasDefinedARIAToken(rowContent,
                                       nsGkAtoms::aria_selected) &&
       !rowContent->AttrValueIs(kNameSpaceID_None,
                                nsGkAtoms::aria_selected,
                                nsGkAtoms::_false, eCaseMatters))
     *aState |= states::SELECTABLE | states::SELECTED;
 }
 
-nsresult
-ARIAGridCellAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
+already_AddRefed<nsIPersistentProperties>
+ARIAGridCellAccessible::NativeAttributes()
 {
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  nsresult rv = HyperTextAccessibleWrap::GetAttributesInternal(aAttributes);
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsIPersistentProperties> attributes =
+    HyperTextAccessibleWrap::NativeAttributes();
 
   // Expose "table-cell-index" attribute.
   Accessible* thisRow = Row();
   if (!thisRow)
-    return NS_OK;
+    return attributes.forget();
 
   int32_t colIdx = 0, colCount = 0;
   uint32_t childCount = thisRow->ChildCount();
   for (uint32_t childIdx = 0; childIdx < childCount; childIdx++) {
     Accessible* child = thisRow->GetChildAt(childIdx);
     if (child == this)
       colIdx = colCount;
 
@@ -640,20 +637,19 @@ ARIAGridCellAccessible::GetAttributesInt
         role == roles::COLUMNHEADER)
       colCount++;
   }
 
   int32_t rowIdx = RowIndexFor(thisRow);
 
   nsAutoString stringIdx;
   stringIdx.AppendInt(rowIdx * colCount + colIdx);
-  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::tableCellIndex,
-                         stringIdx);
+  nsAccUtils::SetAccAttr(attributes, nsGkAtoms::tableCellIndex, stringIdx);
 
-  return NS_OK;
+  return attributes.forget();
 }
 
 void
 ARIAGridCellAccessible::Shutdown()
 {
   mTableCell = nullptr;
   HyperTextAccessibleWrap::Shutdown();
 }
--- a/accessible/src/generic/ARIAGridAccessible.h
+++ b/accessible/src/generic/ARIAGridAccessible.h
@@ -111,17 +111,17 @@ public:
 
   // nsIAccessibleTableCell
   NS_FORWARD_NSIACCESSIBLETABLECELL(xpcAccessibleTableCell::)
 
   // Accessible
   virtual TableCellAccessible* AsTableCell() { return this; }
   virtual void Shutdown();
   virtual void ApplyARIAState(uint64_t* aState) const;
-  virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
+  virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
 
 protected:
 
   /**
    * Return a containing row.
    */
   Accessible* Row() const
   {
--- a/accessible/src/generic/Accessible.cpp
+++ b/accessible/src/generic/Accessible.cpp
@@ -186,22 +186,16 @@ Accessible::Accessible(nsIContent* aCont
 //-----------------------------------------------------
 // destruction
 //-----------------------------------------------------
 Accessible::~Accessible()
 {
 }
 
 void
-Accessible::SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry)
-{
-  mRoleMapEntry = aRoleMapEntry;
-}
-
-void
 Accessible::Init()
 {
 }
 
 NS_IMETHODIMP
 Accessible::GetDocument(nsIAccessibleDocument** aDocument)
 {
   NS_ENSURE_ARG_POINTER(aDocument);
@@ -254,50 +248,51 @@ Accessible::GetName(nsAString& aName)
   return NS_OK;
 }
 
 ENameValueFlag
 Accessible::Name(nsString& aName)
 {
   aName.Truncate();
 
-  GetARIAName(aName);
+  if (!HasOwnContent())
+    return eNameOK;
+
+  ARIAName(aName);
   if (!aName.IsEmpty())
     return eNameOK;
 
   nsCOMPtr<nsIXBLAccessible> xblAccessible(do_QueryInterface(mContent));
   if (xblAccessible) {
     xblAccessible->GetAccessibleName(aName);
     if (!aName.IsEmpty())
       return eNameOK;
   }
 
-  nsresult rv = GetNameInternal(aName);
+  ENameValueFlag nameFlag = NativeName(aName);
   if (!aName.IsEmpty())
-    return eNameOK;
+    return nameFlag;
 
   // In the end get the name from tooltip.
   if (mContent->IsHTML()) {
     if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::title, aName)) {
       aName.CompressWhitespace();
       return eNameFromTooltip;
     }
   } else if (mContent->IsXUL()) {
     if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::tooltiptext, aName)) {
       aName.CompressWhitespace();
       return eNameFromTooltip;
     }
-  } else {
-    return eNameOK;
   }
 
-  if (rv != NS_OK_EMPTY_NAME)
+  if (nameFlag != eNoNameOnPurpose)
     aName.SetIsVoid(true);
 
-  return eNameOK;
+  return nameFlag;
 }
 
 NS_IMETHODIMP
 Accessible::GetDescription(nsAString& aDescription)
 {
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
@@ -312,17 +307,17 @@ void
 Accessible::Description(nsString& aDescription)
 {
   // There are 4 conditions that make an accessible have no accDescription:
   // 1. it's a text node; or
   // 2. It has no DHTML describedby property
   // 3. it doesn't have an accName; or
   // 4. its title attribute already equals to its accName nsAutoString name; 
 
-  if (mContent->IsNodeOfType(nsINode::eTEXT))
+  if (!HasOwnContent() || mContent->IsNodeOfType(nsINode::eTEXT))
     return;
 
   nsTextEquivUtils::
     GetTextEquivFromIDRefs(this, nsGkAtoms::aria_describedby,
                            aDescription);
 
   if (aDescription.IsEmpty()) {
     bool isXUL = mContent->IsXUL();
@@ -361,16 +356,19 @@ Accessible::GetAccessKey(nsAString& aAcc
 
   AccessKey().ToString(aAccessKey);
   return NS_OK;
 }
 
 KeyBinding
 Accessible::AccessKey() const
 {
+  if (!HasOwnContent())
+    return KeyBinding();
+
   uint32_t key = nsCoreUtils::GetAccessKeyFor(mContent);
   if (!key && mContent->IsElement()) {
     Accessible* label = nullptr;
 
     // Copy access key from label node.
     if (mContent->IsHTML()) {
       // Unless it is labeled via an ancestor <label>, in which case that would
       // be redundant.
@@ -673,17 +671,17 @@ Accessible::VisibilityState()
 uint64_t
 Accessible::NativeState()
 {
   uint64_t state = 0;
 
   if (!IsInDocument())
     state |= states::STALE;
 
-  if (mContent->IsElement()) {
+  if (HasOwnContent() && mContent->IsElement()) {
     nsEventStates elementState = mContent->AsElement()->State();
 
     if (elementState.HasState(NS_EVENT_STATE_INVALID))
       state |= states::INVALID;
 
     if (elementState.HasState(NS_EVENT_STATE_REQUIRED))
       state |= states::REQUIRED;
 
@@ -697,32 +695,32 @@ Accessible::NativeState()
 
   nsIFrame *frame = GetFrame();
   if (frame) {
     if (frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW)
       state |= states::FLOATING;
 
     // XXX we should look at layout for non XUL box frames, but need to decide
     // how that interacts with ARIA.
-    if (mContent->IsXUL() && frame->IsBoxFrame()) {
+    if (HasOwnContent() && mContent->IsXUL() && frame->IsBoxFrame()) {
       const nsStyleXUL* xulStyle = frame->GetStyleXUL();
       if (xulStyle && frame->IsBoxFrame()) {
         // In XUL all boxes are either vertical or horizontal
         if (xulStyle->mBoxOrient == NS_STYLE_BOX_ORIENT_VERTICAL)
           state |= states::VERTICAL;
         else
           state |= states::HORIZONTAL;
       }
     }
   }
 
   // Check if a XUL element has the popup attribute (an attached popup menu).
-      if (mContent->IsXUL() && mContent->HasAttr(kNameSpaceID_None,
-                                                 nsGkAtoms::popup))
-        state |= states::HASPOPUP;
+  if (HasOwnContent() && mContent->IsXUL() &&
+      mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::popup))
+    state |= states::HASPOPUP;
 
   // Bypass the link states specialization for non links.
   if (!mRoleMapEntry || mRoleMapEntry->roleRule == kUseNativeRole ||
       mRoleMapEntry->role == roles::LINK)
     state |= NativeLinkState();
 
   return state;
 }
@@ -938,30 +936,28 @@ Accessible::GetBounds(int32_t* aX, int32
   NS_ENSURE_ARG_POINTER(aWidth);
   *aWidth = 0;
   NS_ENSURE_ARG_POINTER(aHeight);
   *aHeight = 0;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsIPresShell* presShell = mDoc->PresShell();
-
   // This routine will get the entire rectangle for all the frames in this node.
   // -------------------------------------------------------------------------
   //      Primary Frame for node
   //  Another frame, same node                <- Example
   //  Another frame, same node
 
   nsRect unionRectTwips;
   nsIFrame* boundingFrame = nullptr;
   GetBoundsRect(unionRectTwips, &boundingFrame);   // Unions up all primary frames for this node and all siblings after it
   NS_ENSURE_STATE(boundingFrame);
 
-  nsPresContext* presContext = presShell->GetPresContext();
+  nsPresContext* presContext = mDoc->PresContext();
   *aX = presContext->AppUnitsToDevPixels(unionRectTwips.x);
   *aY = presContext->AppUnitsToDevPixels(unionRectTwips.y);
   *aWidth = presContext->AppUnitsToDevPixels(unionRectTwips.width);
   *aHeight = presContext->AppUnitsToDevPixels(unionRectTwips.height);
 
   // We have the union of the rectangle, now we need to put it in absolute screen coords
   nsIntRect orgRectPixels = boundingFrame->GetScreenRectInAppUnits().
     ToNearestPixels(presContext->AppUnitsPerDevPixel());
@@ -972,16 +968,19 @@ Accessible::GetBounds(int32_t* aX, int32
 }
 
 NS_IMETHODIMP
 Accessible::SetSelected(bool aSelect)
 {
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
+  if (!HasOwnContent())
+    return NS_OK;
+
   Accessible* select = nsAccUtils::GetSelectableContainer(this, State());
   if (select) {
     if (select->State() & states::MULTISELECTABLE) {
       if (mRoleMapEntry) {
         if (aSelect) {
           return mContent->SetAttr(kNameSpaceID_None,
                                    nsGkAtoms::aria_selected,
                                    NS_LITERAL_STRING("true"), true);
@@ -1043,120 +1042,108 @@ Accessible::TakeFocus()
   nsCOMPtr<nsIDOMElement> element(do_QueryInterface(focusContent));
   nsFocusManager* fm = nsFocusManager::GetFocusManager();
   if (fm)
     fm->SetFocus(element, 0);
 
   return NS_OK;
 }
 
-nsresult
-Accessible::GetHTMLName(nsAString& aLabel)
+ENameValueFlag
+Accessible::GetHTMLName(nsString& aLabel)
 {
-  nsAutoString label;
-
   Accessible* labelAcc = nullptr;
   HTMLLabelIterator iter(Document(), this);
   while ((labelAcc = iter.Next())) {
-    nsresult rv = nsTextEquivUtils::
-      AppendTextEquivFromContent(this, labelAcc->GetContent(), &label);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    label.CompressWhitespace();
+    nsTextEquivUtils::AppendTextEquivFromContent(this, labelAcc->GetContent(),
+                                                 &aLabel);
+    aLabel.CompressWhitespace();
   }
 
-  if (label.IsEmpty())
-    return nsTextEquivUtils::GetNameFromSubtree(this, aLabel);
-
-  aLabel = label;
-  return NS_OK;
+  if (!aLabel.IsEmpty())
+    return eNameOK;
+
+  nsTextEquivUtils::GetNameFromSubtree(this, aLabel);
+  return aLabel.IsEmpty() ? eNameOK : eNameFromSubtree;
 }
 
 /**
   * 3 main cases for XUL Controls to be labeled
   *   1 - control contains label="foo"
   *   2 - control has, as a child, a label element
   *        - label has either value="foo" or children
   *   3 - non-child label contains control="controlID"
   *        - label has either value="foo" or children
   * Once a label is found, the search is discontinued, so a control
   *  that has a label child as well as having a label external to
   *  the control that uses the control="controlID" syntax will use
   *  the child label for its Name.
   */
-nsresult
-Accessible::GetXULName(nsAString& aLabel)
+ENameValueFlag
+Accessible::GetXULName(nsString& aName)
 {
   // CASE #1 (via label attribute) -- great majority of the cases
-  nsresult rv = NS_OK;
-
-  nsAutoString label;
-  nsCOMPtr<nsIDOMXULLabeledControlElement> labeledEl(do_QueryInterface(mContent));
+  nsCOMPtr<nsIDOMXULLabeledControlElement> labeledEl =
+    do_QueryInterface(mContent);
   if (labeledEl) {
-    rv = labeledEl->GetLabel(label);
-  }
-  else {
-    nsCOMPtr<nsIDOMXULSelectControlItemElement> itemEl(do_QueryInterface(mContent));
+    labeledEl->GetLabel(aName);
+  } else {
+    nsCOMPtr<nsIDOMXULSelectControlItemElement> itemEl =
+      do_QueryInterface(mContent);
     if (itemEl) {
-      rv = itemEl->GetLabel(label);
-    }
-    else {
-      nsCOMPtr<nsIDOMXULSelectControlElement> select(do_QueryInterface(mContent));
+      itemEl->GetLabel(aName);
+    } else {
+      nsCOMPtr<nsIDOMXULSelectControlElement> select =
+        do_QueryInterface(mContent);
       // Use label if this is not a select control element which 
       // uses label attribute to indicate which option is selected
       if (!select) {
         nsCOMPtr<nsIDOMXULElement> xulEl(do_QueryInterface(mContent));
-        if (xulEl) {
-          rv = xulEl->GetAttribute(NS_LITERAL_STRING("label"), label);
-        }
+        if (xulEl)
+          xulEl->GetAttribute(NS_LITERAL_STRING("label"), aName);
       }
     }
   }
 
   // CASES #2 and #3 ------ label as a child or <label control="id" ... > </label>
-  if (NS_FAILED(rv) || label.IsEmpty()) {
-    label.Truncate();
-
+  if (aName.IsEmpty()) {
     Accessible* labelAcc = nullptr;
     XULLabelIterator iter(Document(), mContent);
     while ((labelAcc = iter.Next())) {
       nsCOMPtr<nsIDOMXULLabelElement> xulLabel =
         do_QueryInterface(labelAcc->GetContent());
       // Check if label's value attribute is used
-      if (xulLabel && NS_SUCCEEDED(xulLabel->GetValue(label)) && label.IsEmpty()) {
+      if (xulLabel && NS_SUCCEEDED(xulLabel->GetValue(aName)) && aName.IsEmpty()) {
         // If no value attribute, a non-empty label must contain
         // children that define its text -- possibly using HTML
         nsTextEquivUtils::
-          AppendTextEquivFromContent(this, labelAcc->GetContent(), &label);
+          AppendTextEquivFromContent(this, labelAcc->GetContent(), &aName);
       }
     }
   }
 
-  // XXX If CompressWhiteSpace worked on nsAString we could avoid a copy
-  label.CompressWhitespace();
-  if (!label.IsEmpty()) {
-    aLabel = label;
-    return NS_OK;
-  }
+  aName.CompressWhitespace();
+  if (!aName.IsEmpty())
+    return eNameOK;
 
   // Can get text from title of <toolbaritem> if we're a child of a <toolbaritem>
   nsIContent *bindingParent = mContent->GetBindingParent();
   nsIContent *parent = bindingParent? bindingParent->GetParent() :
                                       mContent->GetParent();
   while (parent) {
     if (parent->Tag() == nsGkAtoms::toolbaritem &&
-        parent->GetAttr(kNameSpaceID_None, nsGkAtoms::title, label)) {
-      label.CompressWhitespace();
-      aLabel = label;
-      return NS_OK;
+        parent->GetAttr(kNameSpaceID_None, nsGkAtoms::title, aName)) {
+      aName.CompressWhitespace();
+      return eNameOK;
     }
     parent = parent->GetParent();
   }
 
-  return nsTextEquivUtils::GetNameFromSubtree(this, aLabel);
+  nsTextEquivUtils::GetNameFromSubtree(this, aName);
+  return aName.IsEmpty() ? eNameOK : eNameFromSubtree;
 }
 
 nsresult
 Accessible::HandleAccEvent(AccEvent* aEvent)
 {
   NS_ENSURE_ARG_POINTER(aEvent);
 
   nsCOMPtr<nsIObserverService> obsService =
@@ -1188,205 +1175,216 @@ Accessible::GetRole(uint32_t *aRole)
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   *aRole = Role();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-Accessible::GetAttributes(nsIPersistentProperties **aAttributes)
+Accessible::GetAttributes(nsIPersistentProperties** aAttributes)
 {
-  NS_ENSURE_ARG_POINTER(aAttributes);  // In/out param. Created if necessary.
-  
+  NS_ENSURE_ARG_POINTER(aAttributes);
+  *aAttributes = nullptr;
+
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsCOMPtr<nsIPersistentProperties> attributes = *aAttributes;
-  if (!attributes) {
-    // Create only if an array wasn't already passed in
-    attributes = do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID);
-    NS_ENSURE_TRUE(attributes, NS_ERROR_OUT_OF_MEMORY);
-    NS_ADDREF(*aAttributes = attributes);
-  }
- 
-  nsresult rv = GetAttributesInternal(attributes);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsAutoString id;
-  nsAutoString oldValueUnused;
-  if (nsCoreUtils::GetID(mContent, id)) {
-    // Expose ID. If an <iframe id> exists override the one on the <body> of the source doc,
-    // because the specific instance is what makes the ID useful for scripts
-    attributes->SetStringProperty(NS_LITERAL_CSTRING("id"), id, oldValueUnused);
-  }
-  
-  nsAutoString xmlRoles;
+  nsCOMPtr<nsIPersistentProperties> attributes = Attributes();
+  attributes.swap(*aAttributes);
+
+  return NS_OK;
+}
+
+already_AddRefed<nsIPersistentProperties>
+Accessible::Attributes()
+{
+  nsCOMPtr<nsIPersistentProperties> attributes = NativeAttributes();
+  if (!HasOwnContent() || !mContent->IsElement())
+    return attributes.forget();
+
+  // 'xml-roles' attribute coming from ARIA.
+  nsAutoString xmlRoles, unused;
   if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::role, xmlRoles)) {
-    attributes->SetStringProperty(NS_LITERAL_CSTRING("xml-roles"),  xmlRoles, oldValueUnused);          
+    attributes->SetStringProperty(NS_LITERAL_CSTRING("xml-roles"),
+                                  xmlRoles, unused);
   }
 
-  nsCOMPtr<nsIAccessibleValue> supportsValue = do_QueryInterface(static_cast<nsIAccessible*>(this));
-  if (supportsValue) {
-    // We support values, so expose the string value as well, via the valuetext object attribute
-    // We test for the value interface because we don't want to expose traditional get_accValue()
-    // information such as URL's on links and documents, or text in an input
-    nsAutoString valuetext;
-    GetValue(valuetext);
-    attributes->SetStringProperty(NS_LITERAL_CSTRING("valuetext"), valuetext, oldValueUnused);
-  }
-
-  // Expose checkable object attribute if the accessible has checkable state
-  if (State() & states::CHECKABLE)
-    nsAccUtils::SetAccAttr(attributes, nsGkAtoms::checkable, NS_LITERAL_STRING("true"));
-
-  // Group attributes (level/setsize/posinset)
-  GroupPos groupPos = GroupPosition();
-  nsAccUtils::SetAccGroupAttrs(attributes, groupPos.level,
-                               groupPos.setSize, groupPos.posInSet);
-
   // Expose object attributes from ARIA attributes.
   aria::AttrIterator attribIter(mContent);
   nsAutoString name, value;
-  while(attribIter.Next(name, value)) {
-    attributes->SetStringProperty(NS_ConvertUTF16toUTF8(name), value, 
-                                  oldValueUnused);
-  }
+  while(attribIter.Next(name, value))
+    attributes->SetStringProperty(NS_ConvertUTF16toUTF8(name), value, unused);
 
   // If there is no aria-live attribute then expose default value of 'live'
   // object attribute used for ARIA role of this accessible.
   if (mRoleMapEntry) {
     nsAutoString live;
     nsAccUtils::GetAccAttr(attributes, nsGkAtoms::live, live);
     if (live.IsEmpty()) {
       if (nsAccUtils::GetLiveAttrValue(mRoleMapEntry->liveAttRule, live))
         nsAccUtils::SetAccAttr(attributes, nsGkAtoms::live, live);
     }
   }
 
-  return NS_OK;
+  return attributes.forget();
 }
 
-nsresult
-Accessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
+already_AddRefed<nsIPersistentProperties>
+Accessible::NativeAttributes()
 {
-  // If the accessible isn't primary for its node (such as list item bullet or
-  // xul tree item then don't calculate content based attributes.
-  if (!IsPrimaryForNode())
-    return NS_OK;
-
-  // Attributes set by this method will not be used to override attributes on a sub-document accessible
-  // when there is a <frame>/<iframe> element that spawned the sub-document
-
-  nsEventShell::GetEventAttributes(GetNode(), aAttributes);
- 
-  // Expose class because it may have useful microformat information
-  // Let the class from an iframe's document be exposed, don't override from <iframe class>
-  nsAutoString _class;
-  if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, _class))
-    nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::_class, _class);
-
-  // Get container-foo computed live region properties based on the closest container with
-  // the live region attribute. 
-  // Inner nodes override outer nodes within the same document --
-  //   The inner nodes can be used to override live region behavior on more general outer nodes
-  // However, nodes in outer documents override nodes in inner documents:
-  //   Outer doc author may want to override properties on a widget they used in an iframe
+  nsCOMPtr<nsIPersistentProperties> attributes =
+    do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID);
+
+  nsAutoString unused;
+
+  // We support values, so expose the string value as well, via the valuetext
+  // object attribute. We test for the value interface because we don't want
+  // to expose traditional Value() information such as URL's on links and
+  // documents, or text in an input.
+  if (HasNumericValue()) {
+    nsAutoString valuetext;
+    GetValue(valuetext);
+    attributes->SetStringProperty(NS_LITERAL_CSTRING("valuetext"), valuetext,
+                                  unused);
+  }
+
+  // Expose checkable object attribute if the accessible has checkable state
+  if (State() & states::CHECKABLE) {
+    nsAccUtils::SetAccAttr(attributes, nsGkAtoms::checkable,
+                           NS_LITERAL_STRING("true"));
+  }
+
+  // Expose 'explicit-name' attribute.
+  nsAutoString name;
+  if (Name(name) != eNameFromSubtree && !name.IsVoid()) {
+    attributes->SetStringProperty(NS_LITERAL_CSTRING("explicit-name"),
+                                  NS_LITERAL_STRING("true"), unused);
+  }
+
+  // Group attributes (level/setsize/posinset)
+  GroupPos groupPos = GroupPosition();
+  nsAccUtils::SetAccGroupAttrs(attributes, groupPos.level,
+                               groupPos.setSize, groupPos.posInSet);
+
+  // If the accessible doesn't have own content (such as list item bullet or
+  // xul tree item) then don't calculate content based attributes.
+  if (!HasOwnContent())
+    return attributes.forget();
+
+  nsEventShell::GetEventAttributes(GetNode(), attributes);
+
+  // Get container-foo computed live region properties based on the closest
+  // container with the live region attribute. Inner nodes override outer nodes
+  // within the same document. The inner nodes can be used to override live
+  // region behavior on more general outer nodes. However, nodes in outer
+  // documents override nodes in inner documents: outer doc author may want to
+  // override properties on a widget they used in an iframe.
   nsIContent* startContent = mContent;
   while (startContent) {
     nsIDocument* doc = startContent->GetDocument();
-    nsIContent* rootContent = nsCoreUtils::GetRoleContent(doc);
-    if (!rootContent)
-      return NS_OK;
-
-    nsAccUtils::SetLiveContainerAttributes(aAttributes, startContent,
-                                           rootContent);
+    if (!doc)
+      break;
+
+    nsAccUtils::SetLiveContainerAttributes(attributes, startContent,
+                                           nsCoreUtils::GetRoleContent(doc));
 
     // Allow ARIA live region markup from outer documents to override
     nsCOMPtr<nsISupports> container = doc->GetContainer(); 
     nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
       do_QueryInterface(container);
     if (!docShellTreeItem)
       break;
 
     nsCOMPtr<nsIDocShellTreeItem> sameTypeParent;
     docShellTreeItem->GetSameTypeParent(getter_AddRefs(sameTypeParent));
     if (!sameTypeParent || sameTypeParent == docShellTreeItem)
       break;
 
-    nsIDocument *parentDoc = doc->GetParentDocument();
+    nsIDocument* parentDoc = doc->GetParentDocument();
     if (!parentDoc)
       break;
 
-    startContent = parentDoc->FindContentForSubDocument(doc);      
+    startContent = parentDoc->FindContentForSubDocument(doc);
   }
 
   if (!mContent->IsElement())
-    return NS_OK;
+    return attributes.forget();
+
+  nsAutoString id;
+  if (nsCoreUtils::GetID(mContent, id))
+    attributes->SetStringProperty(NS_LITERAL_CSTRING("id"), id, unused);
+
+  // Expose class because it may have useful microformat information.
+  nsAutoString _class;
+  if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, _class))
+    nsAccUtils::SetAccAttr(attributes, nsGkAtoms::_class, _class);
 
   // Expose tag.
   nsAutoString tagName;
   mContent->NodeInfo()->GetName(tagName);
-  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::tag, tagName);
-
-  // Expose draggable object attribute?
+  nsAccUtils::SetAccAttr(attributes, nsGkAtoms::tag, tagName);
+
+  // 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,
+      nsAccUtils::SetAccAttr(attributes, nsGkAtoms::draggable,
                              NS_LITERAL_STRING("true"));
     }
   }
 
   // Don't calculate CSS-based object attributes when no frame (i.e.
   // the accessible is unattached from the tree).
   if (!mContent->GetPrimaryFrame())
-    return NS_OK;
+    return attributes.forget();
 
   // CSS style based object attributes.
   nsAutoString value;
   StyleInfo styleInfo(mContent->AsElement(), mDoc->PresShell());
 
   // Expose 'display' attribute.
   styleInfo.Display(value);
-  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::display, value);
+  nsAccUtils::SetAccAttr(attributes, nsGkAtoms::display, value);
 
   // Expose 'text-align' attribute.
   styleInfo.TextAlign(value);
-  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textAlign, value);
+  nsAccUtils::SetAccAttr(attributes, nsGkAtoms::textAlign, value);
 
   // Expose 'text-indent' attribute.
   styleInfo.TextIndent(value);
-  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textIndent, value);
+  nsAccUtils::SetAccAttr(attributes, nsGkAtoms::textIndent, value);
 
   // Expose 'margin-left' attribute.
   styleInfo.MarginLeft(value);
-  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginLeft, value);
+  nsAccUtils::SetAccAttr(attributes, nsGkAtoms::marginLeft, value);
 
   // Expose 'margin-right' attribute.
   styleInfo.MarginRight(value);
-  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginRight, value);
+  nsAccUtils::SetAccAttr(attributes, nsGkAtoms::marginRight, value);
 
   // Expose 'margin-top' attribute.
   styleInfo.MarginTop(value);
-  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginTop, value);
+  nsAccUtils::SetAccAttr(attributes, nsGkAtoms::marginTop, value);
 
   // Expose 'margin-bottom' attribute.
   styleInfo.MarginBottom(value);
-  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginBottom, value);
-
-  return NS_OK;
+  nsAccUtils::SetAccAttr(attributes, nsGkAtoms::marginBottom, value);
+
+  return attributes.forget();
 }
 
 GroupPos
 Accessible::GroupPosition()
 {
   GroupPos groupPos;
+  if (!HasOwnContent())
+    return groupPos;
 
   // Get group position from ARIA attributes.
   nsCoreUtils::GetUIntAttr(mContent, nsGkAtoms::aria_level, &groupPos.level);
   nsCoreUtils::GetUIntAttr(mContent, nsGkAtoms::aria_setsize, &groupPos.setSize);
   nsCoreUtils::GetUIntAttr(mContent, nsGkAtoms::aria_posinset, &groupPos.posInSet);
 
   // If ARIA is missed and the accessible is visible then calculate group
   // position from hierarchy.
@@ -1900,16 +1898,19 @@ Accessible::GetRelationByType(uint32_t a
   Relation rel = RelationByType(aType);
   NS_ADDREF(*aRelation = new nsAccessibleRelation(aType, &rel));
   return *aRelation ? NS_OK : NS_ERROR_FAILURE;
 }
 
 Relation
 Accessible::RelationByType(uint32_t aType)
 {
+  if (!HasOwnContent())
+    return Relation();
+
   // Relationships are defined on the same content node that the role would be
   // defined on.
   switch (aType) {
     case nsIAccessibleRelation::RELATION_LABEL_FOR: {
       Relation rel(new RelatedAccIterator(Document(), mContent,
                                           nsGkAtoms::aria_labelledby));
       if (mContent->Tag() == nsGkAtoms::label)
         rel.AppendIter(new IDRefsIterator(mDoc, mContent, mContent->IsHTML() ?
@@ -2422,52 +2423,44 @@ Accessible::Shutdown()
 
   InvalidateChildren();
   if (mParent)
     mParent->RemoveChild(this);
 
   nsAccessNodeWrap::Shutdown();
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// Accessible public methods
-
-nsresult
-Accessible::GetARIAName(nsAString& aName)
+// Accessible protected
+void
+Accessible::ARIAName(nsString& aName)
 {
-  nsAutoString label;
-
   // aria-labelledby now takes precedence over aria-label
   nsresult rv = nsTextEquivUtils::
-    GetTextEquivFromIDRefs(this, nsGkAtoms::aria_labelledby, label);
+    GetTextEquivFromIDRefs(this, nsGkAtoms::aria_labelledby, aName);
   if (NS_SUCCEEDED(rv)) {
-    label.CompressWhitespace();
-    aName = label;
+    aName.CompressWhitespace();
   }
 
-  if (label.IsEmpty() &&
-      mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_label,
-                        label)) {
-    label.CompressWhitespace();
-    aName = label;
+  if (aName.IsEmpty() &&
+      mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_label, aName)) {
+    aName.CompressWhitespace();
   }
-  
-  return NS_OK;
 }
 
-nsresult
-Accessible::GetNameInternal(nsAString& aName)
+// Accessible protected
+ENameValueFlag
+Accessible::NativeName(nsString& aName)
 {
   if (mContent->IsHTML())
     return GetHTMLName(aName);
 
   if (mContent->IsXUL())
     return GetXULName(aName);
 
-  return NS_OK;
+  return eNameOK;
 }
 
 // Accessible protected
 void
 Accessible::BindToParent(Accessible* aParent, uint32_t aIndexInParent)
 {
   NS_PRECONDITION(aParent, "This method isn't used to set null parent!");
 
@@ -2480,25 +2473,29 @@ Accessible::BindToParent(Accessible* aPa
       return;
     }
   }
 
   mParent = aParent;
   mIndexInParent = aIndexInParent;
 }
 
+// Accessible protected
 void
 Accessible::UnbindFromParent()
 {
   mParent = nullptr;
   mIndexInParent = -1;
   mIndexOfEmbeddedChild = -1;
   mGroupInfo = nullptr;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// Accessible public methods
+
 void
 Accessible::InvalidateChildren()
 {
   int32_t childCount = mChildren.Length();
   for (int32_t childIdx = 0; childIdx < childCount; childIdx++) {
     Accessible* child = mChildren.ElementAt(childIdx);
     child->UnbindFromParent();
   }
@@ -2881,28 +2878,30 @@ Accessible::IsActiveWidget() const
   }
 
   return false;
 }
 
 bool
 Accessible::AreItemsOperable() const
 {
-  return mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_activedescendant);
+  return HasOwnContent() &&
+    mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_activedescendant);
 }
 
 Accessible*
 Accessible::CurrentItem()
 {
   // Check for aria-activedescendant, which changes which element has focus.
   // For activedescendant, the ARIA spec does not require that the user agent
   // checks whether pointed node is actually a DOM descendant of the element
   // with the aria-activedescendant attribute.
   nsAutoString id;
-  if (mContent->GetAttr(kNameSpaceID_None,
+  if (HasOwnContent() &&
+      mContent->GetAttr(kNameSpaceID_None,
                         nsGkAtoms::aria_activedescendant, id)) {
     nsIDocument* DOMDoc = mContent->OwnerDoc();
     dom::Element* activeDescendantElm = DOMDoc->GetElementById(id);
     if (activeDescendantElm) {
       DocAccessible* document = Document();
       if (document)
         return document->GetAccessible(activeDescendantElm);
     }
--- a/accessible/src/generic/Accessible.h
+++ b/accessible/src/generic/Accessible.h
@@ -44,20 +44,34 @@ class XULTreeAccessible;
 /**
  * Name type flags.
  */
 enum ENameValueFlag {
   /**
    * Name either
    *  a) present (not empty): !name.IsEmpty()
    *  b) no name (was missed): name.IsVoid()
-   *  c) was left empty by the author on demand: name.IsEmpty() && !name.IsVoid()
    */
  eNameOK,
- eNameFromTooltip // Tooltip was used as a name
+
+ /**
+  * Name was left empty by the author on purpose:
+  * name.IsEmpty() && !name.IsVoid().
+  */
+ eNoNameOnPurpose,
+
+ /**
+  * Name was computed from the subtree.
+  */
+ eNameFromSubtree,
+
+ /**
+  * Tooltip was used as a name.
+  */
+ eNameFromTooltip
 };
 
 /**
  * Group position (level, position in set and set size).
  */
 struct GroupPos
 {
   GroupPos() : level(0), posInSet(0), setSize(0) { }
@@ -127,57 +141,43 @@ public:
 
   /**
    * Get the value of this accessible.
    */
   virtual void Value(nsString& aValue);
 
   /**
    * Get the name of this accessible.
+   *
+   * Note: aName.IsVoid() when name was left empty by the author on purpose.
+   * aName.IsEmpty() when the author missed name, AT can try to repair a name.
    */
   virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
 
   /**
    * Return DOM node associated with this accessible.
    */
   inline already_AddRefed<nsIDOMNode> DOMNode() const
   {
     nsIDOMNode *DOMNode = nullptr;
     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.
    *
    * @param  [in/out] where to fill the states into.
    */
   virtual void ApplyARIAState(uint64_t* aState) const;
 
   /**
-   * Returns the accessible name provided by native markup. It doesn't take
-   * into account ARIA markup used to specify the name.
-   *
-   * @param  aName             [out] the accessible name
-   *
-   * @return NS_OK_EMPTY_NAME  points empty name was specified by native markup
-   *                           explicitly (see nsIAccessible::name attribute for
-   *                           details)
-   */
-  virtual nsresult GetNameInternal(nsAString& aName);
-
-  /**
    * Return enumerated accessible role (see constants in Role.h).
    */
   mozilla::a11y::role Role();
 
   /**
    * Return true if ARIA role is specified on the element.
    */
   bool HasARIARole() const
@@ -243,20 +243,19 @@ public:
   uint64_t VisibilityState();
 
   /**
    * Return true if native unavailable state present.
    */
   virtual bool NativelyUnavailable() const;
 
   /**
-   * Returns attributes for accessible without explicitly setted ARIA
-   * attributes.
+   * Return object attributes for the accessible.
    */
-  virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
+  virtual already_AddRefed<nsIPersistentProperties> Attributes();
 
   /**
    * Return group position (level, position in set and set size).
    */
   virtual mozilla::a11y::GroupPos GroupPosition();
 
   /**
    * Used by ChildAtPoint() method to get direct or deepest child at point.
@@ -307,17 +306,18 @@ public:
 
   /**
    * Set the ARIA role map entry for a new accessible.
    * For a newly created accessible, specify which role map entry should be used.
    *
    * @param aRoleMapEntry The ARIA nsRoleMapEntry* for the accessible, or
    *                      nullptr if none.
    */
-  virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
+  void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry)
+    { mRoleMapEntry = aRoleMapEntry; }
 
   /**
    * Update the children cache.
    */
   inline bool UpdateChildren()
   {
     InvalidateChildren();
     return EnsureChildren();
@@ -505,16 +505,18 @@ public:
   inline bool IsXULDeck() const { return mFlags & eXULDeckAccessible; }
 
   inline bool IsListControl() const { return mFlags & eListControlAccessible; }
 
   inline bool IsMenuButton() const { return mFlags & eMenuButtonAccessible; }
 
   inline bool IsMenuPopup() const { return mFlags & eMenuPopupAccessible; }
 
+  inline bool IsProgress() const { return mFlags & eProgressAccessible; }
+
   inline bool IsRoot() const { return mFlags & eRootAccessible; }
   mozilla::a11y::RootAccessible* AsRoot();
 
   virtual mozilla::a11y::TableAccessible* AsTable() { return nullptr; }
 
   virtual mozilla::a11y::TableCellAccessible* AsTableCell() { return nullptr; }
 
   inline bool IsTextLeaf() const { return mFlags & eTextLeafAccessible; }
@@ -688,31 +690,45 @@ public:
   bool IsDefunct() const { return mFlags & eIsDefunct; }
 
   /**
    * Return true if the accessible is no longer in the document.
    */
   bool IsInDocument() const { return !(mFlags & eIsNotInDocument); }
 
   /**
-  * 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.
-  */
-  bool IsPrimaryForNode() const { return !(mFlags & eSharedNode); }
+   * Return true if the accessible should be contained by document node map.
+   */
+  bool IsNodeMapEntry() const
+    { return HasOwnContent() && !(mFlags & eNotNodeMapEntry); }
+
+  /**
+   * Return true if the accessible has associated DOM content.
+   */
+  bool HasOwnContent() const { return mContent && !(mFlags & eSharedNode); }
 
   /**
   * Return true if the accessible has a numeric value.
   */
   bool HasNumericValue() const;
 
 protected:
 
+  /**
+   * Return the accessible name provided by native markup. It doesn't take
+   * into account ARIA markup used to specify the name.
+   */
+  virtual mozilla::a11y::ENameValueFlag NativeName(nsString& aName);
+
+  /**
+   * Return object attributes provided by native markup. It doesn't take into
+   * account ARIA.
+   */
+  virtual already_AddRefed<nsIPersistentProperties> NativeAttributes();
+
   //////////////////////////////////////////////////////////////////////////////
   // Initializing, cache and tree traverse methods
 
   /**
    * Cache accessible children.
    */
   virtual void CacheChildren();
 
@@ -752,63 +768,66 @@ protected:
   /**
    * Flags used to describe the state of this accessible.
    * @note keep these flags in sync with ChildrenFlags
    */
   enum StateFlags {
     eIsDefunct = 1 << 2, // accessible is defunct
     eIsNotInDocument = 1 << 3, // accessible is not in document
     eSharedNode = 1 << 4, // accessible shares DOM node from another accessible
-    eHasNumericValue = 1 << 5 // accessible has a numeric value
+    eNotNodeMapEntry = 1 << 5, // accessible shouldn't be in document node map
+    eHasNumericValue = 1 << 6 // accessible has a numeric value
   };
 
   /**
    * Flags describing the type of this accessible.
    * @note keep these flags in sync with ChildrenFlags and StateFlags
    */
   enum AccessibleTypes {
-    eApplicationAccessible = 1 << 6,
-    eAutoCompleteAccessible = 1 << 7,
-    eAutoCompletePopupAccessible = 1 << 8,
-    eComboboxAccessible = 1 << 9,
-    eDocAccessible = 1 << 10,
-    eHyperTextAccessible = 1 << 11,
-    eHTMLFileInputAccessible = 1 << 12,
-    eHTMLListItemAccessible = 1 << 13,
-    eImageAccessible = 1 << 14,
-    eImageMapAccessible = 1 << 15,
-    eListControlAccessible = 1 << 16,
-    eMenuButtonAccessible = 1 << 17,
-    eMenuPopupAccessible = 1 << 18,
-    eRootAccessible = 1 << 19,
-    eTextLeafAccessible = 1 << 20,
-    eXULDeckAccessible = 1 << 21,
-    eXULTreeAccessible = 1 << 22
+    eApplicationAccessible = 1 << 7,
+    eAutoCompleteAccessible = 1 << 8,
+    eAutoCompletePopupAccessible = 1 << 9,
+    eComboboxAccessible = 1 << 10,
+    eDocAccessible = 1 << 11,
+    eHyperTextAccessible = 1 << 12,
+    eHTMLFileInputAccessible = 1 << 13,
+    eHTMLListItemAccessible = 1 << 14,
+    eImageAccessible = 1 << 15,
+    eImageMapAccessible = 1 << 16,
+    eListControlAccessible = 1 << 17,
+    eMenuButtonAccessible = 1 << 18,
+    eMenuPopupAccessible = 1 << 19,
+    eProgressAccessible = 1 << 20,
+    eRootAccessible = 1 << 21,
+    eTextLeafAccessible = 1 << 22,
+    eXULDeckAccessible = 1 << 23,
+    eXULTreeAccessible = 1 << 24
   };
 
   //////////////////////////////////////////////////////////////////////////////
   // Miscellaneous helpers
 
   /**
    * Return ARIA role (helper method).
    */
   mozilla::a11y::role ARIATransformRole(mozilla::a11y::role aRole);
 
   //////////////////////////////////////////////////////////////////////////////
   // Name helpers
 
   /**
-   * Compute the name of HTML node.
+   * Returns the accessible name specified by ARIA.
    */
-  nsresult GetHTMLName(nsAString& aName);
+  void ARIAName(nsString& aName);
 
   /**
-   * Compute the name for XUL node.
+   * Compute the name of HTML/XUL node.
    */
-  nsresult GetXULName(nsAString& aName);
+  mozilla::a11y::ENameValueFlag GetHTMLName(nsString& aName);
+  mozilla::a11y::ENameValueFlag GetXULName(nsString& aName);
 
   // helper method to verify frames
   static nsresult GetFullKeyName(const nsAString& aModifierName, const nsAString& aKeyName, nsAString& aStringOut);
 
   /**
    * Return an accessible for the given DOM node, or if that node isn't
    * accessible, return the accessible for the next DOM node which has one
    * (based on forward depth first search).
--- a/accessible/src/generic/ApplicationAccessible.cpp
+++ b/accessible/src/generic/ApplicationAccessible.cpp
@@ -21,17 +21,17 @@
 #include "mozilla/Services.h"
 #include "nsIStringBundle.h"
 
 using namespace mozilla::a11y;
 
 ApplicationAccessible::ApplicationAccessible() :
   AccessibleWrap(nullptr, nullptr)
 {
-  mFlags |= (eApplicationAccessible | eSharedNode);
+  mFlags |= eApplicationAccessible;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsISupports
 
 NS_IMPL_ISUPPORTS_INHERITED1(ApplicationAccessible, Accessible,
                              nsIAccessibleApplication)
 
@@ -105,22 +105,20 @@ ApplicationAccessible::Value(nsString& a
 }
 
 uint64_t
 ApplicationAccessible::State()
 {
   return IsDefunct() ? states::DEFUNCT : 0;
 }
 
-NS_IMETHODIMP
-ApplicationAccessible::GetAttributes(nsIPersistentProperties** aAttributes)
+already_AddRefed<nsIPersistentProperties>
+ApplicationAccessible::NativeAttributes()
 {
-  NS_ENSURE_ARG_POINTER(aAttributes);
-  *aAttributes = nullptr;
-  return NS_OK;
+  return nullptr;
 }
 
 GroupPos
 ApplicationAccessible::GroupPosition()
 {
   return GroupPos();
 }
 
@@ -366,32 +364,16 @@ ApplicationAccessible::GetSiblingAtOffse
 
   return nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessible
 
 NS_IMETHODIMP
-ApplicationAccessible::GetDOMNode(nsIDOMNode** aDOMNode)
-{
-  NS_ENSURE_ARG_POINTER(aDOMNode);
-  *aDOMNode = nullptr;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-ApplicationAccessible::GetDocument(nsIAccessibleDocument** aDocument)
-{
-  NS_ENSURE_ARG_POINTER(aDocument);
-  *aDocument = nullptr;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 ApplicationAccessible::GetRootDocument(nsIAccessibleDocument** aRootDocument)
 {
   NS_ENSURE_ARG_POINTER(aRootDocument);
   *aRootDocument = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/accessible/src/generic/ApplicationAccessible.h
+++ b/accessible/src/generic/ApplicationAccessible.h
@@ -23,36 +23,33 @@ namespace a11y {
  * And this one should be created when Mozilla Startup (if accessibility
  * feature has been enabled) and destroyed when Mozilla Shutdown.
  *
  * All the accessibility objects for toplevel windows are direct children of
  * the ApplicationAccessible instance.
  */
 
 class ApplicationAccessible : public AccessibleWrap,
-                             public nsIAccessibleApplication
+                              public nsIAccessibleApplication
 {
 public:
 
   ApplicationAccessible();
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIAccessible
-  NS_IMETHOD GetDOMNode(nsIDOMNode** aDOMNode);
-  NS_IMETHOD GetDocument(nsIAccessibleDocument** aDocument);
   NS_IMETHOD GetRootDocument(nsIAccessibleDocument** aRootDocument);
   NS_IMETHOD ScrollTo(uint32_t aScrollType);
   NS_IMETHOD ScrollToPoint(uint32_t aCoordinateType, int32_t aX, int32_t aY);
   NS_IMETHOD GetLanguage(nsAString& aLanguage);
   NS_IMETHOD GetParent(nsIAccessible **aParent);
   NS_IMETHOD GetNextSibling(nsIAccessible **aNextSibling);
   NS_IMETHOD GetPreviousSibling(nsIAccessible **aPreviousSibling);
-  NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
   NS_IMETHOD GetBounds(int32_t *aX, int32_t *aY,
                        int32_t *aWidth, int32_t *aHeight);
   NS_IMETHOD SetSelected(bool aIsSelected);
   NS_IMETHOD TakeSelection();
   NS_IMETHOD TakeFocus();
   NS_IMETHOD GetActionName(uint8_t aIndex, nsAString &aName);
   NS_IMETHOD GetActionDescription(uint8_t aIndex, nsAString &aDescription);
   NS_IMETHOD DoAction(uint8_t aIndex);
@@ -60,16 +57,17 @@ public:
   // nsIAccessibleApplication
   NS_DECL_NSIACCESSIBLEAPPLICATION
 
   // nsAccessNode
   virtual void Init();
   virtual void Shutdown();
 
   // Accessible
+  virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
   virtual GroupPos GroupPosition();
   virtual ENameValueFlag Name(nsString& aName);
   virtual void ApplyARIAState(uint64_t* aState) const;
   virtual void Description(nsString& aDescription);
   virtual void Value(nsString& aValue);
   virtual mozilla::a11y::role NativeRole();
   virtual uint64_t State();
   virtual uint64_t NativeState();
--- a/accessible/src/generic/BaseAccessibles.cpp
+++ b/accessible/src/generic/BaseAccessibles.cpp
@@ -232,8 +232,40 @@ EnumRoleAccessible::
 
 NS_IMPL_ISUPPORTS_INHERITED0(EnumRoleAccessible, Accessible)
 
 role
 EnumRoleAccessible::NativeRole()
 {
   return mRole;
 }
+
+////////////////////////////////////////////////////////////////////////////////
+// DummyAccessible
+////////////////////////////////////////////////////////////////////////////////
+
+uint64_t
+DummyAccessible::NativeState()
+{
+  return 0;
+}
+uint64_t
+DummyAccessible::NativeInteractiveState() const
+{
+  return 0;
+}
+
+uint64_t
+DummyAccessible::NativeLinkState() const
+{
+  return 0;
+}
+
+bool
+DummyAccessible::NativelyUnavailable() const
+{
+  return false;
+}
+
+void
+DummyAccessible::ApplyARIAState(uint64_t* aState) const
+{
+}
--- a/accessible/src/generic/BaseAccessibles.h
+++ b/accessible/src/generic/BaseAccessibles.h
@@ -102,12 +102,30 @@ public:
 
   // Accessible
   virtual a11y::role NativeRole();
 
 protected:
   a11y::role mRole;
 };
 
+
+/**
+ * A wrapper accessible around native accessible to connect it with
+ * crossplatform accessible tree.
+ */
+class DummyAccessible : public AccessibleWrap
+{
+public:
+  DummyAccessible() : AccessibleWrap(nullptr, nullptr) { }
+  virtual ~DummyAccessible() { }
+
+  virtual uint64_t NativeState() MOZ_OVERRIDE MOZ_FINAL;
+  virtual uint64_t NativeInteractiveState() const MOZ_OVERRIDE MOZ_FINAL;
+  virtual uint64_t NativeLinkState() const MOZ_OVERRIDE MOZ_FINAL;
+  virtual bool NativelyUnavailable() const MOZ_OVERRIDE MOZ_FINAL;
+  virtual void ApplyARIAState(uint64_t* aState) const MOZ_OVERRIDE MOZ_FINAL;
+};
+
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/src/generic/DocAccessible.cpp
+++ b/accessible/src/generic/DocAccessible.cpp
@@ -38,16 +38,17 @@
 #include "nsIPresShell.h"
 #include "nsIServiceManager.h"
 #include "nsIViewManager.h"
 #include "nsIScrollableFrame.h"
 #include "nsUnicharUtils.h"
 #include "nsIURI.h"
 #include "nsIWebNavigation.h"
 #include "nsFocusManager.h"
+#include "mozilla/Assertions.h"
 #include "mozilla/dom/Element.h"
 
 #ifdef A11Y_LOG
 #include "Logging.h"
 #endif
 
 #ifdef MOZ_XUL
 #include "nsIXULDocument.h"
@@ -79,19 +80,19 @@ DocAccessible::
   DocAccessible(nsIDocument* aDocument, nsIContent* aRootContent,
                   nsIPresShell* aPresShell) :
   HyperTextAccessibleWrap(aRootContent, this),
   mDocument(aDocument), mScrollPositionChangedTicks(0),
   mLoadState(eTreeConstructionPending), mLoadEventType(0),
   mVirtualCursor(nullptr),
   mPresShell(aPresShell)
 {
-  mFlags |= eDocAccessible;
-  if (mPresShell)
-    mPresShell->SetAccDocument(this);
+  mFlags |= eDocAccessible | eNotNodeMapEntry;
+  MOZ_ASSERT(mPresShell, "should have been given a pres shell");
+  mPresShell->SetDocAccessible(this);
 
   mDependentIDsHash.Init();
   // XXX aaronl should we use an algorithm for the initial cache size?
   mAccessibleCache.Init(kDefaultCacheSize);
   mNodeToAccessibleMap.Init(kDefaultCacheSize);
 
   // If this is a XUL Document, it should not implement nsHyperText
   if (mDocument && mDocument->IsXUL())
@@ -237,62 +238,35 @@ DocAccessible::NativeRole()
     else if (itemType == nsIDocShellTreeItem::typeContent) {
       return roles::DOCUMENT;
     }
   }
 
   return roles::PANE; // Fall back;
 }
 
-// Accessible public method
-void
-DocAccessible::SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry)
-{
-  NS_ASSERTION(mDocument, "No document during initialization!");
-  if (!mDocument)
-    return;
-
-  mRoleMapEntry = aRoleMapEntry;
-
-  nsIDocument *parentDoc = mDocument->GetParentDocument();
-  if (!parentDoc)
-    return; // No parent document for the root document
-
-  // Allow use of ARIA role from outer to override
-  nsIContent *ownerContent = parentDoc->FindContentForSubDocument(mDocument);
-  if (ownerContent) {
-    nsRoleMapEntry* roleMapEntry = aria::GetRoleMap(ownerContent);
-    if (roleMapEntry)
-      mRoleMapEntry = roleMapEntry; // Override
-  }
-}
-
 void
 DocAccessible::Description(nsString& aDescription)
 {
   if (mParent)
     mParent->Description(aDescription);
 
-  if (aDescription.IsEmpty())
+  if (HasOwnContent() && aDescription.IsEmpty()) {
     nsTextEquivUtils::
       GetTextEquivFromIDRefs(this, nsGkAtoms::aria_describedby,
                              aDescription);
+  }
 }
 
 // Accessible public method
 uint64_t
 DocAccessible::NativeState()
 {
-  // The root content of the document might be removed so that mContent is
-  // out of date.
-  uint64_t state = (mContent->GetCurrentDoc() == mDocument) ?
-    0 : states::STALE;
-
   // Document is always focusable.
-  state |= states::FOCUSABLE; // keep in sync with NativeIteractiveState() impl
+  uint64_t state = states::FOCUSABLE; // keep in sync with NativeInteractiveState() impl
   if (FocusMgr()->IsFocused(this))
     state |= states::FOCUSED;
 
   // Expose stale state until the document is ready (DOM is loaded and tree is
   // constructed).
   if (!HasLoadState(eReady))
     state |= states::STALE;
 
@@ -325,34 +299,43 @@ DocAccessible::NativelyUnavailable() con
 {
   return false;
 }
 
 // Accessible public method
 void
 DocAccessible::ApplyARIAState(uint64_t* aState) const
 {
-  // Combine with states from outer doc
-  // 
-  Accessible::ApplyARIAState(aState);
+  // Grab states from content element.
+  if (mContent)
+    Accessible::ApplyARIAState(aState);
 
-  // Allow iframe/frame etc. to have final state override via ARIA
+  // Allow iframe/frame etc. to have final state override via ARIA.
   if (mParent)
     mParent->ApplyARIAState(aState);
-
 }
 
-NS_IMETHODIMP
-DocAccessible::GetAttributes(nsIPersistentProperties** aAttributes)
+already_AddRefed<nsIPersistentProperties>
+DocAccessible::Attributes()
 {
-  Accessible::GetAttributes(aAttributes);
-  if (mParent) {
-    mParent->GetAttributes(aAttributes); // Add parent attributes (override inner)
-  }
-  return NS_OK;
+  nsCOMPtr<nsIPersistentProperties> attributes =
+    HyperTextAccessibleWrap::Attributes();
+
+  // No attributes if document is not attached to the tree or if it's a root
+  // document.
+  if (!mParent || IsRoot())
+    return attributes.forget();
+
+  // Override ARIA object attributes from outerdoc.
+  aria::AttrIterator attribIter(mParent->GetContent());
+  nsAutoString name, value, unused;
+  while(attribIter.Next(name, value))
+    attributes->SetStringProperty(NS_ConvertUTF16toUTF8(name), value, unused);
+
+  return attributes.forget();
 }
 
 Accessible*
 DocAccessible::FocusedChild()
 {
   // Return an accessible for the current global focus, which does not have to
   // be contained within the current document.
   return FocusMgr()->FocusedAccessible();
@@ -547,17 +530,17 @@ DocAccessible::GetVirtualCursor(nsIAcces
 
 // HyperTextAccessible method
 already_AddRefed<nsIEditor>
 DocAccessible::GetEditor() const
 {
   // Check if document is editable (designMode="on" case). Otherwise check if
   // the html:body (for HTML document case) or document element is editable.
   if (!mDocument->HasFlag(NODE_IS_EDITABLE) &&
-      !mContent->HasFlag(NODE_IS_EDITABLE))
+      (!mContent || !mContent->HasFlag(NODE_IS_EDITABLE)))
     return nullptr;
 
   nsCOMPtr<nsISupports> container = mDocument->GetContainer();
   nsCOMPtr<nsIEditingSession> editingSession(do_GetInterface(container));
   if (!editingSession)
     return nullptr; // No editing session interface
 
   nsCOMPtr<nsIEditor> editor;
@@ -630,17 +613,17 @@ DocAccessible::Shutdown()
   if (!mPresShell) // already shutdown
     return;
 
 #ifdef A11Y_LOG
   if (logging::IsEnabled(logging::eDocDestroy))
     logging::DocDestroy("document shutdown", mDocument, this);
 #endif
 
-  mPresShell->SetAccDocument(nullptr);
+  mPresShell->SetDocAccessible(nullptr);
 
   if (mNotificationController) {
     mNotificationController->Shutdown();
     mNotificationController = nullptr;
   }
 
   RemoveEventListeners();
 
@@ -1115,16 +1098,24 @@ DocAccessible::AttributeChangedImpl(nsIC
   }
 
   if (aAttribute == nsGkAtoms::contenteditable) {
     nsRefPtr<AccEvent> editableChangeEvent =
       new AccStateChangeEvent(aContent, states::EDITABLE);
     FireDelayedAccessibleEvent(editableChangeEvent);
     return;
   }
+
+  if (aAttribute == nsGkAtoms::value) {
+    Accessible* accessible = GetAccessible(aContent);
+    if(accessible && accessible->IsProgress()) {
+      FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE,
+                                 aContent);
+    }
+  }
 }
 
 // DocAccessible protected member
 void
 DocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute)
 {
   // Note: For universal/global ARIA states and properties we don't care if
   // there is an ARIA role present or not.
@@ -1372,30 +1363,30 @@ Accessible*
 DocAccessible::GetAccessibleOrContainer(nsINode* aNode)
 {
   if (!aNode || !aNode->IsInDoc())
     return nullptr;
 
   nsINode* currNode = aNode;
   Accessible* accessible = nullptr;
   while (!(accessible = GetAccessible(currNode)) &&
-         (currNode = currNode->GetNodeParent()));
+         (currNode = currNode->GetParentNode()));
 
   return accessible;
 }
 
 bool
 DocAccessible::BindToDocument(Accessible* aAccessible,
                               nsRoleMapEntry* aRoleMapEntry)
 {
   if (!aAccessible)
     return false;
 
   // Put into DOM node cache.
-  if (aAccessible->IsPrimaryForNode())
+  if (aAccessible->IsNodeMapEntry())
     mNodeToAccessibleMap.Put(aAccessible->GetNode(), aAccessible);
 
   // Put into unique ID cache.
   mAccessibleCache.Put(aAccessible->UniqueID(), aAccessible);
 
   // Initialize the accessible.
   aAccessible->Init();
 
@@ -1418,17 +1409,17 @@ DocAccessible::UnbindFromDocument(Access
     FocusMgr()->ActiveItemChanged(nullptr);
 #ifdef A11Y_LOG
           if (logging::IsEnabled(logging::eFocus))
             logging::ActiveItemChangeCausedBy("tree shutdown", aAccessible);
 #endif
   }
 
   // Remove an accessible from node-to-accessible map if it exists there.
-  if (aAccessible->IsPrimaryForNode() &&
+  if (aAccessible->IsNodeMapEntry() &&
       mNodeToAccessibleMap.Get(aAccessible->GetNode()) == aAccessible)
     mNodeToAccessibleMap.Remove(aAccessible->GetNode());
 
   void* uniqueID = aAccessible->UniqueID();
 
   NS_ASSERTION(!aAccessible->IsDefunct(), "Shutdown the shutdown accessible!");
   aAccessible->Shutdown();
 
@@ -1559,17 +1550,17 @@ void
 DocAccessible::DoInitialUpdate()
 {
   mLoadState |= eTreeConstructed;
 
   // The content element may be changed before the initial update and then we
   // miss the notification (since content tree change notifications are ignored
   // prior to initial update). Make sure the content element is valid.
   nsIContent* contentElm = nsCoreUtils::GetRoleContent(mDocument);
-  if (contentElm && mContent != contentElm)
+  if (mContent != contentElm)
     mContent = contentElm;
 
   // Build initial tree.
   CacheChildrenInSubtree(this);
 
   // Fire reorder event after the document tree is constructed. Note, since
   // this reorder event is processed by parent document then events targeted to
   // this document may be fired prior to this reorder event. If this is
@@ -1824,17 +1815,17 @@ DocAccessible::ProcessContentInserted(Ac
 {
   // Process the notification if the container accessible is still in tree.
   if (!HasAccessible(aContainer->GetNode()))
     return;
 
   if (aContainer == this) {
     // If new root content has been inserted then update it.
     nsIContent* rootContent = nsCoreUtils::GetRoleContent(mDocument);
-    if (rootContent && rootContent != mContent)
+    if (rootContent != mContent)
       mContent = rootContent;
 
     // Continue to update the tree even if we don't have root content.
     // For example, elements may be inserted under the document element while
     // there is no HTML body element.
   }
 
   // XXX: Invalidate parent-child relations for container accessible and its
@@ -2042,17 +2033,17 @@ DocAccessible::UncacheChildrenInSubtree(
 
   if (aRoot->IsElement())
     RemoveDependentIDsFor(aRoot);
 
   uint32_t count = aRoot->ContentChildCount();
   for (uint32_t idx = 0; idx < count; idx++)
     UncacheChildrenInSubtree(aRoot->ContentChildAt(idx));
 
-  if (aRoot->IsPrimaryForNode() &&
+  if (aRoot->IsNodeMapEntry() &&
       mNodeToAccessibleMap.Get(aRoot->GetNode()) == aRoot)
     mNodeToAccessibleMap.Remove(aRoot->GetNode());
 }
 
 void
 DocAccessible::ShutdownChildrenInSubtree(Accessible* aAccessible)
 {
   // Traverse through children and shutdown them before this accessible. When
--- a/accessible/src/generic/DocAccessible.h
+++ b/accessible/src/generic/DocAccessible.h
@@ -63,44 +63,42 @@ class DocAccessible : public HyperTextAc
 
 public:
 
   DocAccessible(nsIDocument* aDocument, nsIContent* aRootContent,
                 nsIPresShell* aPresShell);
   virtual ~DocAccessible();
 
   // nsIAccessible
-  NS_IMETHOD GetAttributes(nsIPersistentProperties** aAttributes);
   NS_IMETHOD TakeFocus(void);
 
   // nsIScrollPositionListener
   virtual void ScrollPositionWillChange(nscoord aX, nscoord aY) {}
   virtual void ScrollPositionDidChange(nscoord aX, nscoord aY);
 
   // nsIDocumentObserver
   NS_DECL_NSIDOCUMENTOBSERVER
 
   // nsAccessNode
   virtual void Init();
   virtual void Shutdown();
   virtual nsIFrame* GetFrame() const;
   virtual nsINode* GetNode() const { return mDocument; }
-  virtual nsIDocument* GetDocumentNode() const { return mDocument; }
+  nsIDocument* DocumentNode() const { return mDocument; }
 
   // Accessible
   virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
   virtual void Description(nsString& aDescription);
   virtual Accessible* FocusedChild();
   virtual mozilla::a11y::role NativeRole();
   virtual uint64_t NativeState();
   virtual uint64_t NativeInteractiveState() const;
   virtual bool NativelyUnavailable() const;
   virtual void ApplyARIAState(uint64_t* aState) const;
-
-  virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
+  virtual already_AddRefed<nsIPersistentProperties> Attributes();
 
 #ifdef A11Y_LOG
   virtual nsresult HandleAccEvent(AccEvent* aEvent);
 #endif
 
   virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
 
   // HyperTextAccessible
@@ -264,17 +262,17 @@ public:
    */
   Accessible* GetAccessibleOrContainer(nsINode* aNode);
 
   /**
    * Return a container accessible for the given DOM node.
    */
   Accessible* GetContainerAccessible(nsINode* aNode)
   {
-    return aNode ? GetAccessibleOrContainer(aNode->GetNodeParent()) : nullptr;
+    return aNode ? GetAccessibleOrContainer(aNode->GetParentNode()) : nullptr;
   }
 
   /**
    * Return true if the given ID is referred by relation attribute.
    *
    * @note Different elements may share the same ID if they are hosted inside
    *       XBL bindings. Be careful the result of this method may be  senseless
    *       while it's called for XUL elements (where XBL is used widely).
--- a/accessible/src/generic/FormControlAccessible.h
+++ b/accessible/src/generic/FormControlAccessible.h
@@ -16,17 +16,17 @@ namespace a11y {
   */
 template<int Max>
 class ProgressMeterAccessible : public LeafAccessible
 {
 public:
   ProgressMeterAccessible(nsIContent* aContent, DocAccessible* aDoc) :
     LeafAccessible(aContent, aDoc)
   {
-    mFlags = mFlags | eHasNumericValue;
+    mFlags |= eHasNumericValue | eProgressAccessible;
   }
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIACCESSIBLEVALUE
 
   // Accessible
   virtual void Value(nsString& aValue);
   virtual mozilla::a11y::role NativeRole();
--- a/accessible/src/generic/HyperTextAccessible.cpp
+++ b/accessible/src/generic/HyperTextAccessible.cpp
@@ -138,75 +138,74 @@ HyperTextAccessible::NativeState()
   return states;
 }
 
 // Substring must be entirely within the same text node
 nsIntRect
 HyperTextAccessible::GetBoundsForString(nsIFrame* aFrame, uint32_t aStartRenderedOffset,
                                         uint32_t aEndRenderedOffset)
 {
-  nsIntRect screenRect;
-  NS_ENSURE_TRUE(aFrame, screenRect);
+  nsPresContext* presContext = mDoc->PresContext();
   if (aFrame->GetType() != nsGkAtoms::textFrame) {
     // XXX fallback for non-text frames, happens for bullets right now
     // but in the future bullets will have proper text frames
-    return aFrame->GetScreenRectExternal();
+    return aFrame->GetScreenRectInAppUnits().
+      ToNearestPixels(presContext->AppUnitsPerDevPixel());
   }
 
   int32_t startContentOffset, endContentOffset;
   nsresult rv = RenderedToContentOffset(aFrame, aStartRenderedOffset, &startContentOffset);
-  NS_ENSURE_SUCCESS(rv, screenRect);
+  NS_ENSURE_SUCCESS(rv, nsIntRect());
   rv = RenderedToContentOffset(aFrame, aEndRenderedOffset, &endContentOffset);
-  NS_ENSURE_SUCCESS(rv, screenRect);
+  NS_ENSURE_SUCCESS(rv, nsIntRect());
 
   nsIFrame *frame;
   int32_t startContentOffsetInFrame;
   // Get the right frame continuation -- not really a child, but a sibling of
   // the primary frame passed in
   rv = aFrame->GetChildFrameContainingOffset(startContentOffset, false,
                                              &startContentOffsetInFrame, &frame);
-  NS_ENSURE_SUCCESS(rv, screenRect);
+  NS_ENSURE_SUCCESS(rv, nsIntRect());
 
-  nsPresContext* context = mDoc->PresContext();
-
+  nsRect screenRect;
   while (frame && startContentOffset < endContentOffset) {
     // Start with this frame's screen rect, which we will 
     // shrink based on the substring we care about within it.
     // We will then add that frame to the total screenRect we
     // are returning.
-    nsIntRect frameScreenRect = frame->GetScreenRectExternal();
+    nsRect frameScreenRect = frame->GetScreenRectInAppUnits();
 
     // Get the length of the substring in this frame that we want the bounds for
     int32_t startFrameTextOffset, endFrameTextOffset;
     frame->GetOffsets(startFrameTextOffset, endFrameTextOffset);
     int32_t frameTotalTextLength = endFrameTextOffset - startFrameTextOffset;
     int32_t seekLength = endContentOffset - startContentOffset;
     int32_t frameSubStringLength = NS_MIN(frameTotalTextLength - startContentOffsetInFrame, seekLength);
 
     // Add the point where the string starts to the frameScreenRect
     nsPoint frameTextStartPoint;
     rv = frame->GetPointFromOffset(startContentOffset, &frameTextStartPoint);
     NS_ENSURE_SUCCESS(rv, nsIntRect());
-    frameScreenRect.x += context->AppUnitsToDevPixels(frameTextStartPoint.x);
+    frameScreenRect.x += frameTextStartPoint.x;
 
     // Use the point for the end offset to calculate the width
     nsPoint frameTextEndPoint;
     rv = frame->GetPointFromOffset(startContentOffset + frameSubStringLength, &frameTextEndPoint);
     NS_ENSURE_SUCCESS(rv, nsIntRect());
-    frameScreenRect.width = context->AppUnitsToDevPixels(frameTextEndPoint.x - frameTextStartPoint.x);
+    frameScreenRect.width = frameTextEndPoint.x - frameTextStartPoint.x;
 
     screenRect.UnionRect(frameScreenRect, screenRect);
 
     // Get ready to loop back for next frame continuation
     startContentOffset += frameSubStringLength;
     startContentOffsetInFrame = 0;
     frame = frame->GetNextContinuation();
   }
 
-  return screenRect;
+  return screenRect.ToNearestPixels(presContext->AppUnitsPerDevPixel());
 }
 
 /*
  * Gets the specified text.
  */
 nsIFrame*
 HyperTextAccessible::GetPosAndText(int32_t& aStartOffset, int32_t& aEndOffset,
                                    nsAString* aText, nsIFrame** aEndFrame,
@@ -371,18 +370,19 @@ HyperTextAccessible::GetPosAndText(int32
               *aText += kImaginaryEmbeddedObjectChar;
               // Expose imaginary embedded object character if the accessible
               // hans't children.
             } else {
               *aText += kEmbeddedObjectChar;
             }
           }
           if (aBoundsRect) {
-            aBoundsRect->UnionRect(*aBoundsRect,
-                                   frame->GetScreenRectExternal());
+            nsIntRect frameScreenRect = frame->GetScreenRectInAppUnits().
+              ToNearestPixels(frame->PresContext()->AppUnitsPerDevPixel());
+            aBoundsRect->UnionRect(*aBoundsRect, frameScreenRect);
           }
         }
         if (!startFrame) {
           startFrame = frame;
           aStartOffset = 0;
           if (aStartAcc)
             NS_ADDREF(*aStartAcc = childAcc);
         }
@@ -1130,64 +1130,64 @@ HyperTextAccessible::GetLevelInternal()
   if (tag == nsGkAtoms::h5)
     return 5;
   if (tag == nsGkAtoms::h6)
     return 6;
 
   return AccessibleWrap::GetLevelInternal();
 }
 
-nsresult
-HyperTextAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
+already_AddRefed<nsIPersistentProperties>
+HyperTextAccessible::NativeAttributes()
 {
-  nsresult rv = AccessibleWrap::GetAttributesInternal(aAttributes);
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsIPersistentProperties> attributes =
+    AccessibleWrap::NativeAttributes();
 
-  // Indicate when the current object uses block-level formatting
-  // via formatting: block
-  // XXX: 'formatting' attribute is deprecated and will be removed in Mozilla2,
-  // use 'display' attribute instead.
+  // 'formatting' attribute is deprecated, 'display' attribute should be
+  // instead.
   nsIFrame *frame = GetFrame();
   if (frame && frame->GetType() == nsGkAtoms::blockFrame) {
-    nsAutoString oldValueUnused;
-    aAttributes->SetStringProperty(NS_LITERAL_CSTRING("formatting"), NS_LITERAL_STRING("block"),
-                                   oldValueUnused);
+    nsAutoString unused;
+    attributes->SetStringProperty(NS_LITERAL_CSTRING("formatting"),
+                                  NS_LITERAL_STRING("block"), unused);
   }
 
   if (FocusMgr()->IsFocused(this)) {
     int32_t lineNumber = CaretLineNumber();
     if (lineNumber >= 1) {
       nsAutoString strLineNumber;
       strLineNumber.AppendInt(lineNumber);
-      nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::lineNumber,
-                             strLineNumber);
+      nsAccUtils::SetAccAttr(attributes, nsGkAtoms::lineNumber, strLineNumber);
     }
   }
 
+  if (!HasOwnContent())
+    return attributes.forget();
+
   // For the html landmark elements we expose them like we do aria landmarks to
   // make AT navigation schemes "just work". Note html:header is redundant as
   // a landmark since it usually contains headings. We're not yet sure how the
   // web will use html:footer but our best bet right now is as contentinfo.
   if (mContent->Tag() == nsGkAtoms::nav)
-    nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::xmlroles,
+    nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
                            NS_LITERAL_STRING("navigation"));
   else if (mContent->Tag() == nsGkAtoms::section) 
-    nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::xmlroles,
+    nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
                            NS_LITERAL_STRING("region"));
   else if (mContent->Tag() == nsGkAtoms::footer) 
-    nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::xmlroles,
+    nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
                            NS_LITERAL_STRING("contentinfo"));
   else if (mContent->Tag() == nsGkAtoms::aside) 
-    nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::xmlroles,
+    nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
                            NS_LITERAL_STRING("complementary"));
   else if (mContent->Tag() == nsGkAtoms::article)
-    nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::xmlroles,
+    nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
                            NS_LITERAL_STRING("article"));
 
-  return  NS_OK;
+  return attributes.forget();
 }
 
 /*
  * Given an offset, the x, y, width, and height values are filled appropriately.
  */
 NS_IMETHODIMP
 HyperTextAccessible::GetCharacterExtents(int32_t aOffset, int32_t* aX, int32_t* aY,
                                          int32_t* aWidth, int32_t* aHeight,
@@ -1232,33 +1232,32 @@ HyperTextAccessible::GetOffsetAtPoint(in
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   nsIFrame *hyperFrame = GetFrame();
   if (!hyperFrame) {
     return NS_ERROR_FAILURE;
   }
-  nsIntRect frameScreenRect = hyperFrame->GetScreenRectExternal();
 
   nsIntPoint coords;
   nsresult rv = nsAccUtils::ConvertToScreenCoords(aX, aY, aCoordType,
                                                   this, &coords);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  // coords are currently screen coordinates, and we need to turn them into
-  // frame coordinates relative to the current accessible
-  if (!frameScreenRect.Contains(coords.x, coords.y)) {
+  nsPresContext* presContext = mDoc->PresContext();
+  nsPoint coordsInAppUnits =
+    coords.ToAppUnits(presContext->AppUnitsPerDevPixel());
+
+  nsRect frameScreenRect = hyperFrame->GetScreenRectInAppUnits();
+  if (!frameScreenRect.Contains(coordsInAppUnits.x, coordsInAppUnits.y))
     return NS_OK;   // Not found, will return -1
-  }
-  nsIntPoint pxInHyperText(coords.x - frameScreenRect.x,
-                           coords.y - frameScreenRect.y);
-  nsPresContext* context = mDoc->PresContext();
-  nsPoint pointInHyperText(context->DevPixelsToAppUnits(pxInHyperText.x),
-                           context->DevPixelsToAppUnits(pxInHyperText.y));
+
+  nsPoint pointInHyperText(coordsInAppUnits.x - frameScreenRect.x,
+                           coordsInAppUnits.y - frameScreenRect.y);
 
   // Go through the frames to check if each one has the point.
   // When one does, add up the character offsets until we have a match
 
   // We have an point in an accessible child of this, now we need to add up the
   // offsets before it to what we already have
   int32_t offset = 0;
   uint32_t childCount = ChildCount();
@@ -1267,17 +1266,17 @@ HyperTextAccessible::GetOffsetAtPoint(in
 
     nsIFrame *primaryFrame = childAcc->GetFrame();
     NS_ENSURE_TRUE(primaryFrame, NS_ERROR_FAILURE);
 
     nsIFrame *frame = primaryFrame;
     while (frame) {
       nsIContent *content = frame->GetContent();
       NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
-      nsPoint pointInFrame = pointInHyperText - frame->GetOffsetToExternal(hyperFrame);
+      nsPoint pointInFrame = pointInHyperText - frame->GetOffsetTo(hyperFrame);
       nsSize frameSize = frame->GetSize();
       if (pointInFrame.x < frameSize.width && pointInFrame.y < frameSize.height) {
         // Finished
         if (frame->GetType() == nsGkAtoms::textFrame) {
           nsIFrame::ContentOffsets contentOffsets =
             frame->GetContentOffsetsFromPointExternal(pointInFrame, nsIFrame::IGNORE_SELECTION_STYLE);
           if (contentOffsets.IsNull() || contentOffsets.content != content) {
             return NS_OK; // Not found, will return -1
@@ -1480,17 +1479,17 @@ HyperTextAccessible::GetEditor() const
 
   nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
     nsCoreUtils::GetDocShellTreeItemFor(mContent);
   nsCOMPtr<nsIEditingSession> editingSession(do_GetInterface(docShellTreeItem));
   if (!editingSession)
     return nullptr; // No editing session interface
 
   nsCOMPtr<nsIEditor> editor;
-  nsIDocument* docNode = mDoc->GetDocumentNode();
+  nsIDocument* docNode = mDoc->DocumentNode();
   editingSession->GetEditorForWindow(docNode->GetWindow(),
                                      getter_AddRefs(editor));
   return editor.forget();
 }
 
 /**
   * =================== Caret & Selection ======================
   */
@@ -1526,17 +1525,17 @@ HyperTextAccessible::SetSelectionRange(i
   // not focusable. That happens when selection is set within hypertext
   // accessible.
   if (isFocusable)
     return NS_OK;
 
   nsFocusManager* DOMFocusManager = nsFocusManager::GetFocusManager();
   if (DOMFocusManager) {
     NS_ENSURE_TRUE(mDoc, NS_ERROR_FAILURE);
-    nsIDocument* docNode = mDoc->GetDocumentNode();
+    nsIDocument* docNode = mDoc->DocumentNode();
     NS_ENSURE_TRUE(docNode, NS_ERROR_FAILURE);
     nsCOMPtr<nsPIDOMWindow> window = docNode->GetWindow();
     nsCOMPtr<nsIDOMElement> result;
     DOMFocusManager->MoveFocus(window, nullptr, nsIFocusManager::MOVEFOCUS_CARET,
                                nsIFocusManager::FLAG_BYMOVEFOCUS, getter_AddRefs(result));
   }
 
   return NS_OK;
@@ -1897,41 +1896,40 @@ HyperTextAccessible::ScrollSubstringToPo
   nsresult rv = nsAccUtils::ConvertToScreenCoords(aX, aY, aCoordinateType,
                                                   this, &coords);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsRefPtr<nsRange> range = new nsRange();
   rv = HypertextOffsetsToDOMRange(aStartIndex, aEndIndex, range);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsPresContext *presContext = frame->PresContext();
+  nsPresContext* presContext = frame->PresContext();
+  nsPoint coordsInAppUnits =
+    coords.ToAppUnits(presContext->AppUnitsPerDevPixel());
 
   bool initialScrolled = false;
   nsIFrame *parentFrame = frame;
   while ((parentFrame = parentFrame->GetParent())) {
     nsIScrollableFrame *scrollableFrame = do_QueryFrame(parentFrame);
     if (scrollableFrame) {
       if (!initialScrolled) {
         // Scroll substring to the given point. Turn the point into percents
         // relative scrollable area to use nsCoreUtils::ScrollSubstringTo.
-        nsIntRect frameRect = parentFrame->GetScreenRectExternal();
-        int32_t devOffsetX = coords.x - frameRect.x;
-        int32_t devOffsetY = coords.y - frameRect.y;
-
-        nsPoint offsetPoint(presContext->DevPixelsToAppUnits(devOffsetX),
-                            presContext->DevPixelsToAppUnits(devOffsetY));
+        nsRect frameRect = parentFrame->GetScreenRectInAppUnits();
+        nscoord offsetPointX = coordsInAppUnits.x - frameRect.x;
+        nscoord offsetPointY = coordsInAppUnits.y - frameRect.y;
 
         nsSize size(parentFrame->GetSize());
 
         // avoid divide by zero
         size.width = size.width ? size.width : 1;
         size.height = size.height ? size.height : 1;
 
-        int16_t hPercent = offsetPoint.x * 100 / size.width;
-        int16_t vPercent = offsetPoint.y * 100 / size.height;
+        int16_t hPercent = offsetPointX * 100 / size.width;
+        int16_t vPercent = offsetPointY * 100 / size.height;
 
         rv = nsCoreUtils::ScrollSubstringTo(frame, range, vPercent, hPercent);
         NS_ENSURE_SUCCESS(rv, rv);
 
         initialScrolled = true;
       } else {
         // Substring was scrolled to the given point already inside its closest
         // scrollable area. If there are nested scrollable areas then make
@@ -1944,33 +1942,32 @@ HyperTextAccessible::ScrollSubstringToPo
   }
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Accessible public
 
-nsresult
-HyperTextAccessible::GetNameInternal(nsAString& aName)
+// Accessible protected
+ENameValueFlag
+HyperTextAccessible::NativeName(nsString& aName)
 {
-  nsresult rv = AccessibleWrap::GetNameInternal(aName);
-  NS_ENSURE_SUCCESS(rv, rv);
+  ENameValueFlag nameFlag = AccessibleWrap::NativeName(aName);
+  if (!aName.IsEmpty())
+    return nameFlag;
 
   // Get name from title attribute for HTML abbr and acronym elements making it
   // a valid name from markup. Otherwise their name isn't picked up by recursive
   // name computation algorithm. See NS_OK_NAME_FROM_TOOLTIP.
-  if (aName.IsEmpty() && IsAbbreviation()) {
-    nsAutoString name;
-    if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::title, name)) {
-      name.CompressWhitespace();
-      aName = name;
-    }
-  }
-  return NS_OK;
+  if (IsAbbreviation() &&
+      mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::title, aName))
+    aName.CompressWhitespace();
+
+  return eNameOK;
 }
 
 void
 HyperTextAccessible::InvalidateChildren()
 {
   mOffsets.Clear();
 
   AccessibleWrap::InvalidateChildren();
@@ -2222,81 +2219,100 @@ HyperTextAccessible::RangeBoundToHyperte
 // HyperTextAccessible
 nsresult
 HyperTextAccessible::GetSpellTextAttribute(nsINode* aNode,
                                            int32_t aNodeOffset,
                                            int32_t* aHTStartOffset,
                                            int32_t* aHTEndOffset,
                                            nsIPersistentProperties* aAttributes)
 {
-  nsTArray<nsRange*> ranges;
-  GetSelectionDOMRanges(nsISelectionController::SELECTION_SPELLCHECK, &ranges);
+  nsRefPtr<nsFrameSelection> fs = FrameSelection();
+  if (!fs)
+    return NS_OK;
 
-  uint32_t rangeCount = ranges.Length();
-  if (!rangeCount)
+  Selection* domSel = fs->GetSelection(nsISelectionController::SELECTION_SPELLCHECK);
+  if (!domSel)
+    return NS_OK;
+
+  int32_t rangeCount = domSel->GetRangeCount();
+  if (rangeCount <= 0)
     return NS_OK;
 
-  nsCOMPtr<nsIDOMNode> DOMNode = do_QueryInterface(aNode);
-  for (uint32_t index = 0; index < rangeCount; index++) {
-    nsRange* range = ranges[index];
+  int32_t startHTOffset = 0, endHTOffset = 0;
+  nsresult rv = NS_OK;
+  for (int32_t idx = 0; idx < rangeCount; idx++) {
+    nsRange* range = domSel->GetRangeAt(idx);
+    if (range->Collapsed())
+      continue;
 
-    int16_t result;
-    nsresult rv = range->ComparePoint(DOMNode, aNodeOffset, &result);
-    NS_ENSURE_SUCCESS(rv, rv);
-    // ComparePoint checks boundary points, but we need to check that
-    // text at aNodeOffset is inside the range.
-    // See also bug 460690.
-    if (result == 0) {
-      if (aNode == range->GetEndParent() && aNodeOffset == range->EndOffset())
-        result = 1;
-    }
+    // See if the point comes after the range in which case we must continue in
+    // case there is another range after this one.
+    nsINode* endNode = range->GetEndParent();
+    int32_t endOffset = range->EndOffset();
+    if (nsContentUtils::ComparePoints(aNode, aNodeOffset, endNode, endOffset) >= 0)
+      continue;
 
-    if (result == 1) { // range is before point
-      int32_t startHTOffset = 0;
-      nsresult rv = RangeBoundToHypertextOffset(range, false, true,
-                                                &startHTOffset);
+    // At this point our point is either in this range or before it but after
+    // the previous range.  So we check to see if the range starts before the
+    // point in which case the point is in the missspelled range, otherwise it
+    // must be before the range and after the previous one if any.
+    nsINode* startNode = range->GetStartParent();
+    int32_t startOffset = range->StartOffset();
+    if (nsContentUtils::ComparePoints(startNode, startOffset, aNode,
+                                      aNodeOffset) <= 0) {
+      rv = RangeBoundToHypertextOffset(range, true, true, &startHTOffset);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      rv = RangeBoundToHypertextOffset(range, false, false, &endHTOffset);
       NS_ENSURE_SUCCESS(rv, rv);
 
       if (startHTOffset > *aHTStartOffset)
         *aHTStartOffset = startHTOffset;
 
-    } else if (result == -1) { // range is after point
-      int32_t endHTOffset = 0;
-      nsresult rv = RangeBoundToHypertextOffset(range, true, false,
-                                                &endHTOffset);
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      if (endHTOffset < *aHTEndOffset)
-        *aHTEndOffset = endHTOffset;
-
-    } else { // point is in range
-      int32_t startHTOffset = 0;
-      nsresult rv = RangeBoundToHypertextOffset(range, true, true,
-                                                &startHTOffset);
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      int32_t endHTOffset = 0;
-      rv = RangeBoundToHypertextOffset(range, false, false,
-                                       &endHTOffset);
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      if (startHTOffset > *aHTStartOffset)
-        *aHTStartOffset = startHTOffset;
       if (endHTOffset < *aHTEndOffset)
         *aHTEndOffset = endHTOffset;
 
       if (aAttributes) {
         nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::invalid,
                                NS_LITERAL_STRING("spelling"));
       }
 
       return NS_OK;
     }
+
+    // This range came after the point.
+    rv = RangeBoundToHypertextOffset(range, true, false, &endHTOffset);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    if (idx > 0) {
+      rv = RangeBoundToHypertextOffset(domSel->GetRangeAt(idx - 1), false,
+                                       true, &startHTOffset);
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
+
+    if (startHTOffset > *aHTStartOffset)
+      *aHTStartOffset = startHTOffset;
+
+    if (endHTOffset < *aHTEndOffset)
+      *aHTEndOffset = endHTOffset;
+
+    return NS_OK;
   }
 
+  // We never found a range that ended after the point, therefore we know that
+  // the point is not in a range, that we do not need to compute an end offset,
+  // and that we should use the end offset of the last range to compute the
+  // start offset of the text attribute range.
+  rv = RangeBoundToHypertextOffset(domSel->GetRangeAt(rangeCount - 1), false,
+                                   true, &startHTOffset);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (startHTOffset > *aHTStartOffset)
+    *aHTStartOffset = startHTOffset;
+
   return NS_OK;
 }
 
 bool 
 HyperTextAccessible::IsTextRole()
 {
   if (mRoleMapEntry &&
       (mRoleMapEntry->role == roles::GRAPHIC ||
--- a/accessible/src/generic/HyperTextAccessible.h
+++ b/accessible/src/generic/HyperTextAccessible.h
@@ -46,18 +46,17 @@ public:
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIACCESSIBLETEXT
   NS_DECL_NSIACCESSIBLEHYPERTEXT
   NS_DECL_NSIACCESSIBLEEDITABLETEXT
 
   // Accessible
   virtual int32_t GetLevelInternal();
-  virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
-  virtual nsresult GetNameInternal(nsAString& aName);
+  virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
   virtual mozilla::a11y::role NativeRole();
   virtual uint64_t NativeState();
 
   virtual void InvalidateChildren();
   virtual bool RemoveChild(Accessible* aAccessible);
 
   // HyperTextAccessible (static helper method)
 
@@ -238,16 +237,19 @@ public:
   // EditableTextAccessible
 
   /**
    * Return the editor associated with the accessible.
    */
   virtual already_AddRefed<nsIEditor> GetEditor() const;
 
 protected:
+  // Accessible
+  virtual mozilla::a11y::ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
+
   // HyperTextAccessible
 
   /**
    * Transform magic offset into text offset.
    */
   int32_t ConvertMagicOffset(int32_t aOffset)
   {
     if (aOffset == nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT)
--- a/accessible/src/generic/ImageAccessible.cpp
+++ b/accessible/src/generic/ImageAccessible.cpp
@@ -64,36 +64,33 @@ ImageAccessible::NativeState()
     imgContainer->GetAnimated(&animated);
     if (animated)
       state |= states::ANIMATED;
   }
 
   return state;
 }
 
-nsresult
-ImageAccessible::GetNameInternal(nsAString& aName)
+ENameValueFlag
+ImageAccessible::NativeName(nsString& aName)
 {
   bool hasAltAttrib =
     mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName);
   if (!aName.IsEmpty())
-    return NS_OK;
+    return eNameOK;
 
-  nsresult rv = Accessible::GetNameInternal(aName);
-  NS_ENSURE_SUCCESS(rv, rv);
+  ENameValueFlag nameFlag = Accessible::NativeName(aName);
+  if (!aName.IsEmpty())
+    return nameFlag;
 
-  if (aName.IsEmpty() && hasAltAttrib) {
-    // No accessible name but empty 'alt' attribute is present. If further name
-    // computation algorithm doesn't provide non empty name then it means
-    // an empty 'alt' attribute was used to indicate a decorative image (see
-    // nsIAccessible::name attribute for details).
-    return NS_OK_EMPTY_NAME;
-  }
-
-  return NS_OK;
+  // No accessible name but empty 'alt' attribute is present. If further name
+  // computation algorithm doesn't provide non empty name then it means
+  // an empty 'alt' attribute was used to indicate a decorative image (see
+  // Accessible::Name() method for details).
+  return hasAltAttrib ? eNoNameOnPurpose : eNameOK;
 }
 
 role
 ImageAccessible::NativeRole()
 {
   return roles::GRAPHIC;
 }
 
@@ -167,31 +164,28 @@ ImageAccessible::GetImagePosition(uint32
 NS_IMETHODIMP
 ImageAccessible::GetImageSize(int32_t* aWidth, int32_t* aHeight)
 {
   int32_t x, y;
   return GetBounds(&x, &y, aWidth, aHeight);
 }
 
 // Accessible
-nsresult
-ImageAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
+already_AddRefed<nsIPersistentProperties>
+ImageAccessible::NativeAttributes()
 {
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  nsresult rv = LinkableAccessible::GetAttributesInternal(aAttributes);
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsIPersistentProperties> attributes =
+    LinkableAccessible::NativeAttributes();
 
   nsAutoString src;
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::src, src);
   if (!src.IsEmpty())
-    nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::src, src);
+    nsAccUtils::SetAccAttr(attributes, nsGkAtoms::src, src);
 
-  return NS_OK;
+  return attributes.forget();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Private methods
 
 already_AddRefed<nsIURI>
 ImageAccessible::GetLongDescURI() const
 {
--- a/accessible/src/generic/ImageAccessible.h
+++ b/accessible/src/generic/ImageAccessible.h
@@ -31,24 +31,27 @@ public:
   // nsIAccessible
   NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName);
   NS_IMETHOD DoAction(uint8_t index);
 
   // nsIAccessibleImage
   NS_DECL_NSIACCESSIBLEIMAGE
 
   // Accessible
-  virtual nsresult GetNameInternal(nsAString& aName);
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
-  virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
+  virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
 
   // ActionAccessible
   virtual uint8_t ActionCount();
 
+protected:
+  // Accessible
+  virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
+
 private:
   /**
    * Return whether the element has a longdesc URI.
    */
   bool HasLongDesc() const
   {
     nsCOMPtr<nsIURI> uri = GetLongDescURI();
     return uri;
--- a/accessible/src/generic/OuterDocAccessible.cpp
+++ b/accessible/src/generic/OuterDocAccessible.cpp
@@ -62,29 +62,16 @@ OuterDocAccessible::ChildAtPoint(int32_t
   Accessible* child = GetChildAt(0);
   NS_ENSURE_TRUE(child, nullptr);
 
   if (aWhichChild == eDeepestChild)
     return child->ChildAtPoint(aX, aY, eDeepestChild);
   return child;
 }
 
-nsresult
-OuterDocAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
-{
-  nsAutoString tag;
-  aAttributes->GetStringProperty(NS_LITERAL_CSTRING("tag"), tag);
-  if (!tag.IsEmpty()) {
-    // We're overriding the ARIA attributes on an sub document, but we don't want to
-    // override the other attributes
-    return NS_OK;
-  }
-  return Accessible::GetAttributesInternal(aAttributes);
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessible
 
 uint8_t
 OuterDocAccessible::ActionCount()
 {
   // Internal frame, which is the doc's parent, should not have a click action.
   return 0;
@@ -128,17 +115,17 @@ OuterDocAccessible::Shutdown()
     logging::OuterDocDestroy(this);
 #endif
 
   Accessible* childAcc = mChildren.SafeElementAt(0, nullptr);
   if (childAcc) {
 #ifdef A11Y_LOG
     if (logging::IsEnabled(logging::eDocDestroy)) {
       logging::DocDestroy("outerdoc's child document shutdown",
-                          childAcc->GetDocumentNode());
+                          childAcc->AsDoc()->DocumentNode());
     }
 #endif
     childAcc->Shutdown();
   }
 
   AccessibleWrap::Shutdown();
 }
 
@@ -172,17 +159,17 @@ OuterDocAccessible::AppendChild(Accessib
     mChildren[0]->Shutdown();
 
   if (!AccessibleWrap::AppendChild(aAccessible))
     return false;
 
 #ifdef A11Y_LOG
   if (logging::IsEnabled(logging::eDocCreate)) {
     logging::DocCreate("append document to outerdoc",
-                       aAccessible->GetDocumentNode());
+                       aAccessible->AsDoc()->DocumentNode());
     logging::Address("outerdoc", this);
   }
 #endif
 
   return true;
 }
 
 bool
@@ -191,18 +178,18 @@ OuterDocAccessible::RemoveChild(Accessib
   Accessible* child = mChildren.SafeElementAt(0, nullptr);
   if (child != aAccessible) {
     NS_ERROR("Wrong child to remove!");
     return false;
   }
 
 #ifdef A11Y_LOG
   if (logging::IsEnabled(logging::eDocDestroy)) {
-    logging::DocDestroy("remove document from outerdoc", child->GetDocumentNode(),
-                        child->AsDoc());
+    logging::DocDestroy("remove document from outerdoc",
+                        child->AsDoc()->DocumentNode(), child->AsDoc());
     logging::Address("outerdoc", this);
   }
 #endif
 
   bool wasRemoved = AccessibleWrap::RemoveChild(child);
 
   NS_ASSERTION(!mChildren.Length(),
                "This child document of outerdoc accessible wasn't removed!");
--- a/accessible/src/generic/OuterDocAccessible.h
+++ b/accessible/src/generic/OuterDocAccessible.h
@@ -33,17 +33,16 @@ public:
   NS_IMETHOD GetActionDescription(uint8_t aIndex, nsAString& aDescription);
   NS_IMETHOD DoAction(uint8_t aIndex);
 
   // nsAccessNode
   virtual void Shutdown();
 
   // Accessible
   virtual mozilla::a11y::role NativeRole();
-  virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
   virtual Accessible* ChildAtPoint(int32_t aX, int32_t aY,
                                    EWhichChildAtPoint aWhichChild);
 
   virtual void InvalidateChildren();
   virtual bool AppendChild(Accessible* aAccessible);
   virtual bool RemoveChild(Accessible* aAccessible);
 
   // ActionAccessible
--- a/accessible/src/generic/RootAccessible.cpp
+++ b/accessible/src/generic/RootAccessible.cpp
@@ -470,19 +470,23 @@ RootAccessible::ProcessDOMEvent(nsIDOMEv
 
     FocusMgr()->ActiveItemChanged(nullptr);
 #ifdef A11Y_LOG
     if (logging::IsEnabled(logging::eFocus))
       logging::ActiveItemChangeCausedBy("DOMMenuBarInactive", accessible);
 #endif
   }
   else if (eventType.EqualsLiteral("ValueChange")) {
-    targetDocument->
-      FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE,
-                                 targetNode, AccEvent::eRemoveDupes);
+
+    //We don't process 'ValueChange' events for progress meters since we listen
+    //@value attribute change for them.
+    if (!accessible->IsProgress())
+      targetDocument->
+        FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE,
+                                   targetNode);
   }
 #ifdef DEBUG_DRAGDROPSTART
   else if (eventType.EqualsLiteral("mouseover")) {
     nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_DRAGDROP_START,
                             accessible);
   }
 #endif
 }
--- a/accessible/src/html/HTMLElementAccessibles.cpp
+++ b/accessible/src/html/HTMLElementAccessibles.cpp
@@ -36,33 +36,34 @@ HTMLBRAccessible::NativeRole()
 }
 
 uint64_t
 HTMLBRAccessible::NativeState()
 {
   return states::READONLY;
 }
 
-nsresult
-HTMLBRAccessible::GetNameInternal(nsAString& aName)
+ENameValueFlag
+HTMLBRAccessible::NativeName(nsString& aName)
 {
   aName = static_cast<PRUnichar>('\n');    // Newline char
-  return NS_OK;
+  return eNameOK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLLabelAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_IMPL_ISUPPORTS_INHERITED0(HTMLLabelAccessible, HyperTextAccessible)
 
-nsresult
-HTMLLabelAccessible::GetNameInternal(nsAString& aName)
+ENameValueFlag
+HTMLLabelAccessible::NativeName(nsString& aName)
 {
-  return nsTextEquivUtils::GetNameFromSubtree(this, aName);
+  nsTextEquivUtils::GetNameFromSubtree(this, aName);
+  return aName.IsEmpty() ? eNameOK : eNameFromSubtree;
 }
 
 role
 HTMLLabelAccessible::NativeRole()
 {
   return roles::LABEL;
 }
 
@@ -83,20 +84,19 @@ HTMLOutputAccessible::RelationByType(uin
 }
 
 role
 HTMLOutputAccessible::NativeRole()
 {
   return roles::SECTION;
 }
 
-nsresult
-HTMLOutputAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
+already_AddRefed<nsIPersistentProperties>
+HTMLOutputAccessible::NativeAttributes()
 {
-  nsresult rv = AccessibleWrap::GetAttributesInternal(aAttributes);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::live,
+  nsCOMPtr<nsIPersistentProperties> attributes =
+    AccessibleWrap::NativeAttributes();
+  nsAccUtils::SetAccAttr(attributes, nsGkAtoms::live,
                          NS_LITERAL_STRING("polite"));
 
-  return NS_OK;
+  return attributes.forget();
 }
 
--- a/accessible/src/html/HTMLElementAccessibles.h
+++ b/accessible/src/html/HTMLElementAccessibles.h
@@ -27,57 +27,61 @@ public:
 };
 
 /**
  * Used for HTML br element.
  */
 class HTMLBRAccessible : public LeafAccessible
 {
 public:
-
   HTMLBRAccessible(nsIContent* aContent, DocAccessible* aDoc) :
     LeafAccessible(aContent, aDoc) {};
 
   // Accessible
-  virtual nsresult GetNameInternal(nsAString& aName);
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
+
+protected:
+  // Accessible
+  virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
 };
 
 /**
  * Used for HTML label element.
  */
 class HTMLLabelAccessible : public HyperTextAccessibleWrap
 {
 public:
 
   HTMLLabelAccessible(nsIContent* aContent, DocAccessible* aDoc) :
     HyperTextAccessibleWrap(aContent, aDoc) {};
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // Accessible
-  virtual nsresult GetNameInternal(nsAString& aName);
   virtual a11y::role NativeRole();
+
+protected:
+  virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
 };
 
 /**
  * Used for HTML output element.
  */
 class HTMLOutputAccessible : public HyperTextAccessibleWrap
 {
 public:
 
   HTMLOutputAccessible(nsIContent* aContent, DocAccessible* aDoc) :
     HyperTextAccessibleWrap(aContent, aDoc) {};
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // Accessible
   virtual a11y::role NativeRole();
-  virtual nsresult GetAttributesInternal(nsIPersistentProperties* aAttributes);
+  virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
   virtual Relation RelationByType(uint32_t aType);
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/src/html/HTMLFormControlAccessible.cpp
+++ b/accessible/src/html/HTMLFormControlAccessible.cpp
@@ -251,47 +251,42 @@ HTMLButtonAccessible::NativeState()
 }
 
 role
 HTMLButtonAccessible::NativeRole()
 {
   return roles::PUSHBUTTON;
 }
 
-nsresult
-HTMLButtonAccessible::GetNameInternal(nsAString& aName)
+ENameValueFlag
+HTMLButtonAccessible::NativeName(nsString& aName)
 {
-  Accessible::GetNameInternal(aName);
+  ENameValueFlag nameFlag = Accessible::NativeName(aName);
   if (!aName.IsEmpty() || mContent->Tag() != nsGkAtoms::input)
-    return NS_OK;
+    return nameFlag;
 
-  // No name from HTML or ARIA
-  nsAutoString name;
-  if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value,
-                         name) &&
-      !mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt,
-                         name)) {
+  // Note: No need to check @value attribute since it results in anonymous text
+  // node. The name is calculated from subtree in this case.
+  if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName)) {
     // Use the button's (default) label if nothing else works
     nsIFrame* frame = GetFrame();
     if (frame) {
       nsIFormControlFrame* fcFrame = do_QueryFrame(frame);
       if (fcFrame)
-        fcFrame->GetFormProperty(nsGkAtoms::defaultLabel, name);
+        fcFrame->GetFormProperty(nsGkAtoms::defaultLabel, aName);
     }
   }
 
-  if (name.IsEmpty() &&
-      !mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::src, name)) {
-    mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::data, name);
+  if (aName.IsEmpty() &&
+      !mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::src, aName)) {
+    mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::data, aName);
   }
 
-  name.CompressWhitespace();
-  aName = name;
-
-  return NS_OK;
+  aName.CompressWhitespace();
+  return eNameOK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLButtonAccessible: Widgets
 
 bool
 HTMLButtonAccessible::IsWidget() const
 {
@@ -320,44 +315,40 @@ HTMLTextFieldAccessible::NativeRole()
   if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
                             nsGkAtoms::password, eIgnoreCase)) {
     return roles::PASSWORD_TEXT;
   }
   
   return roles::ENTRY;
 }
 
-nsresult
-HTMLTextFieldAccessible::GetNameInternal(nsAString& aName)
+ENameValueFlag
+HTMLTextFieldAccessible::NativeName(nsString& aName)
 {
-  nsresult rv = Accessible::GetNameInternal(aName);
-  NS_ENSURE_SUCCESS(rv, rv);
+  ENameValueFlag nameFlag = Accessible::NativeName(aName);
+  if (!aName.IsEmpty())
+    return nameFlag;
 
-  if (!aName.IsEmpty())
-    return NS_OK;
-
-  if (mContent->GetBindingParent())
-  {
+  if (mContent->GetBindingParent()) {
     // XXX: bug 459640
     // There's a binding parent.
     // This means we're part of another control, so use parent accessible for name.
     // This ensures that a textbox inside of a XUL widget gets
     // an accessible name.
     Accessible* parent = Parent();
     if (parent)
       parent->GetName(aName);
   }
 
   if (!aName.IsEmpty())
-    return NS_OK;
+    return eNameOK;
 
   // text inputs and textareas might have useful placeholder text
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::placeholder, aName);
-
-  return NS_OK;
+  return eNameOK;
 }
 
 void
 HTMLTextFieldAccessible::Value(nsString& aValue)
 {
   aValue.Truncate();
   if (NativeState() & states::PROTECTED)    // Don't return password text!
     return;
@@ -614,32 +605,28 @@ HTMLGroupboxAccessible::GetLegend()
       // Either XHTML namespace or no namespace
       return legendContent;
     }
   }
 
   return nullptr;
 }
 
-nsresult
-HTMLGroupboxAccessible::GetNameInternal(nsAString& aName)
+ENameValueFlag
+HTMLGroupboxAccessible::NativeName(nsString& aName)
 {
-  nsresult rv = Accessible::GetNameInternal(aName);
-  NS_ENSURE_SUCCESS(rv, rv);
-
+  ENameValueFlag nameFlag = Accessible::NativeName(aName);
   if (!aName.IsEmpty())
-    return NS_OK;
+    return nameFlag;
 
-  nsIContent *legendContent = GetLegend();
-  if (legendContent) {
-    return nsTextEquivUtils::
-      AppendTextEquivFromContent(this, legendContent, &aName);
-  }
+  nsIContent* legendContent = GetLegend();
+  if (legendContent)
+    nsTextEquivUtils::AppendTextEquivFromContent(this, legendContent, &aName);
 
-  return NS_OK;
+  return eNameOK;
 }
 
 Relation
 HTMLGroupboxAccessible::RelationByType(uint32_t aType)
 {
   Relation rel = HyperTextAccessibleWrap::RelationByType(aType);
     // No override for label, so use <legend> for this <fieldset>
   if (aType == nsIAccessibleRelation::RELATION_LABELLED_BY)
@@ -683,50 +670,46 @@ HTMLLegendAccessible::NativeRole()
 ////////////////////////////////////////////////////////////////////////////////
 
 HTMLFigureAccessible::
   HTMLFigureAccessible(nsIContent* aContent, DocAccessible* aDoc) :
   HyperTextAccessibleWrap(aContent, aDoc)
 {
 }
 
-nsresult
-HTMLFigureAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
+already_AddRefed<nsIPersistentProperties>
+HTMLFigureAccessible::NativeAttributes()
 {
-  nsresult rv = HyperTextAccessibleWrap::GetAttributesInternal(aAttributes);
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsIPersistentProperties> attributes =
+    HyperTextAccessibleWrap::NativeAttributes();
 
   // Expose figure xml-role.
-  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::xmlroles,
+  nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
                          NS_LITERAL_STRING("figure"));
-  return NS_OK;
+  return attributes.forget();
 }
 
 role
 HTMLFigureAccessible::NativeRole()
 {
   return roles::FIGURE;
 }
 
-nsresult
-HTMLFigureAccessible::GetNameInternal(nsAString& aName)
+ENameValueFlag
+HTMLFigureAccessible::NativeName(nsString& aName)
 {
-  nsresult rv = HyperTextAccessibleWrap::GetNameInternal(aName);
-  NS_ENSURE_SUCCESS(rv, rv);
-
+  ENameValueFlag nameFlag = HyperTextAccessibleWrap::NativeName(aName);
   if (!aName.IsEmpty())
-    return NS_OK;
+    return nameFlag;
 
   nsIContent* captionContent = Caption();
-  if (captionContent) {
-    return nsTextEquivUtils::
-      AppendTextEquivFromContent(this, captionContent, &aName);
-  }
+  if (captionContent)
+    nsTextEquivUtils::AppendTextEquivFromContent(this, captionContent, &aName);
 
-  return NS_OK;
+  return eNameOK;
 }
 
 Relation
 HTMLFigureAccessible::RelationByType(uint32_t aType)
 {
   Relation rel = HyperTextAccessibleWrap::RelationByType(aType);
   if (aType == nsIAccessibleRelation::RELATION_LABELLED_BY)
     rel.AppendTarget(mDoc, Caption());
--- a/accessible/src/html/HTMLFormControlAccessible.h
+++ b/accessible/src/html/HTMLFormControlAccessible.h
@@ -72,26 +72,29 @@ public:
 
   HTMLButtonAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // nsIAccessible
   NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName);
   NS_IMETHOD DoAction(uint8_t index);
 
   // Accessible
-  virtual nsresult GetNameInternal(nsAString& aName);
   virtual mozilla::a11y::role NativeRole();
   virtual uint64_t State();
   virtual uint64_t NativeState();
 
   // ActionAccessible
   virtual uint8_t ActionCount();
 
   // Widgets
   virtual bool IsWidget() const;
+
+protected:
+  // Accessible
+  virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
 };
 
 
 /**
  * Accessible for HTML input@type="text" element.
  */
 class HTMLTextFieldAccessible : public HyperTextAccessibleWrap
 {
@@ -108,27 +111,30 @@ public:
   NS_IMETHOD DoAction(uint8_t index);
 
   // HyperTextAccessible
   virtual already_AddRefed<nsIEditor> GetEditor() const;
 
   // Accessible
   virtual void Value(nsString& aValue);
   virtual void ApplyARIAState(uint64_t* aState) const;
-  virtual nsresult GetNameInternal(nsAString& aName);
   virtual mozilla::a11y::role NativeRole();
   virtual uint64_t State();
   virtual uint64_t NativeState();
 
   // ActionAccessible
   virtual uint8_t ActionCount();
 
   // Widgets
   virtual bool IsWidget() const;
   virtual Accessible* ContainerWidget() const;
+
+protected:
+  // Accessible
+  virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
 };
 
 
 /**
  * Accessible for input@type="file" element.
  */
 class HTMLFileInputAccessible : public HyperTextAccessibleWrap
 {
@@ -144,21 +150,24 @@ public:
  * Accessible for HTML fieldset element.
  */
 class HTMLGroupboxAccessible : public HyperTextAccessibleWrap
 {
 public:
   HTMLGroupboxAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
-  virtual nsresult GetNameInternal(nsAString& aName);
   virtual mozilla::a11y::role NativeRole();
   virtual Relation RelationByType(uint32_t aType);
 
 protected:
+  // Accessible
+  virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
+
+  // HTMLGroupboxAccessible
   nsIContent* GetLegend();
 };
 
 
 /**
  * Accessible for HTML legend element.
  */
 class HTMLLegendAccessible : public HyperTextAccessibleWrap
@@ -175,22 +184,25 @@ public:
  * Accessible for HTML5 figure element.
  */
 class HTMLFigureAccessible : public HyperTextAccessibleWrap
 {
 public:
   HTMLFigureAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
-  virtual nsresult GetAttributesInternal(nsIPersistentProperties* aAttributes);
-  virtual nsresult GetNameInternal(nsAString& aName);
+  virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
   virtual mozilla::a11y::role NativeRole();
   virtual Relation RelationByType(uint32_t aType);
 
 protected:
+  // Accessible
+  virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
+
+  // HTMLLegendAccessible
   nsIContent* Caption() const;
 };
 
 
 /**
  * Accessible for HTML5 figcaption element.
  */
 class HTMLFigcaptionAccessible : public HyperTextAccessibleWrap
--- a/accessible/src/html/HTMLImageMapAccessible.cpp
+++ b/accessible/src/html/HTMLImageMapAccessible.cpp
@@ -147,37 +147,35 @@ HTMLImageMapAccessible::CacheChildren()
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLAreaAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 HTMLAreaAccessible::
   HTMLAreaAccessible(nsIContent* aContent, DocAccessible* aDoc) :
   HTMLLinkAccessible(aContent, aDoc)
 {
-  // Make HTML area DOM element not accessible. HTML image map accessible			
+  // Make HTML area DOM element not accessible. HTML image map accessible
   // manages its tree itself.
-  mFlags |= eSharedNode;
+  mFlags |= eNotNodeMapEntry;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLAreaAccessible: nsIAccessible
 
-nsresult
-HTMLAreaAccessible::GetNameInternal(nsAString& aName)
+ENameValueFlag
+HTMLAreaAccessible::NativeName(nsString& aName)
 {
-  nsresult rv = Accessible::GetNameInternal(aName);
-  NS_ENSURE_SUCCESS(rv, rv);
-
+  ENameValueFlag nameFlag = Accessible::NativeName(aName);
   if (!aName.IsEmpty())
-    return NS_OK;
+    return nameFlag;
 
   if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName))
-    return GetValue(aName);
+    GetValue(aName);
 
-  return NS_OK;
+  return eNameOK;
 }
 
 void
 HTMLAreaAccessible::Description(nsString& aDescription)
 {
   aDescription.Truncate();
 
   // Still to do - follow IE's standard here
--- a/accessible/src/html/HTMLImageMapAccessible.h
+++ b/accessible/src/html/HTMLImageMapAccessible.h
@@ -50,28 +50,27 @@ protected:
 class HTMLAreaAccessible : public HTMLLinkAccessible
 {
 public:
 
   HTMLAreaAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
   virtual void Description(nsString& aDescription);
-  virtual nsresult GetNameInternal(nsAString& aName);
   virtual Accessible* ChildAtPoint(int32_t aX, int32_t aY,
                                    EWhichChildAtPoint aWhichChild);
   virtual void GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame);
 
   // HyperLinkAccessible
   virtual uint32_t StartOffset();
   virtual uint32_t EndOffset();
 
 protected:
-
   // Accessible
+  virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
   virtual void CacheChildren();
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 ////////////////////////////////////////////////////////////////////////////////
 // Accessible downcasting method
--- a/accessible/src/html/HTMLSelectAccessible.cpp
+++ b/accessible/src/html/HTMLSelectAccessible.cpp
@@ -180,44 +180,35 @@ role
 HTMLSelectOptionAccessible::NativeRole()
 {
   if (mParent && mParent->Role() == roles::COMBOBOX_LIST)
     return roles::COMBOBOX_OPTION;
 
   return roles::OPTION;
 }
 
-nsresult
-HTMLSelectOptionAccessible::GetNameInternal(nsAString& aName)
+ENameValueFlag
+HTMLSelectOptionAccessible::NativeName(nsString& aName)
 {
   // CASE #1 -- great majority of the cases
   // find the label attribute - this is what the W3C says we should use
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::label, aName);
   if (!aName.IsEmpty())
-    return NS_OK;
+    return eNameOK;
 
   // CASE #2 -- no label parameter, get the first child, 
   // use it if it is a text node
   nsIContent* text = mContent->GetFirstChild();
-  if (!text)
-    return NS_OK;
-
-  if (text->IsNodeOfType(nsINode::eTEXT)) {
-    nsAutoString txtValue;
-    nsresult rv = nsTextEquivUtils::
-      AppendTextEquivFromTextContent(text, &txtValue);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // Temp var (txtValue) needed until CompressWhitespace built for nsAString
-    txtValue.CompressWhitespace();
-    aName.Assign(txtValue);
-    return NS_OK;
+  if (text && text->IsNodeOfType(nsINode::eTEXT)) {
+    nsTextEquivUtils::AppendTextEquivFromTextContent(text, &aName);
+    aName.CompressWhitespace();
+    return aName.IsEmpty() ? eNameOK : eNameFromSubtree;
   }
 
-  return NS_OK;
+  return eNameOK;
 }
 
 uint64_t
 HTMLSelectOptionAccessible::NativeState()
 {
   // As a HTMLSelectOptionAccessible we can have the following states:
   // SELECTABLE, SELECTED, FOCUSED, FOCUSABLE, OFFSCREEN
   // Upcall to Accessible, but skip HyperTextAccessible impl
--- a/accessible/src/html/HTMLSelectAccessible.h
+++ b/accessible/src/html/HTMLSelectAccessible.h
@@ -79,30 +79,33 @@ public:
   virtual ~HTMLSelectOptionAccessible() {}
 
   // nsIAccessible
   NS_IMETHOD DoAction(uint8_t index);
   NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName);
   NS_IMETHOD SetSelected(bool aSelect);
 
   // Accessible
-  virtual nsresult GetNameInternal(nsAString& aName);
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
   virtual uint64_t NativeInteractiveState() const;
 
   virtual int32_t GetLevelInternal();
   virtual void GetBoundsRect(nsRect& aTotalBounds, nsIFrame** aBoundingFrame);
 
   // ActionAccessible
   virtual uint8_t ActionCount();
 
   // Widgets
   virtual Accessible* ContainerWidget() const;
 
+protected:
+  // Accessible
+  virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
+
 private:
 
   /**
    * Return a select accessible the option belongs to if any.
    */
   Accessible* GetSelect() const
   {
     if (mParent && mParent->IsListControl()) {
--- a/accessible/src/html/HTMLTableAccessible.cpp
+++ b/accessible/src/html/HTMLTableAccessible.cpp
@@ -88,37 +88,35 @@ HTMLTableCellAccessible::NativeState()
 }
 
 uint64_t
 HTMLTableCellAccessible::NativeInteractiveState() const
 {
   return HyperTextAccessibleWrap::NativeInteractiveState() | states::SELECTABLE;
 }
 
-nsresult
-HTMLTableCellAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
+already_AddRefed<nsIPersistentProperties>
+HTMLTableCellAccessible::NativeAttributes()
 {
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  nsresult rv = HyperTextAccessibleWrap::GetAttributesInternal(aAttributes);
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsIPersistentProperties> attributes =
+    HyperTextAccessibleWrap::NativeAttributes();
 
   // table-cell-index attribute
   TableAccessible* table = Table();
   if (!table)
-    return NS_OK;
+    return attributes.forget();
 
   int32_t rowIdx = -1, colIdx = -1;
-  rv = GetCellIndexes(rowIdx, colIdx);
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsresult rv = GetCellIndexes(rowIdx, colIdx);
+  if (NS_FAILED(rv))
+    return attributes.forget();
 
   nsAutoString stringIdx;
   stringIdx.AppendInt(table->CellIndexAt(rowIdx, colIdx));
-  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::tableCellIndex, stringIdx);
+  nsAccUtils::SetAccAttr(attributes, nsGkAtoms::tableCellIndex, stringIdx);
 
   // abbr attribute
 
   // Pick up object attribute from abbr DOM element (a child of the cell) or
   // from abbr DOM attribute.
   nsAutoString abbrText;
   if (ChildCount() == 1) {
     Accessible* abbr = FirstChild();
@@ -127,25 +125,25 @@ HTMLTableCellAccessible::GetAttributesIn
         AppendTextEquivFromTextContent(abbr->GetContent()->GetFirstChild(),
                                        &abbrText);
     }
   }
   if (abbrText.IsEmpty())
     mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::abbr, abbrText);
 
   if (!abbrText.IsEmpty())
-    nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::abbr, abbrText);
+    nsAccUtils::SetAccAttr(attributes, nsGkAtoms::abbr, abbrText);
 
   // axis attribute
   nsAutoString axisText;
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::axis, axisText);
   if (!axisText.IsEmpty())
-    nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::axis, axisText);
+    nsAccUtils::SetAccAttr(attributes, nsGkAtoms::axis, axisText);
 
-  return NS_OK;
+  return attributes.forget();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLTableCellAccessible: nsIAccessibleTableCell implementation
 
 TableAccessible*
 HTMLTableCellAccessible::Table() const
 {
@@ -380,52 +378,51 @@ HTMLTableAccessible::NativeRole()
 }
 
 uint64_t
 HTMLTableAccessible::NativeState()
 {
   return Accessible::NativeState() | states::READONLY;
 }
 
-nsresult
-HTMLTableAccessible::GetNameInternal(nsAString& aName)
+ENameValueFlag
+HTMLTableAccessible::NativeName(nsString& aName)
 {
-  Accessible::GetNameInternal(aName);
+  ENameValueFlag nameFlag = Accessible::NativeName(aName);
   if (!aName.IsEmpty())
-    return NS_OK;
+    return nameFlag;
 
   // Use table caption as a name.
   Accessible* caption = Caption();
   if (caption) {
     nsIContent* captionContent = caption->GetContent();
     if (captionContent) {
       nsTextEquivUtils::AppendTextEquivFromContent(this, captionContent, &aName);
       if (!aName.IsEmpty())
-        return NS_OK;
+        return eNameOK;
     }
   }
 
   // If no caption then use summary as a name.
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::summary, aName);
-  return NS_OK;
+  return eNameOK;
 }
 
-nsresult
-HTMLTableAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
+already_AddRefed<nsIPersistentProperties>
+HTMLTableAccessible::NativeAttributes()
 {
-  nsresult rv = AccessibleWrap::GetAttributesInternal(aAttributes);
-  NS_ENSURE_SUCCESS(rv, rv);
-
+  nsCOMPtr<nsIPersistentProperties> attributes =
+    AccessibleWrap::NativeAttributes();
   if (IsProbablyLayoutTable()) {
-    nsAutoString oldValueUnused;
-    aAttributes->SetStringProperty(NS_LITERAL_CSTRING("layout-guess"),
-                                   NS_LITERAL_STRING("true"), oldValueUnused);
+    nsAutoString unused;
+    attributes->SetStringProperty(NS_LITERAL_CSTRING("layout-guess"),
+                                  NS_LITERAL_STRING("true"), unused);
   }
 
-  return NS_OK;
+  return attributes.forget();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLTableAccessible: nsIAccessible implementation
 
 Relation
 HTMLTableAccessible::RelationByType(uint32_t aType)
 {
@@ -957,17 +954,17 @@ HTMLTableAccessible::Description(nsStrin
 }
 
 bool
 HTMLTableAccessible::HasDescendant(const nsAString& aTagName, bool aAllowEmpty)
 {
   nsCOMPtr<nsIDOMElement> tableElt(do_QueryInterface(mContent));
   NS_ENSURE_TRUE(tableElt, false);
 
-  nsCOMPtr<nsIDOMNodeList> nodeList;
+  nsCOMPtr<nsIDOMHTMLCollection> nodeList;
   tableElt->GetElementsByTagName(aTagName, getter_AddRefs(nodeList));
   NS_ENSURE_TRUE(nodeList, false);
 
   nsCOMPtr<nsIDOMNode> foundItem;
   nodeList->Item(0, getter_AddRefs(foundItem));
   if (!foundItem)
     return false;
 
--- a/accessible/src/html/HTMLTableAccessible.h
+++ b/accessible/src/html/HTMLTableAccessible.h
@@ -37,17 +37,17 @@ public:
   NS_FORWARD_NSIACCESSIBLETABLECELL(xpcAccessibleTableCell::)
 
   // Accessible
   virtual TableCellAccessible* AsTableCell() { return this; }
   virtual void Shutdown();
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
   virtual uint64_t NativeInteractiveState() const;
-  virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
+  virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
 
   // TableCellAccessible
   virtual TableAccessible* Table() const MOZ_OVERRIDE;
   virtual uint32_t ColIdx() const MOZ_OVERRIDE;
   virtual uint32_t RowIdx() const MOZ_OVERRIDE;
   virtual uint32_t ColExtent() const MOZ_OVERRIDE;
   virtual uint32_t RowExtent() const MOZ_OVERRIDE;
   virtual void ColHeaderCells(nsTArray<Accessible*>* aCells) MOZ_OVERRIDE;
@@ -138,38 +138,37 @@ public:
   virtual Accessible* AsAccessible() { return this; }
 
   // nsAccessNode
   virtual void Shutdown();
 
   // Accessible
   virtual TableAccessible* AsTable() { return this; }
   virtual void Description(nsString& aDescription);
-  virtual nsresult GetNameInternal(nsAString& aName);
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
-  virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
+  virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
   virtual Relation RelationByType(uint32_t aRelationType);
 
   // HTMLTableAccessible
 
   /**
    * Retun cell element at the given row and column index.
    */
   nsresult GetCellAt(int32_t aRowIndex, int32_t aColIndex,
                      nsIDOMElement* &aCell);
 
   /**
    * Return nsITableLayout for the frame of the accessible table.
    */
   nsITableLayout* GetTableLayout();
 
 protected:
-
   // Accessible
+  virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
   virtual void CacheChildren();
 
   // HTMLTableAccessible
 
   /**
    * Add row or column to selection.
    *
    * @param aIndex   [in] index of row or column to be selected
--- a/accessible/src/jsat/AccessFu.jsm
+++ b/accessible/src/jsat/AccessFu.jsm
@@ -93,17 +93,19 @@ var AccessFu = {
 
     Input.attach(this.chromeWin);
     Output.attach(this.chromeWin);
     this.touchAdapter.attach(this.chromeWin);
 
     Services.obs.addObserver(this, 'remote-browser-frame-shown', false);
     Services.obs.addObserver(this, 'Accessibility:NextObject', false);
     Services.obs.addObserver(this, 'Accessibility:PreviousObject', false);
-    Services.obs.addObserver(this, 'Accessibility:CurrentObject', false);
+    Services.obs.addObserver(this, 'Accessibility:Focus', false);
+    this.chromeWin.addEventListener('TabOpen', this);
+    this.chromeWin.addEventListener('TabSelect', this);
   },
 
   /**
    * Disable AccessFu and return to default interaction mode.
    */
   _disable: function _disable() {
     if (!this._enabled)
       return;
@@ -113,31 +115,34 @@ var AccessFu = {
     Logger.info('disable');
 
     this.chromeWin.document.removeChild(this.stylesheet);
     for each (let mm in Utils.getAllMessageManagers(this.chromeWin))
       mm.sendAsyncMessage('AccessFu:Stop');
 
     Input.detach();
 
+    this.chromeWin.removeEventListener('TabOpen', this);
+    this.chromeWin.removeEventListener('TabSelect', this);
+
     Services.obs.removeObserver(this, 'remote-browser-frame-shown');
     Services.obs.removeObserver(this, 'Accessibility:NextObject');
     Services.obs.removeObserver(this, 'Accessibility:PreviousObject');
-    Services.obs.removeObserver(this, 'Accessibility:CurrentObject');
+    Services.obs.removeObserver(this, 'Accessibility:Focus');
   },
 
   _enableOrDisable: function _enableOrDisable() {
     try {
       if (this._activatePref == ACCESSFU_ENABLE ||
           this._systemPref && this._activatePref == ACCESSFU_AUTO)
         this._enable();
       else
         this._disable();
     } catch (x) {
-      Logger.error(x);
+      Logger.logException(x);
     }
   },
 
   receiveMessage: function receiveMessage(aMessage) {
     if (Logger.logLevel >= Logger.DEBUG)
       Logger.debug('Recieved', aMessage.name, JSON.stringify(aMessage.json));
 
     switch (aMessage.name) {
@@ -147,17 +152,17 @@ var AccessFu = {
                           {method: 'start', buildApp: Utils.MozBuildApp});
       break;
       case 'AccessFu:Present':
       try {
         for each (let presenter in aMessage.json) {
           Output[presenter.type](presenter.details, aMessage.target);
         }
       } catch (x) {
-        Logger.error(x);
+        Logger.logException(x);
       }
       break;
       case 'AccessFu:Input':
       Input.setEditState(aMessage.json);
       break;
     }
   },
 
@@ -178,21 +183,23 @@ var AccessFu = {
         this._enableOrDisable();
         break;
       case 'Accessibility:NextObject':
         Input.moveCursor('moveNext', 'Simple', 'gesture');
         break;
       case 'Accessibility:PreviousObject':
         Input.moveCursor('movePrevious', 'Simple', 'gesture');
         break;
-      case 'Accessibility:CurrentObject':
-        let mm = Utils.getCurrentBrowser(this.chromeWin).
-          frameLoader.messageManager;
-        mm.sendAsyncMessage('AccessFu:VirtualCursor',
-                            {action: 'presentLastPivot'});
+      case 'Accessibility:Focus':
+        this._focused = JSON.parse(aData);
+        if (this._focused) {
+          let mm = Utils.getMessageManager(Utils.getCurrentBrowser(this.chromeWin));
+          mm.sendAsyncMessage('AccessFu:VirtualCursor',
+                              {action: 'whereIsIt', move: true});
+        }
         break;
       case 'nsPref:changed':
         if (aData == 'activate') {
           this._activatePref = this.prefsBranch.getIntPref('activate');
           this._enableOrDisable();
         }
         break;
       case 'remote-browser-frame-shown':
@@ -200,25 +207,52 @@ var AccessFu = {
         this._loadFrameScript(
           aSubject.QueryInterface(Ci.nsIFrameLoader).messageManager);
         break;
       }
     }
   },
 
   handleEvent: function handleEvent(aEvent) {
-    if (aEvent.type == 'mozContentEvent' &&
-        aEvent.detail.type == 'accessibility-screenreader') {
-      this._systemPref = aEvent.detail.enabled;
-      this._enableOrDisable();
+    switch (aEvent.type) {
+      case 'mozContentEvent':
+      {
+        if (aEvent.detail.type == 'accessibility-screenreader') {
+          this._systemPref = aEvent.detail.enabled;
+          this._enableOrDisable();
+        }
+        break;
+      }
+      case 'TabOpen':
+      {
+        this._loadFrameScript(Utils.getMessageManager(aEvent.target));
+        break;
+      }
+      case 'TabSelect':
+      {
+        if (this._focused) {
+          let mm = Utils.getMessageManager(Utils.getCurrentBrowser(this.chromeWin));
+          // We delay this for half a second so the awesomebar could close,
+          // and we could use the current coordinates for the content item.
+          // XXX TODO figure out how to avoid magic wait here.
+          this.chromeWin.setTimeout(
+            function () {
+              mm.sendAsyncMessage('AccessFu:VirtualCursor', {action: 'whereIsIt'});
+            }, 500);
+        }
+        break;
+      }
     }
   },
 
   // So we don't enable/disable twice
-  _enabled: false
+  _enabled: false,
+
+  // Layerview is focused
+  _focused: false
 };
 
 var Output = {
   attach: function attach(aWindow) {
     this.chromeWin = aWindow;
   },
 
   Speech: function Speech(aDetails, aBrowser) {
@@ -302,17 +336,17 @@ var Input = {
       case 'keypress':
         this._handleKeypress(aEvent);
         break;
       case 'mozAccessFuGesture':
         this._handleGesture(aEvent);
         break;
       }
     } catch (x) {
-      Logger.error(x);
+      Logger.logException(x);
     }
   },
 
   _handleGesture: function _handleGesture(aEvent) {
     let detail = aEvent.detail;
     Logger.info('Gesture', detail.type,
                 '(fingers: ' + detail.touches.length + ')');
 
--- a/accessible/src/jsat/EventManager.jsm
+++ b/accessible/src/jsat/EventManager.jsm
@@ -37,17 +37,18 @@ var EventManager = {
       }
 
       this.present(
         function(p) {
           return p.tabStateChanged(null, 'newtab');
         }
       );
     } catch (x) {
-      Logger.error('Failed to start EventManager:', x);
+      Logger.error('Failed to start EventManager');
+      Logger.logException(x);
     }
   },
 
   stop: function stop() {
     Services.obs.removeObserver(this, 'accessible-event');
     this.presenters = [];
     this._started = false;
   },
@@ -72,51 +73,53 @@ var EventManager = {
             return p.actionInvoked(activatedAcc, 'click');
           }
         );
         break;
       }
       case 'scroll':
       case 'resize':
       {
+        // the target could be an element, document or window
+        let window = null;
+        if (aEvent.target instanceof Ci.nsIDOMWindow)
+          window = aEvent.target;
+        else if (aEvent.target instanceof Ci.nsIDOMDocument)
+          window = aEvent.target.defaultView;
+        else if (aEvent.target instanceof Ci.nsIDOMElement)
+          window = aEvent.target.ownerDocument.defaultView;
         this.present(
           function(p) {
-            return p.viewportChanged();;
+            return p.viewportChanged(window);
           }
         );
         break;
       }
       }
     } catch (x) {
-      Logger.error('Error handling DOM event:', x);
+      Logger.error('Error handling DOM event');
+      Logger.logException(x);
     }
   },
 
   observe: function observe(aSubject, aTopic, aData) {
     switch (aTopic) {
       case 'accessible-event':
         var event;
         try {
           event = aSubject.QueryInterface(Ci.nsIAccessibleEvent);
           this.handleAccEvent(event);
         } catch (x) {
-          Logger.error('Error handing accessible event:', x);
+          Logger.error('Error handing accessible event');
+          Logger.logException(x);
           return;
         }
     }
   },
 
-  presentLastPivot: function presentLastPivot() {
-    this.present(
-      function(p) {
-        return p.presentLastPivot();
-      }
-    );
-  },
-
   handleAccEvent: function handleAccEvent(aEvent) {
     if (Logger.logLevel >= Logger.DEBUG)
       Logger.debug('A11yEvent', Logger.eventToString(aEvent),
                    Logger.accessibleToString(aEvent.accessible));
 
     switch (aEvent.eventType) {
       case Ci.nsIAccessibleEvent.EVENT_VIRTUALCURSOR_CHANGED:
       {
@@ -243,20 +246,31 @@ var EventManager = {
 
   present: function present(aPresenterFunc) {
     try {
       this.sendMsgFunc(
         "AccessFu:Present",
         [aPresenterFunc(p) for each (p in this.presenters)].
           filter(function(d) {return !!d;}));
     } catch (x) {
-      Logger.error(x);
+      Logger.logException(x);
     }
   },
 
+  presentVirtualCursorPosition: function presentVirtualCursorPosition(aVirtualCursor) {
+    let presenterContext =
+      new PresenterContext(aVirtualCursor.position, null);
+
+    this.present(
+      function(p) {
+        return p.pivotChanged(presenterContext, Ci.nsIAccessiblePivot.REASON_NONE);
+      }
+    );
+  },
+
   onStateChange: function onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) {
     let tabstate = '';
 
     let loadingState = Ci.nsIWebProgressListener.STATE_TRANSFERRING |
       Ci.nsIWebProgressListener.STATE_IS_DOCUMENT;
     let loadedState = Ci.nsIWebProgressListener.STATE_STOP |
       Ci.nsIWebProgressListener.STATE_IS_NETWORK;
 
--- a/accessible/src/jsat/Presenters.jsm
+++ b/accessible/src/jsat/Presenters.jsm
@@ -99,22 +99,17 @@ Presenter.prototype = {
    *    landscape/portrait toggle.
    * @param {Window} aWindow window of viewport that changed.
    */
   viewportChanged: function viewportChanged(aWindow) {},
 
   /**
    * We have entered or left text editing mode.
    */
-  editingModeChanged: function editingModeChanged(aIsEditing) {},
-
-  /**
-   * Re-present the last pivot change.
-   */
-  presentLastPivot: function AndroidPresenter_presentLastPivot() {}
+  editingModeChanged: function editingModeChanged(aIsEditing) {}
 };
 
 /**
  * Visual presenter. Draws a box around the virtual cursor's position.
  */
 
 function VisualPresenter() {}
 
@@ -124,31 +119,33 @@ VisualPresenter.prototype = {
   type: 'Visual',
 
   /**
    * The padding in pixels between the object and the highlight border.
    */
   BORDER_PADDING: 2,
 
   viewportChanged: function VisualPresenter_viewportChanged(aWindow) {
-    if (this._currentContext)
+    if (this._currentAccessible) {
+      let context = new PresenterContext(this._currentAccessible);
       return {
         type: this.type,
         details: {
           method: 'show',
-          bounds: this._currentContext.bounds,
+          bounds: context.bounds,
           padding: this.BORDER_PADDING
         }
       };
+    }
 
     return null;
   },
 
   pivotChanged: function VisualPresenter_pivotChanged(aContext, aReason) {
-    this._currentContext = aContext;
+    this._currentAccessible = aContext.accessible;
 
     if (!aContext.accessible)
       return {type: this.type, details: {method: 'hide'}};
 
     try {
       aContext.accessible.scrollTo(
         Ci.nsIAccessibleScrollType.SCROLL_TYPE_ANYWHERE);
       return {
@@ -201,18 +198,16 @@ AndroidPresenter.prototype = {
   ANDROID_VIEW_SCROLLED: 0x1000,
   ANDROID_ANNOUNCEMENT: 0x4000,
   ANDROID_VIEW_ACCESSIBILITY_FOCUSED: 0x8000,
 
   pivotChanged: function AndroidPresenter_pivotChanged(aContext, aReason) {
     if (!aContext.accessible)
       return null;
 
-    this._currentContext = aContext;
-
     let androidEvents = [];
 
     let isExploreByTouch = (aReason == Ci.nsIAccessiblePivot.REASON_POINT &&
                             Utils.AndroidSdkVersion >= 14);
     let focusEventType = (Utils.AndroidSdkVersion >= 16) ?
       this.ANDROID_VIEW_ACCESSIBILITY_FOCUSED :
       this.ANDROID_VIEW_FOCUSED;
 
@@ -268,38 +263,35 @@ AndroidPresenter.prototype = {
                                                              aPageState) {
     return this._appAnnounce(
       UtteranceGenerator.genForTabStateChange(aDocObj, aPageState));
   },
 
   textChanged: function AndroidPresenter_textChanged(aIsInserted, aStart,
                                                      aLength, aText,
                                                      aModifiedText) {
-    let androidEvent = {
-      type: this.type,
-      details: [{
-        eventType: this.ANDROID_VIEW_TEXT_CHANGED,
-        text: [aText],
-        fromIndex: aStart,
-        removedCount: 0,
-        addedCount: 0
-      }]
+    let eventDetails = {
+      eventType: this.ANDROID_VIEW_TEXT_CHANGED,
+      text: [aText],
+      fromIndex: aStart,
+      removedCount: 0,
+      addedCount: 0
     };
 
     if (aIsInserted) {
-      androidEvent.addedCount = aLength;
-      androidEvent.beforeText =
+      eventDetails.addedCount = aLength;
+      eventDetails.beforeText =
         aText.substring(0, aStart) + aText.substring(aStart + aLength);
     } else {
-      androidEvent.removedCount = aLength;
-      androidEvent.beforeText =
+      eventDetails.removedCount = aLength;
+      eventDetails.beforeText =
         aText.substring(0, aStart) + aModifiedText + aText.substring(aStart);
     }
 
-    return androidEvent;
+    return {type: this.type, details: [eventDetails]};
   },
 
   viewportChanged: function AndroidPresenter_viewportChanged(aWindow) {
     if (Utils.AndroidSdkVersion < 14)
       return null;
 
     return {
       type: this.type,
@@ -328,23 +320,16 @@ AndroidPresenter.prototype = {
         eventType: (Utils.AndroidSdkVersion >= 16) ?
           this.ANDROID_ANNOUNCEMENT : this.ANDROID_VIEW_TEXT_CHANGED,
         text: aUtterance,
         addedCount: aUtterance.join(' ').length,
         removedCount: 0,
         fromIndex: 0
       }]
     };
-  },
-
-  presentLastPivot: function AndroidPresenter_presentLastPivot() {
-    if (this._currentContext)
-      return this.pivotChanged(this._currentContext);
-    else
-      return null;
   }
 };
 
 /**
  * A speech presenter for direct TTS output
  */
 
 function SpeechPresenter() {}
--- a/accessible/src/jsat/Utils.jsm
+++ b/accessible/src/jsat/Utils.jsm
@@ -84,42 +84,44 @@ var Utils = {
 
   getCurrentBrowser: function getCurrentBrowser(aWindow) {
     if (this.MozBuildApp == 'b2g')
       return this.getBrowserApp(aWindow).contentBrowser;
     return this.getBrowserApp(aWindow).selectedBrowser;
   },
 
   getCurrentContentDoc: function getCurrentContentDoc(aWindow) {
-    return this.getCurrentBrowser(aWindow).contentDocument;
+    let browser = this.getCurrentBrowser(aWindow);
+    return browser ? browser.contentDocument : null;
   },
 
   getMessageManager: function getMessageManager(aBrowser) {
     try {
       return aBrowser.QueryInterface(Ci.nsIFrameLoaderOwner).
          frameLoader.messageManager;
     } catch (x) {
-      Logger.error(x);
+      Logger.logException(x);
       return null;
     }
   },
 
   getAllMessageManagers: function getAllMessageManagers(aWindow) {
     let messageManagers = [];
 
     for (let i = 0; i < aWindow.messageManager.childCount; i++)
       messageManagers.push(aWindow.messageManager.getChildAt(i));
 
-    let remoteframes = this.getCurrentContentDoc(aWindow).
-      querySelectorAll('iframe[remote=true]');
+    let document = this.getCurrentContentDoc(aWindow);
 
-    for (let i = 0; i < remoteframes.length; ++i)
-      messageManagers.push(this.getMessageManager(remoteframes[i]));
+    if (document) {
+      let remoteframes = document.querySelectorAll('iframe[remote=true]');
 
-    Logger.info(messageManagers.length);
+      for (let i = 0; i < remoteframes.length; ++i)
+        messageManagers.push(this.getMessageManager(remoteframes[i]));
+    }
 
     return messageManagers;
   },
 
   getViewport: function getViewport(aWindow) {
     switch (this.MozBuildApp) {
       case 'mobile/android':
         return aWindow.BrowserApp.selectedTab.getViewport();
@@ -187,16 +189,26 @@ var Logger = {
       this, [this.WARNING].concat(Array.prototype.slice.call(arguments)));
   },
 
   error: function error() {
     this.log.apply(
       this, [this.ERROR].concat(Array.prototype.slice.call(arguments)));
   },
 
+  logException: function logException(aException) {
+    try {
+      this.error(
+        aException.message,
+        '(' + aException.fileName + ':' + aException.lineNumber + ')');
+    } catch (x) {
+      this.error(x);
+    }
+  },
+
   accessibleToString: function accessibleToString(aAccessible) {
     let str = '[ defunct ]';
     try {
       str = '[ ' + Utils.AccRetrieval.getStringRole(aAccessible.role) +
         ' | ' + aAccessible.name + ' ]';
     } catch (x) {
     }
 
--- a/accessible/src/jsat/content-script.js
+++ b/accessible/src/jsat/content-script.js
@@ -49,18 +49,24 @@ function virtualCursorControl(aMessage) 
         let acc = Utils.AccRetrieval.
           getAccessibleFor(content.document.activeElement);
         moved = vc.moveNext(rule, acc, true);
       }
       break;
     case 'moveToPoint':
       moved = vc.moveToPoint(rule, details.x, details.y, true);
       break;
-    case 'presentLastPivot':
-      EventManager.presentLastPivot();
+    case 'whereIsIt':
+      if (!forwardMessage(vc, aMessage)) {
+        if (!vc.position && aMessage.json.move)
+          vc.moveFirst(TraversalRules.Simple);
+        else
+          EventManager.presentVirtualCursorPosition(vc);
+      }
+
       break;
     default:
       break;
     }
 
     if (moved == true) {
       forwardMessage(vc, aMessage);
     } else if (moved == false && details.action != 'moveToPoint') {
--- a/accessible/src/mac/mozAccessible.mm
+++ b/accessible/src/mac/mozAccessible.mm
@@ -434,21 +434,20 @@ GetClosestInterestingAccessible(id anObj
 
 - (NSString*)subrole
 {
   if (!mGeckoAccessible)
     return nil;
 
   // XXX maybe we should cache the subrole.
   nsAutoString xmlRoles;
-  nsCOMPtr<nsIPersistentProperties> attributes;
 
   // XXX we don't need all the attributes (see bug 771113)
-  nsresult rv = mGeckoAccessible->GetAttributes(getter_AddRefs(attributes));
-  if (NS_SUCCEEDED(rv) && attributes)
+  nsCOMPtr<nsIPersistentProperties> attributes = mGeckoAccessible->Attributes();
+  if (attributes)
     nsAccUtils::GetAccAttr(attributes, nsGkAtoms::xmlroles, xmlRoles);
 
   nsWhitespaceTokenizer tokenizer(xmlRoles);
 
   while (tokenizer.hasMoreTokens()) {
     const nsDependentSubstring token(tokenizer.nextToken());
 
     if (token.EqualsLiteral("banner"))
--- a/accessible/src/mac/mozHTMLAccessible.mm
+++ b/accessible/src/mac/mozHTMLAccessible.mm
@@ -13,18 +13,17 @@
 
 @implementation mozHeadingAccessible
 
 - (NSString*)title
 {
   nsAutoString title;
   // XXX use the flattening API when there are available
   // see bug 768298
-  nsresult rv = mGeckoAccessible->GetContent()->GetTextContent(title);
-  NS_ENSURE_SUCCESS(rv, nil);
+  mGeckoAccessible->GetContent()->GetTextContent(title);
 
   return nsCocoaUtils::ToNSString(title);
 }
 
 - (id)value
 {
   if (!mGeckoAccessible || !mGeckoAccessible->IsHyperText())
     return nil;
--- a/accessible/src/msaa/AccessibleWrap.cpp
+++ b/accessible/src/msaa/AccessibleWrap.cpp
@@ -161,17 +161,17 @@ AccessibleWrap::get_accParent( IDispatch
     return CO_E_OBJNOTCONNECTED;
 
   DocAccessible* doc = AsDoc();
   if (doc) {
     // Return window system accessible object for root document and tab document
     // accessibles.
     if (!doc->ParentDocument() ||
         nsWinUtils::IsWindowEmulationStarted() &&
-        nsCoreUtils::IsTabDocument(doc->GetDocumentNode())) {
+        nsCoreUtils::IsTabDocument(doc->DocumentNode())) {
       HWND hwnd = static_cast<HWND>(doc->GetNativeWindow());
       if (hwnd && SUCCEEDED(::AccessibleObjectFromWindow(hwnd, OBJID_WINDOW,
                                                          IID_IAccessible,
                                                          (void**)ppdispParent))) {
         return S_OK;
       }
     }
   }
@@ -259,17 +259,17 @@ AccessibleWrap::get_accName(
   if (xpAccessible->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsAutoString name;
   xpAccessible->Name(name);
 
   // The name was not provided, e.g. no alt attribute for an image. A screen
   // reader may choose to invent its own accessible name, e.g. from an image src
-  // attribute. Refer to NS_OK_EMPTY_NAME return value.
+  // attribute. Refer to eNoNameOnPurpose return value.
   if (name.IsVoid())
     return S_FALSE;
 
   *pszName = ::SysAllocStringLen(name.get(), name.Length());
   if (!*pszName)
     return E_OUTOFMEMORY;
 
 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
@@ -1435,21 +1435,17 @@ AccessibleWrap::get_attributes(BSTR *aAt
   // The format is name:value;name:value; with \ for escaping these
   // characters ":;=,\".
 __try {
   *aAttributes = NULL;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
-  nsCOMPtr<nsIPersistentProperties> attributes;
-  nsresult rv = GetAttributes(getter_AddRefs(attributes));
-  if (NS_FAILED(rv))
-    return GetHRESULT(rv);
-
+  nsCOMPtr<nsIPersistentProperties> attributes = Attributes();
   return ConvertToIA2Attributes(attributes, aAttributes);
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // IDispatch
--- a/accessible/src/msaa/ApplicationAccessibleWrap.cpp
+++ b/accessible/src/msaa/ApplicationAccessibleWrap.cpp
@@ -16,39 +16,34 @@
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsISupports
 NS_IMPL_ISUPPORTS_INHERITED0(ApplicationAccessibleWrap,
                              ApplicationAccessible)
 
-NS_IMETHODIMP
-ApplicationAccessibleWrap::GetAttributes(nsIPersistentProperties** aAttributes)
+already_AddRefed<nsIPersistentProperties>
+ApplicationAccessibleWrap::NativeAttributes()
 {
-  NS_ENSURE_ARG_POINTER(aAttributes);
-  *aAttributes = nullptr;
-
   nsCOMPtr<nsIPersistentProperties> attributes =
     do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID);
-  NS_ENSURE_STATE(attributes);
 
   nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
   if (gfxInfo) {
     bool isD2DEnabled = false;
     gfxInfo->GetD2DEnabled(&isD2DEnabled);
     nsAutoString unused;
     attributes->SetStringProperty(
       NS_LITERAL_CSTRING("D2D"),
       isD2DEnabled ? NS_LITERAL_STRING("true") : NS_LITERAL_STRING("false"),
         unused);
   }
 
-  attributes.swap(*aAttributes);
-  return NS_OK;
+  return attributes.forget();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // IUnknown
 
 STDMETHODIMP
 ApplicationAccessibleWrap::QueryInterface(REFIID iid, void** ppv)
 {
--- a/accessible/src/msaa/ApplicationAccessibleWrap.h
+++ b/accessible/src/msaa/ApplicationAccessibleWrap.h
@@ -17,18 +17,18 @@ namespace a11y {
  
 class ApplicationAccessibleWrap: public ApplicationAccessible,
                                  public IAccessibleApplication
 {
 public:
   // nsISupporst
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIAccessible
-  NS_IMETHOD GetAttributes(nsIPersistentProperties** aAttributes);
+  // nsAccessible
+  virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
 
   // IUnknown
   STDMETHODIMP QueryInterface(REFIID, void**);
 
   // IAccessibleApplication
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_appName(
             /* [retval][out] */ BSTR *name);
 
rename from accessible/src/msaa/nsHTMLWin32ObjectAccessible.cpp
rename to accessible/src/msaa/HTMLWin32ObjectAccessible.cpp
--- a/accessible/src/msaa/nsHTMLWin32ObjectAccessible.cpp
+++ b/accessible/src/msaa/HTMLWin32ObjectAccessible.cpp
@@ -1,99 +1,93 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "nsHTMLWin32ObjectAccessible.h"
+#include "HTMLWin32ObjectAccessible.h"
 
 #include "Role.h"
 #include "States.h"
 
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsHTMLWin32ObjectOwnerAccessible
+// HTMLWin32ObjectOwnerAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
-nsHTMLWin32ObjectOwnerAccessible::
-  nsHTMLWin32ObjectOwnerAccessible(nsIContent* aContent,
-                                   DocAccessible* aDoc, void* aHwnd) :
+HTMLWin32ObjectOwnerAccessible::
+  HTMLWin32ObjectOwnerAccessible(nsIContent* aContent,
+                                 DocAccessible* aDoc, void* aHwnd) :
   AccessibleWrap(aContent, aDoc), mHwnd(aHwnd)
 {
-  // Our only child is a nsHTMLWin32ObjectAccessible object.
-  mNativeAccessible = new nsHTMLWin32ObjectAccessible(mHwnd);
+  // Our only child is a HTMLWin32ObjectAccessible object.
+  mNativeAccessible = new HTMLWin32ObjectAccessible(mHwnd);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsHTMLWin32ObjectOwnerAccessible: nsAccessNode implementation
+// HTMLWin32ObjectOwnerAccessible: nsAccessNode implementation
 
 void
-nsHTMLWin32ObjectOwnerAccessible::Shutdown()
+HTMLWin32ObjectOwnerAccessible::Shutdown()
 {
   AccessibleWrap::Shutdown();
   mNativeAccessible = nullptr;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsHTMLWin32ObjectOwnerAccessible: Accessible implementation
+// HTMLWin32ObjectOwnerAccessible: Accessible implementation
 
 role
-nsHTMLWin32ObjectOwnerAccessible::NativeRole()
+HTMLWin32ObjectOwnerAccessible::NativeRole()
 {
   return roles::EMBEDDED_OBJECT;
 }
 
 bool
-nsHTMLWin32ObjectOwnerAccessible::NativelyUnavailable() const
+HTMLWin32ObjectOwnerAccessible::NativelyUnavailable() const
 {
   // XXX: No HWND means this is windowless plugin which is not accessible in
   // the meantime.
   return !mHwnd;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsHTMLWin32ObjectOwnerAccessible: Accessible protected implementation
+// HTMLWin32ObjectOwnerAccessible: Accessible protected implementation
 
 void
-nsHTMLWin32ObjectOwnerAccessible::CacheChildren()
+HTMLWin32ObjectOwnerAccessible::CacheChildren()
 {
   if (mNativeAccessible)
     AppendChild(mNativeAccessible);
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsHTMLWin32ObjectAccessible
+// HTMLWin32ObjectAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
-nsHTMLWin32ObjectAccessible::nsHTMLWin32ObjectAccessible(void* aHwnd) :
-  LeafAccessible(nullptr, nullptr)
+HTMLWin32ObjectAccessible::HTMLWin32ObjectAccessible(void* aHwnd) :
+  DummyAccessible()
 {
-  // XXX: Mark it as defunct to make sure no single Accessible method is
-  // running on it. We need to allow accessible without DOM nodes.
-  mFlags |= eIsDefunct;
-
   mHwnd = aHwnd;
   if (mHwnd) {
     // The plugin is not windowless. In this situation we use 
     // use its inner child owned by the plugin so that we don't get
     // in an infinite loop, where the WM_GETOBJECT's get forwarded
-    // back to us and create another nsHTMLWin32ObjectAccessible
+    // back to us and create another HTMLWin32ObjectAccessible
     HWND childWnd = ::GetWindow((HWND)aHwnd, GW_CHILD);
     if (childWnd) {
       mHwnd = childWnd;
     }
   }
 }
 
-NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLWin32ObjectAccessible, Accessible)
-
 NS_IMETHODIMP 
-nsHTMLWin32ObjectAccessible::GetNativeInterface(void** aNativeAccessible)
+HTMLWin32ObjectAccessible::GetNativeInterface(void** aNativeAccessible)
 {
   if (mHwnd) {
     ::AccessibleObjectFromWindow(static_cast<HWND>(mHwnd),
                                  OBJID_WINDOW, IID_IAccessible,
                                  aNativeAccessible);
   }
   return NS_OK;
 }
rename from accessible/src/msaa/nsHTMLWin32ObjectAccessible.h
rename to accessible/src/msaa/HTMLWin32ObjectAccessible.h
--- a/accessible/src/msaa/nsHTMLWin32ObjectAccessible.h
+++ b/accessible/src/msaa/HTMLWin32ObjectAccessible.h
@@ -1,32 +1,35 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#ifndef _nsHTMLWin32ObjectAccessible_H_
-#define _nsHTMLWin32ObjectAccessible_H_
+#ifndef mozilla_a11y_HTMLWin32ObjectAccessible_h_
+#define mozilla_a11y_HTMLWin32ObjectAccessible_h_
 
 #include "BaseAccessibles.h"
 
 struct IAccessible;
 
-class nsHTMLWin32ObjectOwnerAccessible : public AccessibleWrap
+namespace mozilla {
+namespace a11y {
+
+class HTMLWin32ObjectOwnerAccessible : public AccessibleWrap
 {
 public:
-  // This will own the nsHTMLWin32ObjectAccessible. We create this where the
+  // This will own the HTMLWin32ObjectAccessible. We create this where the
   // <object> or <embed> exists in the tree, so that get_accNextSibling() etc.
   // will still point to Gecko accessible sibling content. This is necessary
   // because the native plugin accessible doesn't know where it exists in the
   // Mozilla tree, and returns null for previous and next sibling. This would
   // have the effect of cutting off all content after the plugin.
-  nsHTMLWin32ObjectOwnerAccessible(nsIContent* aContent,
+  HTMLWin32ObjectOwnerAccessible(nsIContent* aContent,
                                    DocAccessible* aDoc, void* aHwnd);
-  virtual ~nsHTMLWin32ObjectOwnerAccessible() {}
+  virtual ~HTMLWin32ObjectOwnerAccessible() {}
 
   // nsAccessNode
   virtual void Shutdown();
 
   // Accessible
   virtual mozilla::a11y::role NativeRole();
   virtual bool NativelyUnavailable() const;
 
@@ -43,24 +46,24 @@ protected:
   * This class is used only internally, we never! send out an IAccessible linked
   *   back to this object. This class is used to represent a plugin object when
   *   referenced as a child or sibling of another Accessible node. We need only
   *   a limited portion of the nsIAccessible interface implemented here. The
   *   in depth accessible information will be returned by the actual IAccessible
   *   object returned by us in Accessible::NewAccessible() that gets the IAccessible
   *   from the windows system from the window handle.
   */
-class nsHTMLWin32ObjectAccessible : public mozilla::a11y::LeafAccessible
+class HTMLWin32ObjectAccessible : public DummyAccessible
 {
 public:
-
-  nsHTMLWin32ObjectAccessible(void* aHwnd);
-  virtual ~nsHTMLWin32ObjectAccessible() {}
-
-  NS_DECL_ISUPPORTS_INHERITED
+  HTMLWin32ObjectAccessible(void* aHwnd);
+  virtual ~HTMLWin32ObjectAccessible() {}
 
   NS_IMETHOD GetNativeInterface(void** aNativeAccessible) MOZ_OVERRIDE;
 
 protected:
   void* mHwnd;
 };
 
-#endif  
+} // namespace a11y
+} // namespace mozilla
+
+#endif
--- a/accessible/src/msaa/Makefile.in
+++ b/accessible/src/msaa/Makefile.in
@@ -16,20 +16,20 @@ LIBXUL_LIBRARY = 1
 
 
 CPPSRCS = \
   AccessibleWrap.cpp \
   ApplicationAccessibleWrap.cpp \
   ARIAGridAccessibleWrap.cpp \
   DocAccessibleWrap.cpp \
   HTMLTableAccessibleWrap.cpp \
+  HTMLWin32ObjectAccessible.cpp \
   HyperTextAccessibleWrap.cpp \
   ImageAccessibleWrap.cpp \
   nsAccessNodeWrap.cpp \
-  nsHTMLWin32ObjectAccessible.cpp \
   nsWinUtils.cpp \
   Compatibility.cpp \
   EnumVariant.cpp \
   RootAccessibleWrap.cpp \
   TextLeafAccessibleWrap.cpp \
   $(NULL)
 
 ifdef MOZ_XUL
--- a/accessible/src/msaa/RootAccessibleWrap.cpp
+++ b/accessible/src/msaa/RootAccessibleWrap.cpp
@@ -30,17 +30,17 @@ RootAccessibleWrap::~RootAccessibleWrap(
 
 ////////////////////////////////////////////////////////////////////////////////
 // RootAccessible
 
 void
 RootAccessibleWrap::DocumentActivated(DocAccessible* aDocument)
 {
   if (Compatibility::IsDolphin() &&
-      nsCoreUtils::IsTabDocument(aDocument->GetDocumentNode())) {
+      nsCoreUtils::IsTabDocument(aDocument->DocumentNode())) {
     uint32_t count = mChildDocuments.Length();
     for (uint32_t idx = 0; idx < count; idx++) {
       DocAccessible* childDoc = mChildDocuments[idx];
       HWND childDocHWND = static_cast<HWND>(childDoc->GetNativeWindow());
       if (childDoc != aDocument)
         nsWinUtils::HideNativeWindow(childDocHWND);
       else
         nsWinUtils::ShowNativeWindow(childDocHWND);
--- a/accessible/src/msaa/TextLeafAccessibleWrap.cpp
+++ b/accessible/src/msaa/TextLeafAccessibleWrap.cpp
@@ -194,50 +194,51 @@ TextLeafAccessibleWrap::GetPointFromOffs
 HRESULT
 TextLeafAccessibleWrap::GetCharacterExtents(int32_t aStartOffset,
                                             int32_t aEndOffset,
                                             int32_t* aX,
                                             int32_t* aY,
                                             int32_t* aWidth,
                                             int32_t* aHeight)
 {
+  if (!aX || !aY || !aWidth || !aHeight)
+    return E_INVALIDARG;
+
   *aX = *aY = *aWidth = *aHeight = 0;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
-  nsPresContext* presContext = mDoc->PresContext();
-
   nsIFrame *frame = GetFrame();
   NS_ENSURE_TRUE(frame, E_FAIL);
 
   nsPoint startPoint, endPoint;
   nsIFrame *startFrame = GetPointFromOffset(frame, aStartOffset, true, startPoint);
   nsIFrame *endFrame = GetPointFromOffset(frame, aEndOffset, false, endPoint);
   if (!startFrame || !endFrame) {
     return E_FAIL;
   }
-  
-  nsIntRect sum(0, 0, 0, 0);
+
+  nsRect sum;
   nsIFrame *iter = startFrame;
   nsIFrame *stopLoopFrame = endFrame->GetNextContinuation();
   for (; iter != stopLoopFrame; iter = iter->GetNextContinuation()) {
-    nsIntRect rect = iter->GetScreenRectExternal();
-    nscoord start = (iter == startFrame) ? presContext->AppUnitsToDevPixels(startPoint.x) : 0;
-    nscoord end = (iter == endFrame) ? presContext->AppUnitsToDevPixels(endPoint.x) :
-                                       rect.width;
+    nsRect rect = iter->GetScreenRectInAppUnits();
+    nscoord start = (iter == startFrame) ? startPoint.x : 0;
+    nscoord end = (iter == endFrame) ? endPoint.x : rect.width;
     rect.x += start;
     rect.width = end - start;
     sum.UnionRect(sum, rect);
   }
 
-  *aX      = sum.x;
-  *aY      = sum.y;
-  *aWidth  = sum.width;
-  *aHeight = sum.height;
+  nsPresContext* presContext = mDoc->PresContext();
+  *aX = presContext->AppUnitsToDevPixels(sum.x);
+  *aY = presContext->AppUnitsToDevPixels(sum.y);
+  *aWidth = presContext->AppUnitsToDevPixels(sum.width);
+  *aHeight = presContext->AppUnitsToDevPixels(sum.height);
 
   return S_OK;
 }
 
 STDMETHODIMP
 TextLeafAccessibleWrap::get_fontFamily(
     /* [retval][out] */ BSTR __RPC_FAR *aFontFamily)
 {
--- a/accessible/src/msaa/nsAccessNodeWrap.cpp
+++ b/accessible/src/msaa/nsAccessNodeWrap.cpp
@@ -42,17 +42,17 @@ nsAccessNodeWrap::
 nsAccessNodeWrap::~nsAccessNodeWrap()
 {
 }
 
 //-----------------------------------------------------
 // nsISupports methods
 //-----------------------------------------------------
 
-NS_IMPL_ISUPPORTS_INHERITED1(nsAccessNodeWrap, nsAccessNode, nsIWinAccessNode);
+NS_IMPL_ISUPPORTS_INHERITED1(nsAccessNodeWrap, nsAccessNode, nsIWinAccessNode)
 
 //-----------------------------------------------------
 // nsIWinAccessNode methods
 //-----------------------------------------------------
 
 NS_IMETHODIMP
 nsAccessNodeWrap::QueryNativeInterface(REFIID aIID, void** aInstancePtr)
 {
@@ -87,17 +87,17 @@ nsAccessNodeWrap::QueryService(REFGUID g
   *ppv = nullptr;
 
   // Provide a special service ID for getting the accessible for the browser tab
   // document that contains this accessible object. If this accessible object
   // is not inside a browser tab then the service fails with E_NOINTERFACE.
   // A use case for this is for screen readers that need to switch context or
   // 'virtual buffer' when focus moves from one browser tab area to another.
   static const GUID SID_IAccessibleContentDocument =
-    { 0xa5d8e1f3,0x3571,0x4d8f,0x95,0x21,0x07,0xed,0x28,0xfb,0x07,0x2e };
+    { 0xa5d8e1f3,0x3571,0x4d8f,{0x95,0x21,0x07,0xed,0x28,0xfb,0x07,0x2e} };
   if (guidService == SID_IAccessibleContentDocument) {
     if (iid != IID_IAccessible)
       return E_NOINTERFACE;
 
     nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem = 
       nsCoreUtils::GetDocShellTreeItemFor(mContent);
     if (!docShellTreeItem)
       return E_UNEXPECTED;
@@ -120,17 +120,17 @@ nsAccessNodeWrap::QueryService(REFGUID g
     // Make sure this is a document.
     DocAccessible* docAcc = nsAccUtils::GetDocAccessibleFor(root);
     if (!docAcc)
       return E_UNEXPECTED;
 
     *ppv = static_cast<IAccessible*>(docAcc);
 
     (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
-    return NS_OK;
+    return S_OK;
   }
 
   // Can get to IAccessibleApplication from any node via QS
   if (guidService == IID_IAccessibleApplication) {
     ApplicationAccessible* applicationAcc = ApplicationAcc();
     if (!applicationAcc)
       return E_NOINTERFACE;
 
@@ -148,17 +148,17 @@ nsAccessNodeWrap::QueryService(REFGUID g
    * if (pServProv) {
    *   const GUID unused;
    *   pServProv->QueryService(unused, IID_ISimpleDOMDocument, (void**)&pAccDoc);
    *   pServProv->Release();
    * }
    */
 
   static const GUID IID_SimpleDOMDeprecated =
-    { 0x0c539790,0x12e4,0x11cf,0xb6,0x61,0x00,0xaa,0x00,0x4c,0xd6,0xd8 };
+    { 0x0c539790,0x12e4,0x11cf,{0xb6,0x61,0x00,0xaa,0x00,0x4c,0xd6,0xd8} };
   if (guidService == IID_ISimpleDOMNode ||
       guidService == IID_SimpleDOMDeprecated ||
       guidService == IID_IAccessible ||  guidService == IID_IAccessible2)
     return QueryInterface(iid, ppv);
 
   return E_INVALIDARG;
 }
 
@@ -404,17 +404,17 @@ nsAccessNodeWrap::MakeAccessNode(nsINode
 
 STDMETHODIMP nsAccessNodeWrap::get_parentNode(ISimpleDOMNode __RPC_FAR *__RPC_FAR *aNode)
 {
 __try {
   nsINode* node = GetNode();
   if (!node)
     return E_FAIL;
 
-  *aNode = MakeAccessNode(node->GetNodeParent());
+  *aNode = MakeAccessNode(node->GetParentNode());
 
 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
 
   return S_OK;
 }
 
 STDMETHODIMP nsAccessNodeWrap::get_firstChild(ISimpleDOMNode __RPC_FAR *__RPC_FAR *aNode)
 {
--- a/accessible/src/windows/uia/uiaRawElmProvider.cpp
+++ b/accessible/src/windows/uia/uiaRawElmProvider.cpp
@@ -183,18 +183,17 @@ uiaRawElmProvider::GetPropertyValue(PROP
 
       break;
     }
     
     //ARIA Role / shortcut
     case UIA_AriaRolePropertyId: {
       nsAutoString xmlRoles;
 
-      nsCOMPtr<nsIPersistentProperties> attributes;
-      mAcc->GetAttributes(getter_AddRefs(attributes));
+      nsCOMPtr<nsIPersistentProperties> attributes = mAcc->Attributes();
       attributes->GetStringProperty(NS_LITERAL_CSTRING("xml-roles"), xmlRoles);
 
       if(!xmlRoles.IsEmpty()) {
         aPropertyValue->vt = VT_BSTR;
         aPropertyValue->bstrVal = ::SysAllocString(xmlRoles.get());
         return S_OK;
       }
 
--- a/accessible/src/xforms/nsXFormsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsAccessible.cpp
@@ -55,25 +55,24 @@ nsXFormsAccessible::
 nsresult
 nsXFormsAccessible::GetBoundChildElementValue(const nsAString& aTagName,
                                               nsAString& aValue)
 {
   NS_ENSURE_TRUE(sXFormsService, NS_ERROR_FAILURE);
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsINodeList* nodes = mContent->GetChildNodesList();
-  NS_ENSURE_STATE(nodes);
+  nsINodeList* nodes = mContent->ChildNodes();
 
   uint32_t length;
   nsresult rv = nodes->GetLength(&length);
   NS_ENSURE_SUCCESS(rv, rv);
 
   for (uint32_t index = 0; index < length; index++) {
-    nsIContent* content = nodes->GetNodeAt(index);
+    nsIContent* content = nodes->Item(index);
     if (content->NodeInfo()->Equals(aTagName) &&
         content->NodeInfo()->NamespaceEquals(NS_LITERAL_STRING(NS_NAMESPACE_XFORMS))) {
       nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(content));
       return sXFormsService->GetValue(DOMNode, aValue);
     }
   }
 
   aValue.Truncate();
@@ -153,21 +152,22 @@ nsXFormsAccessible::NativelyUnavailable(
 {
   nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
 
   bool isRelevant = false;
   sXFormsService->IsRelevant(DOMNode, &isRelevant);
   return !isRelevant;
 }
 
-nsresult
-nsXFormsAccessible::GetNameInternal(nsAString& aName)
+ENameValueFlag
+nsXFormsAccessible::NativeName(nsString& aName)
 {
   // search the xforms:label element
-  return GetBoundChildElementValue(NS_LITERAL_STRING("label"), aName);
+  GetBoundChildElementValue(NS_LITERAL_STRING("label"), aName);
+  return eNameOK;
 }
 
 void
 nsXFormsAccessible::Description(nsString& aDescription)
 {
   nsTextEquivUtils::
     GetTextEquivFromIDRefs(this, nsGkAtoms::aria_describedby,
                            aDescription);
@@ -539,17 +539,17 @@ nsXFormsSelectableItemAccessible::DoActi
 }
 
 bool
 nsXFormsSelectableItemAccessible::IsSelected()
 {
   nsresult rv;
 
   nsINode* parent = mContent;
-  while ((parent = parent->GetNodeParent())) {
+  while ((parent = parent->GetParentNode())) {
     nsCOMPtr<nsIContent> content(do_QueryInterface(parent));
     if (!content)
       return false;
 
     nsCOMPtr<nsINodeInfo> nodeinfo = content->NodeInfo();
     if (!nodeinfo->NamespaceEquals(NS_LITERAL_STRING(NS_NAMESPACE_XFORMS)))
       continue;
 
--- a/accessible/src/xforms/nsXFormsAccessible.h
+++ b/accessible/src/xforms/nsXFormsAccessible.h
@@ -41,29 +41,31 @@ public:
 
   // Accessible
   // Returns value of child xforms 'hint' element.
   virtual void Description(nsString& aDescription);
 
   // Returns value of instance node that xforms element is bound to.
   virtual void Value(nsString& aValue);
 
-  // Returns value of child xforms 'label' element.
-  virtual nsresult GetNameInternal(nsAString& aName);
-
   // Returns state of xforms element taking into account state of instance node
   // that it is bound to.
   virtual uint64_t NativeState();
   virtual bool NativelyUnavailable() const;
 
   // Denies accessible nodes in anonymous content of xforms element by
   // always returning false value.
   virtual bool CanHaveAnonChildren();
 
+
 protected:
+  // Accessible
+  // Returns value of child xforms 'label' element.
+  virtual mozilla::a11y::ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
+
   // 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
   // used for full appearance select/select1 elements or for their child choices
   // element. Note, those select/select1 elements that use native widget
--- a/accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
@@ -22,21 +22,21 @@ nsXFormsLabelAccessible::
 }
 
 role
 nsXFormsLabelAccessible::NativeRole()
 {
   return roles::LABEL;
 }
 
-nsresult
-nsXFormsLabelAccessible::GetNameInternal(nsAString& aName)
+ENameValueFlag
+nsXFormsLabelAccessible::NativeName(nsString& aName)
 {
   // XXX Correct name calculation for this, see bug 453594.
-  return NS_OK;
+  return eNameOK;
 }
 
 void
 nsXFormsLabelAccessible::Description(nsString& aDescription)
 {
   nsTextEquivUtils::
     GetTextEquivFromIDRefs(this, nsGkAtoms::aria_describedby,
                            aDescription);
--- a/accessible/src/xforms/nsXFormsFormControlsAccessible.h
+++ b/accessible/src/xforms/nsXFormsFormControlsAccessible.h
@@ -14,18 +14,21 @@
 
 class nsXFormsLabelAccessible : public nsXFormsAccessible
 {
 public:
   nsXFormsLabelAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
   virtual void Description(nsString& aDescription);
-  virtual nsresult GetNameInternal(nsAString& aName);
   virtual mozilla::a11y::role NativeRole();
+
+protected:
+  // Accessible
+  virtual mozilla::a11y::ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
 };
 
 /**
  * Accessible object for xforms:output.
  */
 
 class nsXFormsOutputAccessible : public nsXFormsAccessible
 {
--- a/accessible/src/xforms/nsXFormsWidgetsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsWidgetsAccessible.cpp
@@ -128,22 +128,22 @@ nsXFormsComboboxPopupWidgetAccessible::N
 }
 
 uint64_t
 nsXFormsComboboxPopupWidgetAccessible::NativeInteractiveState() const
 {
   return NativelyUnavailable() ? states::UNAVAILABLE : states::FOCUSABLE;
 }
 
-nsresult
-nsXFormsComboboxPopupWidgetAccessible::GetNameInternal(nsAString& aName)
+ENameValueFlag
+nsXFormsComboboxPopupWidgetAccessible::NativeName(nsString& aName)
 {
   // Override nsXFormsAccessible::GetName() to prevent name calculation by
   // XForms rules.
-  return NS_OK;
+  return eNameOK;
 }
 
 void
 nsXFormsComboboxPopupWidgetAccessible::Description(nsString& aDescription)
 {
   aDescription.Truncate();
 }
 
@@ -151,13 +151,13 @@ void
 nsXFormsComboboxPopupWidgetAccessible::Value(nsString& aValue)
 {
   aValue.Truncate();
 }
 
 void
 nsXFormsComboboxPopupWidgetAccessible::CacheChildren()
 {
-  nsCOMPtr<nsIDOMNode> parent = do_QueryInterface(mContent->GetNodeParent());
+  nsCOMPtr<nsIDOMNode> parent = do_QueryInterface(mContent->GetParentNode());
   // Parent node must be an xforms:select1 element.
   CacheSelectChildren(parent);
 }
 
--- a/accessible/src/xforms/nsXFormsWidgetsAccessible.h
+++ b/accessible/src/xforms/nsXFormsWidgetsAccessible.h
@@ -56,19 +56,19 @@ class nsXFormsComboboxPopupWidgetAccessi
 {
 public:
   nsXFormsComboboxPopupWidgetAccessible(nsIContent* aContent,
                                         DocAccessible* aDoc);
 
   // Accessible
   virtual void Description(nsString& aDescription);
   virtual void Value(nsString& aValue);
-  virtual nsresult GetNameInternal(nsAString& aName);
   virtual mozilla::a11y::role NativeRole();
   virtual uint64_t NativeState();
   virtual uint64_t NativeInteractiveState() const;
 
 protected:
   // Accessible
+  virtual mozilla::a11y::ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
   virtual void CacheChildren();
 };
 
 #endif
--- a/accessible/src/xul/XULElementAccessibles.cpp
+++ b/accessible/src/xul/XULElementAccessibles.cpp
@@ -27,23 +27,23 @@ using namespace mozilla::a11y;
 ////////////////////////////////////////////////////////////////////////////////
 
 XULLabelAccessible::
   XULLabelAccessible(nsIContent* aContent, DocAccessible* aDoc) :
   HyperTextAccessibleWrap(aContent, aDoc)
 {
 }
 
-nsresult
-XULLabelAccessible::GetNameInternal(nsAString& aName)
+ENameValueFlag
+XULLabelAccessible::NativeName(nsString& aName)
 {
   // if the value attr doesn't exist, the screen reader must get the accessible text
   // from the accessible text interface or from the children
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, aName);
-  return NS_OK;
+  return eNameOK;
 }
 
 role
 XULLabelAccessible::NativeRole()
 {
   return roles::LABEL;
 }
 
@@ -116,24 +116,25 @@ NS_IMPL_ISUPPORTS_INHERITED1(XULLinkAcce
 void
 XULLinkAccessible::Value(nsString& aValue)
 {
   aValue.Truncate();
 
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::href, aValue);
 }
 
-nsresult
-XULLinkAccessible::GetNameInternal(nsAString& aName)
+ENameValueFlag
+XULLinkAccessible::NativeName(nsString& aName)
 {
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, aName);
   if (!aName.IsEmpty())
-    return NS_OK;
+    return eNameOK;
 
-  return nsTextEquivUtils::GetNameFromSubtree(this, aName);
+  nsTextEquivUtils::GetNameFromSubtree(this, aName);
+  return aName.IsEmpty() ? eNameOK : eNameFromSubtree;
 }
 
 role
 XULLinkAccessible::NativeRole()
 {
   return roles::LINK;
 }
 
--- a/accessible/src/xul/XULElementAccessibles.h
+++ b/accessible/src/xul/XULElementAccessibles.h
@@ -16,20 +16,23 @@ namespace a11y {
  * Used for XUL description and label elements.
  */
 class XULLabelAccessible : public HyperTextAccessibleWrap
 {
 public:
   XULLabelAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
-  virtual nsresult GetNameInternal(nsAString& aName);
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
   virtual Relation RelationByType(uint32_t aRelationType);
+
+protected:
+  // Accessible
+  virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
 };
 
 /**
  * Used for XUL tooltip element.
  */
 class XULTooltipAccessible : public LeafAccessible
 {
 
@@ -50,30 +53,32 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIAccessible
   NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName);
   NS_IMETHOD DoAction(uint8_t aIndex);
 
   // Accessible
   virtual void Value(nsString& aValue);
-  virtual nsresult GetNameInternal(nsAString& aName);
   virtual a11y::role NativeRole();
   virtual uint64_t NativeLinkState() const;
 
   // ActionAccessible
   virtual uint8_t ActionCount();
 
   // HyperLinkAccessible
   virtual bool IsLink();
   virtual uint32_t StartOffset();
   virtual uint32_t EndOffset();
   virtual already_AddRefed<nsIURI> AnchorURIAt(uint32_t aAnchorIndex);
 
 protected:
+  // Accessible
+  virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
+
   enum { eAction_Jump = 0 };
 
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/src/xul/XULFormControlAccessible.cpp
+++ b/accessible/src/xul/XULFormControlAccessible.cpp
@@ -408,26 +408,26 @@ XULGroupboxAccessible::
 }
 
 role
 XULGroupboxAccessible::NativeRole()
 {
   return roles::GROUPING;
 }
 
-nsresult
-XULGroupboxAccessible::GetNameInternal(nsAString& aName)
+ENameValueFlag
+XULGroupboxAccessible::NativeName(nsString& aName)
 {
   // XXX: we use the first related accessible only.
   Accessible* label =
     RelationByType(nsIAccessibleRelation::RELATION_LABELLED_BY).Next();
   if (label)
-    return label->GetName(aName);
+    return label->Name(aName);
 
-  return NS_OK;
+  return eNameOK;
 }
 
 Relation
 XULGroupboxAccessible::RelationByType(uint32_t aType)
 {
   Relation rel = AccessibleWrap::RelationByType(aType);
   if (aType != nsIAccessibleRelation::RELATION_LABELLED_BY)
     return rel;
@@ -634,26 +634,23 @@ XULToolbarAccessible::
 }
 
 role
 XULToolbarAccessible::NativeRole()
 {
   return roles::TOOLBAR;
 }
 
-nsresult
-XULToolbarAccessible::GetNameInternal(nsAString& aName)
+ENameValueFlag
+XULToolbarAccessible::NativeName(nsString& aName)
 {
-  nsAutoString name;
-  if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::toolbarname, name)) {
-    name.CompressWhitespace();
-    aName = name;
-  }
+  if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::toolbarname, aName))
+    aName.CompressWhitespace();
 
-  return NS_OK;
+  return eNameOK;
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULToolbarAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 XULToolbarSeparatorAccessible::
--- a/accessible/src/xul/XULFormControlAccessible.h
+++ b/accessible/src/xul/XULFormControlAccessible.h
@@ -112,18 +112,21 @@ private:
  */
 class XULGroupboxAccessible : public AccessibleWrap
 {
 public:
   XULGroupboxAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
   virtual mozilla::a11y::role NativeRole();
-  virtual nsresult GetNameInternal(nsAString& aName);
   virtual Relation RelationByType(uint32_t aRelationType);
+
+protected:
+  // Accessible
+  virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
 };
 
 /**
  * Used for XUL radio element (radio button).
  */
 class XULRadioButtonAccessible : public RadioButtonAccessible
 {
 
@@ -189,17 +192,20 @@ public:
  */
 class XULToolbarAccessible : public AccessibleWrap
 {
 public:
   XULToolbarAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
   virtual mozilla::a11y::role NativeRole();
-  virtual nsresult GetNameInternal(nsAString& aName);
+
+protected:
+  // Accessible
+  virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
 };
 
 /**
  * Used for XUL toolbarseparator element.
  */
 class XULToolbarSeparatorAccessible : public LeafAccessible
 {
 public:
--- a/accessible/src/xul/XULListboxAccessible.cpp
+++ b/accessible/src/xul/XULListboxAccessible.cpp
@@ -617,27 +617,28 @@ XULListitemAccessible::Description(nsStr
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULListitemAccessible. nsIAccessible
 
 /**
   * If there is a Listcell as a child ( not anonymous ) use it, otherwise
   *   default to getting the name from GetXULName
   */
-nsresult
-XULListitemAccessible::GetNameInternal(nsAString& aName)
+ENameValueFlag
+XULListitemAccessible::NativeName(nsString& aName)
 {
   nsIContent* childContent = mContent->GetFirstChild();
   if (childContent) {
     if (childContent->NodeInfo()->Equals(nsGkAtoms::listcell,
                                          kNameSpaceID_XUL)) {
       childContent->GetAttr(kNameSpaceID_None, nsGkAtoms::label, aName);
-      return NS_OK;
+      return eNameOK;
     }
   }
+
   return GetXULName(aName);
 }
 
 role
 XULListitemAccessible::NativeRole()
 {
   Accessible* list = GetListAccessible();
   if (!list) {
@@ -851,27 +852,25 @@ XULListCellAccessible::Shutdown()
 }
 
 role
 XULListCellAccessible::NativeRole()
 {
   return roles::CELL;
 }
 
-nsresult
-XULListCellAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
+already_AddRefed<nsIPersistentProperties>
+XULListCellAccessible::NativeAttributes()
 {
-  NS_ENSURE_ARG_POINTER(aAttributes);
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
+  nsCOMPtr<nsIPersistentProperties> attributes =
+    HyperTextAccessibleWrap::NativeAttributes();
 
   // "table-cell-index" attribute
   TableAccessible* table = Table();
-  NS_ENSURE_STATE(table); // we expect to be in a listbox (table)
+  if (!table) // we expect to be in a listbox (table)
+    return attributes.forget();
 
   nsAutoString stringIdx;
   stringIdx.AppendInt(table->CellIndexAt(RowIdx(), ColIdx()));
-  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::tableCellIndex,
-                         stringIdx);
+  nsAccUtils::SetAccAttr(attributes, nsGkAtoms::tableCellIndex, stringIdx);
 
-  return NS_OK;
+  return attributes.forget();
 }
--- a/accessible/src/xul/XULListboxAccessible.h
+++ b/accessible/src/xul/XULListboxAccessible.h
@@ -126,26 +126,30 @@ public:
   virtual ~XULListitemAccessible() {}
 
   // nsIAccessible
   NS_IMETHOD GetActionName(uint8_t index, nsAString& aName);
   // Don't use XUL menuitems's description attribute
 
   // Accessible
   virtual void Description(nsString& aDesc);
-  virtual nsresult GetNameInternal(nsAString& aName);
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
   virtual uint64_t NativeInteractiveState() const;
   virtual bool CanHaveAnonChildren();
 
   // Widgets
   virtual Accessible* ContainerWidget() const;
 
 protected:
+  // Accessible
+  virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
+
+  // XULListitemAccessible
+
   /**
    * Return listbox accessible for the listitem.
    */
   Accessible* GetListAccessible();
 
 private:
   bool mIsCheckbox;
 };
@@ -165,17 +169,17 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIAccessibleTableCell
   NS_FORWARD_NSIACCESSIBLETABLECELL(xpcAccessibleTableCell::)
 
   // Accessible
   virtual TableCellAccessible* AsTableCell() { return this; }
   virtual void Shutdown();
-  virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
+  virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
   virtual a11y::role NativeRole();
 
   // TableCellAccessible
   virtual TableAccessible* Table() const MOZ_OVERRIDE;
   virtual uint32_t ColIdx() const MOZ_OVERRIDE;
   virtual uint32_t RowIdx() const MOZ_OVERRIDE;
   virtual void ColHeaderCells(nsTArray<Accessible*>* aHeaderCells) MOZ_OVERRIDE;
   virtual bool Selected() MOZ_OVERRIDE;
--- a/accessible/src/xul/XULMenuAccessible.cpp
+++ b/accessible/src/xul/XULMenuAccessible.cpp
@@ -129,21 +129,21 @@ XULMenuitemAccessible::NativeInteractive
       return states::UNAVAILABLE;
 
     return states::UNAVAILABLE | states::FOCUSABLE | states::SELECTABLE;
   }
 
   return states::FOCUSABLE | states::SELECTABLE;
 }
 
-nsresult
-XULMenuitemAccessible::GetNameInternal(nsAString& aName)
+ENameValueFlag
+XULMenuitemAccessible::NativeName(nsString& aName)
 {
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::label, aName);
-  return NS_OK;
+  return eNameOK;
 }
 
 void
 XULMenuitemAccessible::Description(nsString& aDescription)
 {
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::description,
                     aDescription);
 }
@@ -391,20 +391,20 @@ XULMenuSeparatorAccessible::
 uint64_t
 XULMenuSeparatorAccessible::NativeState()
 {
   // Isn't focusable, but can be offscreen/invisible -- only copy those states
   return XULMenuitemAccessible::NativeState() &
     (states::OFFSCREEN | states::INVISIBLE);
 }
 
-nsresult
-XULMenuSeparatorAccessible::GetNameInternal(nsAString& aName)
+ENameValueFlag
+XULMenuSeparatorAccessible::NativeName(nsString& aName)
 {
-  return NS_OK;
+  return eNameOK;
 }
 
 role
 XULMenuSeparatorAccessible::NativeRole()
 {
   return roles::SEPARATOR;
 }
 
@@ -464,26 +464,26 @@ XULMenupopupAccessible::NativeState()
 #endif
 
   if (state & states::INVISIBLE)
     state |= states::OFFSCREEN | states::COLLAPSED;
 
   return state;
 }
 
-nsresult
-XULMenupopupAccessible::GetNameInternal(nsAString& aName)
+ENameValueFlag
+XULMenupopupAccessible::NativeName(nsString& aName)
 {
-  nsIContent *content = mContent;
+  nsIContent* content = mContent;
   while (content && aName.IsEmpty()) {
     content->GetAttr(kNameSpaceID_None, nsGkAtoms::label, aName);
     content = content->GetParent();
   }
 
-  return NS_OK;
+  return eNameOK;
 }
 
 role
 XULMenupopupAccessible::NativeRole()
 {
   // If accessible is not bound to the tree (this happens while children are
   // cached) return general role.
   if (mParent) {
@@ -567,21 +567,21 @@ XULMenupopupAccessible::ContainerWidget(
 ////////////////////////////////////////////////////////////////////////////////
 
 XULMenubarAccessible::
   XULMenubarAccessible(nsIContent* aContent, DocAccessible* aDoc) :
   AccessibleWrap(aContent, aDoc)
 {
 }
 
-nsresult
-XULMenubarAccessible::GetNameInternal(nsAString& aName)
+ENameValueFlag
+XULMenubarAccessible::NativeName(nsString& aName)
 {
   aName.AssignLiteral("Application");
-  return NS_OK;
+  return eNameOK;
 }
 
 role
 XULMenubarAccessible::NativeRole()
 {
   return roles::MENUBAR;
 }
 
--- a/accessible/src/xul/XULMenuAccessible.h
+++ b/accessible/src/xul/XULMenuAccessible.h
@@ -24,93 +24,105 @@ public:
   XULMenuitemAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // nsIAccessible
   NS_IMETHOD DoAction(uint8_t index);
   NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName);
 
   // Accessible
   virtual void Description(nsString& aDescription);
-  virtual nsresult GetNameInternal(nsAString& aName);
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
   virtual uint64_t NativeInteractiveState() const;
   virtual int32_t GetLevelInternal();
 
   virtual bool CanHaveAnonChildren();
 
   // ActionAccessible
   virtual uint8_t ActionCount();
   virtual KeyBinding AccessKey() const;
   virtual KeyBinding KeyboardShortcut() const;
 
   // Widgets
   virtual bool IsActiveWidget() const;
   virtual bool AreItemsOperable() const;
   virtual Accessible* ContainerWidget() const;
+
+protected:
+  // Accessible
+  virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
 };
 
 /**
  * Used for XUL menuseparator element.
  */
 class XULMenuSeparatorAccessible : public XULMenuitemAccessible
 {
 public:
   XULMenuSeparatorAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // nsIAccessible
   NS_IMETHOD DoAction(uint8_t index);
   NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName);
 
   // Accessible
-  virtual nsresult GetNameInternal(nsAString& aName);
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
 
   // ActionAccessible
   virtual uint8_t ActionCount();
+
+protected:
+  // Accessible
+  virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
 };
 
 
 /**
  * Used for XUL menupopup and panel.
  */
 class XULMenupopupAccessible : public XULSelectControlAccessible
 {
 public:
   XULMenupopupAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
-  virtual nsresult GetNameInternal(nsAString& aName);
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
 
   // Widgets
   virtual bool IsWidget() const;
   virtual bool IsActiveWidget() const;
   virtual bool AreItemsOperable() const;
 
   virtual Accessible* ContainerWidget() const;
+
+protected:
+  // Accessible
+  virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
 };
 
 /**
  * Used for XUL menubar element.
  */
 class XULMenubarAccessible : public AccessibleWrap
 {
 public:
   XULMenubarAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
-  virtual nsresult GetNameInternal(nsAString& aName);
   virtual a11y::role NativeRole();
 
   // Widget
   virtual bool IsActiveWidget() const;
   virtual bool AreItemsOperable() const;
   virtual Accessible* CurrentItem();
   virtual void SetCurrentItem(Accessible* aItem);
+
+protected:
+  // Accessible
+  virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/src/xul/XULTabAccessible.cpp
+++ b/accessible/src/xul/XULTabAccessible.cpp
@@ -149,21 +149,21 @@ XULTabsAccessible::ActionCount()
 }
 
 void
 XULTabsAccessible::Value(nsString& aValue)
 {
   aValue.Truncate();
 }
 
-nsresult
-XULTabsAccessible::GetNameInternal(nsAString& aName)
+ENameValueFlag
+XULTabsAccessible::NativeName(nsString& aName)
 {
   // no name
-  return NS_OK;
+  return eNameOK;
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULDeckAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 role
--- a/accessible/src/xul/XULTabAccessible.h
+++ b/accessible/src/xul/XULTabAccessible.h
@@ -43,21 +43,24 @@ public:
  */
 class XULTabsAccessible : public XULSelectControlAccessible
 {
 public:
   XULTabsAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
   virtual void Value(nsString& aValue);
-  virtual nsresult GetNameInternal(nsAString& aName);
   virtual a11y::role NativeRole();
 
   // ActionAccessible
   virtual uint8_t ActionCount();
+
+protected:
+  // Accessible
+  virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
 };
 
 
 /**
  * A container of tab panels, xul:tabpanels element.
  */
 class XULDeckAccessible : public AccessibleWrap
 {
--- a/accessible/src/xul/XULTreeGridAccessible.cpp
+++ b/accessible/src/xul/XULTreeGridAccessible.cpp
@@ -722,41 +722,39 @@ XULTreeGridCellAccessible::Init()
     mTreeView->GetCellValue(mRow, mColumn, mCachedTextEquiv);
   else
     mTreeView->GetCellText(mRow, mColumn, mCachedTextEquiv);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeGridCellAccessible: Accessible public implementation
 
-nsresult
-XULTreeGridCellAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
+already_AddRefed<nsIPersistentProperties>
+XULTreeGridCellAccessible::NativeAttributes()
 {
-  NS_ENSURE_ARG_POINTER(aAttributes);
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
+  nsCOMPtr<nsIPersistentProperties> attributes =
+    do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID);
 
   // "table-cell-index" attribute
   TableAccessible* table = Table();
   if (!table)
-    return NS_ERROR_FAILURE;
+    return attributes.forget();
 
   nsAutoString stringIdx;
   stringIdx.AppendInt(table->CellIndexAt(mRow, ColIdx()));
-  nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::tableCellIndex, stringIdx);
+  nsAccUtils::SetAccAttr(attributes, nsGkAtoms::tableCellIndex, stringIdx);
 
   // "cycles" attribute
   bool isCycler = false;
   nsresult rv = mColumn->GetCycler(&isCycler);
   if (NS_SUCCEEDED(rv) && isCycler)
-    nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::cycles,
+    nsAccUtils::SetAccAttr(attributes, nsGkAtoms::cycles,
                            NS_LITERAL_STRING("true"));
 
-  return NS_OK;
+  return attributes.forget();
 }
 
 role
 XULTreeGridCellAccessible::NativeRole()
 {
   return roles::GRID_CELL;
 }
 
--- a/accessible/src/xul/XULTreeGridAccessible.h
+++ b/accessible/src/xul/XULTreeGridAccessible.h
@@ -153,17 +153,17 @@ public:
   // nsAccessNode
   virtual void Init();
 
   // Accessible
   virtual TableCellAccessible* AsTableCell() { return this; }
   virtual void Shutdown();
   virtual ENameValueFlag Name(nsString& aName);
   virtual Accessible* FocusedChild();
-  virtual nsresult GetAttributesInternal(nsIPersistentProperties* aAttributes);
+  virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
   virtual int32_t IndexInParent() const;
   virtual Relation RelationByType(uint32_t aType);
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
   virtual uint64_t NativeInteractiveState() const;
 
   // ActionAccessible
   virtual uint8_t ActionCount();
--- a/accessible/tests/mochitest/Makefile.in
+++ b/accessible/tests/mochitest/Makefile.in
@@ -19,16 +19,17 @@ DIRS	= \
   focus \
   hittest \
   hyperlink \
   hypertext \
   name \
   pivot \
   relations \
   role \
+  scroll \
   selectable \
   states \
   table \
   text \
   textcaret \
   textselection \
   tree \
   treeupdate \
--- a/accessible/tests/mochitest/actions/test_media.html
+++ b/accessible/tests/mochitest/actions/test_media.html
@@ -19,16 +19,17 @@ https://bugzilla.mozilla.org/show_bug.cg
   <script type="application/javascript"
           src="../role.js"></script>
   <script type="application/javascript"
           src="../states.js"></script>
 
   <script type="application/javascript">
 
     // gA11yEventDumpID = "eventDump";
+    //gA11yEventDumpToConsole = true; // debug stuff
 
     function focusChecker(aAcc)
     {
       this.type = EVENT_FOCUS;
       this.target = aAcc;
       this.getID = function focusChecker_getID()
       {
         return "focus handling";
--- a/accessible/tests/mochitest/attributes/test_obj.html
+++ b/accessible/tests/mochitest/attributes/test_obj.html
@@ -33,18 +33,22 @@ https://bugzilla.mozilla.org/show_bug.cg
       testAttrs("dropeffect", {"dropeffect" : "copy"}, true);
       testAttrs("grabbed", {"grabbed" : "true"}, true);
       testAttrs("hidden", {"hidden" : "true"}, true);
       testAttrs("sortAscending", {"sort" : "ascending"}, true);
       testAttrs("sortDescending", {"sort" : "descending"}, true);
       testAttrs("sortNone", {"sort" : "none"}, true);
       testAttrs("sortOther", {"sort" : "other"}, true);
 
+      // inherited attributes by subdocuments
+      var subdoc = getAccessible("iframe").firstChild;
+      testAttrs(subdoc, {"busy" : "true"}, true);
+
       // live object attribute
-      
+
       // HTML
       testAttrs("output", {"live" : "polite"}, true);
 
       // ARIA
       testAttrs("live", {"live" : "polite"}, true);
       testAttrs("live2", {"live" : "polite"}, true);
       testAbsentAttrs("live3", {"live" : ""});
       testAttrs("log", {"live" : "polite"}, true);
@@ -167,16 +171,20 @@ https://bugzilla.mozilla.org/show_bug.cg
   <div id="dropeffect" aria-dropeffect="copy"></div>
   <div id="grabbed" aria-grabbed="true"></div>
   <div id="hidden" aria-hidden="true"></div>
   <div id="sortAscending" role="columnheader" aria-sort="ascending"></div>
   <div id="sortDescending" role="columnheader" aria-sort="descending"></div>
   <div id="sortNone" role="columnheader" aria-sort="none"></div>
   <div id="sortOther" role="columnheader" aria-sort="other"></div>
 
+  <!-- inherited from iframe -->
+  <iframe id="iframe" src="data:text/html,<html><body></body></html>"
+          aria-busy="true"></iframe>
+
   <!-- html -->
   <output id="output"></output>
 
   <!-- back to aria -->
   <div id="live" aria-live="polite">excuse <div id="liveChild">me</div></div>
   <div id="live2" role="marquee" aria-live="polite">excuse <div id="live2Child">me</div></div>
   <div id="live3" role="region">excuse</div>
   <div id="log" role="log">excuse <div id="logChild">me</div></div>
--- a/accessible/tests/mochitest/bounds/Makefile.in
+++ b/accessible/tests/mochitest/bounds/Makefile.in
@@ -9,12 +9,13 @@ srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = accessible/bounds
 
 include $(DEPTH)/config/autoconf.mk
 
 MOCHITEST_A11Y_FILES =\
 		test_list.html \
 		test_select.html \
+		test_zoom_text.html \
 		test_zoom.html \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/bounds/test_zoom_text.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>The text range boundary when page is zoomed</title>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8"></meta>
+  <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="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="../layout.js"></script>
+  <script type="application/javascript"
+          src="../browser.js"></script>
+
+  <script type="application/javascript">
+    function doTest()
+    {
+      var tabDocument = currentTabDocument();
+      var hyperTextNode = tabDocument.getElementById("paragraph");
+      var textNode = hyperTextNode.firstChild;
+
+      var [x, y, width, height] = getBounds(textNode);
+      testTextBounds(hyperTextNode, 0, -1, [x, y, width, height],
+                     COORDTYPE_SCREEN_RELATIVE);
+
+      zoomDocument(tabDocument, 2.0);
+
+      var [x, y, width, height] = getBounds(textNode);
+      testTextBounds(hyperTextNode, 0, -1, [x, y, width, height],
+                     COORDTYPE_SCREEN_RELATIVE);
+
+      zoomDocument(tabDocument, 1.0);
+
+      closeBrowserWindow();
+      SimpleTest.finish();
+    }
+
+    var url = "data:text/html,<html>" +
+      "<meta http-equiv='Content-Type' content='text/html;charset=utf-8'>" +
+      "</meta><body>" +
+      "<p id='paragraph' style='font-family: monospace;'>Tilimilitryamdiya</p>" +
+      "</body></html>";
+
+    SimpleTest.waitForExplicitFinish();
+    openBrowserWindow(doTest,
+                      url,
+                      { left: 0, top: 0, width: 600, height: 600 });
+
+  </script>
+
+</head>
+<body>
+
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=727942"
+     title="Text range boundaries are incorrect when page is zoomed">
+    Mozilla Bug 727942
+  </a>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+</body>
+</html>
--- a/accessible/tests/mochitest/common.js
+++ b/accessible/tests/mochitest/common.js
@@ -68,22 +68,28 @@ const SEAMONKEY = navigator.userAgent.ma
 
 ////////////////////////////////////////////////////////////////////////////////
 // Accessible general
 
 const STATE_BUSY = nsIAccessibleStates.STATE_BUSY;
 
 const SCROLL_TYPE_ANYWHERE = nsIAccessibleScrollType.SCROLL_TYPE_ANYWHERE;
 
+const COORDTYPE_SCREEN_RELATIVE = nsIAccessibleCoordinateType.COORDTYPE_SCREEN_RELATIVE;
+const COORDTYPE_WINDOW_RELATIVE = nsIAccessibleCoordinateType.COORDTYPE_WINDOW_RELATIVE;
+const COORDTYPE_PARENT_RELATIVE = nsIAccessibleCoordinateType.COORDTYPE_PARENT_RELATIVE;
+
 const kEmbedChar = String.fromCharCode(0xfffc);
 
 const kDiscBulletText = String.fromCharCode(0x2022) + " ";
 const kCircleBulletText = String.fromCharCode(0x25e6) + " ";
 const kSquareBulletText = String.fromCharCode(0x25aa) + " ";
 
+const MAX_TRIM_LENGTH = 100;
+
 /**
  * nsIAccessibleRetrieval service.
  */
 var gAccRetrieval = Components.classes["@mozilla.org/accessibleRetrieval;1"].
   getService(nsIAccessibleRetrieval);
 
 /**
  * Enable/disable logging.
@@ -598,17 +604,17 @@ function getTextFromClipboard()
 function prettyName(aIdentifier)
 {
   if (aIdentifier instanceof nsIAccessible) {
     var acc = getAccessible(aIdentifier);
     var msg = "[" + getNodePrettyName(acc.DOMNode);
     try {
       msg += ", role: " + roleToString(acc.role);
       if (acc.name)
-        msg += ", name: '" + acc.name + "'";
+        msg += ", name: '" + shortenString(acc.name) + "'";
     } catch (e) {
       msg += "defunct";
     }
 
     if (acc)
       msg += ", address: " + getObjAddress(acc);
     msg += "]";
 
@@ -616,16 +622,31 @@ function prettyName(aIdentifier)
   }
 
   if (aIdentifier instanceof nsIDOMNode)
     return "[ " + getNodePrettyName(aIdentifier) + " ]";
 
   return " '" + aIdentifier + "' ";
 }
 
+/**
+ * Shorten a long string if it exceeds MAX_TRIM_LENGTH.
+ * @param aString the string to shorten.
+ * @returns the shortened string.
+ */
+function shortenString(aString, aMaxLength)
+{
+  if (aString.length <= MAX_TRIM_LENGTH)
+    return aString;
+
+  // Trim the string if its length is > MAX_TRIM_LENGTH characters.
+  var trimOffset = MAX_TRIM_LENGTH / 2;
+  return aString.substring(0, trimOffset - 1) + "..." +
+    aString.substring(aString.length - trimOffset, aString.length);
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 // Private
 ////////////////////////////////////////////////////////////////////////////////
 
 ////////////////////////////////////////////////////////////////////////////////
 // Accessible general
 
--- a/accessible/tests/mochitest/events/test_aria_objattr.html
+++ b/accessible/tests/mochitest/events/test_aria_objattr.html
@@ -38,18 +38,18 @@
       this.getID = function updateAttribute_getID()
       {
         return aAttr + " for " + aID + " " + aValue;
       }
     }
 
     // Debug stuff.
     // gA11yEventDumpID = "eventdump";
-    // gA11yEventDumpToConsole = true;
-    
+    //gA11yEventDumpToConsole = true;
+
     function doTests()
     {
       gQueue = new eventQueue();
 
       gQueue.push(new updateAttribute("hideable", "aria-hidden", "true"));
 
       gQueue.push(new updateAttribute("sortable", "aria-sort", "ascending"));
 
--- a/accessible/tests/mochitest/events/test_focus_menu.xul
+++ b/accessible/tests/mochitest/events/test_focus_menu.xul
@@ -52,38 +52,29 @@
       // menu and menuitem are both active
       // XXX: intermitent failure because two focus events may be coalesced,
       // think to workaround or fix this issue, when done enable queue invoker
       // below and remove next two.
       //gQueue.push(new synthRightKey("apple",
       //                              [ new focusChecker("vehicle"),
       //                                new focusChecker("cycle")]));
       gQueue.push(new synthClick("vehicle", new focusChecker("vehicle")));
-      gQueue.push(new synthMouseMove("cycle", new focusChecker("cycle")));
-
-      // XXXbug708927 - test times out on Linux, see more info at
-      // https://bugzilla.mozilla.org/show_bug.cgi?id=708927#c360. If needed
-      // then enable logging below.
-      if (LINUX) {
-        todo(false, "Reenable on Linux after fixing bug 708927!");
-      } else {
+      gQueue.push(new synthDownKey("cycle", new focusChecker("cycle")));
 
       // open submenu
       gQueue.push(new synthRightKey("cycle", new focusChecker("tricycle")));
 
       // move to first menu in cycle, DOMMenuItemActive is fired for fruit,
       // cycle and apple menuitems (bug 685191)
       todo(false, "focus is fired for 'cycle' menuitem");
       //gQueue.push(new synthRightKey("vehicle", new focusChecker("apple")));
 
       // click menuitem to close menu, focus gets back to document
       gQueue.push(new synthClick("tricycle", new focusChecker(document)));
 
-      }
-
       //enableLogging("focus,DOMEvents,tree"); // logging for bug708927
       //gQueue.onFinish = function() { disableLogging(); }
 
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTests);
--- a/accessible/tests/mochitest/events/test_text_alg.html
+++ b/accessible/tests/mochitest/events/test_text_alg.html
@@ -51,18 +51,19 @@
 
       this.invoke = function changeText_invoke()
       {
         this.textNode.data = aValue;
       }
 
       this.getID = function changeText_getID()
       {
-        return "change text '" + this.textData + "' -> " + this.textNode.data +
-          "for " + prettyName(this.containerNode);
+        return "change text '" + shortenString(this.textData) + "' -> '" +
+          shortenString(this.textNode.data) + "' for " +
+          prettyName(this.containerNode);
       }
     }
 
     function expStr(x, doublings)
     {
       for (var i = 0; i < doublings; ++i)
         x = x + x;
       return x;
--- a/accessible/tests/mochitest/events/test_valuechange.html
+++ b/accessible/tests/mochitest/events/test_valuechange.html
@@ -21,86 +21,106 @@
 
 
     /**
      * Do tests.
      */
     var gQueue = null;
 
     // Value change invoker
-    function changeValue(aNodeOrID, aValuenow, aValuetext)
+    function changeARIAValue(aNodeOrID, aValuenow, aValuetext)
     {
       this.DOMNode = getNode(aNodeOrID);
 
-      this.invoke = function changeValue_invoke() {
+      this.invoke = function changeARIAValue_invoke() {
 
         // Note: this should not fire an EVENT_VALUE_CHANGE when aria-valuetext
         // is not empty
         if (aValuenow != undefined)
           this.DOMNode.setAttribute("aria-valuenow", aValuenow);
  
         // Note: this should always fire an EVENT_VALUE_CHANGE
         if (aValuetext != undefined)
           this.DOMNode.setAttribute("aria-valuetext", aValuetext);
       }
 
-      this.check = function changeValue_check() {
+      this.check = function changeARIAValue_check() {
         var acc = getAccessible(aNodeOrID, [nsIAccessibleValue]);
         if (!acc)
           return;
 
         // Note: always test against valuetext first because the existence of 
         // aria-valuetext takes precedence over aria-valuenow in gecko.
         is(acc.value, (aValuetext != undefined)? aValuetext : aValuenow,
             "Wrong value of " + prettyName(aNodeOrID));
       }
 
-      this.getID = function changeValue_getID() {
+      this.getID = function changeARIAValue_getID() {
         return prettyName(aNodeOrID) + " value changed";
       }
     }
 
-    function changeInputValue(aID, aValue)
+    function changeValue(aID, aValue)
     {
       this.DOMNode = getNode(aID);
 
-      this.invoke = function changeInputValue_invoke()
+      this.invoke = function changeValue_invoke()
       {
         this.DOMNode.value = aValue;
       }
 
-      this.check = function changeInputValue_check()
+      this.check = function changeValue_check()
       {
         var acc = getAccessible(this.DOMNode);
         is(acc.value, aValue, "Wrong value for " + prettyName(aID));
       }
 
-      this.getID = function changeInputValue_getID()
+      this.getID = function changeValue_getID()
       {
         return prettyName(aID) + " value changed";
       }
     }
 
+    function changeProcessValue(aID, aValue) {
+        this.DOMNode = getNode(aID);
+
+        this.invoke = function changeProcessValue_invoke() {
+            this.DOMNode.value = aValue;
+        }
+
+        this.check = function changeProcessValue_check() {
+            var acc = getAccessible(this.DOMNode);
+            is(acc.value, aValue+"%", "Wrong value for " + prettyName(aID));
+        }
+
+        this.getID = function changeProcessValue_getID() {
+            return prettyName(aID) + " value changed";
+        }
+    }
+
     function doTests()
     {
       // Test initial values
       testValue("slider_vn", "5", 5, 0, 1000, 0);
       testValue("slider_vnvt", "plain", 0, 0, 5, 0);
       testValue("slider_vt", "hi", 0, 0, 3, 0);
       testValue("scrollbar", "5", 5, 0, 1000, 0);
+      testValue("progress", "22%", 22, 0, 100, 0);
 
       // Test value change events
       gQueue = new eventQueue(nsIAccessibleEvent.EVENT_VALUE_CHANGE);
 
-      gQueue.push(new changeValue("slider_vn", "6", undefined));
-      gQueue.push(new changeValue("slider_vt", undefined, "hey!"));
-      gQueue.push(new changeValue("slider_vnvt", "3", "sweet"));
-      gQueue.push(new changeValue("scrollbar", "6", undefined));
+      gQueue.push(new changeARIAValue("slider_vn", "6", undefined));
+      gQueue.push(new changeARIAValue("slider_vt", undefined, "hey!"));
+      gQueue.push(new changeARIAValue("slider_vnvt", "3", "sweet"));
+      gQueue.push(new changeARIAValue("scrollbar", "6", undefined));
 
-      gQueue.push(new changeInputValue("combobox", "hello"));
+      gQueue.push(new changeValue("combobox", "hello"));
+
+      gQueue.push(new changeProcessValue("progress", "50"));
 
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTests);
   </script>
 </head>
@@ -117,16 +137,22 @@
     title="We dont expose new aria role 'scrollbar' and property aria-orientation">
    Mozilla Bug 529289
   </a>
   <a target="_blank"
     href="https://bugzilla.mozilla.org/show_bug.cgi?id=703202"
     title="ARIA comboboxes don't fire value change events">
    Mozilla Bug 703202
   </a>
+  <a target="_blank"
+    href="https://bugzilla.mozilla.org/show_bug.cgi?id=761901"
+    title=" HTML5 progress accessible should fire value change event">
+   Mozilla Bug 761901
+  </a>
+
 
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
   <div id="eventdump"></div>
 
   <!-- ARIA sliders -->
@@ -140,10 +166,14 @@
        aria-valuemin="0" aria-valuemax="5">sweetness slider</div>
 
   <!-- ARIA scrollbar -->
   <div id="scrollbar" role="scrollbar" aria-valuenow="5"
        aria-valuemin="0" aria-valuemax="1000">slider</div>
 
   <!-- ARIA combobox -->
   <input id="combobox" role="combobox" aria-autocomplete="inline">
+
+  <!-- progress bar -->
+  <progress id="progress" value="22" max="100"></progress>
+
 </body>
 </html>
--- a/accessible/tests/mochitest/hittest/Makefile.in
+++ b/accessible/tests/mochitest/hittest/Makefile.in
@@ -9,14 +9,15 @@ srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = accessible/hittest
 
 include $(DEPTH)/config/autoconf.mk
 
 MOCHITEST_A11Y_FILES = \
 		test_browser.html \
 		test_general.html \
+		test_zoom_text.html \
 		test_zoom_tree.xul \
 		test_zoom.html \
 		zoom_tree.xul \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/hittest/test_zoom_text.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>getOffsetAtPoint when page is zoomed</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>
+
+  <script type="application/javascript"
+          src="../common.js"></script>
+  <script type="application/javascript"
+          src="../role.js"></script>
+  <script type="application/javascript"
+          src="../layout.js"></script>
+
+  <script type="application/javascript">
+    function doTest()
+    {
+      var hyperText = getNode("paragraph");
+      var textNode = hyperText.firstChild;
+      var [x, y, width, height] = getBounds(textNode);
+      testOffsetAtPoint(hyperText, x + width / 2, y + height / 2,
+                        COORDTYPE_SCREEN_RELATIVE,
+                        hyperText.textContent.length / 2);
+
+      zoomDocument(document, 2.0);
+
+      var [x, y, width, height] = getBounds(textNode);
+      testOffsetAtPoint(hyperText, x + width / 2, y + height / 2,
+                        COORDTYPE_SCREEN_RELATIVE,
+                        hyperText.textContent.length / 2);
+
+      zoomDocument(document, 1.0);
+
+      SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  </script>
+</head>
+<body>
+
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=727942"
+     title="getOffsetAtPoint returns incorrect value when page is zoomed">
+    Mozilla Bug 727942
+  </a>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+  <p id="paragraph" style="font-family: monospace;">Болтали две сороки</p>
+</body>
+</html>
--- a/accessible/tests/mochitest/layout.js
+++ b/accessible/tests/mochitest/layout.js
@@ -42,16 +42,28 @@ function hitTest(aContainerID, aChildID,
            "Wrong direct child of " + prettyName(aContainerID));
 
   var actualGrandChild = container.getDeepestChildAtPoint(x + 1, y + 1);
   isObject(actualGrandChild, grandChild,
            "Wrong deepest child of " + prettyName(aContainerID));
 }
 
 /**
+ * Test if getOffsetAtPoint returns the given text offset at given coordinates.
+ */
+function testOffsetAtPoint(aHyperTextID, aX, aY, aCoordType, aExpectedOffset)
+{
+  var hyperText = getAccessible(aHyperTextID, [nsIAccessibleText]);
+  var offset = hyperText.getOffsetAtPoint(aX, aY, aCoordType);
+  is(offset, aExpectedOffset,
+     "Wrong offset at given point (" + aX + ", " + aY + ") for " +
+     prettyName(aHyperTextID));
+}
+
+/**
  * Zoom the given document.
  */
 function zoomDocument(aDocument, aZoom)
 {
   var docShell = aDocument.defaultView.
     QueryInterface(Components.interfaces.nsIInterfaceRequestor).
     getInterface(Components.interfaces.nsIWebNavigation).
     QueryInterface(Components.interfaces.nsIDocShell);
@@ -87,32 +99,104 @@ function getChildAtPoint(aIdentifier, aX
       return acc.getDeepestChildAtPoint(x, y);
     return acc.getChildAtPoint(x, y);
   } catch (e) {  }
 
   return null;
 }
 
 /**
+ * Test the accessible position.
+ */
+function testPos(aID, aPoint)
+{
+  var [expectedX, expectedY] =
+    (aPoint != undefined) ? aPoint : getBoundsForDOMElm(aID);
+
+  var [x, y] = getBounds(aID);
+  is(x, expectedX, "Wrong x coordinate of " + prettyName(aID));
+  is(y, expectedY, "Wrong y coordinate of " + prettyName(aID));
+}
+
+/**
  * Test the accessible boundaries.
  */
 function testBounds(aID, aRect)
 {
   var [expectedX, expectedY, expectedWidth, expectedHeight] =
     (aRect != undefined) ? aRect : getBoundsForDOMElm(aID);
 
   var [x, y, width, height] = getBounds(aID);
   is(x, expectedX, "Wrong x coordinate of " + prettyName(aID));
   is(y, expectedY, "Wrong y coordinate of " + prettyName(aID));
   is(width, expectedWidth, "Wrong width of " + prettyName(aID));
   is(height, expectedHeight, "Wrong height of " + prettyName(aID));
 }
 
 /**
- * Return the accessible coordinates and size relative to the screen.
+ * Test text position at the given offset.
+ */
+function testTextPos(aID, aOffset, aPoint, aCoordOrigin)
+{
+  var [expectedX, expectedY] = aPoint;
+
+  var xObj = {}, yObj = {};
+  var hyperText = getAccessible(aID, [nsIAccessibleText]);
+  hyperText.getCharacterExtents(aOffset, xObj, yObj, {}, {}, aCoordOrigin);
+  is(xObj.value, expectedX,
+     "Wrong x coordinate at offset " + aOffset + " for " + prettyName(aID));
+  ok(yObj.value - expectedY < 2 && expectedY - yObj.value < 2,
+     "Wrong y coordinate at offset " + aOffset + " for " + prettyName(aID) +
+     " - got " + yObj.value + ", expected " + expectedY +
+     "The difference doesn't exceed 1.");
+}
+
+/**
+ * Test text bounds that is enclosed betwene the given offsets.
+ */
+function testTextBounds(aID, aStartOffset, aEndOffset, aRect, aCoordOrigin)
+{
+  var [expectedX, expectedY, expectedWidth, expectedHeight] = aRect;
+
+  var xObj = {}, yObj = {}, widthObj = {}, heightObj = {};
+  var hyperText = getAccessible(aID, [nsIAccessibleText]);
+  hyperText.getRangeExtents(0, -1, xObj, yObj, widthObj, heightObj, aCoordOrigin);
+  is(xObj.value, expectedX,
+     "Wrong x coordinate of text between offsets (" + aStartOffset + ", " +
+     aEndOffset + ") for " + prettyName(aID));
+  is(yObj.value, expectedY,
+     "Wrong y coordinate of text between offsets (" + aStartOffset + ", " +
+     aEndOffset + ") for " + prettyName(aID));
+
+  var msg = "Wrong width of text between offsets (" + aStartOffset + ", " +
+    aEndOffset + ") for " + prettyName(aID);
+  if (widthObj.value == expectedWidth)
+    ok(true, msg);
+  else
+    todo(false, msg); // fails on some windows machines
+
+  is(heightObj.value, expectedHeight,
+     "Wrong height of text between offsets (" + aStartOffset + ", " +
+     aEndOffset + ") for " + prettyName(aID));
+}
+
+/**
+ * Return the accessible coordinates relative to the screen in device pixels.
+ */
+function getPos(aID)
+{
+  var accessible = getAccessible(aID);
+  var x = {}, y = {};
+  accessible.getBounds(x, y, {}, {});
+  return [x.value, y.value];
+}
+
+/**
+ * Return the accessible coordinates and size relative to the screen in device
+ * pixels.
  */
 function getBounds(aID)
 {
   var accessible = getAccessible(aID);
   var x = {}, y = {}, width = {}, height = {};
   accessible.getBounds(x, y, width, height);
   return [x.value, y.value, width.value, height.value];
 }
--- a/accessible/tests/mochitest/name/markup.js
+++ b/accessible/tests/mochitest/name/markup.js
@@ -1,24 +1,26 @@
 ////////////////////////////////////////////////////////////////////////////////
 // Name tests described by "markuprules.xml" file.
 
 var gNameRulesFileURL = "markuprules.xml";
 
 var gRuleDoc = null;
 
 // Debuggin stuff.
-var gDumpToConsole = false;
+var gDumpToConsole = true;
 
 /**
  * Start name tests. Run through markup elements and test names for test
  * element (see namerules.xml for details).
  */
 function testNames()
 {
+  enableLogging("tree");
+
   var request = new XMLHttpRequest();
   request.open("get", gNameRulesFileURL, false);
   request.send();
 
   gRuleDoc = request.responseXML;
 
   var markupElms = evaluateXPath(gRuleDoc, "//rules/rulesample/markup");
   gTestIterator.iterateMarkups(markupElms);
@@ -53,18 +55,23 @@ var gTestIterator =
     if (this.markupIdx == -1) {
       this.markupIdx++;
       testNamesForMarkup(this.markupElms[this.markupIdx]);
       return;
     }
 
     this.ruleIdx++;
     if (this.ruleIdx == this.ruleElms.length) {
+      // When test is finished then name is empty and no explict-name.
+      testName(this.elm, null, "No name test. ");
+      testAbsentAttrs(this.elm, {"explicit-name" : "true"});
+
       this.markupIdx++;
       if (this.markupIdx == this.markupElms.length) {
+        disableLogging("tree");
         SimpleTest.finish();
         return;
       }
 
       this.ruleIdx = -1;
 
       if (gDumpToConsole) {
         dump("\nPend next markup processing. Wait for reorder event on " +
@@ -183,16 +190,21 @@ function testNameForAttrRule(aElm, aRule
         name += " ";
 
       name += labelElm.getAttribute("a11yname");
     }
   }
 
   var msg = "Attribute '" + attr + "' test. ";
   testName(aElm, name, msg);
+  if (aRule.getAttribute("explict-name") != "false")
+    testAttrs(aElm, {"explicit-name" : "true"}, true);
+  else
+    testAbsentAttrs(aElm, {"explicit-name" : "true"});
+
   aElm.removeAttribute(attr);
 
   gTestIterator.iterateNext();
 }
 
 function testNameForElmRule(aElm, aRule)
 {
   var labelElm;
@@ -230,16 +242,17 @@ function testNameForElmRule(aElm, aRule)
   if (!labelElm) {
     ok(false, msg + " Failed to find '" + tagname + "' element.");
     gTestIterator.iterateNext();
     return;
   }
 
   var msg = "Element '" + tagname + "' test.";
   testName(aElm, labelElm.getAttribute("a11yname"), msg);
+  testAttrs(aElm, {"explicit-name" : "true"}, true);
 
   var parentNode = labelElm.parentNode;
 
   if (gDumpToConsole) {
     dump("\nProcessed elm rule. Wait for reorder event on " +
          prettyName(parentNode) + "\n");
   }
   waitForEvent(EVENT_REORDER, parentNode,
@@ -247,16 +260,17 @@ function testNameForElmRule(aElm, aRule)
 
   parentNode.removeChild(labelElm);
 }
 
 function testNameForSubtreeRule(aElm, aRule)
 {
   var msg = "From subtree test.";
   testName(aElm, aElm.getAttribute("a11yname"), msg);
+  testAbsentAttrs(aElm, {"explicit-name" : "true"});
 
   if (gDumpToConsole) {
     dump("\nProcessed from subtree rule. Wait for reorder event on " +
          prettyName(aElm) + "\n");
   }
   waitForEvent(EVENT_REORDER, aElm, gTestIterator.iterateNext, gTestIterator);
 
   while (aElm.firstChild)
--- a/accessible/tests/mochitest/name/markuprules.xml
+++ b/accessible/tests/mochitest/name/markuprules.xml
@@ -120,17 +120,17 @@
     <ruleset id="htmlelm">
       <ruleset ref="htmlelm_start"/>
       <ruleset ref="htmlelm_end"/>
     </ruleset>
 
     <!-- specific -->
     <ruleset id="htmlinputbutton">
       <ruleset ref="htmlelm_start"/>
-      <rule attr="value" type="string"/>
+      <rule attr="value" type="string" explict-name="false"/>
       <rule attr="alt" type="string"/>
       <rule attr="src" type="string"/>
       <rule attr="data" type="string"/>
       <ruleset ref="htmlelm_end"/>
     </ruleset>
 
     <ruleset id="htmloption">
       <ruleset ref="aria"/>
@@ -197,39 +197,39 @@
                      aria-labelledby="l1 l2"
                      label="test4"
                      title="test5"
                      a11yname="option1">option1</html:option>
         <html:option>option2</html:option>
       </html:select>
     </markup>
 
-<!-- Temporarily disabled for causing bug 733848
-    <markup ref="html:img" ruleset="htmlimage">
+    <markup ref="html:img" ruleset="htmlimage"
+            id="markupHTMLImageTest">
       <html:span id="l1" a11yname="test2">test2</html:span>
       <html:span id="l2" a11yname="test3">test3</html:span>
       <html:img id="img"
                 aria-label="Logo of Mozilla"
                 aria-labelledby="l1 l2"
                 alt="Mozilla logo"
                 title="This is a logo"
                 src="../moz.png"/>
     </markup>
 
     <markup ref="html:img" ruleset="htmlimageemptyalt">
+            id="markupHTMLImageEmptyAltTest"
       <html:span id="l1" a11yname="test2">test2</html:span>
       <html:span id="l2" a11yname="test3">test3</html:span>
-      <html:img id="img"
+      <html:img id="imgemptyalt"
                  aria-label="Logo of Mozilla"
                  aria-labelledby="l1 l2"
                  title="This is a logo"
                  alt=""
                  src="../moz.png"/>
     </markup>
--->
 
     <markup ref="html:table/html:tr/html:td" ruleset="htmlelm"
             id="markup4test">
       <html:span id="l1" a11yname="test2">test2</html:span>
       <html:span id="l2" a11yname="test3">test3</html:span>
       <html:label for="tc" a11yname="test4">test4</html:label>
       <html:table>
         <html:tr>
@@ -285,11 +285,11 @@
                   summary="summary_tst6"
                   title="title_tst6">
         <html:caption a11yname="caption_tst6">caption_tst6</html:caption><html:tr>
           <html:td>cell1</html:td>
           <html:td>cell2</html:td>
         </html:tr>
       </html:table>
     </markup>
+
   </rulesample>
-
 </rules>
--- a/accessible/tests/mochitest/name/test_markup.html
+++ b/accessible/tests/mochitest/name/test_markup.html
@@ -1,23 +1,27 @@
 <html>
 
 <head>
   <title>nsIAccessible::name calculation for elements</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>
+  <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="../events.js"></script>
   <script type="application/javascript"
           src="../name.js"></script>
+  <script type="application/javascript"
+          src="../attributes.js"></script>
 
   <script type="application/javascript"
           src="markup.js"></script>
 
   <script type="application/javascript">
     // gA11yEventDumpID = "eventdump";
     //gDumpToConsole = true;
     //gA11yEventDumpToConsole = true;
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/scroll/Makefile.in
@@ -0,0 +1,19 @@
+#
+# 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/.
+
+DEPTH		= @DEPTH@
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+relativesrcdir  = accessible/scroll
+
+include $(DEPTH)/config/autoconf.mk
+
+MOCHITEST_A11Y_FILES =\
+		test_zoom_text.html \
+		test_zoom.html \
+		$(NULL)
+
+include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/scroll/test_zoom.html
@@ -0,0 +1,147 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Test scrollToPoint when page is zoomed</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>
+  <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="../layout.js"></script>
+
+  <script type="application/javascript">
+    function testScrollToPoint()
+    {
+      // scrollToPoint relative screen
+      var anchor = getAccessible("bottom1");
+      var [x, y] = getPos(anchor);
+      var [docX, docY] = getPos(document);
+
+      anchor.scrollToPoint(COORDTYPE_SCREEN_RELATIVE, docX, docY);
+      testPos(anchor, [x, docY]);
+
+      // scrollToPoint relative window
+      anchor = getAccessible("bottom2");
+      var [x, y] = getPos(anchor);
+      var wnd = getRootAccessible().DOMDocument.defaultView;
+      var scrollToX = docX - wnd.screenX, scrollToY = docY - wnd.screenY;
+
+      anchor.scrollToPoint(COORDTYPE_WINDOW_RELATIVE, scrollToX, scrollToY);
+      testPos(anchor, [x, docY]);
+
+      // scrollToPoint relative parent
+      anchor = getAccessible("bottom3");
+      var [x, y] = getPos(anchor);
+      var [parentX, parentY] = getPos(anchor.parent);
+      var scrollToX = parentX - docX, scrollToY = parentY - docY;
+
+      anchor.scrollToPoint(COORDTYPE_PARENT_RELATIVE, scrollToX, scrollToY);
+      testPos(anchor, [x, docY]);
+    }
+
+    function doTest()
+    {
+      testScrollToPoint();
+      zoomDocument(document, 2.0);
+      testScrollToPoint(); // zoom and test again
+
+      zoomDocument(document, 1.0);
+      SimpleTest.finish();
+    }
+
+    addA11yLoadEvent(doTest);
+    SimpleTest.waitForExplicitFinish();
+  </script>
+
+</head>
+<body>
+
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=727942"
+     title="scrollToPoint is broken when page is zoomed">
+    Mozilla Bug 727942
+  </a>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+
+  <h1>Below there is a bunch of named anchors</h1>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  This is in the middle anchor #1<a id="bottom1"></a>
+  <br><br><br><br><br><br><br><br><br><br>
+  This is in the middle anchor #2<a id="bottom2"></a>
+  <br><br><br><br><br><br><br><br><br><br>
+  This is in the middle anchor #3<a id="bottom3"></a>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+  <br><br><br><br><br><br><br><br><br><br>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/scroll/test_zoom_text.html
@@ -0,0 +1,158 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Test scrollSubstringToPoint when page is zoomed</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>
+  <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="../layout.js"></script>
+  <script type="application/javascript"
+          src="../browser.js"></script>
+
+  <script type="application/javascript">
+    function doTest()
+    {
+      var tabDocument = currentTabDocument();
+      var paragraphNode = tabDocument.getElementById("paragraph");
+      var paragraph = getAccessible(paragraphNode, [nsIAccessibleText]);
+      var offset = 64; // beginning of 4th stanza
+
+      var [x, y] = getPos(paragraph);
+      var [docX, docY] = getPos(tabDocument);
+
+      paragraph.scrollSubstringToPoint(offset, offset,
+                                       COORDTYPE_SCREEN_RELATIVE, docX, docY);
+      testTextPos(paragraph, offset, [x, docY], COORDTYPE_SCREEN_RELATIVE);
+
+      zoomDocument(tabDocument, 2.0);
+
+      paragraphNode = tabDocument.getElementById("paragraph2");
+      paragraph = getAccessible(paragraphNode, [nsIAccessibleText]);
+      offset = 52; // // beginning of 4th stanza
+      var [x, y] = getPos(paragraph);
+      paragraph.scrollSubstringToPoint(offset, offset,
+                                       COORDTYPE_SCREEN_RELATIVE, docX, docY);
+      testTextPos(paragraph, offset, [x, docY], COORDTYPE_SCREEN_RELATIVE);
+
+      closeBrowserWindow();
+      SimpleTest.finish();
+    }
+
+    var url = "data:text/html,<html>" +
+      "<meta http-equiv='Content-Type' content='text/html;charset=utf-8' />" +
+      "<body>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br><hr>" +
+      "<p id='paragraph'>" +
+      "  Пошел котик на торжок<br>" +
+      "  Купил котик пирожок<br>" +
+      "  Пошел котик на улочку<br>" +
+      "  Купил котик булочку<br>" +
+      "</p>" +
+      "<hr><br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br><hr>" +
+      "<p id='paragraph2'>" +
+      "  Самому ли съесть<br>" +
+      "  Либо Сашеньке снесть<br>" +
+      "  Я и сам укушу<br>" +
+      "  Я и Сашеньке снесу<br>" +
+      "</p>" +
+      "<hr><br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "<br><br><br><br><br><br><br><br><br><br>" +
+      "</body></html>";
+
+    SimpleTest.waitForExplicitFinish();
+    openBrowserWindow(doTest,
+                      url,
+                      { left: 0, top: 0, width: 600, height: 600 });
+  </script>
+
+</head>
+<body>
+
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=727942"
+     title="scrollSubstringToPoint is broken when page is zoomed">
+    Mozilla Bug 727942
+  </a>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+</body>
+</html>
--- a/accessible/tests/mochitest/treeupdate/test_doc.html
+++ b/accessible/tests/mochitest/treeupdate/test_doc.html
@@ -67,21 +67,16 @@
         var text = getAccessible(getAccessible(getDocNode(aID)).firstChild);
         this.eventSeq[0].target = text;
       }
 
       this.finalCheck = function rootContentRemoved_finalCheck()
       {
         var tree = {
           role: ROLE_DOCUMENT,
-          states: {
-            // Out of date root content involves stale state presence.
-            states: 0,
-            extraStates: EXT_STATE_STALE
-          },
           children: [ ]
         };
         testAccessibleTree(getDocNode(aID), tree);
       }
     }
 
     function rootContentInserted(aID, aTextName)
     {
@@ -89,22 +84,16 @@
         new invokerChecker(EVENT_SHOW, getDocChildNode, aID),
         new invokerChecker(EVENT_REORDER, getDocNode, aID)
       ];
 
       this.finalCheck = function rootContentInserted_finalCheck()
       {
         var tree = {
           role: ROLE_DOCUMENT,
-          states: {
-            states: 0,
-            extraStates: 0,
-            absentStates: 0,
-            absentExtraStates: EXT_STATE_STALE
-          },
           children: [
             {
               role: ROLE_TEXT_LEAF,
               name: aTextName
             }
           ]
         };
         testAccessibleTree(getDocNode(aID), tree);
--- a/allmakefiles.sh
+++ b/allmakefiles.sh
@@ -54,17 +54,17 @@ if [ ! "$LIBXUL_SDK" ]; then
       build/stlport/stl/config/_android.h
     "
   fi
   add_makefiles "
     memory/mozalloc/Makefile
     mozglue/Makefile
     mozglue/build/Makefile
   "
-  if [ "$MOZ_JEMALLOC" ]; then
+  if [ "$MOZ_JEMALLOC" -a -z "$MOZ_NATIVE_JEMALLOC" ]; then
     add_makefiles "
       memory/jemalloc/Makefile
     "
   fi
   if [ "$MOZ_MEMORY" ]; then
     add_makefiles "
       memory/mozjemalloc/Makefile
       memory/build/Makefile
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -186,16 +186,17 @@ pref("breakpad.reportURL", "http://crash
 pref("app.releaseNotesURL", "http://www.mozilla.com/%LOCALE%/b2g/%VERSION%/releasenotes/");
 pref("app.support.baseURL", "http://support.mozilla.com/b2g");
 pref("app.feedbackURL", "http://input.mozilla.com/feedback/");
 pref("app.privacyURL", "http://www.mozilla.com/%LOCALE%/m/privacy.html");
 pref("app.creditsURL", "http://www.mozilla.org/credits/");
 pref("app.featuresURL", "http://www.mozilla.com/%LOCALE%/b2g/features/");
 pref("app.faqURL", "http://www.mozilla.com/%LOCALE%/b2g/faq/");
 // Whether we want to report crashes (headless)
+//XXX Remove this pref when bug 801932 is fixed
 pref("app.reportCrashes", true);
 
 // Name of alternate about: page for certificate errors (when undefined, defaults to about:neterror)
 pref("security.alternate_certificate_error_page", "certerror");
 
 pref("security.warn_viewing_mixed", false); // Warning is disabled.  See Bug 616712.
 
 // Override some named colors to avoid inverse OS themes
@@ -261,23 +262,24 @@ pref("media.cache_size", 4096);    // 4M
 pref("media.video-queue.default-size", 3);
 
 //  0: don't show fullscreen keyboard
 //  1: always show fullscreen keyboard
 // -1: show fullscreen keyboard based on threshold pref
 pref("widget.ime.android.landscape_fullscreen", -1);
 pref("widget.ime.android.fullscreen_threshold", 250); // in hundreths of inches
 
-// optimize images memory usage
+// optimize images' memory usage
 pref("image.mem.decodeondraw", true);
 pref("content.image.allow_locking", false);
 pref("image.mem.min_discard_timeout_ms", 10000);
+pref("image.mem.max_decoded_image_kb", 5120); /* 5MB */
 
 // enable touch events interfaces
-pref("dom.w3c_touch_events.enabled", true);
+pref("dom.w3c_touch_events.enabled", 1);
 pref("dom.w3c_touch_events.safetyX", 0); // escape borders in units of 1/240"
 pref("dom.w3c_touch_events.safetyY", 120); // escape borders in units of 1/240"
 
 #ifdef MOZ_SAFE_BROWSING
 // Safe browsing does nothing unless this pref is set
 pref("browser.safebrowsing.enabled", true);
 
 // Prevent loading of pages identified as malware
@@ -463,20 +465,16 @@ pref("app.update.staging.enabled", true)
 pref("app.update.service.enabled", true);
 
 // The URL hosting the update manifest.
 pref("app.update.url", "http://update.boot2gecko.org/%CHANNEL%/update.xml");
 pref("app.update.channel", "@MOZ_UPDATE_CHANNEL@");
 
 // Interval at which update manifest is fetched.  In units of seconds.
 pref("app.update.interval", 86400); // 1 day
-// First interval to elapse before checking for update.  In units of
-// milliseconds.  Capped at 10 seconds.
-pref("app.update.timerFirstInterval", 3600000); // 1 hour
-pref("app.update.timerMinimumDelay", 3600); // 1 hour in seconds
 // Don't throttle background updates.
 pref("app.update.download.backgroundInterval", 0);
 
 // Enable update logging for now, to diagnose growing pains in the
 // field.
 pref("app.update.log", true);
 #else
 // Explicitly disable the shutdown watchdog.  It's enabled by default.
@@ -506,27 +504,28 @@ pref("dom.disable_window_showModalDialog
 
 // Enable new experimental html forms
 pref("dom.experimental_forms", true);
 
 // Turns on gralloc-based direct texturing for Gonk
 pref("gfx.gralloc.enabled", false);
 
 // XXXX REMOVE FOR PRODUCTION. Turns on GC and CC logging
-pref("javascript.options.mem.log", true);
+pref("javascript.options.mem.log", false);
 
 // Increase mark slice time from 10ms to 30ms
 pref("javascript.options.mem.gc_incremental_slice_ms", 30);
 
 pref("javascript.options.mem.gc_high_frequency_heap_growth_max", 120);
 pref("javascript.options.mem.gc_high_frequency_heap_growth_min", 101);
 pref("javascript.options.mem.gc_high_frequency_high_limit_mb", 40);
 pref("javascript.options.mem.gc_high_frequency_low_limit_mb", 10);
 pref("javascript.options.mem.gc_low_frequency_heap_growth", 105);
 pref("javascript.options.mem.high_water_mark", 6);
+pref("javascript.options.mem.gc_allocation_threshold_mb", 3);
 
 // Show/Hide scrollbars when active/inactive
 pref("ui.showHideScrollbars", 1);
 
 // Enable the ProcessPriorityManager, and give processes with no visible
 // documents a 1s grace period before they're eligible to be marked as
 // background.
 pref("dom.ipc.processPriorityManager.enabled", true);
--- a/b2g/build.mk
+++ b/b2g/build.mk
@@ -13,19 +13,17 @@ endif
 endif
 
 TIERS += app
 
 ifdef MOZ_EXTENSIONS
 tier_app_dirs += extensions
 endif
 
-ifdef MOZ_SERVICES_SYNC
 tier_app_dirs += services
-endif
 
 tier_app_dirs += \
   $(MOZ_BRANDING_DIRECTORY) \
   b2g \
   $(NULL)
 
 
 installer: 
--- a/b2g/chrome/content/dbg-browser-actors.js
+++ b/b2g/chrome/content/dbg-browser-actors.js
@@ -112,17 +112,17 @@ DeviceTabActor.prototype.grip = function
   let response = {
     'actor': this.actorID,
     'title': this.browser.title,
     'url': this.browser.document.documentURI
   };
 
   // Walk over tab actors added by extensions and add them to a new ActorPool.
   let actorPool = new ActorPool(this.conn);
-  this._createExtraActors(DebuggerServer.globalActorFactories, actorPool);
+  this._createExtraActors(DebuggerServer.tabActorFactories, actorPool);
   if (!actorPool.isEmpty()) {
     this._tabActorPool = actorPool;
     this.conn.addActorPool(this._tabActorPool);
   }
 
   this._appendExtraActors(response);
   return response;
 };
--- a/b2g/chrome/content/forms.js
+++ b/b2g/chrome/content/forms.js
@@ -27,32 +27,48 @@ let HTMLOptionElement = Ci.nsIDOMHTMLOpt
 let FormAssistant = {
   init: function fa_init() {
     addEventListener("focus", this, true, false);
     addEventListener("blur", this, true, false);
     addEventListener("keypress", this, true, false);
     addEventListener("resize", this, true, false);
     addMessageListener("Forms:Select:Choice", this);
     addMessageListener("Forms:Input:Value", this);
+    addMessageListener("Forms:Select:Blur", this);
     Services.obs.addObserver(this, "ime-enabled-state-changed", false);
     Services.obs.addObserver(this, "xpcom-shutdown", false);
   },
 
   isKeyboardOpened: false,
-  focusedElement : null,
   selectionStart: 0,
   selectionEnd: 0,
 
+  _focusedElement: null,
+
+  get focusedElement() {
+    if (this._focusedElement && Cu.isDeadWrapper(this._focusedElement))
+      this._focusedElement = null;
+
+    return this._focusedElement;
+  },
+
+  set focusedElement(val) {
+    this._focusedElement = val;
+  },
+
   setFocusedElement: function fa_setFocusedElement(element) {
     if (element === this.focusedElement)
       return;
 
     if (this.focusedElement) {
       this.focusedElement.removeEventListener('mousedown', this);
       this.focusedElement.removeEventListener('mouseup', this);
+      if (!element) {
+        this.focusedElement.blur();
+      }
     }
 
     if (element) {
       element.addEventListener('mousedown', this);
       element.addEventListener('mouseup', this);
     }
 
     this.focusedElement = element;
@@ -181,16 +197,21 @@ let FormAssistant = {
 
         // only fire onchange event if any selected option is changed
         if (valueChanged) {
           let event = content.document.createEvent('HTMLEvents');
           event.initEvent('change', true, true);
           target.dispatchEvent(event);
         }
         break;
+
+      case "Forms:Select:Blur": {
+        this.setFocusedElement(null);
+        break;
+      }
     }
   },
 
   observe: function fa_observe(subject, topic, data) {
     switch (topic) {
       case "ime-enabled-state-changed":
         let isOpen = this.isKeyboardOpened;
         let shouldOpen = parseInt(data);
@@ -254,22 +275,27 @@ function getJSON(element) {
       case "time":
       case "datetime":
       case "datetime-local":
         type = typeLowerCase;
         break;
     }
   }
 
-  // If Gecko knows about the inputmode attribute, use that value.
-  // Otherwise, query the attribute explicitly, but be sure to convert
-  // to lowercase
-  let inputmode = element.inputmode || element.getAttribute('inputmode');
+  // Gecko supports the inputmode attribute on text fields (but not textareas).
+  // But it doesn't recognize "verbatim" and other modes that we're interested
+  // in in Gaia, and the inputmode property returns "auto" for any value
+  // that gecko does not support. So we must query the inputmode attribute
+  // with getAttribute() rather than just using the inputmode property here.
+  // See https://bugzilla.mozilla.org/show_bug.cgi?id=746142
+  let inputmode = element.getAttribute('inputmode');
   if (inputmode) {
     inputmode = inputmode.toLowerCase();
+  } else {
+    inputmode = '';
   }
 
   return {
     "type": type.toLowerCase(),
     "choices": getListForElement(element),
     "value": element.value,
     "inputmode": inputmode,
     "selectionStart": element.selectionStart,
new file mode 100644
--- /dev/null
+++ b/b2g/chrome/content/identity.js
@@ -0,0 +1,186 @@
+/* -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
+/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// This JS shim contains the callbacks to fire DOMRequest events for
+// navigator.pay API within the payment processor's scope.
+
+"use strict";
+
+let { classes: Cc, interfaces: Ci, utils: Cu }  = Components;
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
+                                   "@mozilla.org/childprocessmessagemanager;1",
+                                   "nsIMessageSender");
+
+XPCOMUtils.defineLazyServiceGetter(this, "uuidgen",
+                                   "@mozilla.org/uuid-generator;1",
+                                   "nsIUUIDGenerator");
+
+XPCOMUtils.defineLazyModuleGetter(this, "Logger",
+                                  "resource://gre/modules/identity/LogUtils.jsm");
+
+function log(...aMessageArgs) {
+  Logger.log.apply(Logger, ["injected identity.js"].concat(aMessageArgs));
+}
+
+log("\n\n======================= identity.js =======================\n\n");
+
+// This script may be injected more than once into an iframe.
+// Ensure we don't redefine contstants
+if (typeof kIdentityJSLoaded === 'undefined') {
+  const kReceivedIdentityAssertion = "received-id-assertion";
+  const kIdentityDelegateWatch = "identity-delegate-watch";
+  const kIdentityDelegateRequest = "identity-delegate-request";
+  const kIdentityDelegateLogout = "identity-delegate-logout";
+  const kIdentityDelegateReady = "identity-delegate-ready";
+  const kIdentityDelegateFinished = "identity-delegate-finished";
+  const kIdentityControllerDoMethod = "identity-controller-doMethod";
+  const kIdentktyJSLoaded = true;
+}
+
+var showUI = false;
+var options = null;
+var isLoaded = false;
+var func = null;
+
+/*
+ * Message back to the SignInToWebsite pipe.  Message should be an
+ * object with the following keys:
+ *
+ *   method:             one of 'login', 'logout', 'ready'
+ *   assertion:          optional assertion
+ */
+function identityCall(message) {
+  sendAsyncMessage(kIdentityControllerDoMethod, message);
+}
+
+function identityFinished() {
+  log("identity finished.  closing dialog");
+  closeIdentityDialog(function notifySuccess() {
+    // get ready for next call with a reinit
+    func = null; options = null;
+
+    sendAsyncMessage(kIdentityDelegateFinished);
+  });
+}
+
+/*
+ * Notify the UI to close the dialog and return to the caller application
+ */
+function closeIdentityDialog(aCallback) {
+  let randomId = uuidgen.generateUUID().toString();
+  let id = kReceivedIdentityAssertion + "-" + randomId;
+  let browser = Services.wm.getMostRecentWindow("navigator:browser");
+
+  let detail = {
+    type: kReceivedIdentityAssertion,
+    id: id,
+    showUI: showUI
+  };
+
+  // In order to avoid race conditions, we wait for the UI to notify that
+  // it has successfully closed the identity flow and has recovered the
+  // caller app, before notifying the parent process.
+  content.addEventListener("mozContentEvent", function closeIdentityDialogFinished(evt) {
+    content.removeEventListener("mozContentEvent", closeIdentityDialogFinished);
+
+    if (evt.detail.id == id && aCallback) {
+      aCallback();
+    }
+  });
+
+  browser.shell.sendChromeEvent(detail);
+}
+
+/*
+ * doInternalWatch - call the internal.watch api and relay the results
+ * up to the controller.
+ */
+function doInternalWatch() {
+  log("doInternalWatch:", options, isLoaded);
+  if (options && isLoaded) {
+    log("internal watch options:", options);
+    let BrowserID = content.wrappedJSObject.BrowserID;
+    BrowserID.internal.watch(function(aParams) {
+        log("sending watch method message:", aParams.method);
+        identityCall(aParams);
+        if (aParams.method === "ready") {
+          log("watch finished.");
+          identityFinished();
+        }
+      },
+      JSON.stringify({loggedInUser: options.loggedInUser, origin: options.origin}),
+      function(...things) {
+        log("internal: ", things);
+      }
+    );
+  }
+}
+
+function doInternalRequest() {
+  log("doInternalRequest:", options && isLoaded);
+  if (options && isLoaded) {
+    content.wrappedJSObject.BrowserID.internal.get(
+      options.origin,
+      function(assertion) {
+        if (assertion) {
+          log("request -> assertion, so do login");
+          identityCall({method:'login',assertion:assertion});
+        }
+        identityFinished();
+      },
+      options);
+  }
+}
+
+function doInternalLogout(aOptions) {
+  log("doInternalLogout:", (options && isLoaded));
+  if (options && isLoaded) {
+    let BrowserID = content.wrappedJSObject.BrowserID;
+    log("logging you out of ", options.origin);
+    BrowserID.internal.logout(options.origin, function() {
+      identityCall({method:'logout'});
+      identityFinished();
+    });
+  }
+}
+
+addEventListener("DOMContentLoaded", function(e) {
+  content.addEventListener("load", function(e) {
+    isLoaded = true;
+     // bring da func
+     if (func) func();
+  });
+});
+
+// listen for request
+addMessageListener(kIdentityDelegateRequest, function(aMessage) {
+    log("\n\n* * * * injected identity.js received", kIdentityDelegateRequest, "\n\n\n");
+  options = aMessage.json;
+  showUI = true;
+  func = doInternalRequest;
+  func();
+});
+
+// listen for watch
+addMessageListener(kIdentityDelegateWatch, function(aMessage) {
+    log("\n\n* * * * injected identity.js received", kIdentityDelegateWatch, "\n\n\n");
+  options = aMessage.json;
+  showUI = false;
+  func = doInternalWatch;
+  func();
+});
+
+// listen for logout
+addMessageListener(kIdentityDelegateLogout, function(aMessage) {
+    log("\n\n* * * * injected identity.js received", kIdentityDelegateLogout, "\n\n\n");
+  options = aMessage.json;
+  showUI = false;
+  func = doInternalLogout;
+  func();
+});
--- a/b2g/chrome/content/payment.js
+++ b/b2g/chrome/content/payment.js
@@ -61,16 +61,20 @@ function closePaymentFlowDialog(aCallbac
   content.addEventListener("mozContentEvent",
                            function closePaymentFlowReturn(evt) {
     if (evt.detail.id == id && aCallback) {
       aCallback();
     }
 
     content.removeEventListener("mozContentEvent",
                                 closePaymentFlowReturn);
+
+    let glue = Cc["@mozilla.org/payment/ui-glue;1"]
+                 .createInstance(Ci.nsIPaymentUIGlue);
+    glue.cleanup();
   });
 
   browser.shell.sendChromeEvent(detail);
 }
 
 addEventListener("DOMContentLoaded", function(e) {
   content.wrappedJSObject.paymentSuccess = paymentSuccess;
   content.wrappedJSObject.paymentFailed = paymentFailed;
--- a/b2g/chrome/content/runapp.js
+++ b/b2g/chrome/content/runapp.js
@@ -1,44 +1,72 @@
+"use strict";
+
 // runapp.js:
 // Provide a --runapp APPNAME command-line option.
 
+let runAppObj;
 window.addEventListener('load', function() {
   // Get the command line arguments that were passed to the b2g client
   let args = window.arguments[0].QueryInterface(Ci.nsICommandLine);
   let appname;
 
   // - Check if the argument is present before doing any work.
   try {
     // Returns null if the argument was not specified.  Throws
     // NS_ERROR_INVALID_ARG if there is no parameter specified (because
     // it was the last argument or the next argument starts with '-').
     // However, someone could still explicitly pass an empty argument!
     appname = args.handleFlagWithParam('runapp', false);
-  }
-  catch(e) {
+  } catch(e) {
     // treat a missing parameter like an empty parameter (=> show usage)
     appname = '';
   }
 
   // not specified, bail.
-  if (appname === null)
+  if (appname === null) {
     return;
+  }
+
+  runAppObj = new AppRunner(appname);
+  Services.obs.addObserver(runAppObj, 'webapps-registry-ready', false);
+});
+
+window.addEventListener('unload', function() {
+  Services.obs.removeObserver(runAppObj, 'webapps-registry-ready');
+});
 
-  // - Get the list of apps since the parameter was specified
-  let appsReq = navigator.mozApps.mgmt.getAll();
-  appsReq.onsuccess = function() {
-    let apps = appsReq.result;
+function AppRunner(aName) {
+  this._req = null;
+  this._appName = aName;
+}
+AppRunner.prototype = {
+  observe: function(aSubject, aTopic, aData) {
+    if (aTopic == 'webapps-registry-ready') {
+      this.doRunApp();
+    }
+  },
+
+  doRunApp: function() {
+    // - Get the list of apps since the parameter was specified
+    this._req = navigator.mozApps.mgmt.getAll();
+    this._req.onsuccess = this.getAllSuccess.bind(this);
+    this._req.onerror = this.getAllError.bind(this);
+  },
+
+  getAllSuccess: function() {
+    let apps = this._req.result;
+
     function findAppWithName(name) {
       let normalizedSearchName = name.replace(/[- ]+/g, '').toLowerCase();
 
       for (let i = 0; i < apps.length; i++) {
         let app = apps[i];
         let normalizedAppName =
-              app.manifest.name.replace(/[- ]+/g, '').toLowerCase();
+          app.manifest.name.replace(/[- ]+/g, '').toLowerCase();
         if (normalizedSearchName === normalizedAppName) {
           return app;
         }
       }
       return null;
     }
 
     function usageAndDie(justApps) {
@@ -54,40 +82,41 @@ window.addEventListener('load', function
       for (let i = 0; i < apps.length; i++) {
         dump('  ' + apps[i].manifest.name + '\n');
       }
 
       // Exit the b2g client
       Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit);
     }
 
-    if (appname === '') {
+    if (this._appName === '') {
       usageAndDie();
       return;
     }
 
-    let app = findAppWithName(appname);
+    let app = findAppWithName(this._appName);
     if (!app) {
-      dump('Could not find app: "' + appname + '". Maybe you meant one of:\n');
+      dump('Could not find app: "' + this._appName + '". Maybe you meant one of:\n');
       usageAndDie(true);
       return;
     }
 
     let setReq =
       navigator.mozSettings.createLock().set({'lockscreen.enabled': false});
     setReq.onsuccess = function() {
-      // give the event loop another turn to disable the lock screen
+      // give the event loop 100ms to disable the lock screen
       window.setTimeout(function() {
         dump('--runapp launching app: ' + app.manifest.name + '\n');
         app.launch();
-      }, 0);
+      }, 100);
     };
     setReq.onerror = function() {
       dump('--runapp failed to disable lock-screen.  Giving up.\n');
     };
 
     dump('--runapp found app: ' + app.manifest.name +
          ', disabling lock screen...\n');
- };
- appsReq.onerror = function() {
-   dump('Problem getting the list of all apps!');
- };
-});
+  },
+
+  getAllError: function() {
+    dump('Problem getting the list of all apps!');
+  }
+};
\ No newline at end of file
--- a/b2g/chrome/content/settings.js
+++ b/b2g/chrome/content/settings.js
@@ -1,16 +1,24 @@
 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
 /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
 /* 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;
+const Cr = Components.results;
+