Merged latest mozilla-central. CLOSED TREE webcl tip
authorTomi Aarnio <tomi.aarnio@nokia.com>
Wed, 03 Apr 2013 12:06:14 +0000
branchwebcl
changeset 127139 2fb50725fc74
parent 126177 b6b481b72b44 (current diff)
parent 127138 3a5929ebc886 (diff)
push id117
push usertomi.aarnio@nokia.com
push dateWed, 03 Apr 2013 12:07:07 +0000
milestone23.0a1
Merged latest mozilla-central. CLOSED TREE
browser/components/build/nsModule.cpp
browser/components/moz.build
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_zoom.js
browser/components/privatebrowsing/test/browser/browser_privatebrowsing_zoomrestore.js
browser/devtools/styleinspector/csshtmltree.xul
browser/devtools/styleinspector/cssruleview.xul
browser/devtools/styleinspector/styleinspector.css
browser/devtools/styleinspector/test/browser_computedview_bug_703643_context_menu_copy.js
browser/devtools/styleinspector/test/browser_ruleview_bug_703643_context_menu_copy.js
browser/installer/package-manifest.in
browser/installer/removed-files.in
browser/metro/base/content/LoginManagerChild.js
browser/metro/base/content/helperui/MasterPasswordUI.js
browser/metro/base/content/prompt/masterPassword.xul
browser/metro/base/content/prompt/removeMasterPassword.xul
browser/metro/base/tests/addons/browser_install1_1/bootstrap.js
browser/metro/base/tests/addons/browser_install1_1/install.rdf
browser/metro/base/tests/addons/browser_install1_2/install.rdf
browser/metro/base/tests/addons/browser_install1_3/install.rdf
browser/metro/base/tests/addons/browser_locale1/boostrap.js
browser/metro/base/tests/addons/browser_locale1/chrome.manifest
browser/metro/base/tests/addons/browser_locale1/install.rdf
browser/metro/base/tests/browser_canonizeURL.js
browser/metro/base/tests/browser_context_menu_tests.js
browser/metro/base/tests/browser_context_menu_tests_01.html
browser/metro/base/tests/browser_context_menu_tests_02.html
browser/metro/base/tests/browser_context_menu_tests_03.html
browser/metro/base/tests/browser_context_ui.js
browser/metro/base/tests/browser_downloads.js
browser/metro/base/tests/browser_onscreen_keyboard.html
browser/metro/base/tests/browser_onscreen_keyboard.js
browser/metro/base/tests/browser_plugin_input.html
browser/metro/base/tests/browser_plugin_input_keyboard.js
browser/metro/base/tests/browser_plugin_input_mouse.js
browser/metro/base/tests/browser_remotetabs.js
browser/metro/base/tests/browser_test.js
browser/metro/base/tests/browser_tilegrid.xul
browser/metro/base/tests/browser_tiles.js
browser/metro/base/tests/head.js
browser/metro/base/tests/res/image01.png
browser/metro/base/tests/text-block.html
browser/metro/components/LoginManager.js
browser/metro/components/LoginManagerPrompter.idl
browser/themes/linux/devtools/csshtmltree.css
browser/themes/osx/devtools/csshtmltree.css
browser/themes/windows/devtools/csshtmltree.css
content/html/content/src/nsHTMLInputElement.cpp
content/html/content/src/nsHTMLInputElement.h
content/html/content/test/test_input_file_picker.html
content/svg/content/src/DOMSVGTransform.cpp
content/svg/content/src/DOMSVGTransform.h
content/svg/content/src/SVGAnimatedTransformList.cpp
content/svg/content/src/SVGAnimatedTransformList.h
content/svg/content/src/SVGFEConvolveMatrixElement.cpp
content/svg/content/src/SVGFEConvolveMatrixElement.h
content/svg/content/src/SVGFEDiffuseLightingElement.cpp
content/svg/content/src/SVGFEDiffuseLightingElement.h
content/svg/content/src/SVGFEDisplacementMapElement.cpp
content/svg/content/src/SVGFEDisplacementMapElement.h
content/svg/content/src/SVGFEMorphologyElement.cpp
content/svg/content/src/SVGFEMorphologyElement.h
content/svg/content/src/SVGFESpecularLightingElement.cpp
content/svg/content/src/SVGFESpecularLightingElement.h
content/svg/content/src/SVGFESpotLightElement.cpp
content/svg/content/src/SVGFESpotLightElement.h
content/svg/content/src/SVGFETurbulenceElement.cpp
content/svg/content/src/SVGFETurbulenceElement.h
content/svg/content/src/SVGTransform.cpp
content/svg/content/src/SVGTransform.h
content/svg/content/src/nsSVGFilters.cpp
content/svg/content/src/nsSVGRect.cpp
content/svg/content/src/nsSVGRect.h
content/svg/content/src/nsSVGUnknownElement.cpp
content/svg/content/test/getSubStringLength-helper.svg
content/svg/content/test/test_getSubStringLength.xhtml
content/xul/document/src/nsXULDocument.cpp
content/xul/document/src/nsXULDocument.h
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/bluetooth/BluetoothDevice.cpp
dom/bluetooth/nsIDOMBluetoothDevice.idl
dom/bluetooth/nsIDOMBluetoothDeviceAddressEvent.idl
dom/dom-config.mk
dom/imptests/failures/webapps/DOMCore/tests/submissions/Ms2ger/test_EventTarget-dispatchEvent.html.json
dom/indexedDB/nsIIDBFactory.idl
dom/interfaces/svg/nsIDOMSVGFilters.idl
dom/interfaces/svg/nsIDOMSVGUnitTypes.idl
dom/power/test/browser_bug697132.js
intl/icu/source/config/mh-cygwin-msvc
ipc/chromium/src/base/base.gyp
ipc/chromium/src/base/build/base.vsprops
ipc/chromium/src/base/build/base_gfx.vsprops
ipc/chromium/src/base/build/base_unittests.vsprops
ipc/chromium/src/base/crypto/cssm_init.cc
ipc/chromium/src/base/crypto/cssm_init.h
ipc/chromium/src/base/crypto/signature_verifier.h
ipc/chromium/src/base/crypto/signature_verifier_mac.cc
ipc/chromium/src/base/crypto/signature_verifier_nss.cc
ipc/chromium/src/base/crypto/signature_verifier_unittest.cc
ipc/chromium/src/base/crypto/signature_verifier_win.cc
ipc/chromium/src/base/data/data_pack_unittest/sample.pak
ipc/chromium/src/base/data/file_util_unittest/binary_file.bin
ipc/chromium/src/base/data/file_util_unittest/binary_file_diff.bin
ipc/chromium/src/base/data/file_util_unittest/binary_file_same.bin
ipc/chromium/src/base/data/file_util_unittest/different.txt
ipc/chromium/src/base/data/file_util_unittest/different_first.txt
ipc/chromium/src/base/data/file_util_unittest/different_last.txt
ipc/chromium/src/base/data/file_util_unittest/empty1.txt
ipc/chromium/src/base/data/file_util_unittest/empty2.txt
ipc/chromium/src/base/data/file_util_unittest/original.txt
ipc/chromium/src/base/data/file_util_unittest/same.txt
ipc/chromium/src/base/data/file_util_unittest/same_length.txt
ipc/chromium/src/base/data/file_util_unittest/shortened.txt
ipc/chromium/src/base/data/file_version_info_unittest/FileVersionInfoTest1.dll
ipc/chromium/src/base/data/file_version_info_unittest/FileVersionInfoTest2.dll
ipc/chromium/src/base/data/purify/base_unittests.exe.gtest.txt
ipc/chromium/src/base/data/purify/base_unittests.exe_MLK.txt
ipc/chromium/src/base/data/purify/base_unittests.exe_MLK_flakey.txt
ipc/chromium/src/base/data/purify/base_unittests.exe_MLK_ignore.txt
ipc/chromium/src/base/data/purify/base_unittests.exe_PAR_ignore.txt
ipc/chromium/src/base/data/purify/base_unittests.exe_UMR.txt
ipc/chromium/src/base/data/valgrind/base_unittests.gtest.txt
ipc/chromium/src/base/gfx/gdi_util.cc
ipc/chromium/src/base/gfx/gtk_native_view_id_manager.cc
ipc/chromium/src/base/gfx/gtk_native_view_id_manager.h
ipc/chromium/src/base/gfx/gtk_util.cc
ipc/chromium/src/base/gfx/gtk_util.h
ipc/chromium/src/base/gfx/jpeg_codec.cc
ipc/chromium/src/base/gfx/jpeg_codec.h
ipc/chromium/src/base/gfx/jpeg_codec_unittest.cc
ipc/chromium/src/base/gfx/native_theme.cc
ipc/chromium/src/base/gfx/native_theme.h
ipc/chromium/src/base/gfx/native_theme_unittest.cc
ipc/chromium/src/base/gfx/native_widget_types_gtk.cc
ipc/chromium/src/base/gfx/platform_canvas.h
ipc/chromium/src/base/gfx/platform_canvas_linux.h
ipc/chromium/src/base/gfx/platform_canvas_mac.h
ipc/chromium/src/base/gfx/platform_device_linux.h
ipc/chromium/src/base/gfx/platform_device_mac.h
ipc/chromium/src/base/gfx/png_codec_unittest.cc
ipc/chromium/src/base/gfx/png_decoder.cc
ipc/chromium/src/base/gfx/png_decoder.h
ipc/chromium/src/base/gfx/png_encoder.cc
ipc/chromium/src/base/gfx/point.cc
ipc/chromium/src/base/gfx/rect.cc
ipc/chromium/src/base/gfx/rect.h
ipc/chromium/src/base/gfx/rect_unittest.cc
ipc/chromium/src/base/gfx/size.cc
ipc/chromium/src/base/gfx/size.h
ipc/chromium/src/base/keyboard_codes.h
ipc/chromium/src/base/keyboard_codes_posix.h
ipc/chromium/src/base/keyboard_codes_win.h
ipc/chromium/src/base/scoped_vector.h
ipc/chromium/src/third_party/libevent/README.chromium
ipc/chromium/src/third_party/libevent/compat/sys/_time.h
ipc/chromium/src/third_party/libevent/evbuffer.c
ipc/chromium/src/third_party/libevent/evdns.3
ipc/chromium/src/third_party/libevent/event-config.h
ipc/chromium/src/third_party/libevent/event.3
ipc/chromium/src/third_party/libevent/evsignal.h
ipc/chromium/src/third_party/libevent/libevent.gyp
ipc/chromium/src/third_party/libevent/linux/config.h
ipc/chromium/src/third_party/libevent/log.h
ipc/chromium/src/third_party/libevent/mac/config.h
ipc/chromium/src/third_party/libevent/min_heap.h
ipc/chromium/src/third_party/libevent/mkinstalldirs
ipc/chromium/src/third_party/libevent/quotes.patch
ipc/chromium/src/third_party/libevent/sys-queue-macros.patch
js/src/jsapi-tests/testIsAboutToBeFinalized.cpp
js/src/jsfun.cpp
js/xpconnect/src/dom_quickstubs.qsconf
layout/base/tests/test_image_layers.html
layout/build/Makefile.in
layout/forms/nsICapturePicker.idl
layout/reftests/svg/text/simple-selection.svg
layout/style/test/file_flexbox_min_size_auto.html
layout/style/test/test_flexbox_min_size_auto.html
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_locks.c
media/webrtc/signaling/src/sipcc/cpr/android/cpr_android_locks.h
media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_locks.c
media/webrtc/signaling/src/sipcc/cpr/darwin/cpr_darwin_locks.h
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_locks.c
media/webrtc/signaling/src/sipcc/cpr/linux/cpr_linux_locks.h
mobile/android/base/AboutHomeContent.java
mobile/android/base/AboutHomePromoBox.java
mobile/android/base/AboutHomeSection.java
mobile/android/base/LinkTextView.java
mobile/android/base/OnInterceptTouchListener.java
mobile/android/base/resources/layout-land-v14/browser_toolbar.xml
mobile/android/base/resources/layout/browser_toolbar.xml
mobile/android/base/resources/layout/gecko_app.xml
mobile/android/base/widget/AboutHomeContent.java
modules/libpref/src/init/all.js
security/nss/TAG-INFO-CKBI
testing/mozbase/mozdevice/README.md
testing/mozbase/mozdevice/mozdevice/b2gemulator.py
testing/mozbase/mozdevice/mozdevice/emulator.py
testing/mozbase/mozdevice/mozdevice/emulator_battery.py
testing/mozbase/mozdevice/sut_tests/test_cat2.py
testing/mozbase/mozdevice/sut_tests/test_isdir.py
testing/mozbase/mozfile/README.md
testing/mozbase/mozprocess/README.md
testing/mozbase/mozprocess/tests/mozprocess1.py
testing/mozbase/mozprocess/tests/mozprocess2.py
testing/mozbase/mozprofile/README.md
testing/mozbase/mozrunner/README.md
toolkit/crashreporter/google-breakpad/src/processor/logging.cc
toolkit/crashreporter/google-breakpad/src/processor/logging.h
toolkit/crashreporter/google-breakpad/src/processor/pathname_stripper.cc
toolkit/crashreporter/google-breakpad/src/processor/pathname_stripper.h
toolkit/crashreporter/google-breakpad/src/processor/pathname_stripper_unittest.cc
toolkit/mozapps/extensions/test/browser/addons/browser_inlinesettings1/bootstrap.js
toolkit/mozapps/extensions/test/browser/addons/browser_inlinesettings1/install.rdf
toolkit/mozapps/extensions/test/browser/addons/browser_inlinesettings1/options.xul
toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js
tools/profiler/ProfileEntry2.cpp
tools/profiler/ProfileEntry2.h
tools/profiler/TableTicker2.cpp
tools/profiler/sampler.h
tools/profiler/sps_sampler.h
xpcom/build/FrozenFunctions.cpp
xpcom/glue/standalone/nsGlueLinking.h
xpcom/glue/standalone/nsGlueLinkingDlopen.cpp
xpcom/glue/standalone/nsGlueLinkingNull.cpp
xpcom/glue/standalone/nsGlueLinkingOS2.cpp
xpcom/glue/standalone/nsGlueLinkingOSX.cpp
xpcom/glue/standalone/nsGlueLinkingWin.cpp
xpcom/stub/Makefile.in
xpcom/stub/dependentlibs.py
xpcom/stub/moz.build
xpcom/stub/nsXPComStub.cpp
--- a/.gdbinit
+++ b/.gdbinit
@@ -83,17 +83,17 @@ end
 def pa
   set $atom = $arg0
   if (sizeof(*((&*$atom)->mString)) == 2)
     pu (&*$atom)->mString
   end
 end
 
 # define a "pxul" command to display the type of a XUL element from
-# an nsXULDocument* pointer.
+# an nsXULElement* pointer.
 def pxul
   set $p = $arg0
   print $p->mNodeInfo.mRawPtr->mInner.mName->mStaticAtom->mString
 end
 
 # define a "prefcnt" command to display the refcount of an XPCOM obj
 def prefcnt
   set $p = $arg0
--- a/.hgtags
+++ b/.hgtags
@@ -86,8 +86,9 @@ 0000000000000000000000000000000000000000
 9697eadafa13b4e9233b39aaeecfeac79503cb54 FIREFOX_AURORA_16_BASE
 9697eadafa13b4e9233b39aaeecfeac79503cb54 FIREFOX_AURORA_16_BASE
 6fdf9985acfe6f939da584b2559464ab22264fe7 FIREFOX_AURORA_16_BASE
 fd72dbbd692012224145be1bf13df1d7675fd277 FIREFOX_AURORA_17_BASE
 2704e441363fe2a48e992dfac694482dfd82664a FIREFOX_AURORA_18_BASE
 cf8750abee06cde395c659f8ecd8ae019d7512e3 FIREFOX_AURORA_19_BASE
 5bb309998e7050c9ee80b0147de1e473f008e221 FIREFOX_AURORA_20_BASE
 cc37417e2c284aed960f98ffa479de4ccdd5c7c3 FIREFOX_AURORA_21_BASE
+1c070ab0f9db59f13423b9c1db60419f7a9098f9 FIREFOX_AURORA_22_BASE
--- a/Makefile.in
+++ b/Makefile.in
@@ -30,24 +30,30 @@ include $(topsrcdir)/config/config.mk
 
 GARBAGE_DIRS += dist _javagen _profile _tests staticlib
 DIST_GARBAGE = config.cache config.log config.status* config-defs.h \
    config/autoconf.mk \
    unallmakefiles mozilla-config.h \
    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
+default alldep all:: CLOBBER $(topsrcdir)/configure config.status
 	$(RM) -r $(DIST)/sdk
 	$(RM) -r $(DIST)/include
 	$(RM) -r $(DIST)/private
 	$(RM) -r $(DIST)/public
 	$(RM) $(DIST)/bin/chrome.manifest $(DIST)/bin/components/components.manifest
 	$(RM) -r _tests
 
+CLOBBER: $(topsrcdir)/CLOBBER
+	@echo "STOP!  The CLOBBER file has changed."
+	@echo "Please run the build through a sanctioned build wrapper, such as"
+	@echo "'mach build' or client.mk."
+	@exit 1
+
 $(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
 
 config.status: $(topsrcdir)/configure
--- a/accessible/build/moz.build
+++ b/accessible/build/moz.build
@@ -1,7 +1,8 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'accessibility'
 
--- a/accessible/build/nsAccessibilityFactory.cpp
+++ b/accessible/build/nsAccessibilityFactory.cpp
@@ -27,24 +27,24 @@ NS_ConstructAccessibilityService(nsISupp
     NS_ASSERTION(NS_SUCCEEDED(rv), "unable to find correct interface");
     NS_RELEASE(accessibility);
     return rv;
 }
 
 NS_DEFINE_NAMED_CID(NS_ACCESSIBILITY_SERVICE_CID);
 
 static const mozilla::Module::CIDEntry kA11yCIDs[] = {
-    { &kNS_ACCESSIBILITY_SERVICE_CID, false, NULL, NS_ConstructAccessibilityService },
-    { NULL }
+    { &kNS_ACCESSIBILITY_SERVICE_CID, false, nullptr, NS_ConstructAccessibilityService },
+    { nullptr }
 };
 
 static const mozilla::Module::ContractIDEntry kA11yContracts[] = {
     { "@mozilla.org/accessibilityService;1", &kNS_ACCESSIBILITY_SERVICE_CID },
     { "@mozilla.org/accessibleRetrieval;1", &kNS_ACCESSIBILITY_SERVICE_CID },
-    { NULL }
+    { nullptr }
 };
 
 static const mozilla::Module kA11yModule = {
     mozilla::Module::kVersion,
     kA11yCIDs,
     kA11yContracts
 };
 
--- a/accessible/moz.build
+++ b/accessible/moz.build
@@ -1,8 +1,9 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 DIRS += ['public', 'src', 'build']
 TEST_DIRS += ['tests']
 
--- a/accessible/public/ia2/moz.build
+++ b/accessible/public/ia2/moz.build
@@ -1,7 +1,8 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'accessibility'
 
--- a/accessible/public/moz.build
+++ b/accessible/public/moz.build
@@ -1,8 +1,9 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
     DIRS += ['msaa', 'ia2']
 
--- a/accessible/public/msaa/moz.build
+++ b/accessible/public/msaa/moz.build
@@ -1,7 +1,8 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'accessibility'
 
--- a/accessible/src/atk/AccessibleWrap.cpp
+++ b/accessible/src/atk/AccessibleWrap.cpp
@@ -93,37 +93,37 @@ static GType GetAtkTypeForMai(MaiInterfa
   }
   return G_TYPE_INVALID;
 }
 
 static const char* kNonUserInputEvent = ":system";
     
 static const GInterfaceInfo atk_if_infos[] = {
     {(GInterfaceInitFunc)componentInterfaceInitCB,
-     (GInterfaceFinalizeFunc) NULL, NULL}, 
+     (GInterfaceFinalizeFunc) nullptr, nullptr}, 
     {(GInterfaceInitFunc)actionInterfaceInitCB,
-     (GInterfaceFinalizeFunc) NULL, NULL},
+     (GInterfaceFinalizeFunc) nullptr, nullptr},
     {(GInterfaceInitFunc)valueInterfaceInitCB,
-     (GInterfaceFinalizeFunc) NULL, NULL},
+     (GInterfaceFinalizeFunc) nullptr, nullptr},
     {(GInterfaceInitFunc)editableTextInterfaceInitCB,
-     (GInterfaceFinalizeFunc) NULL, NULL},
+     (GInterfaceFinalizeFunc) nullptr, nullptr},
     {(GInterfaceInitFunc)hypertextInterfaceInitCB,
-     (GInterfaceFinalizeFunc) NULL, NULL},
+     (GInterfaceFinalizeFunc) nullptr, nullptr},
     {(GInterfaceInitFunc)hyperlinkImplInterfaceInitCB,
-     (GInterfaceFinalizeFunc) NULL, NULL},
+     (GInterfaceFinalizeFunc) nullptr, nullptr},
     {(GInterfaceInitFunc)selectionInterfaceInitCB,
-     (GInterfaceFinalizeFunc) NULL, NULL},
+     (GInterfaceFinalizeFunc) nullptr, nullptr},
     {(GInterfaceInitFunc)tableInterfaceInitCB,
-     (GInterfaceFinalizeFunc) NULL, NULL},
+     (GInterfaceFinalizeFunc) nullptr, nullptr},
     {(GInterfaceInitFunc)textInterfaceInitCB,
-     (GInterfaceFinalizeFunc) NULL, NULL},
+     (GInterfaceFinalizeFunc) nullptr, nullptr},
     {(GInterfaceInitFunc)documentInterfaceInitCB,
-     (GInterfaceFinalizeFunc) NULL, NULL},
+     (GInterfaceFinalizeFunc) nullptr, nullptr},
     {(GInterfaceInitFunc)imageInterfaceInitCB,
-     (GInterfaceFinalizeFunc) NULL, NULL}
+     (GInterfaceFinalizeFunc) nullptr, nullptr}
 };
 
 /**
  * This MaiAtkObject is a thin wrapper, in the MAI namespace, for AtkObject
  */
 struct MaiAtkObject
 {
   AtkObject parent;
@@ -192,37 +192,37 @@ static AtkRelationSet*     refRelationSe
   gboolean state_set);
   static void                VisibleDataChangedCB(AtkObject *aAtkObj);
 */
 G_END_DECLS
 
 static GType GetMaiAtkType(uint16_t interfacesBits);
 static const char * GetUniqueMaiAtkTypeName(uint16_t interfacesBits);
 
-static gpointer parent_class = NULL;
+static gpointer parent_class = nullptr;
 
 static GQuark quark_mai_hyperlink = 0;
 
 GType
 mai_atk_object_get_type(void)
 {
     static GType type = 0;
 
     if (!type) {
         static const GTypeInfo tinfo = {
             sizeof(MaiAtkObjectClass),
-            (GBaseInitFunc)NULL,
-            (GBaseFinalizeFunc)NULL,
+            (GBaseInitFunc)nullptr,
+            (GBaseFinalizeFunc)nullptr,
             (GClassInitFunc)classInitCB,
-            (GClassFinalizeFunc)NULL,
-            NULL, /* class data */
+            (GClassFinalizeFunc)nullptr,
+            nullptr, /* class data */
             sizeof(MaiAtkObject), /* instance size */
             0, /* nb preallocs */
-            (GInstanceInitFunc)NULL,
-            NULL /* value table */
+            (GInstanceInitFunc)nullptr,
+            nullptr /* value table */
         };
 
         type = g_type_register_static(ATK_TYPE_OBJECT,
                                       "MaiAtkObject", &tinfo, GTypeFlags(0));
         quark_mai_hyperlink = g_quark_from_static_string("MaiHyperlink");
     }
     return type;
 }
@@ -305,17 +305,17 @@ AccessibleWrap::GetNativeInterface(void*
             // nsIAccessible plain text leaves
             return NS_ERROR_FAILURE;
         }
 
         GType type = GetMaiAtkType(CreateMaiInterfaces());
         NS_ENSURE_TRUE(type, NS_ERROR_FAILURE);
         mAtkObject =
             reinterpret_cast<AtkObject *>
-                            (g_object_new(type, NULL));
+                            (g_object_new(type, nullptr));
         NS_ENSURE_TRUE(mAtkObject, NS_ERROR_OUT_OF_MEMORY);
 
         atk_object_initialize(mAtkObject, this);
         mAtkObject->role = ATK_ROLE_INVALID;
         mAtkObject->layer = ATK_LAYER_INVALID;
     }
 
     *aOutAccessible = mAtkObject;
@@ -396,25 +396,25 @@ AccessibleWrap::CreateMaiInterfaces(void
 }
 
 static GType
 GetMaiAtkType(uint16_t interfacesBits)
 {
     GType type;
     static const GTypeInfo tinfo = {
         sizeof(MaiAtkObjectClass),
-        (GBaseInitFunc) NULL,
-        (GBaseFinalizeFunc) NULL,
-        (GClassInitFunc) NULL,
-        (GClassFinalizeFunc) NULL,
-        NULL, /* class data */
+        (GBaseInitFunc) nullptr,
+        (GBaseFinalizeFunc) nullptr,
+        (GClassInitFunc) nullptr,
+        (GClassFinalizeFunc) nullptr,
+        nullptr, /* class data */
         sizeof(MaiAtkObject), /* instance size */
         0, /* nb preallocs */
-        (GInstanceInitFunc) NULL,
-        NULL /* value table */
+        (GInstanceInitFunc) nullptr,
+        nullptr /* value table */
     };
 
     /*
      * The members we use to register GTypes are GetAtkTypeForMai
      * and atk_if_infos, which are constant values to each MaiInterface
      * So we can reuse the registered GType when having
      * the same MaiInterface types.
      */
@@ -492,73 +492,73 @@ classInitCB(AtkObjectClass *aClass)
 
     gobject_class->finalize = finalizeCB;
 
     mai_atk_object_signals [ACTIVATE] =
     g_signal_new ("activate",
                   MAI_TYPE_ATK_OBJECT,
                   G_SIGNAL_RUN_LAST,
                   0, /* default signal handler */
-                  NULL, NULL,
+                  nullptr, nullptr,
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
     mai_atk_object_signals [CREATE] =
     g_signal_new ("create",
                   MAI_TYPE_ATK_OBJECT,
                   G_SIGNAL_RUN_LAST,
                   0, /* default signal handler */
-                  NULL, NULL,
+                  nullptr, nullptr,
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
     mai_atk_object_signals [DEACTIVATE] =
     g_signal_new ("deactivate",
                   MAI_TYPE_ATK_OBJECT,
                   G_SIGNAL_RUN_LAST,
                   0, /* default signal handler */
-                  NULL, NULL,
+                  nullptr, nullptr,
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
     mai_atk_object_signals [DESTROY] =
     g_signal_new ("destroy",
                   MAI_TYPE_ATK_OBJECT,
                   G_SIGNAL_RUN_LAST,
                   0, /* default signal handler */
-                  NULL, NULL,
+                  nullptr, nullptr,
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
     mai_atk_object_signals [MAXIMIZE] =
     g_signal_new ("maximize",
                   MAI_TYPE_ATK_OBJECT,
                   G_SIGNAL_RUN_LAST,
                   0, /* default signal handler */
-                  NULL, NULL,
+                  nullptr, nullptr,
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
     mai_atk_object_signals [MINIMIZE] =
     g_signal_new ("minimize",
                   MAI_TYPE_ATK_OBJECT,
                   G_SIGNAL_RUN_LAST,
                   0, /* default signal handler */
-                  NULL, NULL,
+                  nullptr, nullptr,
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
     mai_atk_object_signals [RESIZE] =
     g_signal_new ("resize",
                   MAI_TYPE_ATK_OBJECT,
                   G_SIGNAL_RUN_LAST,
                   0, /* default signal handler */
-                  NULL, NULL,
+                  nullptr, nullptr,
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
     mai_atk_object_signals [RESTORE] =
     g_signal_new ("restore",
                   MAI_TYPE_ATK_OBJECT,
                   G_SIGNAL_RUN_LAST,
                   0, /* default signal handler */
-                  NULL, NULL,
+                  nullptr, nullptr,
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
 
 }
 
 void
 initializeCB(AtkObject *aAtkObj, gpointer aData)
 {
@@ -612,17 +612,17 @@ getNameCB(AtkObject* aAtkObj)
 
 const gchar *
 getDescriptionCB(AtkObject *aAtkObj)
 {
     AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
     if (!accWrap || accWrap->IsDefunct())
         return nullptr;
 
-    /* nsIAccessible is responsible for the non-NULL description */
+    /* nsIAccessible is responsible for the non-nullptr description */
     nsAutoString uniDesc;
     accWrap->Description(uniDesc);
 
     NS_ConvertUTF8toUTF16 objDesc(aAtkObj->description);
     if (!uniDesc.Equals(objDesc))
         atk_object_set_description(aAtkObj,
                                    NS_ConvertUTF16toUTF8(uniDesc).get());
 
@@ -1214,23 +1214,23 @@ AccessibleWrap::FireAtkTextChangedEvent(
         eHaveNewAtkTextSignals : eNoNewAtkSignals;
 
   if (gAvailableAtkSignals == eNoNewAtkSignals) {
     // XXX remove this code and the gHaveNewTextSignals check when we can
     // stop supporting old atk since it doesn't really work anyway
     // see bug 619002
     signal_name = g_strconcat(isInserted ? "text_changed::insert" :
                               "text_changed::delete",
-                              isFromUserInput ? "" : kNonUserInputEvent, NULL);
+                              isFromUserInput ? "" : kNonUserInputEvent, nullptr);
     g_signal_emit_by_name(aObject, signal_name, start, length);
   } else {
     nsAutoString text;
     event->GetModifiedText(text);
     signal_name = g_strconcat(isInserted ? "text-insert" : "text-remove",
-                              isFromUserInput ? "" : "::system", NULL);
+                              isFromUserInput ? "" : "::system", nullptr);
     g_signal_emit_by_name(aObject, signal_name, start, length,
                           NS_ConvertUTF16toUTF8(text).get());
   }
 
   g_free(signal_name);
   return NS_OK;
 }
 
@@ -1239,14 +1239,14 @@ AccessibleWrap::FireAtkShowHideEvent(Acc
                                      AtkObject* aObject, bool aIsAdded)
 {
     int32_t indexInParent = getIndexInParentCB(aObject);
     AtkObject *parentObject = getParentCB(aObject);
     NS_ENSURE_STATE(parentObject);
 
     bool isFromUserInput = aEvent->IsFromUserInput();
     char *signal_name = g_strconcat(aIsAdded ? "children_changed::add" :  "children_changed::remove",
-                                    isFromUserInput ? "" : kNonUserInputEvent, NULL);
-    g_signal_emit_by_name(parentObject, signal_name, indexInParent, aObject, NULL);
+                                    isFromUserInput ? "" : kNonUserInputEvent, nullptr);
+    g_signal_emit_by_name(parentObject, signal_name, indexInParent, aObject, nullptr);
     g_free(signal_name);
 
     return NS_OK;
 }
--- a/accessible/src/atk/ApplicationAccessibleWrap.cpp
+++ b/accessible/src/atk/ApplicationAccessibleWrap.cpp
@@ -64,17 +64,17 @@ toplevel_event_watcher(GSignalInvocation
     } else {
 
       // Deattach the dialog accessible
       Accessible* windowAcc =
         reinterpret_cast<Accessible*>
                         (g_object_get_qdata(G_OBJECT(child), sQuark_gecko_acc_obj));
       if (windowAcc) {
         GetAccService()->RemoveNativeRootAccessible(windowAcc);
-        g_object_set_qdata(G_OBJECT(child), sQuark_gecko_acc_obj, NULL);
+        g_object_set_qdata(G_OBJECT(child), sQuark_gecko_acc_obj, nullptr);
       }
 
     }
   }
 
   return TRUE;
 }
 
@@ -92,17 +92,17 @@ ApplicationAccessibleWrap::Name(nsString
 NS_IMETHODIMP
 ApplicationAccessibleWrap::GetNativeInterface(void** aOutAccessible)
 {
     *aOutAccessible = nullptr;
 
     if (!mAtkObject) {
         mAtkObject =
             reinterpret_cast<AtkObject *>
-                            (g_object_new(MAI_TYPE_ATK_OBJECT, NULL));
+                            (g_object_new(MAI_TYPE_ATK_OBJECT, nullptr));
         NS_ENSURE_TRUE(mAtkObject, NS_ERROR_OUT_OF_MEMORY);
 
         atk_object_initialize(mAtkObject, this);
         mAtkObject->role = ATK_ROLE_INVALID;
         mAtkObject->layer = ATK_LAYER_INVALID;
     }
 
     *aOutAccessible = mAtkObject;
@@ -114,17 +114,17 @@ struct AtkRootAccessibleAddedEvent {
   AtkObject *root_accessible;
   uint32_t index;
 };
 
 gboolean fireRootAccessibleAddedCB(gpointer data)
 {
     AtkRootAccessibleAddedEvent* eventData = (AtkRootAccessibleAddedEvent*)data;
     g_signal_emit_by_name(eventData->app_accessible, "children_changed::add",
-                          eventData->index, eventData->root_accessible, NULL);
+                          eventData->index, eventData->root_accessible, nullptr);
     g_object_unref(eventData->app_accessible);
     g_object_unref(eventData->root_accessible);
     free(data);
 
     return FALSE;
 }
 
 bool
@@ -155,15 +155,15 @@ ApplicationAccessibleWrap::InsertChildAt
 }
 
 bool
 ApplicationAccessibleWrap::RemoveChild(Accessible* aChild)
 {
   int32_t index = aChild->IndexInParent();
 
   AtkObject* atkAccessible = AccessibleWrap::GetAtkObject(aChild);
-  atk_object_set_parent(atkAccessible, NULL);
+  atk_object_set_parent(atkAccessible, nullptr);
   g_signal_emit_by_name(mAtkObject, "children_changed::remove", index,
-                        atkAccessible, NULL);
+                        atkAccessible, nullptr);
 
   return ApplicationAccessible::RemoveChild(aChild);
 }
 
--- a/accessible/src/atk/AtkSocketAccessible.cpp
+++ b/accessible/src/atk/AtkSocketAccessible.cpp
@@ -8,17 +8,17 @@
 #include "AtkSocketAccessible.h"
 
 #include "InterfaceInitFuncs.h"
 #include "nsMai.h"
 #include "mozilla/Likely.h"
 
 using namespace mozilla::a11y;
 
-AtkSocketEmbedType AtkSocketAccessible::g_atk_socket_embed = NULL;
+AtkSocketEmbedType AtkSocketAccessible::g_atk_socket_embed = nullptr;
 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;
 
 extern "C" void mai_atk_component_iface_init(AtkComponentIface* aIface);
 extern "C" GType mai_atk_socket_get_type(void);
@@ -64,21 +64,21 @@ mai_atk_socket_class_init(MaiAtkSocketCl
 void
 mai_atk_socket_init(MaiAtkSocket* aAcc)
 {
 }
 
 static AtkObject*
 mai_atk_socket_new(AccessibleWrap* aAccWrap)
 {
-  NS_ENSURE_TRUE(aAccWrap, NULL);
+  NS_ENSURE_TRUE(aAccWrap, nullptr);
 
   MaiAtkSocket* acc = nullptr;
-  acc = static_cast<MaiAtkSocket*>(g_object_new(MAI_TYPE_ATK_SOCKET, NULL));
-  NS_ENSURE_TRUE(acc, NULL);
+  acc = static_cast<MaiAtkSocket*>(g_object_new(MAI_TYPE_ATK_SOCKET, nullptr));
+  NS_ENSURE_TRUE(acc, nullptr);
 
   acc->accWrap = aAccWrap;
   return ATK_OBJECT(acc);
 }
 
 extern "C" {
 static AtkObject*
 RefAccessibleAtPoint(AtkComponent* aComponent, gint aX, gint aY,
--- a/accessible/src/atk/Platform.cpp
+++ b/accessible/src/atk/Platform.cpp
@@ -48,28 +48,28 @@ struct GnomeAccessibilityModule
     const char *initName;
     GnomeAccessibilityInit init;
     const char *shutdownName;
     GnomeAccessibilityShutdown shutdown;
 };
 
 static GnomeAccessibilityModule sAtkBridge = {
 #ifdef AIX
-    "libatk-bridge.a(libatk-bridge.so.0)", NULL,
+    "libatk-bridge.a(libatk-bridge.so.0)", nullptr,
 #else
-    "libatk-bridge.so", NULL,
+    "libatk-bridge.so", nullptr,
 #endif
-    "gnome_accessibility_module_init", NULL,
-    "gnome_accessibility_module_shutdown", NULL
+    "gnome_accessibility_module_init", nullptr,
+    "gnome_accessibility_module_shutdown", nullptr
 };
 
 static GnomeAccessibilityModule sGail = {
-    "libgail.so", NULL,
-    "gnome_accessibility_module_init", NULL,
-    "gnome_accessibility_module_shutdown", NULL
+    "libgail.so", nullptr,
+    "gnome_accessibility_module_init", nullptr,
+    "gnome_accessibility_module_shutdown", nullptr
 };
 
 static nsresult
 LoadGtkModule(GnomeAccessibilityModule& aModule)
 {
     NS_ENSURE_ARG(aModule.libName);
 
     if (!(aModule.lib = PR_LoadLibrary(aModule.libName))) {
@@ -107,17 +107,17 @@ LoadGtkModule(GnomeAccessibilityModule& 
     //we have loaded the library, try to get the function ptrs
     if (!(aModule.init = PR_FindFunctionSymbol(aModule.lib,
                                                aModule.initName)) ||
         !(aModule.shutdown = PR_FindFunctionSymbol(aModule.lib,
                                                    aModule.shutdownName))) {
 
         //fail, :(
         PR_UnloadLibrary(aModule.lib);
-        aModule.lib = NULL;
+        aModule.lib = nullptr;
         return NS_ERROR_FAILURE;
     }
     return NS_OK;
 }
 
 void
 a11y::PlatformInit()
 {
@@ -160,22 +160,22 @@ a11y::PlatformInit()
   }
 
   if (!sToplevel_event_hook_added) {
     sToplevel_event_hook_added = true;
     sToplevel_show_hook =
       g_signal_add_emission_hook(g_signal_lookup("show", GTK_TYPE_WINDOW),
                                  0, toplevel_event_watcher,
                                  reinterpret_cast<gpointer>(nsIAccessibleEvent::EVENT_SHOW),
-                                 NULL);
+                                 nullptr);
     sToplevel_hide_hook =
       g_signal_add_emission_hook(g_signal_lookup("hide", GTK_TYPE_WINDOW), 0,
                                  toplevel_event_watcher,
                                  reinterpret_cast<gpointer>(nsIAccessibleEvent::EVENT_HIDE),
-                                 NULL);
+                                 nullptr);
   }
 }
 
 void
 a11y::PlatformShutdown()
 {
     if (sToplevel_event_hook_added) {
       sToplevel_event_hook_added = false;
@@ -186,30 +186,30 @@ a11y::PlatformShutdown()
     }
 
     if (sAtkBridge.lib) {
         // Do not shutdown/unload atk-bridge,
         // an exit function registered will take care of it
         // if (sAtkBridge.shutdown)
         //     (*sAtkBridge.shutdown)();
         // PR_UnloadLibrary(sAtkBridge.lib);
-        sAtkBridge.lib = NULL;
-        sAtkBridge.init = NULL;
-        sAtkBridge.shutdown = NULL;
+        sAtkBridge.lib = nullptr;
+        sAtkBridge.init = nullptr;
+        sAtkBridge.shutdown = nullptr;
     }
     if (sGail.lib) {
         // Do not shutdown gail because
         // 1) Maybe it's not init-ed by us. e.g. GtkEmbed
         // 2) We need it to avoid assert in spi_atk_tidy_windows
         // if (sGail.shutdown)
         //   (*sGail.shutdown)();
         // PR_UnloadLibrary(sGail.lib);
-        sGail.lib = NULL;
-        sGail.init = NULL;
-        sGail.shutdown = NULL;
+        sGail.lib = nullptr;
+        sGail.init = nullptr;
+        sGail.shutdown = nullptr;
     }
     // if (sATKLib) {
     //     PR_UnloadLibrary(sATKLib);
     //     sATKLib = nullptr;
     // }
 }
 
   static const char sAccEnv [] = "GNOME_ACCESSIBILITY";
--- a/accessible/src/atk/UtilInterface.cpp
+++ b/accessible/src/atk/UtilInterface.cpp
@@ -37,17 +37,17 @@ struct MaiUtilListenerInfo
   gulong hook_id;
   // For window create/destory/minimize/maximize/restore/activate/deactivate
   // events, we'll chain gail_util's add/remove_global_event_listener.
   // So we store the listenerid returned by gail's add_global_event_listener
   // in this structure to call gail's remove_global_event_listener later.
   guint gail_listenerid;
 };
 
-static GHashTable* sListener_list = NULL;
+static GHashTable* sListener_list = nullptr;
 static gint sListener_idx = 1;
 
 extern "C" {
 static guint
 add_listener (GSignalEmissionHook listener,
               const gchar *object_type,
               const gchar *signal,
               const gchar *hook_data,
@@ -124,17 +124,17 @@ mai_util_remove_global_event_listener(gu
 {
     if (remove_listener > 0) {
         MaiUtilListenerInfo *listener_info;
         gint tmp_idx = remove_listener;
 
         listener_info = (MaiUtilListenerInfo *)
             g_hash_table_lookup(sListener_list, &tmp_idx);
 
-        if (listener_info != NULL) {
+        if (listener_info != nullptr) {
             if (gail_remove_global_event_listener &&
                 listener_info->gail_listenerid) {
               gail_remove_global_event_listener(listener_info->gail_listenerid);
             }
 
             /* Hook id of 0 and signal id of 0 are invalid */
             if (listener_info->hook_id != 0 && listener_info->signal_id != 0) {
                 /* Remove the emission hook */
@@ -173,17 +173,17 @@ atk_key_event_from_gdk_event_key (GdkEve
     case GDK_KEY_PRESS:
         event->type = ATK_KEY_EVENT_PRESS;
         break;
     case GDK_KEY_RELEASE:
         event->type = ATK_KEY_EVENT_RELEASE;
         break;
     default:
         g_assert_not_reached ();
-        return NULL;
+        return nullptr;
     }
     event->state = key->state;
     event->keyval = key->keyval;
     event->length = key->length;
     if (key->string && key->string [0] &&
         (key->state & GDK_CONTROL_MASK ||
          g_unichar_isgraph (g_utf8_get_char (key->string)))) {
         event->string = key->string;
@@ -221,27 +221,27 @@ notify_hf(gpointer key, gpointer value, 
 
 static void
 insert_hf(gpointer key, gpointer value, gpointer data)
 {
     GHashTable *new_table = (GHashTable *) data;
     g_hash_table_insert (new_table, key, value);
 }
 
-static GHashTable* sKey_listener_list = NULL;
+static GHashTable* sKey_listener_list = nullptr;
 
 static gint
 mai_key_snooper(GtkWidget *the_widget, GdkEventKey *event, gpointer func_data)
 {
     /* notify each AtkKeySnoopFunc in turn... */
 
     MaiKeyEventInfo *info = g_new0(MaiKeyEventInfo, 1);
     gint consumed = 0;
     if (sKey_listener_list) {
-        GHashTable *new_hash = g_hash_table_new(NULL, NULL);
+        GHashTable *new_hash = g_hash_table_new(nullptr, nullptr);
         g_hash_table_foreach (sKey_listener_list, insert_hf, new_hash);
         info->key_event = atk_key_event_from_gdk_event_key (event);
         info->func_data = func_data;
         consumed = g_hash_table_foreach_steal (new_hash, notify_hf, info);
         g_hash_table_destroy (new_hash);
         g_free(info->key_event);
     }
     g_free(info);
@@ -255,17 +255,17 @@ mai_util_add_key_event_listener (AtkKeyS
                                  gpointer data)
 {
   if (MOZ_UNLIKELY(!listener))
     return 0;
 
     static guint key=0;
 
     if (!sKey_listener_list) {
-        sKey_listener_list = g_hash_table_new(NULL, NULL);
+        sKey_listener_list = g_hash_table_new(nullptr, nullptr);
         sKey_snooper_id = gtk_key_snooper_install(mai_key_snooper, data);
     }
     AtkKeySnoopFuncPointer atkKeySnoop;
     atkKeySnoop.func_ptr = listener;
     g_hash_table_insert(sKey_listener_list, GUINT_TO_POINTER (key++),
                         atkKeySnoop.data);
     return key;
 }
@@ -363,42 +363,42 @@ UtilInterfaceInit(MaiUtilClass* klass)
     atk_class->remove_global_event_listener =
         mai_util_remove_global_event_listener;
     atk_class->add_key_event_listener = mai_util_add_key_event_listener;
     atk_class->remove_key_event_listener = mai_util_remove_key_event_listener;
     atk_class->get_root = mai_util_get_root;
     atk_class->get_toolkit_name = mai_util_get_toolkit_name;
     atk_class->get_toolkit_version = mai_util_get_toolkit_version;
 
-    sListener_list = g_hash_table_new_full(g_int_hash, g_int_equal, NULL,
+    sListener_list = g_hash_table_new_full(g_int_hash, g_int_equal, nullptr,
                                            _listener_info_destroy);
     // Keep track of added/removed windows.
     AtkObject *root = atk_get_root ();
-    g_signal_connect (root, "children-changed::add", (GCallback) window_added, NULL);
-    g_signal_connect (root, "children-changed::remove", (GCallback) window_removed, NULL);
+    g_signal_connect (root, "children-changed::add", (GCallback) window_added, nullptr);
+    g_signal_connect (root, "children-changed::remove", (GCallback) window_removed, nullptr);
 }
 }
 
 GType
 mai_util_get_type()
 {
     static GType type = 0;
 
     if (!type) {
         static const GTypeInfo tinfo = {
             sizeof(MaiUtilClass),
-            (GBaseInitFunc) NULL, /* base init */
-            (GBaseFinalizeFunc) NULL, /* base finalize */
+            (GBaseInitFunc) nullptr, /* base init */
+            (GBaseFinalizeFunc) nullptr, /* base finalize */
             (GClassInitFunc) UtilInterfaceInit, /* class init */
-            (GClassFinalizeFunc) NULL, /* class finalize */
-            NULL, /* class data */
+            (GClassFinalizeFunc) nullptr, /* class finalize */
+            nullptr, /* class data */
             sizeof(MaiUtil), /* instance size */
             0, /* nb preallocs */
-            (GInstanceInitFunc) NULL, /* instance init */
-            NULL /* value table */
+            (GInstanceInitFunc) nullptr, /* instance init */
+            nullptr /* value table */
         };
 
         type = g_type_register_static(ATK_TYPE_UTIL,
                                       "MaiUtil", &tinfo, GTypeFlags(0));
     }
     return type;
 }
 
--- a/accessible/src/atk/moz.build
+++ b/accessible/src/atk/moz.build
@@ -1,7 +1,8 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'accessibility'
 
--- a/accessible/src/atk/nsMaiHyperlink.cpp
+++ b/accessible/src/atk/nsMaiHyperlink.cpp
@@ -55,37 +55,37 @@ static void finalizeCB(GObject *aObj);
 static gchar *getUriCB(AtkHyperlink *aLink, gint aLinkIndex);
 static AtkObject *getObjectCB(AtkHyperlink *aLink, gint aLinkIndex);
 static gint getEndIndexCB(AtkHyperlink *aLink);
 static gint getStartIndexCB(AtkHyperlink *aLink);
 static gboolean isValidCB(AtkHyperlink *aLink);
 static gint getAnchorCountCB(AtkHyperlink *aLink);
 G_END_DECLS
 
-static gpointer parent_class = NULL;
+static gpointer parent_class = nullptr;
 static Accessible*
 get_accessible_hyperlink(AtkHyperlink *aHyperlink);
 
 GType
 mai_atk_hyperlink_get_type(void)
 {
     static GType type = 0;
 
     if (!type) {
         static const GTypeInfo tinfo = {
             sizeof(MaiAtkHyperlinkClass),
-            (GBaseInitFunc)NULL,
-            (GBaseFinalizeFunc)NULL,
+            (GBaseInitFunc)nullptr,
+            (GBaseFinalizeFunc)nullptr,
             (GClassInitFunc)classInitCB,
-            (GClassFinalizeFunc)NULL,
-            NULL, /* class data */
+            (GClassFinalizeFunc)nullptr,
+            nullptr, /* class data */
             sizeof(MaiAtkHyperlink), /* instance size */
             0, /* nb preallocs */
-            (GInstanceInitFunc)NULL,
-            NULL /* value table */
+            (GInstanceInitFunc)nullptr,
+            nullptr /* value table */
         };
 
         type = g_type_register_static(ATK_TYPE_HYPERLINK,
                                       "MaiAtkHyperlink",
                                       &tinfo, GTypeFlags(0));
     }
     return type;
 }
@@ -112,17 +112,17 @@ MaiHyperlink::GetAtkHyperlink(void)
   if (mMaiAtkHyperlink)
     return mMaiAtkHyperlink;
 
   if (!mHyperlink->IsLink())
     return nullptr;
 
     mMaiAtkHyperlink =
         reinterpret_cast<AtkHyperlink *>
-                        (g_object_new(mai_atk_hyperlink_get_type(), NULL));
+                        (g_object_new(mai_atk_hyperlink_get_type(), nullptr));
     NS_ASSERTION(mMaiAtkHyperlink, "OUT OF MEMORY");
     NS_ENSURE_TRUE(mMaiAtkHyperlink, nullptr);
 
     /* be sure to initialize it with "this" */
     MaiHyperlink::Initialize(mMaiAtkHyperlink, this);
 
     return mMaiAtkHyperlink;
 }
--- a/accessible/src/base/Makefile.in
+++ b/accessible/src/base/Makefile.in
@@ -80,16 +80,17 @@ LOCAL_INCLUDES += \
   -I$(srcdir)/../generic \
   -I$(srcdir)/../html \
   -I$(srcdir)/../xpcom \
   -I$(srcdir)/../xul \
   -I$(srcdir)/../../../layout/generic \
   -I$(srcdir)/../../../layout/style \
   -I$(srcdir)/../../../layout/svg \
   -I$(srcdir)/../../../layout/xul/base/src \
+  -I$(srcdir)/../../../layout/xul/tree/ \
   $(NULL)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
 LOCAL_INCLUDES += \
   -I$(srcdir)/../atk \
   $(NULL)
 else
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
--- a/accessible/src/base/TextAttrs.cpp
+++ b/accessible/src/base/TextAttrs.cpp
@@ -1,15 +1,16 @@
 /* -*- 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 "TextAttrs.h"
 
+#include "Accessible-inl.h"
 #include "HyperTextAccessibleWrap.h"
 #include "nsAccUtils.h"
 #include "nsCoreUtils.h"
 #include "StyleInfo.h"
 
 #include "gfxFont.h"
 #include "gfxUserFontSet.h"
 #include "nsFontMetrics.h"
--- a/accessible/src/base/moz.build
+++ b/accessible/src/base/moz.build
@@ -1,7 +1,8 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'accessibility'
 
--- a/accessible/src/base/nsAccCache.h
+++ b/accessible/src/base/nsAccCache.h
@@ -16,17 +16,17 @@
 
 /**
  * Shutdown and removes the accessible from cache.
  */
 template <class T>
 static PLDHashOperator
 ClearCacheEntry(const void* aKey, nsRefPtr<T>& aAccessible, void* aUserArg)
 {
-  NS_ASSERTION(aAccessible, "Calling ClearCacheEntry with a NULL pointer!");
+  NS_ASSERTION(aAccessible, "Calling ClearCacheEntry with a nullptr pointer!");
   if (aAccessible)
     aAccessible->Shutdown();
 
   return PL_DHASH_REMOVE;
 }
 
 /**
  * Clear the cache and shutdown the accessibles.
--- a/accessible/src/base/nsAccUtils.cpp
+++ b/accessible/src/base/nsAccUtils.cpp
@@ -131,48 +131,47 @@ nsAccUtils::SetLiveContainerAttributes(n
                                        nsIContent *aTopContent)
 {
   nsAutoString atomic, live, relevant, busy;
   nsIContent *ancestor = aStartContent;
   while (ancestor) {
 
     // container-relevant attribute
     if (relevant.IsEmpty() &&
-        nsAccUtils::HasDefinedARIAToken(ancestor, nsGkAtoms::aria_relevant) &&
+        HasDefinedARIAToken(ancestor, nsGkAtoms::aria_relevant) &&
         ancestor->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_relevant, relevant))
       SetAccAttr(aAttributes, nsGkAtoms::containerRelevant, relevant);
 
     // container-live, and container-live-role attributes
     if (live.IsEmpty()) {
       nsRoleMapEntry* role = aria::GetRoleMap(ancestor);
-      if (nsAccUtils::HasDefinedARIAToken(ancestor,
-                                          nsGkAtoms::aria_live)) {
+      if (HasDefinedARIAToken(ancestor, nsGkAtoms::aria_live)) {
         ancestor->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_live,
                           live);
       } else if (role) {
         GetLiveAttrValue(role->liveAttRule, live);
       }
       if (!live.IsEmpty()) {
         SetAccAttr(aAttributes, nsGkAtoms::containerLive, live);
         if (role) {
-          nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::containerLiveRole,
-                                 role->ARIARoleString());
+          SetAccAttr(aAttributes, nsGkAtoms::containerLiveRole,
+                     role->ARIARoleString());
         }
       }
     }
 
     // container-atomic attribute
     if (atomic.IsEmpty() &&
-        nsAccUtils::HasDefinedARIAToken(ancestor, nsGkAtoms::aria_atomic) &&
+        HasDefinedARIAToken(ancestor, nsGkAtoms::aria_atomic) &&
         ancestor->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_atomic, atomic))
       SetAccAttr(aAttributes, nsGkAtoms::containerAtomic, atomic);
 
     // container-busy attribute
     if (busy.IsEmpty() &&
-        nsAccUtils::HasDefinedARIAToken(ancestor, nsGkAtoms::aria_busy) &&
+        HasDefinedARIAToken(ancestor, nsGkAtoms::aria_busy) &&
         ancestor->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_busy, busy))
       SetAccAttr(aAttributes, nsGkAtoms::containerBusy, busy);
 
     if (ancestor == aTopContent)
       break;
 
     ancestor = ancestor->GetParent();
     if (!ancestor)
@@ -193,17 +192,17 @@ nsAccUtils::HasDefinedARIAToken(nsIConte
         return false;
   }
   return true;
 }
 
 nsIAtom*
 nsAccUtils::GetARIAToken(dom::Element* aElement, nsIAtom* aAttr)
 {
-  if (!nsAccUtils::HasDefinedARIAToken(aElement, aAttr))
+  if (!HasDefinedARIAToken(aElement, aAttr))
     return nsGkAtoms::_empty;
 
   static nsIContent::AttrValuesArray tokens[] =
     { &nsGkAtoms::_false, &nsGkAtoms::_true,
       &nsGkAtoms::mixed, nullptr};
 
   int32_t idx = aElement->FindAttrValueIn(kNameSpaceID_None,
                                           aAttr, tokens, eCaseMatters);
@@ -235,17 +234,17 @@ nsAccUtils::GetSelectableContainer(Acces
   if (!aAccessible)
     return nullptr;
 
   if (!(aState & states::SELECTABLE))
     return nullptr;
 
   Accessible* parent = aAccessible;
   while ((parent = parent->Parent()) && !parent->IsSelect()) {
-    if (Role(parent) == nsIAccessibleRole::ROLE_PANE)
+    if (parent->Role() == roles::PANE)
       return nullptr;
   }
   return parent;
 }
 
 bool
 nsAccUtils::IsARIASelected(Accessible* aAccessible)
 {
--- a/accessible/src/base/nsAccUtils.h
+++ b/accessible/src/base/nsAccUtils.h
@@ -1,18 +1,17 @@
 /* -*- 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 nsAccUtils_h_
 #define nsAccUtils_h_
 
-#include "nsIAccessible.h"
-#include "nsIAccessibleRole.h"
+#include "mozilla/a11y/Accessible.h"
 #include "nsIAccessibleText.h"
 
 #include "nsAccessibilityService.h"
 #include "nsCoreUtils.h"
 
 #include "mozilla/dom/Element.h"
 #include "nsIDocShell.h"
 #include "nsIPersistentProperties2.h"
@@ -188,28 +187,16 @@ public:
   /**
    * Returns coordinates relative screen for the parent of the given accessible.
    *
    * @param [in] aAccessible  the accessible
    */
   static nsIntPoint GetScreenCoordsForParent(Accessible* aAccessible);
 
   /**
-   * Return the role of the given accessible.
-   */
-  static uint32_t Role(nsIAccessible *aAcc)
-  {
-    uint32_t role = nsIAccessibleRole::ROLE_NOTHING;
-    if (aAcc)
-      aAcc->GetRole(&role);
-
-    return role;
-  }
-
-  /**
    * Get the ARIA attribute characteristics for a given ARIA attribute.
    * 
    * @param aAtom  ARIA attribute
    * @return       A bitflag representing the attribute characteristics
    *               (see nsARIAMap.h for possible bit masks, prefixed "ARIA_")
    */
   static uint8_t GetAttributeCharacteristics(nsIAtom* aAtom);
 
@@ -235,22 +222,22 @@ public:
   /**
    * Return text length of the given accessible, return 0 on failure.
    */
   static uint32_t TextLength(Accessible* aAccessible);
 
   /**
    * Return true if the given accessible is embedded object.
    */
-  static bool IsEmbeddedObject(nsIAccessible *aAcc)
+  static bool IsEmbeddedObject(Accessible* aAcc)
   {
-    uint32_t role = Role(aAcc);
-    return role != nsIAccessibleRole::ROLE_TEXT_LEAF &&
-           role != nsIAccessibleRole::ROLE_WHITESPACE &&
-           role != nsIAccessibleRole::ROLE_STATICTEXT;
+    uint32_t role = aAcc->Role();
+    return role != roles::TEXT_LEAF &&
+           role != roles::WHITESPACE &&
+           role != roles::STATICTEXT;
   }
 
   /**
    * Transform nsIAccessibleStates constants to internal state constant.
    */
   static inline uint64_t To64State(uint32_t aState1, uint32_t aState2)
   {
     return static_cast<uint64_t>(aState1) +
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -32,16 +32,17 @@
 #include "Statistics.h"
 #include "TextLeafAccessibleWrap.h"
 
 #ifdef MOZ_ACCESSIBILITY_ATK
 #include "AtkSocketAccessible.h"
 #endif
 
 #ifdef XP_WIN
+#include "mozilla/a11y/Compatibility.h"
 #include "HTMLWin32ObjectAccessible.h"
 #endif
 
 #ifdef A11Y_LOG
 #include "Logging.h"
 #endif
 
 #ifdef MOZ_CRASHREPORTER
@@ -52,19 +53,23 @@
 #include "nsIDOMHTMLObjectElement.h"
 #include "nsIDOMXULElement.h"
 #include "nsImageFrame.h"
 #include "nsIObserverService.h"
 #include "nsLayoutUtils.h"
 #include "nsNPAPIPluginInstance.h"
 #include "nsObjectFrame.h"
 #include "nsSVGPathGeometryFrame.h"
+#include "nsTreeBodyFrame.h"
+#include "nsTreeColumns.h"
+#include "nsTreeUtils.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
+#include "mozilla/StaticPtr.h"
 #include "mozilla/Util.h"
 #include "nsDeckFrame.h"
 
 #ifdef MOZ_XUL
 #include "XULAlertAccessible.h"
 #include "XULColorPickerAccessible.h"
 #include "XULComboboxAccessible.h"
 #include "XULElementAccessibles.h"
@@ -202,31 +207,87 @@ nsAccessibilityService::GetRootDocumentA
       }
 
       return aCanCreate ? GetDocAccessible(ps) : ps->GetDocAccessible();
     }
   }
   return nullptr;
 }
 
+#ifdef XP_WIN
+static StaticAutoPtr<nsTArray<nsCOMPtr<nsIContent> > > sPendingPlugins;
+static StaticAutoPtr<nsTArray<nsCOMPtr<nsITimer> > > sPluginTimers;
+
+class PluginTimerCallBack MOZ_FINAL : public nsITimerCallback
+{
+public:
+  PluginTimerCallBack(nsIContent* aContent) : mContent(aContent) {}
+
+  NS_DECL_ISUPPORTS
+
+  NS_IMETHODIMP Notify(nsITimer* aTimer) MOZ_FINAL
+  {
+    nsIPresShell* ps = mContent->OwnerDoc()->GetShell();
+    if (ps) {
+      DocAccessible* doc = ps->GetDocAccessible();
+      if (doc) {
+        // Make sure that if we created an accessible for the plugin that wasn't
+        // a plugin accessible we remove it before creating the right accessible.
+        doc->RecreateAccessible(mContent);
+        sPluginTimers->RemoveElement(aTimer);
+        return NS_OK;
+      }
+    }
+
+    // We couldn't get a doc accessible so presumably the document went away.
+    // In this case don't leak our ref to the content or timer.
+    sPendingPlugins->RemoveElement(mContent);
+    sPluginTimers->RemoveElement(aTimer);
+    return NS_OK;
+  }
+
+private:
+  nsCOMPtr<nsIContent> mContent;
+};
+
+NS_IMPL_ISUPPORTS1(PluginTimerCallBack, nsITimerCallback)
+#endif
+
 already_AddRefed<Accessible>
 nsAccessibilityService::CreatePluginAccessible(nsObjectFrame* aFrame,
                                                nsIContent* aContent,
                                                Accessible* aContext)
 {
   // nsObjectFrame means a plugin, so we need to use the accessibility support
   // of the plugin.
   if (aFrame->GetRect().IsEmpty())
     return nullptr;
 
 #if defined(XP_WIN) || defined(MOZ_ACCESSIBILITY_ATK)
   nsRefPtr<nsNPAPIPluginInstance> pluginInstance;
   if (NS_SUCCEEDED(aFrame->GetPluginInstance(getter_AddRefs(pluginInstance))) &&
       pluginInstance) {
 #ifdef XP_WIN
+    if (!sPendingPlugins->Contains(aContent) &&
+        (Preferences::GetBool("accessibility.delay_plugins") ||
+         Compatibility::IsJAWS() || Compatibility::IsWE())) {
+      nsCOMPtr<nsITimer> timer = do_CreateInstance(NS_TIMER_CONTRACTID);
+      nsRefPtr<PluginTimerCallBack> cb = new PluginTimerCallBack(aContent);
+      timer->InitWithCallback(cb, Preferences::GetUint("accessibility.delay_plugin_time"),
+                              nsITimer::TYPE_ONE_SHOT);
+      sPluginTimers->AppendElement(timer);
+      sPendingPlugins->AppendElement(aContent);
+      return nullptr;
+    }
+
+    // We need to remove aContent from the pending plugins here to avoid
+    // reentrancy.  When the timer fires it calls
+    // DocAccessible::ContentInserted() which does the work async.
+    sPendingPlugins->RemoveElement(aContent);
+
     // Note: pluginPort will be null if windowless.
     HWND pluginPort = nullptr;
     aFrame->GetPluginPort(&pluginPort);
 
     Accessible* accessible =
       new HTMLWin32ObjectOwnerAccessible(aContent, aContext->Document(),
                                          pluginPort);
     NS_ADDREF(accessible);
@@ -996,16 +1057,21 @@ nsAccessibilityService::Init()
   NS_ADDREF(gApplicationAccessible); // will release in Shutdown()
 
 #ifdef MOZ_CRASHREPORTER
   CrashReporter::
     AnnotateCrashReport(NS_LITERAL_CSTRING("Accessibility"),
                         NS_LITERAL_CSTRING("Active"));
 #endif
 
+#ifdef XP_WIN
+  sPendingPlugins = new nsTArray<nsCOMPtr<nsIContent> >;
+  sPluginTimers = new nsTArray<nsCOMPtr<nsITimer> >;
+#endif
+
   gIsShutdown = false;
 
   // Now its safe to start platform accessibility.
   PlatformInit();
 
   return true;
 }
 
@@ -1022,16 +1088,26 @@ nsAccessibilityService::Shutdown()
     observerService->NotifyObservers(nullptr, "a11y-init-or-shutdown", kShutdownIndicator);
   }
 
   // Stop accessible document loader.
   DocManager::Shutdown();
 
   SelectionManager::Shutdown();
 
+#ifdef XP_WIN
+  sPendingPlugins = nullptr;
+
+  uint32_t timerCount = sPluginTimers->Length();
+  for (uint32_t i = 0; i < timerCount; i++)
+    sPluginTimers->ElementAt(i)->Cancel();
+
+  sPluginTimers = nullptr;
+#endif
+
   // Application is going to be closed, shutdown accessibility and mark
   // accessibility service as shutdown to prevent calls of its methods.
   // Don't null accessibility service static member at this point to be safe
   // if someone will try to operate with it.
 
   NS_ASSERTION(!gIsShutdown, "Accessibility was shutdown already");
 
   gIsShutdown = true;
@@ -1567,37 +1643,38 @@ NS_GetAccessibilityService(nsIAccessibil
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessibilityService private (DON'T put methods here)
 
 #ifdef MOZ_XUL
 already_AddRefed<Accessible>
 nsAccessibilityService::CreateAccessibleForXULTree(nsIContent* aContent,
                                                    DocAccessible* aDoc)
 {
-  nsCOMPtr<nsITreeBoxObject> treeBoxObj = nsCoreUtils::GetTreeBoxObject(aContent);
-  if (!treeBoxObj)
+  nsIContent* child = nsTreeUtils::GetDescendantChild(aContent,
+                                                      nsGkAtoms::treechildren);
+  if (!child)
     return nullptr;
 
-  nsCOMPtr<nsITreeColumns> treeColumns;
-  treeBoxObj->GetColumns(getter_AddRefs(treeColumns));
-  if (!treeColumns)
+  nsTreeBodyFrame* treeFrame = do_QueryFrame(child->GetPrimaryFrame());
+  if (!treeFrame)
     return nullptr;
 
+  nsRefPtr<nsTreeColumns> treeCols = treeFrame->Columns();
   int32_t count = 0;
-  treeColumns->GetCount(&count);
+  treeCols->GetCount(&count);
 
   // Outline of list accessible.
   if (count == 1) {
-    Accessible* accessible = new XULTreeAccessible(aContent, aDoc);
+    Accessible* accessible = new XULTreeAccessible(aContent, aDoc, treeFrame);
     NS_ADDREF(accessible);
     return accessible;
   }
 
   // Table or tree table accessible.
-  Accessible* accessible = new XULTreeGridAccessibleWrap(aContent, aDoc);
+  Accessible* accessible = new XULTreeGridAccessibleWrap(aContent, aDoc, treeFrame);
   NS_ADDREF(accessible);
   return accessible;
 }
 #endif
 
 ////////////////////////////////////////////////////////////////////////////////
 // Services
 ////////////////////////////////////////////////////////////////////////////////
--- a/accessible/src/generic/Accessible.cpp
+++ b/accessible/src/generic/Accessible.cpp
@@ -9,16 +9,17 @@
 
 #include "AccCollector.h"
 #include "AccGroupInfo.h"
 #include "AccIterator.h"
 #include "nsAccUtils.h"
 #include "nsAccessibleRelation.h"
 #include "nsAccessibilityService.h"
 #include "nsIAccessibleRelation.h"
+#include "nsIAccessibleRole.h"
 #include "nsEventShell.h"
 #include "nsTextEquivUtils.h"
 #include "Relation.h"
 #include "Role.h"
 #include "RootAccessible.h"
 #include "States.h"
 #include "StyleInfo.h"
 #include "TableAccessible.h"
@@ -837,17 +838,17 @@ Accessible::ChildAtPoint(int32_t aX, int
   if (!foundFrame || !(content = foundFrame->GetContent()))
     return fallbackAnswer;
 
   // Get accessible for the node with the point or the first accessible in
   // the DOM parent chain.
   DocAccessible* contentDocAcc = GetAccService()->
     GetDocAccessible(content->OwnerDoc());
 
-  // contentDocAcc in some circumstances can be NULL. See bug 729861
+  // contentDocAcc in some circumstances can be nullptr. See bug 729861
   NS_ASSERTION(contentDocAcc, "could not get the document accessible");
   if (!contentDocAcc)
     return fallbackAnswer;
 
   Accessible* accessible = contentDocAcc->GetAccessibleOrContainer(content);
   if (!accessible)
     return fallbackAnswer;
 
@@ -2649,17 +2650,18 @@ Accessible::InsertChildAt(uint32_t aInde
     if (!mChildren.AppendElement(aChild))
       return false;
 
   } else {
     if (!mChildren.InsertElementAt(aIndex, aChild))
       return false;
 
     for (uint32_t idx = aIndex + 1; idx < mChildren.Length(); idx++) {
-      NS_ASSERTION(mChildren[idx]->mIndexInParent == idx - 1, "Accessible child index doesn't match");
+      NS_ASSERTION(static_cast<uint32_t>(mChildren[idx]->mIndexInParent) == idx - 1,
+                   "Accessible child index doesn't match");
       mChildren[idx]->mIndexInParent = idx;
     }
 
     mEmbeddedObjCollector = nullptr;
   }
 
   if (!nsAccUtils::IsEmbeddedObject(aChild))
     SetChildrenFlag(eMixedChildren);
@@ -2680,17 +2682,18 @@ Accessible::RemoveChild(Accessible* aChi
   uint32_t index = static_cast<uint32_t>(aChild->mIndexInParent);
   if (index >= mChildren.Length() || mChildren[index] != aChild) {
     NS_ERROR("Child is bound to parent but parent hasn't this child at its index!");
     aChild->UnbindFromParent();
     return false;
   }
 
   for (uint32_t idx = index + 1; idx < mChildren.Length(); idx++) {
-    NS_ASSERTION(mChildren[idx]->mIndexInParent == idx, "Accessible child index doesn't match");
+    NS_ASSERTION(static_cast<uint32_t>(mChildren[idx]->mIndexInParent) == idx,
+                 "Accessible child index doesn't match");
     mChildren[idx]->mIndexInParent = idx - 1;
   }
 
   aChild->UnbindFromParent();
   mChildren.RemoveElementAt(index);
   mEmbeddedObjCollector = nullptr;
 
   return true;
--- a/accessible/src/generic/HyperTextAccessible.cpp
+++ b/accessible/src/generic/HyperTextAccessible.cpp
@@ -1,9 +1,10 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 sw=2 et tw=78: */
 /* 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 "HyperTextAccessible.h"
 
 #include "Accessible-inl.h"
 #include "nsAccessibilityService.h"
@@ -282,17 +283,18 @@ HyperTextAccessible::GetPosAndText(int32
                                           ourContentStart) - ourRenderedStart;
         }
       }
       if (substringEndOffset < 0) {
         // XXX for non-textframe text like list bullets,
         // should go away after list bullet rewrite
         substringEndOffset = nsAccUtils::TextLength(childAcc);
       }
-      if (startOffset < substringEndOffset) {
+      if (startOffset < substringEndOffset ||
+          (startOffset == substringEndOffset && (childIdx == childCount - 1))) {
         // Our start is within this substring
         if (startOffset > 0 || endOffset < substringEndOffset) {
           // We don't want the whole string for this accessible
           // Get out the continuing text frame with this offset
           int32_t outStartLineUnused;
           int32_t contentOffset;
           if (frame->GetType() == nsGkAtoms::textFrame) {
             contentOffset = iter.ConvertSkippedToOriginal(startOffset) +
@@ -687,43 +689,39 @@ HyperTextAccessible::HypertextOffsetsToD
 
 int32_t
 HyperTextAccessible::GetRelativeOffset(nsIPresShell* aPresShell,
                                        nsIFrame* aFromFrame,
                                        int32_t aFromOffset,
                                        Accessible* aFromAccessible,
                                        nsSelectionAmount aAmount,
                                        nsDirection aDirection,
-                                       bool aNeedsStart)
+                                       bool aNeedsStart,
+                                       EWordMovementType aWordMovementType)
 {
   const bool kIsJumpLinesOk = true;          // okay to jump lines
   const bool kIsScrollViewAStop = false;     // do not stop at scroll views
   const bool kIsKeyboardSelect = true;       // is keyboard selection
   const bool kIsVisualBidi = false;          // use visual order for bidi text
 
-  EWordMovementType wordMovementType = aNeedsStart ? eStartWord : eEndWord;
-  if (aAmount == eSelectLine) {
-    aAmount = (aDirection == eDirNext) ? eSelectEndLine : eSelectBeginLine;
-  }
-
   // Ask layout for the new node and offset, after moving the appropriate amount
 
   nsresult rv;
   int32_t contentOffset = aFromOffset;
   nsIFrame *frame = aFromAccessible->GetFrame();
   NS_ENSURE_TRUE(frame, -1);
 
   if (frame->GetType() == nsGkAtoms::textFrame) {
     rv = RenderedToContentOffset(frame, aFromOffset, &contentOffset);
     NS_ENSURE_SUCCESS(rv, -1);
   }
 
   nsPeekOffsetStruct pos(aAmount, aDirection, contentOffset,
                          0, kIsJumpLinesOk, kIsScrollViewAStop, kIsKeyboardSelect, kIsVisualBidi,
-                         wordMovementType);
+                         aWordMovementType);
   rv = aFromFrame->PeekOffset(&pos);
   if (NS_FAILED(rv)) {
     if (aDirection == eDirPrevious) {
       // Use passed-in frame as starting point in failure case for now,
       // this is a hack to deal with starting on a list bullet frame,
       // which fails in PeekOffset() because the line iterator doesn't see it.
       // XXX Need to look at our overall handling of list bullets, which are an odd case
       pos.mResultContent = aFromFrame->GetContent();
@@ -778,75 +776,91 @@ HyperTextAccessible::GetRelativeOffset(n
     if (!aNeedsStart) {
       -- hyperTextOffset;
     }
   }
 
   return hyperTextOffset;
 }
 
+int32_t
+HyperTextAccessible::FindWordBoundary(int32_t aOffset, nsDirection aDirection,
+                                      EWordMovementType aWordMovementType)
+{
+  // Convert hypertext offset to frame-relative offset.
+  int32_t offsetInFrame = aOffset, notUsedOffset = aOffset;
+  nsRefPtr<Accessible> accAtOffset;
+  nsIFrame* frameAtOffset =
+    GetPosAndText(offsetInFrame, notUsedOffset, nullptr, nullptr,
+                  nullptr, getter_AddRefs(accAtOffset));
+  if (!frameAtOffset) {
+    if (aOffset == CharacterCount()) {
+      // Asking for start of line, while on last character.
+      if (accAtOffset)
+        frameAtOffset = accAtOffset->GetFrame();
+    }
+    NS_ASSERTION(frameAtOffset, "No start frame for text getting!");
+    if (!frameAtOffset)
+      return -1;
+
+    // We're on the last continuation since we're on the last character.
+    frameAtOffset = frameAtOffset->GetLastContinuation();
+  }
+
+  // Return hypertext offset of the boundary of the found word.
+  return GetRelativeOffset(mDoc->PresShell(), frameAtOffset, offsetInFrame,
+                           accAtOffset, eSelectWord, aDirection,
+                           (aWordMovementType == eStartWord),
+                           aWordMovementType);
+}
+
 /*
 Gets the specified text relative to aBoundaryType, which means:
 BOUNDARY_CHAR             The character before/at/after the offset is returned.
 BOUNDARY_WORD_START       From the word start before/at/after the offset to the next word start.
 BOUNDARY_WORD_END         From the word end before/at/after the offset to the next work end.
 BOUNDARY_LINE_START       From the line start before/at/after the offset to the next line start.
 BOUNDARY_LINE_END         From the line end before/at/after the offset to the next line start.
 */
 
 nsresult
-HyperTextAccessible::GetTextHelper(EGetTextType aType, AccessibleTextBoundary aBoundaryType,
-                                   int32_t aOffset, int32_t* aStartOffset, int32_t* aEndOffset,
+HyperTextAccessible::GetTextHelper(EGetTextType aType,
+                                   AccessibleTextBoundary aBoundaryType,
+                                   int32_t aOffset,
+                                   int32_t* aStartOffset, int32_t* aEndOffset,
                                    nsAString& aText)
 {
   aText.Truncate();
 
   NS_ENSURE_ARG_POINTER(aStartOffset);
   NS_ENSURE_ARG_POINTER(aEndOffset);
   *aStartOffset = *aEndOffset = 0;
 
-  if (!mDoc)
-    return NS_ERROR_FAILURE;
-
-  nsIPresShell* presShell = mDoc->PresShell();
-  if (!presShell) {
-    return NS_ERROR_FAILURE;
-  }
+  int32_t offset = ConvertMagicOffset(aOffset);
+  if (offset < 0)
+    return NS_ERROR_INVALID_ARG;
 
-  if (aOffset == nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT) {
-    aOffset = CharacterCount();
-  }
-  if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET) {
-    GetCaretOffset(&aOffset);
-    if (aOffset > 0 && (aBoundaryType == BOUNDARY_LINE_START ||
-                        aBoundaryType == BOUNDARY_LINE_END)) {
-      // It is the same character offset when the caret is visually at the very end of a line
-      // or the start of a new line. Getting text at the line should provide the line with the visual caret,
-      // otherwise screen readers will announce the wrong line as the user presses up or down arrow and land
-      // at the end of a line.
-      nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
-      if (frameSelection &&
-          frameSelection->GetHint() == nsFrameSelection::HINTLEFT) {
-        -- aOffset;  // We are at the start of a line
-      }
+  if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET && offset > 0 &&
+      (aBoundaryType == BOUNDARY_LINE_START ||
+       aBoundaryType == BOUNDARY_LINE_END)) {
+    // It is the same character offset when the caret is visually at
+    // the very end of a line or the start of a new line. Getting text at
+    // the line should provide the line with the visual caret,
+    // otherwise screen readers will announce the wrong line as the user
+    // presses up or down arrow and land at the end of a line.
+    nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
+    if (frameSelection &&
+        frameSelection->GetHint() == nsFrameSelection::HINTLEFT) {
+      -- offset;  // We are at the start of a line
     }
   }
-  else if (aOffset < 0) {
-    return NS_ERROR_FAILURE;
-  }
 
   nsSelectionAmount amount;
   bool needsStart = false;
   switch (aBoundaryType) {
-    case BOUNDARY_CHAR:
-      amount = eSelectCluster;
-      if (aType == eGetAt)
-        aType = eGetAfter; // Avoid returning 2 characters
-      break;
-
     case BOUNDARY_WORD_START:
       needsStart = true;
       amount = eSelectWord;
       break;
 
     case BOUNDARY_WORD_END:
       amount = eSelectWord;
       break;
@@ -863,67 +877,71 @@ HyperTextAccessible::GetTextHelper(EGetT
       // Newlines are considered at the end of a line. Since getting
       // the BOUNDARY_END_START gets the text from the line-end to the next
       //line-end, the newline is included at the beginning of the string.
       amount = eSelectLine;
       break;
 
     case BOUNDARY_ATTRIBUTE_RANGE:
     {
-      nsresult rv = GetTextAttributes(false, aOffset,
+      nsresult rv = GetTextAttributes(false, offset,
                                       aStartOffset, aEndOffset, nullptr);
       NS_ENSURE_SUCCESS(rv, rv);
       
       return GetText(*aStartOffset, *aEndOffset, aText);
     }
 
     default:  // Note, sentence support is deprecated and falls through to here
       return NS_ERROR_INVALID_ARG;
   }
 
-  int32_t startOffset = aOffset + (aBoundaryType == BOUNDARY_LINE_END);  // Avoid getting the previous line
+  int32_t startOffset = offset + (aBoundaryType == BOUNDARY_LINE_END);  // Avoid getting the previous line
   int32_t endOffset = startOffset;
 
   // Convert offsets to frame-relative
   nsRefPtr<Accessible> startAcc;
   nsIFrame *startFrame = GetPosAndText(startOffset, endOffset, nullptr, nullptr,
                                        nullptr, getter_AddRefs(startAcc));
 
   if (!startFrame) {
     int32_t textLength = CharacterCount();
-    if (aBoundaryType == BOUNDARY_LINE_START && aOffset > 0 && aOffset == textLength) {
+    if (aBoundaryType == BOUNDARY_LINE_START && offset > 0 && offset == textLength) {
       // Asking for start of line, while on last character
       if (startAcc)
         startFrame = startAcc->GetFrame();
     }
     if (!startFrame) {
-      return aOffset > textLength ? NS_ERROR_FAILURE : NS_OK;
+      return offset > textLength ? NS_ERROR_FAILURE : NS_OK;
     }
     else {
       // We're on the last continuation since we're on the last character
       startFrame = startFrame->GetLastContinuation();
     }
   }
 
-  int32_t finalStartOffset, finalEndOffset;
+  int32_t finalStartOffset = 0, finalEndOffset = 0;
+  EWordMovementType wordMovementType = needsStart ? eStartWord : eEndWord;
 
+  nsIPresShell* presShell = mDoc->PresShell();
   // If aType == eGetAt we'll change both the start and end offset from
   // the original offset
   if (aType == eGetAfter) {
-    finalStartOffset = aOffset;
+    finalStartOffset = offset;
   }
   else {
     finalStartOffset = GetRelativeOffset(presShell, startFrame, startOffset,
-                                         startAcc, amount, eDirPrevious,
-                                         needsStart);
+                                         startAcc,
+                                         (amount == eSelectLine ? eSelectBeginLine : amount),
+                                         eDirPrevious, needsStart,
+                                         wordMovementType);
     NS_ENSURE_TRUE(finalStartOffset >= 0, NS_ERROR_FAILURE);
   }
 
   if (aType == eGetBefore) {
-    finalEndOffset = aOffset;
+    finalEndOffset = offset;
   }
   else {
     // Start moving forward from the start so that we don't get 
     // 2 words/lines if the offset occurred on whitespace boundary
     // Careful, startOffset and endOffset are passed by reference to GetPosAndText() and changed
     // For BOUNDARY_LINE_END, make sure we start of this line
     startOffset = endOffset = finalStartOffset + (aBoundaryType == BOUNDARY_LINE_END);
     nsRefPtr<Accessible> endAcc;
@@ -938,86 +956,183 @@ HyperTextAccessible::GetTextHelper(EGetT
 
       endFrame = GetPosAndText(startOffset, endOffset, nullptr, nullptr,
                                nullptr, getter_AddRefs(endAcc));
     }
     if (!endFrame) {
       return NS_ERROR_FAILURE;
     }
     finalEndOffset = GetRelativeOffset(presShell, endFrame, endOffset, endAcc,
-                                       amount, eDirNext, needsStart);
+                                       (amount == eSelectLine ? eSelectEndLine : amount),
+                                       eDirNext, needsStart, wordMovementType);
     NS_ENSURE_TRUE(endOffset >= 0, NS_ERROR_FAILURE);
-    if (finalEndOffset == aOffset) {
+    if (finalEndOffset == offset) {
       if (aType == eGetAt && amount == eSelectWord) { 
         // Fix word error for the first character in word: PeekOffset() will return the previous word when 
-        // aOffset points to the first character of the word, but accessibility APIs want the current word 
+        // offset points to the first character of the word, but accessibility APIs want the current word
         // that the first character is in
-        return GetTextHelper(eGetAfter, aBoundaryType, aOffset, aStartOffset, aEndOffset, aText);
+        return GetTextHelper(eGetAfter, aBoundaryType, offset,
+                             aStartOffset, aEndOffset, aText);
       }
       int32_t textLength = CharacterCount();
       if (finalEndOffset < textLength) {
         // This happens sometimes when current character at finalStartOffset 
         // is an embedded object character representing another hypertext, that
         // the AT really needs to dig into separately
         ++ finalEndOffset;
       }
     }
   }
 
   *aStartOffset = finalStartOffset;
   *aEndOffset = finalEndOffset;
 
-  NS_ASSERTION((finalStartOffset < aOffset && finalEndOffset >= aOffset) || aType != eGetBefore, "Incorrect results for GetTextHelper");
-  NS_ASSERTION((finalStartOffset <= aOffset && finalEndOffset > aOffset) || aType == eGetBefore, "Incorrect results for GetTextHelper");
+  NS_ASSERTION((finalStartOffset < offset && finalEndOffset >= offset) || aType != eGetBefore, "Incorrect results for GetTextHelper");
+  NS_ASSERTION((finalStartOffset <= offset && finalEndOffset > offset) || aType == eGetBefore, "Incorrect results for GetTextHelper");
 
   GetPosAndText(finalStartOffset, finalEndOffset, &aText);
   return NS_OK;
 }
 
 /**
   * nsIAccessibleText impl.
   */
 NS_IMETHODIMP
 HyperTextAccessible::GetTextBeforeOffset(int32_t aOffset,
                                          AccessibleTextBoundary aBoundaryType,
                                          int32_t* aStartOffset,
                                          int32_t* aEndOffset, nsAString& aText)
 {
-  if (aBoundaryType == BOUNDARY_CHAR) {
-    GetCharAt(aOffset, eGetBefore, aText, aStartOffset, aEndOffset);
-    return NS_OK;
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  int32_t offset = ConvertMagicOffset(aOffset);
+  if (offset < 0)
+    return NS_ERROR_INVALID_ARG;
+
+  switch (aBoundaryType) {
+    case BOUNDARY_CHAR:
+      GetCharAt(offset, eGetBefore, aText, aStartOffset, aEndOffset);
+      return NS_OK;
+
+    case BOUNDARY_WORD_START: {
+      if (offset == 0) { // no word before 0 offset
+        *aStartOffset = *aEndOffset = 0;
+        return NS_OK;
+      }
+
+      // If the offset is a word start then move backward to find start offset
+      // (end offset is the given offset). Otherwise move backward twice to find
+      // both start and end offsets.
+      int32_t midOffset = FindWordBoundary(offset, eDirPrevious, eStartWord);
+      *aEndOffset = FindWordBoundary(midOffset, eDirNext, eStartWord);
+      if (*aEndOffset == offset) {
+        *aStartOffset = midOffset;
+        return GetText(*aStartOffset, *aEndOffset, aText);
+      }
+
+      *aStartOffset = FindWordBoundary(midOffset, eDirPrevious, eStartWord);
+      *aEndOffset = midOffset;
+      return GetText(*aStartOffset, *aEndOffset, aText);
+    }
+
+    case BOUNDARY_WORD_END: {
+      if (offset == 0) { // no word before 0 offset
+        *aStartOffset = *aEndOffset = 0;
+        return NS_OK;
+      }
+
+      // Move word backward twice to find start and end offsets.
+      *aEndOffset = FindWordBoundary(offset, eDirPrevious, eEndWord);
+      *aStartOffset = FindWordBoundary(*aEndOffset, eDirPrevious, eEndWord);
+      return GetText(*aStartOffset, *aEndOffset, aText);
+    }
+
+    case BOUNDARY_LINE_START:
+    case BOUNDARY_LINE_END:
+    case BOUNDARY_ATTRIBUTE_RANGE:
+      return GetTextHelper(eGetBefore, aBoundaryType, aOffset,
+                           aStartOffset, aEndOffset, aText);
+
+    default:
+      return NS_ERROR_INVALID_ARG;
   }
-
-  return GetTextHelper(eGetBefore, aBoundaryType, aOffset, aStartOffset, aEndOffset, aText);
 }
 
 NS_IMETHODIMP
 HyperTextAccessible::GetTextAtOffset(int32_t aOffset,
                                      AccessibleTextBoundary aBoundaryType,
                                      int32_t* aStartOffset,
                                      int32_t* aEndOffset, nsAString& aText)
 {
-  if (aBoundaryType == BOUNDARY_CHAR) {
-    GetCharAt(aOffset, eGetAt, aText, aStartOffset, aEndOffset);
-    return NS_OK;
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  int32_t offset = ConvertMagicOffset(aOffset);
+  if (offset < 0)
+    return NS_ERROR_INVALID_ARG;
+
+  EWordMovementType wordMovementType = eDefaultBehavior;
+  bool moveForwardThenBack = true;
+
+  switch (aBoundaryType) {
+    case BOUNDARY_CHAR:
+      return GetCharAt(aOffset, eGetAt, aText, aStartOffset, aEndOffset) ?
+        NS_OK : NS_ERROR_INVALID_ARG;
+
+    case BOUNDARY_WORD_START: {
+      uint32_t textLen =  CharacterCount();
+      if (offset == textLen) {
+        *aStartOffset = *aEndOffset = textLen;
+        return NS_OK;
+      }
+
+      *aEndOffset = FindWordBoundary(offset, eDirNext, eStartWord);
+      *aStartOffset = FindWordBoundary(*aEndOffset, eDirPrevious, eStartWord);
+      return GetText(*aStartOffset, *aEndOffset, aText);
+    }
+
+    case BOUNDARY_WORD_END: {
+      if (offset == 0) {
+        *aStartOffset = *aEndOffset = 0;
+        return NS_OK;
+      }
+
+      *aStartOffset = FindWordBoundary(offset, eDirPrevious, eEndWord);
+      *aEndOffset = FindWordBoundary(*aStartOffset, eDirNext, eEndWord);
+      return GetText(*aStartOffset, *aEndOffset, aText);
+    }
+
+    case BOUNDARY_LINE_START:
+    case BOUNDARY_LINE_END:
+    case BOUNDARY_ATTRIBUTE_RANGE:
+      return GetTextHelper(eGetAt, aBoundaryType, aOffset,
+                           aStartOffset, aEndOffset, aText);
+
+    default:
+      return NS_ERROR_INVALID_ARG;
   }
-
-  return GetTextHelper(eGetAt, aBoundaryType, aOffset, aStartOffset, aEndOffset, aText);
 }
 
 NS_IMETHODIMP
-HyperTextAccessible::GetTextAfterOffset(int32_t aOffset, AccessibleTextBoundary aBoundaryType,
-                                        int32_t* aStartOffset, int32_t* aEndOffset, nsAString& aText)
+HyperTextAccessible::GetTextAfterOffset(int32_t aOffset,
+                                        AccessibleTextBoundary aBoundaryType,
+                                        int32_t* aStartOffset,
+                                        int32_t* aEndOffset, nsAString& aText)
 {
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
   if (aBoundaryType == BOUNDARY_CHAR) {
     GetCharAt(aOffset, eGetAfter, aText, aStartOffset, aEndOffset);
     return NS_OK;
   }
 
-  return GetTextHelper(eGetAfter, aBoundaryType, aOffset, aStartOffset, aEndOffset, aText);
+  return GetTextHelper(eGetAfter, aBoundaryType, aOffset,
+                       aStartOffset, aEndOffset, aText);
 }
 
 // nsIPersistentProperties
 // nsIAccessibleText::getTextAttributes(in boolean includeDefAttrs,
 //                                      in long offset,
 //                                      out long rangeStartOffset,
 //                                      out long rangeEndOffset);
 NS_IMETHODIMP
@@ -1161,37 +1276,58 @@ HyperTextAccessible::NativeAttributes()
       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)
+  // make AT navigation schemes "just work".
+  nsIAtom* tag = mContent->Tag();
+  if (tag == nsGkAtoms::nav) {
     nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
                            NS_LITERAL_STRING("navigation"));
-  else if (mContent->Tag() == nsGkAtoms::section) 
+  } else if (tag == nsGkAtoms::section)  {
     nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
                            NS_LITERAL_STRING("region"));
-  else if (mContent->Tag() == nsGkAtoms::footer) 
+  } else if (tag == nsGkAtoms::header || tag == nsGkAtoms::footer) {
+    // Only map header and footer if they are not descendants
+    // of an article or section tag.
+    nsIContent* parent = mContent->GetParent();
+    while (parent) {
+      if (parent->Tag() == nsGkAtoms::article ||
+          parent->Tag() == nsGkAtoms::section)
+        break;
+      parent = parent->GetParent();
+    }
+
+    // No article or section elements found.
+    if (!parent) {
+      if (tag == nsGkAtoms::header) {
+        nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
+                               NS_LITERAL_STRING("banner"));
+      } else if (tag == nsGkAtoms::footer) {
+        nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
+                               NS_LITERAL_STRING("contentinfo"));
+      }
+    }
+  } else if (tag == nsGkAtoms::footer) {
     nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
                            NS_LITERAL_STRING("contentinfo"));
-  else if (mContent->Tag() == nsGkAtoms::aside) 
+  } else if (tag == nsGkAtoms::aside) {
     nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
                            NS_LITERAL_STRING("complementary"));
-  else if (mContent->Tag() == nsGkAtoms::article)
+  } else if (tag == nsGkAtoms::article) {
     nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
                            NS_LITERAL_STRING("article"));
-  else if (mContent->Tag() == nsGkAtoms::main)
+  } else if (tag == nsGkAtoms::main) {
     nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles,
                            NS_LITERAL_STRING("main"));
+  }
 
   return attributes.forget();
 }
 
 /*
  * Given an offset, the x, y, width, and height values are filled appropriately.
  */
 NS_IMETHODIMP
--- a/accessible/src/generic/HyperTextAccessible.h
+++ b/accessible/src/generic/HyperTextAccessible.h
@@ -258,16 +258,22 @@ protected:
       int32_t caretOffset = -1;
       GetCaretOffset(&caretOffset);
       return caretOffset;
     }
 
     return aOffset;
   }
 
+  /**
+   * Return an offset of the found word boundary.
+   */
+  int32_t FindWordBoundary(int32_t aOffset, nsDirection aDirection,
+                           EWordMovementType aWordMovementType);
+
   /*
    * This does the work for nsIAccessibleText::GetText[At|Before|After]Offset
    * @param aType, eGetBefore, eGetAt, eGetAfter
    * @param aBoundaryType, char/word-start/word-end/line-start/line-end/paragraph/attribute
    * @param aOffset, offset into the hypertext to start from
    * @param *aStartOffset, the resulting start offset for the returned substring
    * @param *aEndOffset, the resulting end offset for the returned substring
    * @param aText, the resulting substring
@@ -289,17 +295,18 @@ protected:
     * @param  aDirection       forward or backward?
     * @param  aNeedsStart      for word and line cases, are we basing this on
     *                          the start or end?
     * @return                  the resulting offset into this hypertext
     */
   int32_t GetRelativeOffset(nsIPresShell *aPresShell, nsIFrame *aFromFrame,
                             int32_t aFromOffset, Accessible* aFromAccessible,
                             nsSelectionAmount aAmount, nsDirection aDirection,
-                            bool aNeedsStart);
+                            bool aNeedsStart,
+                            EWordMovementType aWordMovementType);
 
   /**
     * Provides information for substring that is defined by the given start
     * and end offsets for this hyper text.
     *
     * @param  aStartOffset  [inout] the start offset into the hyper text. This
     *                       is also an out parameter used to return the offset
     *                       into the start frame's rendered text content
--- a/accessible/src/generic/RootAccessible.cpp
+++ b/accessible/src/generic/RootAccessible.cpp
@@ -160,19 +160,19 @@ const char* const kEventTypes[] = {
   "select",
   // Fired when value changes immediately, wether or not focused changed.
   "ValueChange",
   "AlertActive",
   "TreeRowCountChanged",
   "TreeInvalidated",
   // add ourself as a OpenStateChange listener (custom event fired in tree.xml)
   "OpenStateChange",
-  // add ourself as a CheckboxStateChange listener (custom event fired in nsHTMLInputElement.cpp)
+  // add ourself as a CheckboxStateChange listener (custom event fired in HTMLInputElement.cpp)
   "CheckboxStateChange",
-  // add ourself as a RadioStateChange Listener ( custom event fired in in nsHTMLInputElement.cpp  & radio.xml)
+  // add ourself as a RadioStateChange Listener ( custom event fired in in HTMLInputElement.cpp  & radio.xml)
   "RadioStateChange",
   "popupshown",
   "popuphiding",
   "DOMMenuInactive",
   "DOMMenuItemActive",
   "DOMMenuItemInactive",
   "DOMMenuBarActive",
   "DOMMenuBarInactive"
--- a/accessible/src/generic/moz.build
+++ b/accessible/src/generic/moz.build
@@ -1,7 +1,8 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'accessibility'
 
--- a/accessible/src/html/HTMLFormControlAccessible.cpp
+++ b/accessible/src/html/HTMLFormControlAccessible.cpp
@@ -10,33 +10,34 @@
 #include "nsARIAMap.h"
 #include "nsEventShell.h"
 #include "nsTextEquivUtils.h"
 #include "Relation.h"
 #include "Role.h"
 #include "States.h"
 
 #include "nsContentList.h"
-#include "nsHTMLInputElement.h"
+#include "mozilla/dom/HTMLInputElement.h"
 #include "nsIAccessibleRelation.h"
 #include "nsIDOMNSEditableElement.h"
 #include "nsIDOMHTMLTextAreaElement.h"
 #include "nsIEditor.h"
 #include "nsIFormControl.h"
 #include "nsIFrame.h"
 #include "nsINameSpaceManager.h"
 #include "nsISelectionController.h"
 #include "jsapi.h"
 #include "nsIJSContextStack.h"
 #include "nsIServiceManager.h"
 #include "nsITextControlFrame.h"
 
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
+using namespace mozilla::dom;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLCheckboxAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 HTMLCheckboxAccessible::
   HTMLCheckboxAccessible(nsIContent* aContent, DocAccessible* aDoc) :
@@ -86,17 +87,17 @@ HTMLCheckboxAccessible::DoAction(uint8_t
 }
 
 uint64_t
 HTMLCheckboxAccessible::NativeState()
 {
   uint64_t state = LeafAccessible::NativeState();
 
   state |= states::CHECKABLE;
-  nsHTMLInputElement* input = nsHTMLInputElement::FromContent(mContent);
+  HTMLInputElement* input = HTMLInputElement::FromContent(mContent);
   if (!input)
     return state;
 
   if (input->Indeterminate())
     return state | states::MIXED;
 
   if (input->Checked())
     return state | states::CHECKED;
@@ -126,17 +127,17 @@ HTMLRadioButtonAccessible::
 
 uint64_t
 HTMLRadioButtonAccessible::NativeState()
 {
   uint64_t state = AccessibleWrap::NativeState();
 
   state |= states::CHECKABLE;
 
-  nsHTMLInputElement* input = nsHTMLInputElement::FromContent(mContent);
+  HTMLInputElement* input = HTMLInputElement::FromContent(mContent);
   if (input && input->Checked())
     state |= states::CHECKED;
 
   return state;
 }
 
 void
 HTMLRadioButtonAccessible::GetPositionAndSizeInternal(int32_t* aPosInSet,
@@ -351,65 +352,46 @@ HTMLTextFieldAccessible::Value(nsString&
     return;
 
   nsCOMPtr<nsIDOMHTMLTextAreaElement> textArea(do_QueryInterface(mContent));
   if (textArea) {
     textArea->GetValue(aValue);
     return;
   }
 
-  nsHTMLInputElement* input = nsHTMLInputElement::FromContent(mContent);
+  HTMLInputElement* input = HTMLInputElement::FromContent(mContent);
   if (input)
     input->GetValue(aValue);
 }
 
 void
 HTMLTextFieldAccessible::ApplyARIAState(uint64_t* aState) const
 {
   HyperTextAccessibleWrap::ApplyARIAState(aState);
 
   aria::MapToState(aria::eARIAAutoComplete, mContent->AsElement(), aState);
 }
 
 uint64_t
-HTMLTextFieldAccessible::State()
-{
-  uint64_t state = HyperTextAccessibleWrap::State();
-  if (state & states::DEFUNCT)
-    return state;
-
-  // Inherit states from input@type="file" suitable for the button. Note,
-  // no special processing for unavailable state since inheritance is supplied
-  // by other code paths.
-  if (mParent && mParent->IsHTMLFileInput()) {
-    uint64_t parentState = mParent->State();
-    state |= parentState & (states::BUSY | states::REQUIRED |
-      states::HASPOPUP | states::INVALID);
-  }
-
-  return state;
-}
-
-uint64_t
 HTMLTextFieldAccessible::NativeState()
 {
   uint64_t state = HyperTextAccessibleWrap::NativeState();
 
   // can be focusable, focused, protected. readonly, unavailable, selected
   if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
                             nsGkAtoms::password, eIgnoreCase)) {
     state |= states::PROTECTED;
   }
 
   if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::readonly)) {
     state |= states::READONLY;
   }
 
   // Is it an <input> or a <textarea> ?
-  nsHTMLInputElement* input = nsHTMLInputElement::FromContent(mContent);
+  HTMLInputElement* input = HTMLInputElement::FromContent(mContent);
   state |= input && input->IsSingleLineTextControl() ?
     states::SINGLE_LINE : states::MULTI_LINE;
 
   if (!(state & states::EDITABLE) ||
       (state & (states::PROTECTED | states::MULTI_LINE)))
     return state;
 
   // Expose autocomplete states if this input is part of autocomplete widget.
@@ -465,17 +447,17 @@ HTMLTextFieldAccessible::GetActionName(u
   }
   return NS_ERROR_INVALID_ARG;
 }
 
 NS_IMETHODIMP
 HTMLTextFieldAccessible::DoAction(uint8_t aIndex)
 {
   if (aIndex == 0) {
-    nsHTMLInputElement* element = nsHTMLInputElement::FromContent(mContent);
+    HTMLInputElement* element = HTMLInputElement::FromContent(mContent);
     if (element)
       return element->Focus();
 
     return NS_ERROR_FAILURE;
   }
   return NS_ERROR_INVALID_ARG;
 }
 
@@ -550,34 +532,27 @@ HTMLFileInputAccessible::HandleAccEvent(
   // unavailable state is not redirected. That's a standard for unavailable
   // state handling.
   AccStateChangeEvent* event = downcast_accEvent(aEvent);
   if (event &&
       (event->GetState() == states::BUSY ||
        event->GetState() == states::REQUIRED ||
        event->GetState() == states::HASPOPUP ||
        event->GetState() == states::INVALID)) {
-    Accessible* input = GetChildAt(0);
-    if (input && input->Role() == roles::ENTRY) {
-      nsRefPtr<AccStateChangeEvent> childEvent =
-        new AccStateChangeEvent(input, event->GetState(),
-                                event->IsStateEnabled(),
-                                (event->IsFromUserInput() ? eFromUserInput : eNoUserInput));
-      nsEventShell::FireEvent(childEvent);
-    }
-
-    Accessible* button = GetChildAt(1);
+    Accessible* button = GetChildAt(0);
     if (button && button->Role() == roles::PUSHBUTTON) {
       nsRefPtr<AccStateChangeEvent> childEvent =
         new AccStateChangeEvent(button, event->GetState(),
                                 event->IsStateEnabled(),
-                                (event->IsFromUserInput() ? eFromUserInput : eNoUserInput));
+                                (event->IsFromUserInput() ? eFromUserInput
+                                                          : eNoUserInput));
       nsEventShell::FireEvent(childEvent);
     }
   }
+
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLGroupboxAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 HTMLGroupboxAccessible::
--- a/accessible/src/html/HTMLFormControlAccessible.h
+++ b/accessible/src/html/HTMLFormControlAccessible.h
@@ -112,17 +112,16 @@ public:
 
   // HyperTextAccessible
   virtual already_AddRefed<nsIEditor> GetEditor() const;
 
   // Accessible
   virtual void Value(nsString& aValue);
   virtual void ApplyARIAState(uint64_t* aState) const;
   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;
--- a/accessible/src/html/moz.build
+++ b/accessible/src/html/moz.build
@@ -1,7 +1,8 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'accessibility'
 
--- a/accessible/src/jsat/moz.build
+++ b/accessible/src/jsat/moz.build
@@ -1,7 +1,8 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'alerts'
 
--- a/accessible/src/mac/moz.build
+++ b/accessible/src/mac/moz.build
@@ -1,7 +1,8 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'accessibility'
 
--- a/accessible/src/moz.build
+++ b/accessible/src/moz.build
@@ -1,8 +1,9 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 toolkit = CONFIG['MOZ_WIDGET_TOOLKIT']
 
 if toolkit == 'gtk2':
--- a/accessible/src/other/moz.build
+++ b/accessible/src/other/moz.build
@@ -1,7 +1,8 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'accessibility'
 
--- a/accessible/src/windows/ia2/ia2AccessibleAction.cpp
+++ b/accessible/src/windows/ia2/ia2AccessibleAction.cpp
@@ -13,17 +13,17 @@
 
 using namespace mozilla::a11y;
 
 // IUnknown
 
 STDMETHODIMP
 ia2AccessibleAction::QueryInterface(REFIID iid, void** ppv)
 {
-  *ppv = NULL;
+  *ppv = nullptr;
 
   if (IID_IAccessibleAction == iid) {
     *ppv = static_cast<IAccessibleAction*>(this);
     (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
     return S_OK;
   }
 
   return E_NOINTERFACE;
@@ -67,17 +67,17 @@ ia2AccessibleAction::doAction(long aActi
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleAction::get_description(long aActionIndex, BSTR *aDescription)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aDescription = NULL;
+  *aDescription = nullptr;
 
   AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
   if (acc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsAutoString description;
   uint8_t index = static_cast<uint8_t>(aActionIndex);
   nsresult rv = acc->GetActionDescription(index, description);
@@ -98,17 +98,17 @@ STDMETHODIMP
 ia2AccessibleAction::get_keyBinding(long aActionIndex, long aNumMaxBinding,
                                   BSTR **aKeyBinding,
                                   long *aNumBinding)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aKeyBinding)
     return E_INVALIDARG;
-  *aKeyBinding = NULL;
+  *aKeyBinding = nullptr;
 
   if (!aNumBinding)
     return E_INVALIDARG;
   *aNumBinding = 0;
 
   if (aActionIndex != 0 || aNumMaxBinding < 1)
     return E_INVALIDARG;
 
@@ -144,17 +144,17 @@ ia2AccessibleAction::get_keyBinding(long
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleAction::get_name(long aActionIndex, BSTR *aName)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aName = NULL;
+  *aName = nullptr;
 
   AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
   if (acc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsAutoString name;
   uint8_t index = static_cast<uint8_t>(aActionIndex);
   nsresult rv = acc->GetActionName(index, name);
@@ -170,14 +170,14 @@ ia2AccessibleAction::get_name(long aActi
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleAction::get_localizedName(long aActionIndex, BSTR *aLocalizedName)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aLocalizedName = NULL;
+  *aLocalizedName = nullptr;
   return E_NOTIMPL;
 
   A11Y_TRYBLOCK_END
 }
 
--- a/accessible/src/windows/ia2/ia2AccessibleComponent.cpp
+++ b/accessible/src/windows/ia2/ia2AccessibleComponent.cpp
@@ -16,17 +16,17 @@
 
 using namespace mozilla::a11y;
 
 // IUnknown
 
 STDMETHODIMP
 ia2AccessibleComponent::QueryInterface(REFIID iid, void** ppv)
 {
-  *ppv = NULL;
+  *ppv = nullptr;
 
   if (IID_IAccessibleComponent == iid) {
     *ppv = static_cast<IAccessibleComponent*>(this);
     (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
     return S_OK;
   }
 
   return E_NOINTERFACE;
--- a/accessible/src/windows/ia2/ia2AccessibleHyperlink.cpp
+++ b/accessible/src/windows/ia2/ia2AccessibleHyperlink.cpp
@@ -13,17 +13,17 @@
 
 using namespace mozilla::a11y;
 
 // IUnknown
 
 STDMETHODIMP
 ia2AccessibleHyperlink::QueryInterface(REFIID iid, void** ppv)
 {
-  *ppv = NULL;
+  *ppv = nullptr;
 
   if (IID_IAccessibleHyperlink == iid) {
     if (!static_cast<AccessibleWrap*>(this)->IsLink())
       return E_NOINTERFACE;
 
     *ppv = static_cast<IAccessibleHyperlink*>(this);
     (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
     return S_OK;
@@ -51,17 +51,17 @@ ia2AccessibleHyperlink::get_anchor(long 
   if (!thisObj->IsLink())
     return S_FALSE;
 
   AccessibleWrap* anchor =
     static_cast<AccessibleWrap*>(thisObj->AnchorAt(aIndex));
   if (!anchor)
     return S_FALSE;
 
-  void* instancePtr = NULL;
+  void* instancePtr = nullptr;
   HRESULT result = anchor->QueryInterface(IID_IUnknown, &instancePtr);
   if (FAILED(result))
     return result;
 
   IUnknown* unknownPtr = static_cast<IUnknown*>(instancePtr);
   aAnchor->ppunkVal = &unknownPtr;
   aAnchor->vt = VT_UNKNOWN;
   return S_OK;
--- a/accessible/src/windows/ia2/ia2AccessibleHypertext.cpp
+++ b/accessible/src/windows/ia2/ia2AccessibleHypertext.cpp
@@ -33,17 +33,17 @@ ia2AccessibleHypertext::get_nHyperlinks(
 }
 
 STDMETHODIMP
 ia2AccessibleHypertext::get_hyperlink(long aLinkIndex,
                                       IAccessibleHyperlink** aHyperlink)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aHyperlink = NULL;
+  *aHyperlink = nullptr;
 
   HyperTextAccessibleWrap* hyperText = static_cast<HyperTextAccessibleWrap*>(this);
   if (hyperText->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   Accessible* hyperLink = hyperText->GetLinkAt(aLinkIndex);
   if (!hyperLink)
     return E_FAIL;
--- a/accessible/src/windows/ia2/ia2AccessibleImage.cpp
+++ b/accessible/src/windows/ia2/ia2AccessibleImage.cpp
@@ -21,17 +21,17 @@
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 // IUnknown
 
 STDMETHODIMP
 ia2AccessibleImage::QueryInterface(REFIID iid, void** ppv)
 {
-  *ppv = NULL;
+  *ppv = nullptr;
 
   if (IID_IAccessibleImage == iid) {
     *ppv = static_cast<IAccessibleImage*>(this);
     (static_cast<IUnknown*>(*ppv))->AddRef();
     return S_OK;
   }
 
   return E_NOINTERFACE;
@@ -39,17 +39,17 @@ ia2AccessibleImage::QueryInterface(REFII
 
 // IAccessibleImage
 
 STDMETHODIMP
 ia2AccessibleImage::get_description(BSTR* aDescription)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aDescription = NULL;
+  *aDescription = nullptr;
 
   ImageAccessibleWrap* acc = static_cast<ImageAccessibleWrap*>(this);
   if (acc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsAutoString description;
   nsresult rv = acc->GetName(description);
   if (NS_FAILED(rv))
--- a/accessible/src/windows/ia2/ia2AccessibleRelation.cpp
+++ b/accessible/src/windows/ia2/ia2AccessibleRelation.cpp
@@ -27,17 +27,17 @@ ia2AccessibleRelation::ia2AccessibleRela
 // IUnknown
 
 STDMETHODIMP
 ia2AccessibleRelation::QueryInterface(REFIID iid, void** ppv)
 {
   if (!ppv)
     return E_INVALIDARG;
 
-  *ppv = NULL;
+  *ppv = nullptr;
 
   if (IID_IAccessibleRelation == iid || IID_IUnknown == iid) {
     *ppv = static_cast<IAccessibleRelation*>(this);
     (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
     return S_OK;
   }
 
   return E_NOINTERFACE;
@@ -65,17 +65,17 @@ ia2AccessibleRelation::Release()
 STDMETHODIMP
 ia2AccessibleRelation::get_relationType(BSTR *aRelationType)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aRelationType)
     return E_INVALIDARG;
 
-  *aRelationType = NULL;
+  *aRelationType = nullptr;
 
   switch (mType) {
     case nsIAccessibleRelation::RELATION_CONTROLLED_BY:
       *aRelationType = ::SysAllocString(IA2_RELATION_CONTROLLED_BY);
       break;
     case nsIAccessibleRelation::RELATION_CONTROLLER_FOR:
       *aRelationType = ::SysAllocString(IA2_RELATION_CONTROLLER_FOR);
       break;
@@ -130,17 +130,17 @@ ia2AccessibleRelation::get_relationType(
 STDMETHODIMP
 ia2AccessibleRelation::get_localizedRelationType(BSTR *aLocalizedRelationType)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aLocalizedRelationType)
     return E_INVALIDARG;
 
-  *aLocalizedRelationType = NULL;
+  *aLocalizedRelationType = nullptr;
   return E_NOTIMPL;
 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleRelation::get_nTargets(long *aNTargets)
 {
--- a/accessible/src/windows/ia2/ia2AccessibleTable.cpp
+++ b/accessible/src/windows/ia2/ia2AccessibleTable.cpp
@@ -20,17 +20,17 @@
 
 using namespace mozilla::a11y;
 
 // IUnknown
 
 STDMETHODIMP
 ia2AccessibleTable::QueryInterface(REFIID iid, void** ppv)
 {
-  *ppv = NULL;
+  *ppv = nullptr;
 
   if (IID_IAccessibleTable == iid) {
     statistics::IAccessibleTableUsed();
     *ppv = static_cast<IAccessibleTable*>(this);
     (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
     return S_OK;
   }
 
@@ -53,17 +53,17 @@ ia2AccessibleTable::get_accessibleAt(lon
   return get_cellAt(aRowIdx, aColIdx, aAccessible);
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_caption(IUnknown** aAccessible)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aAccessible = NULL;
+  *aAccessible = nullptr;
   if (!mTable)
     return CO_E_OBJNOTCONNECTED;
 
   AccessibleWrap* caption = static_cast<AccessibleWrap*>(mTable->Caption());
   if (!caption)
     return S_FALSE;
 
   (*aAccessible = static_cast<IAccessible*>(caption))->AddRef();
@@ -93,17 +93,17 @@ ia2AccessibleTable::get_childIndex(long 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_columnDescription(long aColIdx, BSTR* aDescription)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aDescription = NULL;
+  *aDescription = nullptr;
   if (!mTable)
     return CO_E_OBJNOTCONNECTED;
 
   if (aColIdx < 0 || static_cast<uint32_t>(aColIdx) >= mTable->ColCount())
     return E_INVALIDARG;
 
   nsAutoString descr;
   mTable->ColDescription(aColIdx, descr);
@@ -138,17 +138,17 @@ ia2AccessibleTable::get_columnExtentAt(l
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_columnHeader(IAccessibleTable** aAccessibleTable,
                                     long* aStartingRowIndex)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aAccessibleTable = NULL;
+  *aAccessibleTable = nullptr;
   *aStartingRowIndex = -1;
   return E_NOTIMPL;
 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_columnIndex(long aCellIdx, long* aColIdx)
@@ -236,17 +236,17 @@ ia2AccessibleTable::get_nSelectedRows(lo
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_rowDescription(long aRowIdx, BSTR* aDescription)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aDescription = NULL;
+  *aDescription = nullptr;
   if (!mTable)
     return CO_E_OBJNOTCONNECTED;
 
   if (aRowIdx < 0 || static_cast<uint32_t>(aRowIdx) >= mTable->RowCount())
     return E_INVALIDARG;
 
   nsAutoString descr;
   mTable->RowDescription(aRowIdx, descr);
@@ -280,17 +280,17 @@ ia2AccessibleTable::get_rowExtentAt(long
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_rowHeader(IAccessibleTable** aAccessibleTable,
                                   long* aStartingColumnIndex)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aAccessibleTable = NULL;
+  *aAccessibleTable = nullptr;
   *aStartingColumnIndex = -1;
   return E_NOTIMPL;
 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_rowIndex(long aCellIdx, long* aRowIdx)
@@ -312,17 +312,17 @@ ia2AccessibleTable::get_rowIndex(long aC
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_selectedChildren(long aMaxChildren, long** aChildren,
                                          long* aNChildren)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aChildren = NULL;
+  *aChildren = nullptr;
   *aNChildren = 0;
   if (!mTable)
     return CO_E_OBJNOTCONNECTED;
 
   nsAutoTArray<uint32_t, 30> cellIndices;
   mTable->SelectedCellIndices(&cellIndices);
 
   uint32_t maxCells = cellIndices.Length();
@@ -365,17 +365,17 @@ ia2AccessibleTable::get_summary(IUnknown
 {
   A11Y_TRYBLOCK_BEGIN
 
   // Neither html:table nor xul:tree nor ARIA grid/tree have an ability to
   // link an accessible object to specify a summary. There is closes method
   // in nsIAccessibleTable::summary to get a summary as a string which is not
   // mapped directly to IAccessible2.
 
-  *aAccessible = NULL;
+  *aAccessible = nullptr;
   return S_FALSE;
 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_isColumnSelected(long aColIdx, boolean* aIsSelected)
 {
@@ -544,17 +544,17 @@ ia2AccessibleTable::get_modelChange(IA2T
 ////////////////////////////////////////////////////////////////////////////////
 // IAccessibleTable2
 
 STDMETHODIMP
 ia2AccessibleTable::get_cellAt(long aRowIdx, long aColIdx, IUnknown** aCell)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aCell = NULL;
+  *aCell = nullptr;
 
   if (!mTable)
     return CO_E_OBJNOTCONNECTED;
 
   AccessibleWrap* cell =
     static_cast<AccessibleWrap*>(mTable->CellAt(aRowIdx, aColIdx));
   if (!cell)
     return E_INVALIDARG;
@@ -580,17 +580,17 @@ ia2AccessibleTable::get_nSelectedCells(l
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_selectedCells(IUnknown*** aCells, long* aNSelectedCells)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aCells = NULL;
+  *aCells = nullptr;
   *aNSelectedCells = 0;
   if (!mTable)
     return CO_E_OBJNOTCONNECTED;
 
   nsAutoTArray<Accessible*, 30> cells;
   mTable->SelectedCells(&cells);
   if (cells.IsEmpty())
     return S_FALSE;
@@ -613,17 +613,17 @@ ia2AccessibleTable::get_selectedCells(IU
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_selectedColumns(long** aColumns, long* aNColumns)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aColumns = NULL;
+  *aColumns = nullptr;
   *aNColumns = 0;
   if (!mTable)
     return CO_E_OBJNOTCONNECTED;
 
   nsAutoTArray<uint32_t, 30> colIndices;
   mTable->SelectedColIndices(&colIndices);
 
   uint32_t maxCols = colIndices.Length();
@@ -640,17 +640,17 @@ ia2AccessibleTable::get_selectedColumns(
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleTable::get_selectedRows(long** aRows, long* aNRows)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aRows = NULL;
+  *aRows = nullptr;
   *aNRows = 0;
   if (!mTable)
     return CO_E_OBJNOTCONNECTED;
 
   nsAutoTArray<uint32_t, 30> rowIndices;
   mTable->SelectedRowIndices(&rowIndices);
 
   uint32_t maxRows = rowIndices.Length();
--- a/accessible/src/windows/ia2/ia2AccessibleTableCell.cpp
+++ b/accessible/src/windows/ia2/ia2AccessibleTableCell.cpp
@@ -20,17 +20,17 @@
 
 using namespace mozilla::a11y;
 
 // IUnknown
 
 STDMETHODIMP
 ia2AccessibleTableCell::QueryInterface(REFIID iid, void** ppv)
 {
-  *ppv = NULL;
+  *ppv = nullptr;
 
   if (IID_IAccessibleTableCell == iid) {
     *ppv = static_cast<IAccessibleTableCell*>(this);
     (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
     return S_OK;
   }
 
   return E_NOINTERFACE;
@@ -39,17 +39,17 @@ ia2AccessibleTableCell::QueryInterface(R
 ////////////////////////////////////////////////////////////////////////////////
 // IAccessibleTableCell
 
 STDMETHODIMP
 ia2AccessibleTableCell::get_table(IUnknown** aTable)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aTable = NULL;
+  *aTable = nullptr;
   if (!mTableCell)
     return CO_E_OBJNOTCONNECTED;
 
   TableAccessible* table = mTableCell->Table();
   if (!table)
     return E_FAIL;
 
   AccessibleWrap* wrap = static_cast<AccessibleWrap*>(table->AsAccessible());
@@ -77,17 +77,17 @@ ia2AccessibleTableCell::get_columnExtent
 }
 
 STDMETHODIMP
 ia2AccessibleTableCell::get_columnHeaderCells(IUnknown*** aCellAccessibles,
                                               long* aNColumnHeaderCells)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aCellAccessibles = NULL;
+  *aCellAccessibles = nullptr;
   *aNColumnHeaderCells = 0;
   if (!mTableCell)
     return CO_E_OBJNOTCONNECTED;
 
   nsAutoTArray<Accessible*, 10> cells;
   mTableCell->ColHeaderCells(&cells);
 
   *aNColumnHeaderCells = cells.Length();
@@ -140,17 +140,17 @@ ia2AccessibleTableCell::get_rowExtent(lo
 }
 
 STDMETHODIMP
 ia2AccessibleTableCell::get_rowHeaderCells(IUnknown*** aCellAccessibles,
                                            long* aNRowHeaderCells)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aCellAccessibles = NULL;
+  *aCellAccessibles = nullptr;
   *aNRowHeaderCells = 0;
   if (!mTableCell)
     return CO_E_OBJNOTCONNECTED;
 
   nsAutoTArray<Accessible*, 10> cells;
   mTableCell->RowHeaderCells(&cells);
 
   *aNRowHeaderCells = cells.Length();
--- a/accessible/src/windows/ia2/ia2AccessibleText.cpp
+++ b/accessible/src/windows/ia2/ia2AccessibleText.cpp
@@ -39,17 +39,17 @@ ia2AccessibleText::get_attributes(long a
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aStartOffset || !aEndOffset || !aTextAttributes)
     return E_INVALIDARG;
 
   *aStartOffset = 0;
   *aEndOffset = 0;
-  *aTextAttributes = NULL;
+  *aTextAttributes = nullptr;
 
   HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   int32_t startOffset = 0, endOffset = 0;
   nsCOMPtr<nsIPersistentProperties> attributes;
   nsresult rv = textAcc->GetTextAttributes(true, aOffset,
@@ -205,17 +205,17 @@ ia2AccessibleText::get_selection(long aS
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ia2AccessibleText::get_text(long aStartOffset, long aEndOffset, BSTR *aText)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aText = NULL;
+  *aText = nullptr;
 
   HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsAutoString text;
   nsresult rv = textAcc->GetText(aStartOffset, aEndOffset, text);
   if (NS_FAILED(rv))
@@ -235,17 +235,17 @@ ia2AccessibleText::get_textBeforeOffset(
                                         enum IA2TextBoundaryType aBoundaryType,
                                         long *aStartOffset, long *aEndOffset,
                                         BSTR *aText)
 {
   A11Y_TRYBLOCK_BEGIN
 
   *aStartOffset = 0;
   *aEndOffset = 0;
-  *aText = NULL;
+  *aText = nullptr;
 
   HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsresult rv = NS_OK;
   nsAutoString text;
   int32_t startOffset = 0, endOffset = 0;
@@ -282,17 +282,17 @@ ia2AccessibleText::get_textAfterOffset(l
                                        enum IA2TextBoundaryType aBoundaryType,
                                        long *aStartOffset, long *aEndOffset,
                                        BSTR *aText)
 {
   A11Y_TRYBLOCK_BEGIN
 
   *aStartOffset = 0;
   *aEndOffset = 0;
-  *aText = NULL;
+  *aText = nullptr;
 
   HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsresult rv = NS_OK;
   nsAutoString text;
   int32_t startOffset = 0, endOffset = 0;
@@ -329,17 +329,17 @@ ia2AccessibleText::get_textAtOffset(long
                                     enum IA2TextBoundaryType aBoundaryType,
                                     long *aStartOffset, long *aEndOffset,
                                     BSTR *aText)
 {
   A11Y_TRYBLOCK_BEGIN
 
   *aStartOffset = 0;
   *aEndOffset = 0;
-  *aText = NULL;
+  *aText = nullptr;
 
   HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
   if (textAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsresult rv = NS_OK;
   nsAutoString text;
   int32_t startOffset = 0, endOffset = 0;
--- a/accessible/src/windows/ia2/ia2AccessibleValue.cpp
+++ b/accessible/src/windows/ia2/ia2AccessibleValue.cpp
@@ -14,17 +14,17 @@
 
 using namespace mozilla::a11y;
 
 // IUnknown
 
 STDMETHODIMP
 ia2AccessibleValue::QueryInterface(REFIID iid, void** ppv)
 {
-  *ppv = NULL;
+  *ppv = nullptr;
 
   if (IID_IAccessibleValue == iid) {
     AccessibleWrap* valueAcc = static_cast<AccessibleWrap*>(this);
     if (valueAcc->HasNumericValue()) {
       *ppv = static_cast<IAccessibleValue*>(this);
       valueAcc->AddRef();
       return S_OK;
     }
--- a/accessible/src/windows/ia2/moz.build
+++ b/accessible/src/windows/ia2/moz.build
@@ -1,7 +1,8 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'accessibility'
 
--- a/accessible/src/windows/moz.build
+++ b/accessible/src/windows/moz.build
@@ -1,7 +1,8 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 DIRS += ['msaa', 'ia2', 'sdn', 'uia']
 
--- a/accessible/src/windows/msaa/AccessibleWrap.cpp
+++ b/accessible/src/windows/msaa/AccessibleWrap.cpp
@@ -59,31 +59,31 @@ static gAccessibles = 0;
 #endif
 
 static const int32_t kIEnumVariantDisconnected = -1;
 
 ////////////////////////////////////////////////////////////////////////////////
 // AccessibleWrap
 ////////////////////////////////////////////////////////////////////////////////
 
-ITypeInfo* AccessibleWrap::gTypeInfo = NULL;
+ITypeInfo* AccessibleWrap::gTypeInfo = nullptr;
 
 NS_IMPL_ISUPPORTS_INHERITED0(AccessibleWrap, Accessible)
 
 //-----------------------------------------------------
 // IUnknown interface methods - see iunknown.h for documentation
 //-----------------------------------------------------
 
 // Microsoft COM QueryInterface
 STDMETHODIMP
 AccessibleWrap::QueryInterface(REFIID iid, void** ppv)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *ppv = NULL;
+  *ppv = nullptr;
 
   if (IID_IUnknown == iid || IID_IDispatch == iid || IID_IAccessible == iid)
     *ppv = static_cast<IAccessible*>(this);
   else if (IID_IEnumVARIANT == iid) {
     // Don't support this interface for leaf elements.
     if (!HasChildren() || nsAccUtils::MustPrune(this))
       return E_NOINTERFACE;
 
@@ -94,35 +94,35 @@ AccessibleWrap::QueryInterface(REFIID ii
     *ppv = static_cast<IAccessible2*>(this);
   else if (IID_ISimpleDOMNode == iid) {
     if (IsDefunct() || (!HasOwnContent() && !IsDoc()))
       return E_NOINTERFACE;
 
     *ppv = new sdnAccessible(GetNode());
   }
 
-  if (NULL == *ppv) {
+  if (nullptr == *ppv) {
     HRESULT hr = ia2AccessibleComponent::QueryInterface(iid, ppv);
     if (SUCCEEDED(hr))
       return hr;
   }
 
-  if (NULL == *ppv) {
+  if (nullptr == *ppv) {
     HRESULT hr = ia2AccessibleHyperlink::QueryInterface(iid, ppv);
     if (SUCCEEDED(hr))
       return hr;
   }
 
-  if (NULL == *ppv) {
+  if (nullptr == *ppv) {
     HRESULT hr = ia2AccessibleValue::QueryInterface(iid, ppv);
     if (SUCCEEDED(hr))
       return hr;
   }
 
-  if (NULL == *ppv)
+  if (nullptr == *ppv)
     return E_NOINTERFACE;
 
   (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
   return S_OK;
 
   A11Y_TRYBLOCK_END
 }
 
@@ -130,17 +130,17 @@ AccessibleWrap::QueryInterface(REFIID ii
 // IAccessible methods
 //-----------------------------------------------------
 
 STDMETHODIMP
 AccessibleWrap::get_accParent( IDispatch __RPC_FAR *__RPC_FAR *ppdispParent)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *ppdispParent = NULL;
+  *ppdispParent = nullptr;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   DocAccessible* doc = AsDoc();
   if (doc) {
     // Return window system accessible object for root document and tab document
     // accessibles.
@@ -190,17 +190,17 @@ AccessibleWrap::get_accChildCount( long 
 
 STDMETHODIMP
 AccessibleWrap::get_accChild(
       /* [in] */ VARIANT varChild,
       /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppdispChild)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *ppdispChild = NULL;
+  *ppdispChild = nullptr;
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   // IAccessible::accChild is used to return this accessible or child accessible
   // at the given index or to get an accessible by child ID in the case of
   // document accessible (it's handled by overriden GetXPAccessibleFor method
   // on the document accessible). The getting an accessible by child ID is used
   // by AccessibleObjectFromEvent() called by AT when AT handles our MSAA event.
@@ -219,17 +219,17 @@ AccessibleWrap::get_accChild(
 
 STDMETHODIMP
 AccessibleWrap::get_accName(
       /* [optional][in] */ VARIANT varChild,
       /* [retval][out] */ BSTR __RPC_FAR *pszName)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *pszName = NULL;
+  *pszName = nullptr;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   Accessible* xpAccessible = GetXPAccessibleFor(varChild);
   if (!xpAccessible)
     return E_INVALIDARG;
 
@@ -256,17 +256,17 @@ AccessibleWrap::get_accName(
 
 STDMETHODIMP
 AccessibleWrap::get_accValue(
       /* [optional][in] */ VARIANT varChild,
       /* [retval][out] */ BSTR __RPC_FAR *pszValue)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *pszValue = NULL;
+  *pszValue = nullptr;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   Accessible* xpAccessible = GetXPAccessibleFor(varChild);
   if (!xpAccessible)
     return E_INVALIDARG;
 
@@ -294,17 +294,17 @@ AccessibleWrap::get_accValue(
 }
 
 STDMETHODIMP
 AccessibleWrap::get_accDescription(VARIANT varChild,
                                    BSTR __RPC_FAR *pszDescription)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *pszDescription = NULL;
+  *pszDescription = nullptr;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   Accessible* xpAccessible = GetXPAccessibleFor(varChild);
   if (!xpAccessible)
     return E_INVALIDARG;
 
@@ -456,47 +456,47 @@ AccessibleWrap::get_accState(
 
 STDMETHODIMP
 AccessibleWrap::get_accHelp(
       /* [optional][in] */ VARIANT varChild,
       /* [retval][out] */ BSTR __RPC_FAR *pszHelp)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *pszHelp = NULL;
+  *pszHelp = nullptr;
   return S_FALSE;
 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 AccessibleWrap::get_accHelpTopic(
       /* [out] */ BSTR __RPC_FAR *pszHelpFile,
       /* [optional][in] */ VARIANT varChild,
       /* [retval][out] */ long __RPC_FAR *pidTopic)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *pszHelpFile = NULL;
+  *pszHelpFile = nullptr;
   *pidTopic = 0;
   return S_FALSE;
 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 AccessibleWrap::get_accKeyboardShortcut(
       /* [optional][in] */ VARIANT varChild,
       /* [retval][out] */ BSTR __RPC_FAR *pszKeyboardShortcut)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!pszKeyboardShortcut)
     return E_INVALIDARG;
-  *pszKeyboardShortcut = NULL;
+  *pszKeyboardShortcut = nullptr;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   Accessible* acc = GetXPAccessibleFor(varChild);
   if (!acc)
     return E_INVALIDARG;
 
@@ -595,17 +595,17 @@ AccessibleEnumerator::QueryInterface(REF
     return S_OK;
   }
   if (iid == IID_IUnknown) {
     *ppvObject = static_cast<IUnknown*>(this);
     AddRef();
     return S_OK;
   }
 
-  *ppvObject = NULL;
+  *ppvObject = nullptr;
   return E_NOINTERFACE;
 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP_(ULONG)
 AccessibleEnumerator::AddRef(void)
 {
@@ -737,17 +737,17 @@ AccessibleWrap::get_accSelection(VARIANT
 
 STDMETHODIMP
 AccessibleWrap::get_accDefaultAction(
       /* [optional][in] */ VARIANT varChild,
       /* [retval][out] */ BSTR __RPC_FAR *pszDefaultAction)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *pszDefaultAction = NULL;
+  *pszDefaultAction = nullptr;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   Accessible* xpAccessible = GetXPAccessibleFor(varChild);
   if (!xpAccessible)
     return E_INVALIDARG;
 
@@ -1061,17 +1061,17 @@ STDMETHODIMP
 AccessibleWrap::get_relation(long aRelationIndex,
                              IAccessibleRelation** aRelation)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aRelation)
     return E_INVALIDARG;
 
-  *aRelation = NULL;
+  *aRelation = nullptr;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   long relIdx = 0;
   for (unsigned int idx = 0; idx < ArrayLength(sRelationTypesForIA2); idx++) {
     uint32_t relType = sRelationTypesForIA2[idx];
     Relation rel = RelationByType(relType);
@@ -1275,28 +1275,28 @@ AccessibleWrap::get_states(AccessibleSta
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 AccessibleWrap::get_extendedRole(BSTR *aExtendedRole)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aExtendedRole = NULL;
+  *aExtendedRole = nullptr;
   return E_NOTIMPL;
 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 AccessibleWrap::get_localizedExtendedRole(BSTR *aLocalizedExtendedRole)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aLocalizedExtendedRole = NULL;
+  *aLocalizedExtendedRole = nullptr;
   return E_NOTIMPL;
 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 AccessibleWrap::get_nExtendedStates(long *aNExtendedStates)
 {
@@ -1310,31 +1310,31 @@ AccessibleWrap::get_nExtendedStates(long
 
 STDMETHODIMP
 AccessibleWrap::get_extendedStates(long aMaxExtendedStates,
                                    BSTR **aExtendedStates,
                                    long *aNExtendedStates)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aExtendedStates = NULL;
+  *aExtendedStates = nullptr;
   *aNExtendedStates = 0;
   return E_NOTIMPL;
 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 AccessibleWrap::get_localizedExtendedStates(long aMaxLocalizedExtendedStates,
                                             BSTR** aLocalizedExtendedStates,
                                             long* aNLocalizedExtendedStates)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aLocalizedExtendedStates = NULL;
+  *aLocalizedExtendedStates = nullptr;
   *aNLocalizedExtendedStates = 0;
   return E_NOTIMPL;
 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 AccessibleWrap::get_uniqueID(long *uniqueID)
@@ -1433,17 +1433,17 @@ AccessibleWrap::get_locale(IA2Locale *aL
 
 STDMETHODIMP
 AccessibleWrap::get_attributes(BSTR *aAttributes)
 {
   A11Y_TRYBLOCK_BEGIN
 
   // The format is name:value;name:value; with \ for escaping these
   // characters ":;=,\".
-  *aAttributes = NULL;
+  *aAttributes = nullptr;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsCOMPtr<nsIPersistentProperties> attributes = Attributes();
   return ConvertToIA2Attributes(attributes, aAttributes);
 
   A11Y_TRYBLOCK_END
@@ -1457,17 +1457,17 @@ AccessibleWrap::GetTypeInfoCount(UINT *p
 {
   *pctinfo = 1;
   return S_OK;
 }
 
 STDMETHODIMP
 AccessibleWrap::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
 {
-  *ppTInfo = NULL;
+  *ppTInfo = nullptr;
 
   if (iTInfo != 0)
     return DISP_E_BADINDEX;
 
   ITypeInfo * typeInfo = GetTI(lcid);
   if (!typeInfo)
     return E_FAIL;
 
@@ -1642,17 +1642,17 @@ AccessibleWrap::GetHWNDFor(Accessible* a
   }
   return nullptr;
 }
 
 HRESULT
 AccessibleWrap::ConvertToIA2Attributes(nsIPersistentProperties *aAttributes,
                                        BSTR *aIA2Attributes)
 {
-  *aIA2Attributes = NULL;
+  *aIA2Attributes = nullptr;
 
   // The format is name:value;name:value; with \ for escaping these
   // characters ":;=,\".
 
   if (!aAttributes)
     return S_FALSE;
 
   nsCOMPtr<nsISimpleEnumerator> propEnum;
@@ -1706,17 +1706,17 @@ AccessibleWrap::ConvertToIA2Attributes(n
   return *aIA2Attributes ? S_OK : E_OUTOFMEMORY;
 }
 
 IDispatch*
 AccessibleWrap::NativeAccessible(nsIAccessible* aAccessible)
 {
   if (!aAccessible) {
    NS_WARNING("Not passing in an aAccessible");
-   return NULL;
+   return nullptr;
   }
 
   IAccessible* msaaAccessible = nullptr;
   aAccessible->GetNativeInterface(reinterpret_cast<void**>(&msaaAccessible));
   return static_cast<IDispatch*>(msaaAccessible);
 }
 
 Accessible*
@@ -1784,37 +1784,37 @@ AccessibleWrap::UpdateSystemCaret()
   nsIntRect caretRect = SelectionMgr()->GetCaretRect(&widget);
   HWND caretWnd; 
   if (caretRect.IsEmpty() || !(caretWnd = (HWND)widget->GetNativeData(NS_NATIVE_WINDOW))) {
     return;
   }
 
   // Create invisible bitmap for caret, otherwise its appearance interferes
   // with Gecko caret
-  HBITMAP caretBitMap = CreateBitmap(1, caretRect.height, 1, 1, NULL);
+  HBITMAP caretBitMap = CreateBitmap(1, caretRect.height, 1, 1, nullptr);
   if (::CreateCaret(caretWnd, caretBitMap, 1, caretRect.height)) {  // Also destroys the last caret
     ::ShowCaret(caretWnd);
     RECT windowRect;
     ::GetWindowRect(caretWnd, &windowRect);
     ::SetCaretPos(caretRect.x - windowRect.left, caretRect.y - windowRect.top);
     ::DeleteObject(caretBitMap);
   }
 }
 
 ITypeInfo*
 AccessibleWrap::GetTI(LCID lcid)
 {
   if (gTypeInfo)
     return gTypeInfo;
 
-  ITypeLib *typeLib = NULL;
+  ITypeLib *typeLib = nullptr;
   HRESULT hr = LoadRegTypeLib(LIBID_Accessibility, 1, 0, lcid, &typeLib);
   if (FAILED(hr))
-    return NULL;
+    return nullptr;
 
   hr = typeLib->GetTypeInfoOfGuid(IID_IAccessible, &gTypeInfo);
   typeLib->Release();
 
   if (FAILED(hr))
-    return NULL;
+    return nullptr;
 
   return gTypeInfo;
 }
--- a/accessible/src/windows/msaa/AccessibleWrap.h
+++ b/accessible/src/windows/msaa/AccessibleWrap.h
@@ -41,17 +41,17 @@ virtual HRESULT STDMETHODCALLTYPE QueryI
 
 #define IMPL_IUNKNOWN_QUERY_HEAD(Class)                                        \
 STDMETHODIMP                                                                   \
 Class::QueryInterface(REFIID aIID, void** aInstancePtr)                        \
 {                                                                              \
   A11Y_TRYBLOCK_BEGIN                                                          \
   if (!aInstancePtr)                                                           \
     return E_INVALIDARG;                                                       \
-  *aInstancePtr = NULL;                                                        \
+  *aInstancePtr = nullptr;                                                        \
                                                                                \
   HRESULT hr = E_NOINTERFACE;
 
 #define IMPL_IUNKNOWN_QUERY_TAIL                                               \
   return hr;                                                                   \
   A11Y_TRYBLOCK_END                                                            \
 }
 
--- a/accessible/src/windows/msaa/ApplicationAccessibleWrap.cpp
+++ b/accessible/src/windows/msaa/ApplicationAccessibleWrap.cpp
@@ -42,17 +42,17 @@ ApplicationAccessibleWrap::NativeAttribu
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // IUnknown
 
 STDMETHODIMP
 ApplicationAccessibleWrap::QueryInterface(REFIID iid, void** ppv)
 {
-  *ppv = NULL;
+  *ppv = nullptr;
 
   if (IID_IAccessibleApplication == iid) {
     *ppv = static_cast<IAccessibleApplication*>(this);
     (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
     return S_OK;
   }
 
   return AccessibleWrap::QueryInterface(iid, ppv);
@@ -61,17 +61,17 @@ ApplicationAccessibleWrap::QueryInterfac
 ////////////////////////////////////////////////////////////////////////////////
 // IAccessibleApplication
 
 STDMETHODIMP
 ApplicationAccessibleWrap::get_appName(BSTR* aName)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aName = NULL;
+  *aName = nullptr;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsAutoString name;
   nsresult rv = GetAppName(name);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
@@ -85,17 +85,17 @@ ApplicationAccessibleWrap::get_appName(B
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ApplicationAccessibleWrap::get_appVersion(BSTR* aVersion)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aVersion = NULL;
+  *aVersion = nullptr;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsAutoString version;
   nsresult rv = GetAppVersion(version);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
@@ -131,17 +131,17 @@ ApplicationAccessibleWrap::get_toolkitNa
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 ApplicationAccessibleWrap::get_toolkitVersion(BSTR* aVersion)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aVersion = NULL;
+  *aVersion = nullptr;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsAutoString version;
   nsresult rv = GetPlatformVersion(version);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
--- a/accessible/src/windows/msaa/Compatibility.cpp
+++ b/accessible/src/windows/msaa/Compatibility.cpp
@@ -25,17 +25,17 @@ IsModuleVersionLessThan(HMODULE aModuleH
 
   DWORD dummy = 0;
   DWORD length = ::GetFileVersionInfoSizeW(fileName, &dummy);
 
   LPBYTE versionInfo = new BYTE[length];
   ::GetFileVersionInfoW(fileName, 0, length, versionInfo);
 
   UINT uLen;
-  VS_FIXEDFILEINFO* fixedFileInfo = NULL;
+  VS_FIXEDFILEINFO* fixedFileInfo = nullptr;
   ::VerQueryValueW(versionInfo, L"\\", (LPVOID*)&fixedFileInfo, &uLen);
   DWORD dwFileVersionMS = fixedFileInfo->dwFileVersionMS;
   DWORD dwFileVersionLS = fixedFileInfo->dwFileVersionLS;
   delete [] versionInfo;
 
   DWORD dwLeftMost = HIWORD(dwFileVersionMS);
   DWORD dwSecondRight = HIWORD(dwFileVersionLS);
   return (dwLeftMost < aMajor ||
--- a/accessible/src/windows/msaa/DocAccessibleWrap.cpp
+++ b/accessible/src/windows/msaa/DocAccessibleWrap.cpp
@@ -33,17 +33,17 @@ using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // DocAccessibleWrap
 ////////////////////////////////////////////////////////////////////////////////
 
 DocAccessibleWrap::
   DocAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
                     nsIPresShell* aPresShell) :
-  DocAccessible(aDocument, aRootContent, aPresShell), mHWND(NULL)
+  DocAccessible(aDocument, aRootContent, aPresShell), mHWND(nullptr)
 {
 }
 
 DocAccessibleWrap::~DocAccessibleWrap()
 {
 }
 
 //-----------------------------------------------------
@@ -59,33 +59,33 @@ STDMETHODIMP_(ULONG) DocAccessibleWrap::
 {
   return nsAccessNode::Release();
 }
 
 // Microsoft COM QueryInterface
 STDMETHODIMP
 DocAccessibleWrap::QueryInterface(REFIID iid, void** ppv)
 {
-  *ppv = NULL;
+  *ppv = nullptr;
 
   if (IID_ISimpleDOMDocument != iid)
     return HyperTextAccessibleWrap::QueryInterface(iid, ppv);
 
   statistics::ISimpleDOMUsed();
   *ppv = static_cast<ISimpleDOMDocument*>(this);
   (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
   return S_OK;
 }
 
 STDMETHODIMP
 DocAccessibleWrap::get_URL(/* [out] */ BSTR __RPC_FAR *aURL)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aURL = NULL;
+  *aURL = nullptr;
 
   nsAutoString URL;
   nsresult rv = GetURL(URL);
   if (NS_FAILED(rv))
     return E_FAIL;
 
   if (URL.IsEmpty())
     return S_FALSE;
@@ -96,17 +96,17 @@ DocAccessibleWrap::get_URL(/* [out] */ B
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 DocAccessibleWrap::get_title( /* [out] */ BSTR __RPC_FAR *aTitle)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aTitle = NULL;
+  *aTitle = nullptr;
 
   nsAutoString title;
   nsresult rv = GetTitle(title);
   if (NS_FAILED(rv))
     return E_FAIL;
 
   *aTitle = ::SysAllocStringLen(title.get(), title.Length());
   return *aTitle ? S_OK : E_OUTOFMEMORY;
@@ -114,17 +114,17 @@ DocAccessibleWrap::get_title( /* [out] *
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 DocAccessibleWrap::get_mimeType(/* [out] */ BSTR __RPC_FAR *aMimeType)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aMimeType = NULL;
+  *aMimeType = nullptr;
 
   nsAutoString mimeType;
   nsresult rv = GetMimeType(mimeType);
   if (NS_FAILED(rv))
     return E_FAIL;
 
   if (mimeType.IsEmpty())
     return S_FALSE;
@@ -135,17 +135,17 @@ DocAccessibleWrap::get_mimeType(/* [out]
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 DocAccessibleWrap::get_docType(/* [out] */ BSTR __RPC_FAR *aDocType)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aDocType = NULL;
+  *aDocType = nullptr;
 
   nsAutoString docType;
   nsresult rv = GetDocType(docType);
   if (NS_FAILED(rv))
     return E_FAIL;
 
   if (docType.IsEmpty())
     return S_FALSE;
@@ -157,17 +157,17 @@ DocAccessibleWrap::get_docType(/* [out] 
 }
 
 STDMETHODIMP
 DocAccessibleWrap::get_nameSpaceURIForID(/* [in] */  short aNameSpaceID,
   /* [out] */ BSTR __RPC_FAR *aNameSpaceURI)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aNameSpaceURI = NULL;
+  *aNameSpaceURI = nullptr;
 
   if (aNameSpaceID < 0)
     return E_INVALIDARG;  // -1 is kNameSpaceID_Unknown
 
   nsAutoString nameSpaceURI;
   nsresult rv = GetNameSpaceURIForID(aNameSpaceID, nameSpaceURI);
   if (NS_FAILED(rv))
     return E_FAIL;
@@ -183,29 +183,29 @@ DocAccessibleWrap::get_nameSpaceURIForID
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 DocAccessibleWrap::put_alternateViewMediaTypes( /* [in] */ BSTR __RPC_FAR *aCommaSeparatedMediaTypes)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aCommaSeparatedMediaTypes = NULL;
+  *aCommaSeparatedMediaTypes = nullptr;
   return E_NOTIMPL;
 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 DocAccessibleWrap::get_accValue(
       /* [optional][in] */ VARIANT varChild,
       /* [retval][out] */ BSTR __RPC_FAR *pszValue)
 {
   // For backwards-compat, we still support old MSAA hack to provide URL in accValue
-  *pszValue = NULL;
+  *pszValue = nullptr;
   // Check for real value first
   HRESULT hr = AccessibleWrap::get_accValue(varChild, pszValue);
   if (FAILED(hr) || *pszValue || varChild.lVal != CHILDID_SELF)
     return hr;
   // If document is being used to create a widget, don't use the URL hack
   roles::Role role = Role();
   if (role != roles::DOCUMENT && role != roles::APPLICATION && 
       role != roles::DIALOG && role != roles::ALERT) 
--- a/accessible/src/windows/msaa/HyperTextAccessibleWrap.cpp
+++ b/accessible/src/windows/msaa/HyperTextAccessibleWrap.cpp
@@ -25,17 +25,17 @@ NS_IMPL_ISUPPORTS_INHERITED0(HyperTextAc
                              HyperTextAccessible)
 
 STDMETHODIMP
 HyperTextAccessibleWrap::QueryInterface(REFIID aIID, void** aInstancePtr)
 {
   if (!aInstancePtr)
     return E_FAIL;
 
-  *aInstancePtr = NULL;
+  *aInstancePtr = nullptr;
 
   if (IsTextRole()) {
     if (aIID == IID_IAccessibleText)
       *aInstancePtr =
         static_cast<IAccessibleText*>(static_cast<ia2AccessibleText*>(this));
     else if (aIID == IID_IAccessibleHypertext)
       *aInstancePtr = static_cast<IAccessibleHypertext*>(this);
     else if (aIID == IID_IAccessibleEditableText)
--- a/accessible/src/windows/msaa/ServiceProvider.cpp
+++ b/accessible/src/windows/msaa/ServiceProvider.cpp
@@ -32,17 +32,17 @@ A11Y_TRYBLOCK_END
 
 STDMETHODIMP
 ServiceProvider::QueryService(REFGUID aGuidService, REFIID aIID,
                               void** aInstancePtr)
 {
   if (!aInstancePtr)
     return E_INVALIDARG;
 
-  *aInstancePtr = NULL;
+  *aInstancePtr = nullptr;
 
   // UIA IAccessibleEx
   if (aGuidService == IID_IAccessibleEx &&
       Preferences::GetBool("accessibility.uia.enable")) {
     uiaRawElmProvider* accEx = new uiaRawElmProvider(mAccessible);
     HRESULT hr = accEx->QueryInterface(aIID, aInstancePtr);
     if (FAILED(hr))
       delete accEx;
--- a/accessible/src/windows/msaa/TextLeafAccessibleWrap.cpp
+++ b/accessible/src/windows/msaa/TextLeafAccessibleWrap.cpp
@@ -59,17 +59,17 @@ TextLeafAccessibleWrap::QueryInterface(R
 }
 
 STDMETHODIMP
 TextLeafAccessibleWrap::get_domText( 
     /* [retval][out] */ BSTR __RPC_FAR *aDomText)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aDomText = NULL;
+  *aDomText = nullptr;
 
   if (IsDefunct())
     return E_FAIL;
 
   nsAutoString nodeValue;
 
   nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
   DOMNode->GetNodeValue(nodeValue);
@@ -241,17 +241,17 @@ TextLeafAccessibleWrap::GetCharacterExte
 }
 
 STDMETHODIMP
 TextLeafAccessibleWrap::get_fontFamily(
     /* [retval][out] */ BSTR __RPC_FAR *aFontFamily)
 {
   A11Y_TRYBLOCK_BEGIN
 
-  *aFontFamily = NULL;
+  *aFontFamily = nullptr;
 
   nsIFrame* frame = GetFrame();
   if (!frame) {
     return E_FAIL;
   }
 
   nsRefPtr<nsFontMetrics> fm;
   nsLayoutUtils::GetFontMetricsForFrame(frame, getter_AddRefs(fm));
--- a/accessible/src/windows/msaa/XULTreeGridAccessibleWrap.h
+++ b/accessible/src/windows/msaa/XULTreeGridAccessibleWrap.h
@@ -17,18 +17,19 @@ namespace a11y {
 /**
  * IA2 wrapper class for XULTreeGridAccessible class implementing
  * IAccessibleTable and IAccessibleTable2 interfaces.
  */
 class XULTreeGridAccessibleWrap : public XULTreeGridAccessible,
                                   public ia2AccessibleTable
 {
 public:
-  XULTreeGridAccessibleWrap(nsIContent* aContent, DocAccessible* aDoc) :
-    XULTreeGridAccessible(aContent, aDoc), ia2AccessibleTable(this) {}
+  XULTreeGridAccessibleWrap(nsIContent* aContent, DocAccessible* aDoc,
+                            nsTreeBodyFrame* aTree) :
+    XULTreeGridAccessible(aContent, aDoc, aTree), ia2AccessibleTable(this) {}
 
   // IUnknown
   DECL_IUNKNOWN_INHERITED
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   virtual void Shutdown() MOZ_OVERRIDE;
--- a/accessible/src/windows/msaa/moz.build
+++ b/accessible/src/windows/msaa/moz.build
@@ -1,7 +1,8 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'accessibility'
 
--- a/accessible/src/windows/msaa/nsAccessNodeWrap.cpp
+++ b/accessible/src/windows/msaa/nsAccessNodeWrap.cpp
@@ -85,17 +85,17 @@ nsAccessNodeWrap::WindowProc(HWND hWnd, 
   // message semantics.
 
   switch (msg) {
     case WM_GETOBJECT:
     {
       if (lParam == OBJID_CLIENT) {
         DocAccessible* document = sHWNDCache.GetWeak(static_cast<void*>(hWnd));
         if (document) {
-          IAccessible* msaaAccessible = NULL;
+          IAccessible* msaaAccessible = nullptr;
           document->GetNativeInterface((void**)&msaaAccessible); // does an addref
           if (msaaAccessible) {
             LRESULT result = ::LresultFromObject(IID_IAccessible, wParam,
                                                  msaaAccessible); // does an addref
             msaaAccessible->Release(); // release extra addref
             return result;
           }
         }
--- a/accessible/src/windows/msaa/nsWinUtils.cpp
+++ b/accessible/src/windows/msaa/nsWinUtils.cpp
@@ -60,67 +60,67 @@ nsWinUtils::MaybeStartWindowEmulation()
 }
 
 void
 nsWinUtils::ShutdownWindowEmulation()
 {
   // Unregister window call that's used for document accessibles associated
   // with tabs.
   if (IsWindowEmulationStarted())
-    ::UnregisterClassW(kClassNameTabContent, GetModuleHandle(NULL));
+    ::UnregisterClassW(kClassNameTabContent, GetModuleHandle(nullptr));
 }
 
 bool
 nsWinUtils::IsWindowEmulationStarted()
 {
   return nsAccessNodeWrap::sHWNDCache.IsInitialized();
 }
 
 void
 nsWinUtils::RegisterNativeWindow(LPCWSTR aWindowClass)
 {
   WNDCLASSW wc;
   wc.style = CS_GLOBALCLASS;
   wc.lpfnWndProc = nsAccessNodeWrap::WindowProc;
   wc.cbClsExtra = 0;
   wc.cbWndExtra = 0;
-  wc.hInstance = GetModuleHandle(NULL);
-  wc.hIcon = NULL;
-  wc.hCursor = NULL;
-  wc.hbrBackground = NULL;
-  wc.lpszMenuName = NULL;
+  wc.hInstance = GetModuleHandle(nullptr);
+  wc.hIcon = nullptr;
+  wc.hCursor = nullptr;
+  wc.hbrBackground = nullptr;
+  wc.lpszMenuName = nullptr;
   wc.lpszClassName = aWindowClass;
   ::RegisterClassW(&wc);
 }
 
 HWND
 nsWinUtils::CreateNativeWindow(LPCWSTR aWindowClass, HWND aParentWnd,
                                int aX, int aY, int aWidth, int aHeight,
                                bool aIsActive)
 {
   HWND hwnd = ::CreateWindowExW(WS_EX_TRANSPARENT, aWindowClass,
                                 L"NetscapeDispatchWnd",
                                 WS_CHILD | (aIsActive ? WS_VISIBLE : 0),
                                 aX, aY, aWidth, aHeight,
                                 aParentWnd,
-                                NULL,
-                                GetModuleHandle(NULL),
-                                NULL);
+                                nullptr,
+                                GetModuleHandle(nullptr),
+                                nullptr);
   if (hwnd) {
     // Mark this window so that ipc related code can identify it.
     ::SetPropW(hwnd, kPropNameTabContent, (HANDLE)1);
   }
   return hwnd;
 }
 
 void
 nsWinUtils::ShowNativeWindow(HWND aWnd)
 {
   ::ShowWindow(aWnd, SW_SHOW);
 }
 
 void
 nsWinUtils::HideNativeWindow(HWND aWnd)
 {
-  ::SetWindowPos(aWnd, NULL, 0, 0, 0, 0,
+  ::SetWindowPos(aWnd, nullptr, 0, 0, 0, 0,
                  SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE |
                  SWP_NOZORDER | SWP_NOACTIVATE);
 }
--- a/accessible/src/windows/sdn/moz.build
+++ b/accessible/src/windows/sdn/moz.build
@@ -1,7 +1,8 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'accessibility'
 
--- a/accessible/src/windows/sdn/sdnAccessible.cpp
+++ b/accessible/src/windows/sdn/sdnAccessible.cpp
@@ -26,17 +26,17 @@ using namespace mozilla::a11y;
 
 STDMETHODIMP
 sdnAccessible::QueryInterface(REFIID aREFIID, void** aInstancePtr)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aInstancePtr)
     return E_FAIL;
-  *aInstancePtr = NULL;
+  *aInstancePtr = nullptr;
 
   if (aREFIID == IID_ISimpleDOMNode) {
     *aInstancePtr = this;
     AddRef();
     return S_OK;
   }
 
   AccessibleWrap* accessible = static_cast<AccessibleWrap*>(GetAccessible());
@@ -65,19 +65,19 @@ sdnAccessible::get_nodeInfo(BSTR __RPC_F
                             unsigned short __RPC_FAR* aNodeType)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aNodeName || !aNameSpaceID || !aNodeValue || !aNumChildren ||
       !aUniqueID || !aNodeType)
     return E_INVALIDARG;
 
-  *aNodeName = NULL;
+  *aNodeName = nullptr;
   *aNameSpaceID = 0;
-  *aNodeValue = NULL;
+  *aNodeValue = nullptr;
   *aNumChildren = 0;
   *aUniqueID = 0;
   *aNodeType = 0;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mNode));
@@ -138,17 +138,17 @@ sdnAccessible::get_attributes(unsigned  
   uint32_t numAttribs = elm->GetAttrCount();
   if (numAttribs > aMaxAttribs)
     numAttribs = aMaxAttribs;
 
   *aNumAttribs = static_cast<unsigned short>(numAttribs);
 
   for (uint32_t index = 0; index < numAttribs; index++) {
     aNameSpaceIDs[index] = 0;
-    aAttribValues[index] = aAttribNames[index] = NULL;
+    aAttribValues[index] = aAttribNames[index] = nullptr;
     nsAutoString attributeValue;
 
     const nsAttrName* name = elm->GetAttrNameAt(index);
     aNameSpaceIDs[index] = static_cast<short>(name->NamespaceID());
     aAttribNames[index] = ::SysAllocString(name->LocalName()->GetUTF16String());
     elm->GetAttr(name->NamespaceID(), name->LocalName(), attributeValue);
     aAttribValues[index] = ::SysAllocString(attributeValue.get());
   }
@@ -176,17 +176,17 @@ sdnAccessible::get_attributesForNames(un
     return S_FALSE;
 
   nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(mNode));
   nsCOMPtr<nsINameSpaceManager> nameSpaceManager =
     do_GetService(NS_NAMESPACEMANAGER_CONTRACTID);
 
   int32_t index = 0;
   for (index = 0; index < aMaxAttribs; index++) {
-    aAttribValues[index] = NULL;
+    aAttribValues[index] = nullptr;
     if (aAttribNames[index]) {
       nsAutoString attributeValue, nameSpaceURI;
       nsAutoString attributeName(nsDependentString(
         static_cast<PRUnichar*>(aAttribNames[index])));
 
       nsresult rv = NS_OK;
       if (aNameSpaceID[index]>0 &&
         NS_SUCCEEDED(nameSpaceManager->GetNameSpaceURI(aNameSpaceID[index],
@@ -316,17 +316,17 @@ sdnAccessible::scrollTo(boolean aScrollT
 
 STDMETHODIMP
 sdnAccessible::get_parentNode(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aNode)
     return E_INVALIDARG;
-  *aNode = NULL;
+  *aNode = nullptr;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsINode* resultNode = mNode->GetParentNode();
   if (resultNode) {
     *aNode = new sdnAccessible(resultNode);
     (*aNode)->AddRef();
@@ -339,17 +339,17 @@ sdnAccessible::get_parentNode(ISimpleDOM
 
 STDMETHODIMP
 sdnAccessible::get_firstChild(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aNode)
     return E_INVALIDARG;
-  *aNode = NULL;
+  *aNode = nullptr;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsINode* resultNode = mNode->GetFirstChild();
   if (resultNode) {
     *aNode = new sdnAccessible(resultNode);
     (*aNode)->AddRef();
@@ -362,17 +362,17 @@ sdnAccessible::get_firstChild(ISimpleDOM
 
 STDMETHODIMP
 sdnAccessible::get_lastChild(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aNode)
     return E_INVALIDARG;
-  *aNode = NULL;
+  *aNode = nullptr;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsINode* resultNode = mNode->GetLastChild();
   if (resultNode) {
     *aNode = new sdnAccessible(resultNode);
     (*aNode)->AddRef();
@@ -385,17 +385,17 @@ sdnAccessible::get_lastChild(ISimpleDOMN
 
 STDMETHODIMP
 sdnAccessible::get_previousSibling(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aNode)
     return E_INVALIDARG;
-  *aNode = NULL;
+  *aNode = nullptr;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsINode* resultNode = mNode->GetPreviousSibling();
   if (resultNode) {
     *aNode = new sdnAccessible(resultNode);
     (*aNode)->AddRef();
@@ -408,17 +408,17 @@ sdnAccessible::get_previousSibling(ISimp
 
 STDMETHODIMP
 sdnAccessible::get_nextSibling(ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aNode)
     return E_INVALIDARG;
-  *aNode = NULL;
+  *aNode = nullptr;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsINode* resultNode = mNode->GetNextSibling();
   if (resultNode) {
     *aNode = new sdnAccessible(resultNode);
     (*aNode)->AddRef();
@@ -432,17 +432,17 @@ sdnAccessible::get_nextSibling(ISimpleDO
 STDMETHODIMP
 sdnAccessible::get_childAt(unsigned aChildIndex,
                            ISimpleDOMNode __RPC_FAR *__RPC_FAR* aNode)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aNode)
     return E_INVALIDARG;
-  *aNode = NULL;
+  *aNode = nullptr;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsINode* resultNode = mNode->GetChildAt(aChildIndex);
   if (resultNode) {
     *aNode = new sdnAccessible(resultNode);
     (*aNode)->AddRef();
@@ -456,17 +456,17 @@ sdnAccessible::get_childAt(unsigned aChi
 
 STDMETHODIMP
 sdnAccessible::get_innerHTML(BSTR __RPC_FAR* aInnerHTML)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aInnerHTML)
     return E_INVALIDARG;
-  *aInnerHTML = NULL;
+  *aInnerHTML = nullptr;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(mNode);
   if (!htmlElement)
     return S_FALSE;
 
@@ -486,17 +486,17 @@ sdnAccessible::get_innerHTML(BSTR __RPC_
 
 STDMETHODIMP
 sdnAccessible::get_localInterface(void __RPC_FAR *__RPC_FAR* aLocalInterface)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aLocalInterface)
     return E_INVALIDARG;
-  *aLocalInterface = NULL;
+  *aLocalInterface = nullptr;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   *aLocalInterface = this;
   AddRef();
 
   return S_OK;
@@ -506,17 +506,17 @@ sdnAccessible::get_localInterface(void _
 
 STDMETHODIMP
 sdnAccessible::get_language(BSTR __RPC_FAR* aLanguage)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aLanguage)
     return E_INVALIDARG;
-  *aLanguage = NULL;
+  *aLanguage = nullptr;
 
   if (IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsAutoString language;
   if (mNode->IsElement())
     nsCoreUtils::GetLanguageFor(mNode->AsElement(), nullptr, language);
   if (language.IsEmpty()) { // Nothing found, so use document's language
--- a/accessible/src/windows/uia/moz.build
+++ b/accessible/src/windows/uia/moz.build
@@ -1,7 +1,8 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'accessibility'
 
--- a/accessible/src/windows/uia/uiaRawElmProvider.cpp
+++ b/accessible/src/windows/uia/uiaRawElmProvider.cpp
@@ -28,33 +28,33 @@ STDMETHODIMP
 uiaRawElmProvider::GetObjectForChild(long aIdChild,
                                      __RPC__deref_out_opt IAccessibleEx** aAccEx)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aAccEx)
     return E_INVALIDARG;
 
-  *aAccEx = NULL;
+  *aAccEx = nullptr;
 
   return mAcc->IsDefunct() ? CO_E_OBJNOTCONNECTED : S_OK;
 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 uiaRawElmProvider::GetIAccessiblePair(__RPC__deref_out_opt IAccessible** aAcc,
                                       __RPC__out long* aIdChild)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aAcc || !aIdChild)
     return E_INVALIDARG;
 
-  *aAcc = NULL;
+  *aAcc = nullptr;
   *aIdChild = 0;
 
   if (mAcc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   *aIdChild = CHILDID_SELF;
   *aAcc = mAcc;
   mAcc->AddRef();
@@ -89,19 +89,19 @@ STDMETHODIMP
 uiaRawElmProvider::ConvertReturnedElement(__RPC__in_opt IRawElementProviderSimple* aRawElmProvider,
                                           __RPC__deref_out_opt IAccessibleEx** aAccEx)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aRawElmProvider || !aAccEx)
     return E_INVALIDARG;
 
-  *aAccEx = NULL;
+  *aAccEx = nullptr;
 
-  void* instancePtr = NULL;
+  void* instancePtr = nullptr;
   HRESULT hr = aRawElmProvider->QueryInterface(IID_IAccessibleEx, &instancePtr);
   if (SUCCEEDED(hr))
     *aAccEx = static_cast<IAccessibleEx*>(instancePtr);
 
   return hr;
 
   A11Y_TRYBLOCK_END
 }
@@ -128,17 +128,17 @@ STDMETHODIMP
 uiaRawElmProvider::GetPatternProvider(PATTERNID aPatternId,
                                       __RPC__deref_out_opt IUnknown** aPatternProvider)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aPatternProvider)
     return E_INVALIDARG;
 
-  *aPatternProvider = NULL;
+  *aPatternProvider = nullptr;
   return S_OK;
 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
 uiaRawElmProvider::GetPropertyValue(PROPERTYID aPropertyId,
                                     __RPC__out VARIANT* aPropertyValue)
@@ -234,13 +234,13 @@ STDMETHODIMP
 uiaRawElmProvider::get_HostRawElementProvider(__RPC__deref_out_opt IRawElementProviderSimple** aRawElmProvider)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aRawElmProvider)
     return E_INVALIDARG;
 
   // This method is not used with IAccessibleEx implementations.
-  *aRawElmProvider = NULL;
+  *aRawElmProvider = nullptr;
   return S_OK;
 
   A11Y_TRYBLOCK_END
 }
--- a/accessible/src/xpcom/moz.build
+++ b/accessible/src/xpcom/moz.build
@@ -1,7 +1,8 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'accessibility'
 
--- a/accessible/src/xul/Makefile.in
+++ b/accessible/src/xul/Makefile.in
@@ -38,16 +38,17 @@ include $(topsrcdir)/config/rules.mk
 LOCAL_INCLUDES = \
   -I$(srcdir) \
   -I$(srcdir)/../base \
   -I$(srcdir)/../generic \
   -I$(srcdir)/../html \
   -I$(srcdir)/../xpcom \
   -I$(srcdir)/../../../layout/generic \
   -I$(srcdir)/../../../layout/xul/base/src \
+  -I$(srcdir)/../../../layout/xul/tree// \
   $(NULL)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
 LOCAL_INCLUDES += \
   -I$(srcdir)/../atk \
   $(NULL)
 else
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
--- a/accessible/src/xul/XULTreeAccessible.cpp
+++ b/accessible/src/xul/XULTreeAccessible.cpp
@@ -22,39 +22,40 @@
 #include "nsIAutoCompleteInput.h"
 #include "nsIAutoCompletePopup.h"
 #include "nsIDOMXULElement.h"
 #include "nsIDOMXULMenuListElement.h"
 #include "nsIDOMXULMultSelectCntrlEl.h"
 #include "nsIDOMXULTreeElement.h"
 #include "nsITreeSelection.h"
 #include "nsIMutableArray.h"
+#include "nsTreeBodyFrame.h"
+#include "nsTreeColumns.h"
+#include "nsTreeUtils.h"
 
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 XULTreeAccessible::
-  XULTreeAccessible(nsIContent* aContent, DocAccessible* aDoc) :
+  XULTreeAccessible(nsIContent* aContent, DocAccessible* aDoc,
+                    nsTreeBodyFrame* aTreeFrame) :
   AccessibleWrap(aContent, aDoc)
 {
   mType = eXULTreeType;
   mGenericTypes |= eSelect;
 
+  nsCOMPtr<nsITreeView> view = aTreeFrame->GetExistingView();
+  mTreeView = view;
+
   mTree = nsCoreUtils::GetTreeBoxObject(aContent);
   NS_ASSERTION(mTree, "Can't get mTree!\n");
 
-  if (mTree) {
-    nsCOMPtr<nsITreeView> treeView;
-    mTree->GetView(getter_AddRefs(treeView));
-    mTreeView = treeView;
-  }
-
   nsIContent* parentContent = mContent->GetParent();
   if (parentContent) {
     nsCOMPtr<nsIAutoCompletePopup> autoCompletePopupElm =
       do_QueryInterface(parentContent);
     if (autoCompletePopupElm)
       mGenericTypes |= eAutoCompletePopup;
   }
 
@@ -154,21 +155,26 @@ XULTreeAccessible::Shutdown()
 // XULTreeAccessible: Accessible implementation (put methods here)
 
 role
 XULTreeAccessible::NativeRole()
 {
   // No primary column means we're in a list. In fact, history and mail turn off
   // the primary flag when switching to a flat view.
 
-  nsCOMPtr<nsITreeColumns> cols;
-  mTree->GetColumns(getter_AddRefs(cols));
+  nsIContent* child = nsTreeUtils::GetDescendantChild(mContent, nsGkAtoms::treechildren);
+  NS_ASSERTION(child, "tree without treechildren!");
+  nsTreeBodyFrame* treeFrame = do_QueryFrame(child->GetPrimaryFrame());
+  NS_ASSERTION(treeFrame, "xul tree accessible for tree without a frame!");
+  if (!treeFrame)
+    return roles::LIST;
+
+  nsRefPtr<nsTreeColumns> cols = treeFrame->Columns();
   nsCOMPtr<nsITreeColumn> primaryCol;
-  if (cols)
-    cols->GetPrimaryColumn(getter_AddRefs(primaryCol));
+  cols->GetPrimaryColumn(getter_AddRefs(primaryCol));
 
   return primaryCol ? roles::OUTLINE : roles::LIST;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeAccessible: Accessible implementation (DON'T put methods here)
 
 Accessible*
--- a/accessible/src/xul/XULTreeAccessible.h
+++ b/accessible/src/xul/XULTreeAccessible.h
@@ -6,16 +6,18 @@
 #ifndef mozilla_a11y_XULTreeAccessible_h__
 #define mozilla_a11y_XULTreeAccessible_h__
 
 #include "nsITreeBoxObject.h"
 #include "nsITreeView.h"
 #include "nsITreeColumns.h"
 #include "XULListboxAccessible.h"
 
+class nsTreeBodyFrame;
+
 namespace mozilla {
 namespace a11y {
 
 /*
  * A class the represents the XUL Tree widget.
  */
 const uint32_t kMaxTreeColumns = 100;
 const uint32_t kDefaultTreeCacheSize = 256;
@@ -24,17 +26,18 @@ const uint32_t kDefaultTreeCacheSize = 2
  * Accessible class for XUL tree element.
  */
 
 class XULTreeAccessible : public AccessibleWrap
 {
 public:
   using Accessible::GetChildAt;
 
-  XULTreeAccessible(nsIContent* aContent, DocAccessible* aDoc);
+  XULTreeAccessible(nsIContent* aContent, DocAccessible* aDoc,
+                    nsTreeBodyFrame* aTreeframe);
 
   // nsISupports and cycle collection
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(XULTreeAccessible, Accessible)
 
   // nsAccessNode
   virtual void Shutdown();
 
--- a/accessible/src/xul/XULTreeGridAccessible.cpp
+++ b/accessible/src/xul/XULTreeGridAccessible.cpp
@@ -16,27 +16,16 @@
 
 #include "nsIMutableArray.h"
 #include "nsITreeSelection.h"
 #include "nsComponentManagerUtils.h"
 
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
-// XULTreeGridAccessible
-////////////////////////////////////////////////////////////////////////////////
-
-XULTreeGridAccessible::
-  XULTreeGridAccessible(nsIContent* aContent, DocAccessible* aDoc) :
-  XULTreeAccessible(aContent, aDoc), xpcAccessibleTable(this)
-{
-  mGenericTypes |= eTable;
-}
-
-////////////////////////////////////////////////////////////////////////////////
 // XULTreeGridAccessible: nsISupports implementation
 
 NS_IMPL_ISUPPORTS_INHERITED1(XULTreeGridAccessible,
                              XULTreeAccessible,
                              nsIAccessibleTable)
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeGridAccessible: nsIAccessibleTable implementation
--- a/accessible/src/xul/XULTreeGridAccessible.h
+++ b/accessible/src/xul/XULTreeGridAccessible.h
@@ -19,17 +19,20 @@ namespace a11y {
  * Represents accessible for XUL tree in the case when it has multiple columns.
  */
 class XULTreeGridAccessible : public XULTreeAccessible,
                               public xpcAccessibleTable,
                               public nsIAccessibleTable,
                               public TableAccessible
 {
 public:
-  XULTreeGridAccessible(nsIContent* aContent, DocAccessible* aDoc);
+  XULTreeGridAccessible(nsIContent* aContent, DocAccessible* aDoc,
+                        nsTreeBodyFrame* aTreeFrame) :
+    XULTreeAccessible(aContent, aDoc, aTreeFrame), xpcAccessibleTable(this)
+    { mGenericTypes |= eTable; }
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIAccessibleTable
   NS_FORWARD_NSIACCESSIBLETABLE(xpcAccessibleTable::)
 
   // TableAccessible
--- a/accessible/src/xul/moz.build
+++ b/accessible/src/xul/moz.build
@@ -1,7 +1,8 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'accessibility'
 
--- a/accessible/tests/mochitest/actions/moz.build
+++ b/accessible/tests/mochitest/actions/moz.build
@@ -1,7 +1,8 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 MODULE = 'alerts'
 
--- a/accessible/tests/mochitest/attributes/moz.build
+++ b/accessible/tests/mochitest/attributes/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/mochitest/attributes/test_xml-roles.html
+++ b/accessible/tests/mochitest/attributes/test_xml-roles.html
@@ -16,17 +16,22 @@
           src="../attributes.js"></script>
 
   <script type="application/javascript">
 
     function doTest()
     {
       // Some AT may look for this
       testAttrs("nav", {"xml-roles" : "navigation"}, true);
+      testAttrs("header", {"xml-roles" : "banner"}, true);
+      testAbsentAttrs("article_header", {"xml-roles" : "banner"});
+      testAbsentAttrs("section_header", {"xml-roles" : "banner"});
       testAttrs("footer", {"xml-roles" : "contentinfo"}, true);
+      testAbsentAttrs("article_footer", {"xml-roles" : "contentinfo"});
+      testAbsentAttrs("section_footer", {"xml-roles" : "contentinfo"});
       testAttrs("aside", {"xml-roles" : "complementary"}, true);
       testAttrs("section", {"xml-roles" : "region"}, true);
       testAttrs("main", {"xml-roles" : "main"}, true); // // ARIA override
       testAttrs("form", {"xml-roles" : "form"}, true);
       testAttrs("article", {"xml-roles" : "article"}, true);
       testAttrs("main_element", {"xml-roles" : "main"}, true);
 
       SimpleTest.finish();
@@ -63,23 +68,37 @@
      title="Map ARIA role FORM">
     Bug 734982
   </a>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=761891"
      title="HTML5 article element should expose xml-roles:article object attribute">
     Bug 761891
   </a>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=849624"
+     title="modify HTML5 header and footer accessibility API mapping">
+    Bug 849624
+  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <nav id="nav">a nav</nav>
+  <header id="header">a header</header>
   <footer id="footer">a footer</footer>
+  <article id="article_with_header_and_footer">
+    <header id="article_header">a header within an article</header>
+    <footer id="article_footer">a footer within an article</footer>
+  </article>
+  <section id="section_with_header_and_footer">
+    <header id="section_header">a header within an section</header>
+    <footer id="section_footer">a footer within an section</footer>
+  </section>
   <aside id="aside">by the way I am an aside</aside>
   <section id="section">a section</section>
   <article id="main" role="main">a main area</article>
   <article id="form" role="form">a form area</article>
   <article id="article">article</article>
   <main id="main_element">another main area</main>
 
 </body>
--- a/accessible/tests/mochitest/bounds/moz.build
+++ b/accessible/tests/mochitest/bounds/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/mochitest/editabletext/moz.build
+++ b/accessible/tests/mochitest/editabletext/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/mochitest/elm/moz.build
+++ b/accessible/tests/mochitest/elm/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/mochitest/events/moz.build
+++ b/accessible/tests/mochitest/events/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/mochitest/events/test_focus_autocomplete.xul
+++ b/accessible/tests/mochitest/events/test_focus_autocomplete.xul
@@ -27,19 +27,16 @@
   <script type="application/javascript"
           src="../events.js" />
 
   <script type="application/javascript"
           src="../autocomplete.js" />
 
   <script type="application/javascript">
   <![CDATA[
-    if (!navigator.platform.startsWith("Mac")) {
-      SimpleTest.expectAssertions(2);
-    }
     ////////////////////////////////////////////////////////////////////////////
     // Hacky stuffs
 
     // This is the hack needed for searchbar work outside of browser.
     function getBrowser()
     {
       return {
         mCurrentBrowser: { engines: new Array() }
--- a/accessible/tests/mochitest/events/test_statechange.html
+++ b/accessible/tests/mochitest/events/test_statechange.html
@@ -72,27 +72,26 @@
       };
     }
 
     function stateChangeOnFileInput(aID, aAttr, aValue,
                                     aState, aIsExtraState, aIsEnabled)
     {
       this.fileControlNode = getNode(aID);
       this.fileControl = getAccessible(this.fileControlNode);
-      this.textEntry = this.fileControl.firstChild;
-      this.browseButton = this.fileControl.lastChild;
+      this.browseButton = this.fileControl.firstChild;
+      // No state change events on the label.
 
       this.invoke = function stateChangeOnFileInput_invoke()
       {
         this.fileControlNode.setAttribute(aAttr, aValue);
       }
 
       this.eventSeq = [
         new stateChangeChecker(aState, aIsExtraState, aIsEnabled, this.fileControl),
-        new stateChangeChecker(aState, aIsExtraState, aIsEnabled, this.textEntry),
         new stateChangeChecker(aState, aIsExtraState, aIsEnabled, this.browseButton)
       ];
 
       this.getID = function stateChangeOnFileInput_getID()
       {
         return "inherited state change on file input on attribute '" + aAttr + "' change";
       }
     }
--- a/accessible/tests/mochitest/focus/moz.build
+++ b/accessible/tests/mochitest/focus/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/mochitest/focus/test_focusedChild.html
+++ b/accessible/tests/mochitest/focus/test_focusedChild.html
@@ -52,17 +52,17 @@
       }
     }
 
     gA11yEventDumpToConsole = true;
     var gQueue = null;
 
     function doTest()
     {
-      enableLogging("focus");
+      enableLogging("focus,doclifecycle");
       gQueue = new eventQueue();
 
       gQueue.push(new openWnd());
 
       gQueue.onFinish = function() { disableLogging(); }
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
--- a/accessible/tests/mochitest/hittest/moz.build
+++ b/accessible/tests/mochitest/hittest/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/mochitest/hyperlink/moz.build
+++ b/accessible/tests/mochitest/hyperlink/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/mochitest/hypertext/moz.build
+++ b/accessible/tests/mochitest/hypertext/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/mochitest/moz.build
+++ b/accessible/tests/mochitest/moz.build
@@ -1,8 +1,9 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 DIRS += [
     'actions',
     'attributes',
--- a/accessible/tests/mochitest/name/moz.build
+++ b/accessible/tests/mochitest/name/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/mochitest/pivot/moz.build
+++ b/accessible/tests/mochitest/pivot/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/mochitest/relations/moz.build
+++ b/accessible/tests/mochitest/relations/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/mochitest/role/moz.build
+++ b/accessible/tests/mochitest/role/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/mochitest/scroll/moz.build
+++ b/accessible/tests/mochitest/scroll/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/mochitest/selectable/moz.build
+++ b/accessible/tests/mochitest/selectable/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/mochitest/states/moz.build
+++ b/accessible/tests/mochitest/states/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/mochitest/states/test_aria.html
+++ b/accessible/tests/mochitest/states/test_aria.html
@@ -127,22 +127,20 @@
       // aria-selectable
       testStates("aria_selectable_listitem", STATE_SELECTABLE | STATE_SELECTED);
 
       // active state caused by aria-activedescendant
       testStates("as_item1", 0, EXT_STATE_ACTIVE);
       testStates("as_item2", 0, 0, 0, EXT_STATE_ACTIVE);
 
       // universal ARIA properties inherited from file input control
-      var fileTextField = getAccessible("fileinput").firstChild;
-      testStates(fileTextField,
-                 STATE_BUSY | STATE_UNAVAILABLE | STATE_REQUIRED | STATE_HASPOPUP | STATE_INVALID);
-      var fileBrowseButton = getAccessible("fileinput").lastChild;
+      var fileBrowseButton = getAccessible("fileinput").firstChild;
       testStates(fileBrowseButton,
                  STATE_BUSY | STATE_UNAVAILABLE | STATE_REQUIRED | STATE_HASPOPUP | STATE_INVALID);
+      // No states on the label.
 
       // offscreen test
       testStates("aria_offscreen_textbox", STATE_OFFSCREEN);
 
       //
       // This section tests aria roles on links/anchors for underlying
       // HTMLLinkAccessible creation. (see closed bug 494807)
       //
--- a/accessible/tests/mochitest/states/test_inputs.html
+++ b/accessible/tests/mochitest/states/test_inputs.html
@@ -62,20 +62,19 @@
     ////////////////////////////////////////////////////////////////////////////
     // inherited 'unavailable' state
     testStates("f", STATE_UNAVAILABLE);
     testStates("f_input", STATE_UNAVAILABLE);
     testStates("f_input_disabled", STATE_UNAVAILABLE);
 
     ////////////////////////////////////////////////////////////////////////////
     // inherited from file control
-    var fileTextField = getAccessible("file").firstChild;
-    testStates(fileTextField, STATE_UNAVAILABLE | STATE_REQUIRED);
-    var fileBrowseButton = getAccessible("file").lastChild;
+    var fileBrowseButton = getAccessible("file").firstChild;
     testStates(fileBrowseButton, STATE_UNAVAILABLE | STATE_REQUIRED);
+    // No states on the label.
 
     ////////////////////////////////////////////////////////////////////////////
     // 'invalid' state
 
     // XXX: maxlength doesn't make the element invalid until bug 613016 and
     // bug 613019 are fixed. Commenting out related lines and adding a todo to
     // make sure it will be uncommented as soon as possible.
     var todoInput = document.createElement("input");
--- a/accessible/tests/mochitest/states/test_tree.xul
+++ b/accessible/tests/mochitest/states/test_tree.xul
@@ -91,20 +91,18 @@
       gQueue.push(new statesChecker("tree", new nsTreeTreeView()));
       gQueue.push(new statesChecker("treesingle", new nsTreeTreeView()));
       gQueue.push(new statesChecker("tabletree", new nsTreeTreeView()));
 
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     if (MAC && (navigator.userAgent.indexOf("Mac OS X 10.6") != -1)) {
-
       todo(false,
            "Re-enable on Mac OS 10.6 after fixing bug 845095 - intermittent orange");
-      SimpleTest.finish();
     } else {
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
     }
   ]]>
   </script>
 
   <hbox flex="1" style="overflow: auto;">
--- a/accessible/tests/mochitest/table/moz.build
+++ b/accessible/tests/mochitest/table/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/mochitest/text.js
+++ b/accessible/tests/mochitest/text.js
@@ -107,26 +107,39 @@ function testCharAtOffset(aIDs, aOffset,
 /**
  * Test getTextAtOffset function over different elements
  *
  * @param aOffset         [in] the offset to get the text at
  * @param aBoundaryType   [in] Boundary type for text to be retrieved
  * @param aText           [in] expected return text for getTextAtOffset
  * @param aStartOffset    [in] expected return start offset for getTextAtOffset
  * @param aEndOffset      [in] expected return end offset for getTextAtOffset
- * @param ...             [in] list of tuples made of:
+ * @param ...             [in] list of ids or list of tuples made of:
  *                              element identifier
  *                              kTodo or kOk for returned text
  *                              kTodo or kOk for returned start offset
  *                              kTodo or kOk for returned offset result
- *          
  */
 function testTextAtOffset(aOffset, aBoundaryType, aText,
                           aStartOffset, aEndOffset)
 {
+  // List of IDs.
+  if (arguments[5] instanceof Array) {
+    var ids = arguments[5];
+    for (var i = 0; i < ids.length; i++) {
+      var acc = getAccessible(ids[i], nsIAccessibleText);
+      testTextHelper(ids[i], aOffset, aBoundaryType,
+                     aText, aStartOffset, aEndOffset,
+                     kOk, kOk, kOk,
+                     acc.getTextAtOffset, "getTextAtOffset ");
+    }
+
+    return;
+  }
+
   for (var i = 5; i < arguments.length; i = i + 4) {
     var ID = arguments[i];
     var acc = getAccessible(ID, nsIAccessibleText);
     var toDoFlag1 = arguments[i + 1];
     var toDoFlag2 = arguments[i + 2];
     var toDoFlag3 = arguments[i + 3];
 
     testTextHelper(ID, aOffset, aBoundaryType,
@@ -161,25 +174,40 @@ function testCharAfterOffset(aIDs, aOffs
 /**
  * Test getTextAfterOffset function over different elements
  *
  * @param aOffset         [in] the offset to get the text after
  * @param aBoundaryType   [in] Boundary type for text to be retrieved
  * @param aText           [in] expected return text for getTextAfterOffset
  * @param aStartOffset    [in] expected return start offset for getTextAfterOffset
  * @param aEndOffset      [in] expected return end offset for getTextAfterOffset
- * @param ...             [in] list of tuples made of:
+ * @param ...             [in] list of ids or list of tuples made of:
  *                              element identifier
  *                              kTodo or kOk for returned text
  *                              kTodo or kOk for returned start offset
  *                              kTodo or kOk for returned offset result
  */
 function testTextAfterOffset(aOffset, aBoundaryType,
                              aText, aStartOffset, aEndOffset)
 {
+  // List of IDs.
+  if (arguments[5] instanceof Array) {
+    var ids = arguments[5];
+    for (var i = 0; i < ids.length; i++) {
+      var acc = getAccessible(ids[i], nsIAccessibleText);
+      testTextHelper(ids[i], aOffset, aBoundaryType,
+                     aText, aStartOffset, aEndOffset,
+                     kOk, kOk, kOk,
+                     acc.getTextAfterOffset, "getTextAfterOffset ");
+    }
+
+    return;
+  }
+
+  // List of tuples.
   for (var i = 5; i < arguments.length; i = i + 4) {
     var ID = arguments[i];
     var acc = getAccessible(ID, nsIAccessibleText);
     var toDoFlag1 = arguments[i + 1];
     var toDoFlag2 = arguments[i + 2];
     var toDoFlag3 = arguments[i + 3];
 
     testTextHelper(ID, aOffset, aBoundaryType,
@@ -214,26 +242,39 @@ function testCharBeforeOffset(aIDs, aOff
 /**
  * Test getTextBeforeOffset function over different elements
  *
  * @param aOffset         [in] the offset to get the text before
  * @param aBoundaryType   [in] Boundary type for text to be retrieved
  * @param aText           [in] expected return text for getTextBeforeOffset
  * @param aStartOffset    [in] expected return start offset for getTextBeforeOffset
  * @param aEndOffset      [in] expected return end offset for getTextBeforeOffset
- * @param ...             [in] list of tuples made of:
+ * @param ...             [in] list of ids or list of tuples made of:
  *                              element identifier
  *                              kTodo or kOk for returned text
  *                              kTodo or kOk for returned start offset
  *                              kTodo or kOk for returned offset result
- *          
  */
 function testTextBeforeOffset(aOffset, aBoundaryType,
                               aText, aStartOffset, aEndOffset)
 {
+  // List of IDs.
+  if (arguments[5] instanceof Array) {
+    var ids = arguments[5];
+    for (var i = 0; i < ids.length; i++) {
+      var acc = getAccessible(ids[i], nsIAccessibleText);
+      testTextHelper(ids[i], aOffset, aBoundaryType,
+                     aText, aStartOffset, aEndOffset,
+                     kOk, kOk, kOk,
+                     acc.getTextBeforeOffset, "getTextBeforeOffset ");
+    }
+
+    return;
+  }
+
   for (var i = 5; i < arguments.length; i = i + 4) {
     var ID = arguments[i];
     var acc = getAccessible(ID, nsIAccessibleText);
     var toDoFlag1 = arguments[i + 1];
     var toDoFlag2 = arguments[i + 2];
     var toDoFlag3 = arguments[i + 3];
 
     testTextHelper(ID, aOffset, aBoundaryType,
@@ -262,68 +303,74 @@ function testWordCount(aElement, aCount,
     var text = acc.getTextAtOffset(offset, BOUNDARY_WORD_START,
                                    startOffsetObj, endOffsetObj);
     if (offset >= length)
       break;
 
     wordCount++;
     offset = endOffsetObj.value;
   }
-  isFunc(wordCount, aCount,  "wrong words count for '" + acc.getText(0, -1) + "': " +
-         wordCount);
+  isFunc(wordCount, aCount,
+        "wrong words count for '" + acc.getText(0, -1) + "': " + wordCount +
+        " in " + prettyName(aElement));
 }
 
 /**
  * Test word at a position for an element.
  *
  * @param aElement    [in] element identifier
  * @param aWordIndex  [in] index of the word to test
  * @param aText       [in] expected text for that word
  * @param aToDoFlag   [in] kTodo or kOk for returned text
  */
 function testWordAt(aElement, aWordIndex, aText, aToDoFlag)
 {
   var isFunc = (aToDoFlag == kTodo) ? todo_is : is;
   var acc = getAccessible(aElement, nsIAccessibleText);
-  var startOffsetObj = {}, endOffsetObj = {};
-  var length = acc.characterCount;
-  var offset = 0;
-  var wordIndex = -1;
-  var wordFountAtOffset = -1;
-  while (true) {
-    var text = acc.getTextAtOffset(offset, BOUNDARY_WORD_START,
-                                   startOffsetObj, endOffsetObj);
-    if (offset >= length)
+
+  var textLength = acc.characterCount;
+  var wordIdx = aWordIndex;
+  var startOffsetObj = { value: 0 }, endOffsetObj = { value: 0 };
+  for (offset = 0; offset < textLength; offset = endOffsetObj.value) {
+    acc.getTextAtOffset(offset, BOUNDARY_WORD_START,
+                        startOffsetObj, endOffsetObj);
+
+    wordIdx--;
+    if (wordIdx < 0)
       break;
+  }
+
+  if (wordIdx >= 0) {
+    ok(false,
+       "the given word index '" + aWordIndex + "' exceeds words amount in " +
+       prettyName(aElement));
+
+    return;
+  }
 
-    wordIndex++;
-    offset = endOffsetObj.value;
-    if (wordIndex == aWordIndex) {
-       wordFountAtOffset = startOffsetObj.value;
-       break;
-    }
-  } 
-  if (wordFountAtOffset >= 0) {
-    var text = acc.getTextAtOffset(wordFountAtOffset, BOUNDARY_WORD_END,
-                                   startOffsetObj, endOffsetObj);
+  var startWordOffset = startOffsetObj.value;
+  var endWordOffset = endOffsetObj.value;
+
+  // Calculate the end word offset.
+  acc.getTextAtOffset(endOffsetObj.value, BOUNDARY_WORD_END,
+                      startOffsetObj, endOffsetObj);
+  if (startOffsetObj.value != textLength)
+    endWordOffset = startOffsetObj.value
 
-    if (endOffsetObj.value < wordFountAtOffset) {
-      todo(false,  "wrong start and end offset for word '" + aWordIndex + "': " +
-           " of text '" + acc.getText(0, -1) + "'");
-      return;
-    }
+  if (endWordOffset <= startWordOffset) {
+    todo(false,
+         "wrong start and end offset for word at index '" + aWordIndex + "': " +
+         " of text '" + acc.getText(0, -1) + "' in " + prettyName(aElement));
 
-    text = acc.getText(wordFountAtOffset, endOffsetObj.value);
-    isFunc(text, aText,  "wrong text for word at pos '" + aWordIndex + "': " +
-           " of text '" + acc.getText(0, -1) + "'");
+    return;
   }
-  else {
-    isFunc(false, "failed to find word " + aText + " at word pos " + aWordIndex +
-           " of text '" + acc.getText(0, -1) + "'");
-  }
+
+  text = acc.getText(startWordOffset, endWordOffset);
+  isFunc(text, aText,  "wrong text for word at index '" + aWordIndex + "': " +
+         " of text '" + acc.getText(0, -1) + "' in " + prettyName(aElement));
 }
 
 /**
  * Test words in a element.
  *
  * @param aElement   [in]           element identifier
  * @param aWords     [in]           array of expected words
  * @param aToDoFlag  [in, optional] kTodo or kOk for returned text
@@ -458,36 +505,41 @@ function testTextGetSelection(aID, aStar
 function testTextHelper(aID, aOffset, aBoundaryType,
                         aText, aStartOffset, aEndOffset,
                         aToDoFlag1, aToDoFlag2, aToDoFlag3,
                         aTextFunc, aTextFuncName)
 {
   var exceptionFlag = aToDoFlag1 == undefined ||
                       aToDoFlag2 == undefined ||
                       aToDoFlag3 == undefined;
+
+  var startMsg = aTextFuncName + "(" + boundaryToString(aBoundaryType) + "): ";
+  var endMsg = ", id: " + prettyName(aID) + ";";
+
   try {
     var startOffsetObj = {}, endOffsetObj = {};
     var text = aTextFunc(aOffset, aBoundaryType,
                          startOffsetObj, endOffsetObj);
-    
+
+    if (exceptionFlag) {
+      ok(false, startMsg + "no expected failure at offset " + aOffset + endMsg);
+      return;
+    }
+
     var isFunc1 = (aToDoFlag1 == kTodo) ? todo_is : is;
     var isFunc2 = (aToDoFlag2 == kTodo) ? todo_is : is;
     var isFunc3 = (aToDoFlag3 == kTodo) ? todo_is : is;
 
-    var startMsg = aTextFuncName + "(" + boundaryToString(aBoundaryType) + "): ";
-
-    var endMsg = ", id: '" + prettyName(aID) + "';";
-    
     isFunc1(text, aText,
             startMsg + "wrong text, offset: " + aOffset + endMsg);
     isFunc2(startOffsetObj.value, aStartOffset,
             startMsg + "wrong start offset, offset: " + aOffset + endMsg);
     isFunc3(endOffsetObj.value, aEndOffset,
             startMsg + "wrong end offset, offset: " + aOffset + endMsg);
-    
+
   } catch (e) {
     var okFunc = exceptionFlag ? todo : ok;
     okFunc(false, startMsg + "failed at offset " + aOffset + endMsg);
   }
 }
 
 function boundaryToString(aBoundaryType)
 {
--- a/accessible/tests/mochitest/text/moz.build
+++ b/accessible/tests/mochitest/text/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/mochitest/text/test_atcaretoffset.html
+++ b/accessible/tests/mochitest/text/test_atcaretoffset.html
@@ -39,17 +39,17 @@
       this.__proto__ = new synthFocus("textarea");
 
       this.finalCheck = function moveToLastLineEnd_finalCheck()
       {
         testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_START, "", 15, 15,
                             "textarea", kTodo, kOk, kTodo);
 
         testTextAfterOffset(kCaretOffset, BOUNDARY_LINE_END, "", 15, 15,
-                            "textarea", kOk, kTodo, kTodo);
+                            "textarea", kTodo, kOk, kTodo);
 
         testTextAtOffset(kCaretOffset, BOUNDARY_LINE_START, "", 15, 15,
                          "textarea", kTodo, kTodo, kTodo);
 
         testTextAtOffset(kCaretOffset, BOUNDARY_LINE_END, "words", 10, 15,
                          "textarea", kTodo, kTodo, kTodo);
 
         testTextBeforeOffset(kCaretOffset, BOUNDARY_LINE_START, "words", 10, 15,
--- a/accessible/tests/mochitest/text/test_multiline.html
+++ b/accessible/tests/mochitest/text/test_multiline.html
@@ -11,17 +11,17 @@
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../text.js"></script>
   <script type="application/javascript">
 
     function doTest()
     {
-      SimpleTest.expectAssertions(52);
+      SimpleTest.expectAssertions(44);
 
       // __o__n__e__w__o__r__d__\n
       //  0  1  2  3  4  5  6  7
       // __\n
       //  8
       // __t__w__o__ __w__o__r__d__s__\n
       //  9 10 11 12 13 14 15 16 17 18
 
@@ -61,19 +61,19 @@
       testTextAfterOffset(0, BOUNDARY_WORD_START, "two ", 9, 13,
                           "div", kTodo, kTodo, kTodo,
                           "divbr", kTodo, kTodo, kTodo,
                           "editable", kTodo, kTodo, kTodo,
                           "editablebr", kTodo, kTodo, kTodo,
                           "textarea", kTodo, kTodo, kTodo);
       testTextAfterOffset(8, BOUNDARY_WORD_START, "two ", 9, 13,
                           "div", kTodo, kTodo, kTodo,
-                          "divbr", kTodo, kTodo, kTodo,
+                          "divbr", kTodo, kTodo, kOk,
                           "editable", kTodo, kTodo, kTodo,
-                          "editablebr", kTodo, kTodo, kTodo,
+                          "editablebr", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kTodo);
       testTextAfterOffset(9, BOUNDARY_WORD_START, "words\n", 13, 19,
                           "div", kTodo, kTodo, kTodo,
                           "divbr", kTodo, kTodo, kTodo,
                           "editable", kTodo, kTodo, kTodo,
                           "editablebr", kTodo, kTodo, kTodo,
                           "textarea", kTodo, kTodo, kTodo);
 
@@ -124,21 +124,21 @@
                           "textarea", kTodo, kTodo, kTodo);
       testTextAfterOffset(9, BOUNDARY_LINE_START, "", 19, 19,
                           "div", kTodo, kTodo, kTodo,
                           "divbr", kTodo, kTodo, kOk,
                           "editable", kTodo, kTodo, kTodo,
                           "editablebr", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kOk);
       testTextAfterOffset(19, BOUNDARY_LINE_START, "", 19, 19,
-                          "div", undefined, undefined, undefined,
-                          "divbr", undefined, undefined, undefined,
-                          "editable", undefined, undefined, undefined,
-                          "editablebr", undefined, undefined, undefined,
-                          "textarea", kTodo, undefined, kTodo);
+                          "div", kOk, kOk, kTodo,
+                          "divbr", kOk, kOk, kOk,
+                          "editable", kOk, kOk, kTodo,
+                          "editablebr", kOk, kOk, kOk,
+                          "textarea", kOk, kOk, kOk);
 
       // BOUNDARY_LINE_END
       testTextAfterOffset(0, BOUNDARY_LINE_END, "\n", 7, 8,
                           "div", kTodo, kTodo, kTodo,
                           "divbr", kTodo, kTodo, kTodo,
                           "editable", kTodo, kTodo, kTodo,
                           "editablebr", kTodo, kTodo, kTodo,
                           "textarea", kTodo, kTodo, kTodo);
@@ -156,21 +156,21 @@
                           "textarea", kOk, kOk, kOk);
       testTextAfterOffset(9, BOUNDARY_LINE_END, "\n", 18, 19,
                           "div", kTodo, kTodo, kTodo,
                           "divbr", kTodo, kTodo, kTodo,
                           "editable", kTodo, kTodo, kTodo,
                           "editablebr", kTodo, kTodo, kTodo,
                           "textarea", kTodo, kTodo, kTodo);
       testTextAfterOffset(18, BOUNDARY_LINE_END, "\n", 18, 19,
-                          "div", kTodo, kTodo, kTodo,
-                          "divbr", kTodo, kTodo, kTodo,
-                          "editable", kTodo, kTodo, kTodo,
-                          "editablebr", kTodo, kTodo, kTodo,
-                          "textarea", kTodo, kTodo, kTodo);
+                          "div", kTodo, kOk, kTodo,
+                          "divbr", kOk, kOk, kOk,
+                          "editable", kTodo, kOk, kTodo,
+                          "editablebr", kOk, kOk, kOk,
+                          "textarea", kOk, kOk, kOk);
       testTextAfterOffset(19, BOUNDARY_LINE_END, "", 19, 19,
                           "div", kOk, kTodo, kTodo,
                           "divbr", kOk, kTodo, kTodo,
                           "editable", kOk, kTodo, kTodo,
                           "editablebr", kOk, kTodo, kTodo,
                           "textarea", kOk, kTodo, kTodo);
 
       ////////////////////////////////////////////////////////////////////////
@@ -192,106 +192,46 @@
       testTextBeforeOffset(10, BOUNDARY_CHAR, "t", 9, 10,
                            "div", kOk, kOk, kOk,
                            "divbr", kOk, kOk, kOk,
                            "editable", kOk, kOk, kOk,
                            "editablebr", kOk, kOk, kOk,
                            "textarea", kOk, kOk, kOk);
 
       // BOUNDARY_WORD_START
-      testTextBeforeOffset(0, BOUNDARY_WORD_START, "", 0, 0,
-                           "div", kOk, kOk, kOk,
-                           "divbr", kOk, kOk, kOk,
-                           "editable", kOk, kOk, kOk,
-                           "editablebr", kOk, kOk, kOk,
-                           "textarea", kOk, kOk, kOk);
-      testTextBeforeOffset(7, BOUNDARY_WORD_START, "", 0, 0,
-                           "div", kTodo, kOk, kTodo,
-                           "divbr", kTodo, kOk, kTodo,
-                           "editable", kTodo, kOk, kTodo,
-                           "editablebr", kTodo, kOk, kTodo,
-                           "textarea", kTodo, kOk, kTodo);
-      testTextBeforeOffset(8, BOUNDARY_WORD_START, "", 0, 0,
-                           "div", kTodo, kOk, kTodo,
-                           "divbr", kTodo, kOk, kTodo,
-                           "editable", kTodo, kOk, kTodo,
-                           "editablebr", kTodo, kOk, kTodo,
-                           "textarea", kTodo, kOk, kTodo);
-      testTextBeforeOffset(9, BOUNDARY_WORD_START, "oneword\n\n", 0, 9,
-                           "div", kOk, kOk, kOk,
-                           "divbr", kOk, kOk, kOk,
-                           "editable", kOk, kOk, kOk,
-                           "editablebr", kOk, kOk, kOk,
-                           "textarea", kOk, kOk, kOk);
-      testTextBeforeOffset(13, BOUNDARY_WORD_START, "two ", 9, 13,
-                           "div", kOk, kOk, kOk,
-                           "divbr", kOk, kOk, kOk,
-                           "editable", kOk, kOk, kOk,
-                           "editablebr", kOk, kOk, kOk,
-                           "textarea", kOk, kOk, kOk);
-      testTextBeforeOffset(18, BOUNDARY_WORD_START, "two ", 9, 13,
-                           "div", kTodo, kTodo, kTodo,
-                           "divbr", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "editablebr", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(19, BOUNDARY_WORD_START, "two ", 9, 13,
-                           "div", kTodo, kTodo, kTodo,
-                           "divbr", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "editablebr", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
+      testTextBeforeOffset(0, BOUNDARY_WORD_START, "", 0, 0, IDs);
+      testTextBeforeOffset(7, BOUNDARY_WORD_START, "", 0, 0, IDs);
+      testTextBeforeOffset(8, BOUNDARY_WORD_START, "", 0, 0, IDs);
+      testTextBeforeOffset(9, BOUNDARY_WORD_START, "oneword\n\n", 0, 9, IDs);
+      testTextBeforeOffset(13, BOUNDARY_WORD_START, "two ", 9, 13, IDs);
+      testTextBeforeOffset(18, BOUNDARY_WORD_START, "two ", 9, 13, IDs);
+      testTextBeforeOffset(19, BOUNDARY_WORD_START, "words\n", 13, 19, IDs);
 
       // BOUNDARY_WORD_END
-      testTextBeforeOffset(0, BOUNDARY_WORD_END, "", 0, 0,
+      testTextBeforeOffset(0, BOUNDARY_WORD_END, "", 0, 0, IDs);
+      testTextBeforeOffset(7, BOUNDARY_WORD_END, "", 0, 0, IDs);
+      testTextBeforeOffset(8, BOUNDARY_WORD_END, "oneword", 0, 7,
                            "div", kOk, kOk, kOk,
-                           "divbr", kOk, kOk, kOk,
-                           "editable", kOk, kOk, kOk,
-                           "editablebr", kOk, kOk, kOk,
-                           "textarea", kOk, kOk, kOk);
-      testTextBeforeOffset(7, BOUNDARY_WORD_END, "", 0, 0,
-                           "div", kTodo, kOk, kTodo,
                            "divbr", kTodo, kOk, kTodo,
-                           "editable", kTodo, kOk, kTodo,
-                           "editablebr", kTodo, kOk, kTodo,
-                           "textarea", kTodo, kOk, kTodo);
-      testTextBeforeOffset(8, BOUNDARY_WORD_END, "oneword", 0, 7,
-                           "div", kTodo, kTodo, kTodo,
-                           "divbr", kTodo, kOk, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "editablebr", kTodo, kOk, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(9, BOUNDARY_WORD_END, "oneword", 0, 7,
-                           "div", kTodo, kTodo, kTodo,
-                           "divbr", kTodo, kOk, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
+                           "editable", kOk, kOk, kOk,
                            "editablebr", kTodo, kOk, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(12, BOUNDARY_WORD_END, "oneword", 0, 7,
-                           "div", kTodo, kTodo, kTodo,
-                           "divbr", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "editablebr", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(13, BOUNDARY_WORD_END, "\n\ntwo", 7, 12,
-                           "div", kTodo, kTodo, kTodo,
+                           "textarea", kOk, kOk, kOk);
+      testTextBeforeOffset(9, BOUNDARY_WORD_END, "oneword", 0, 7,
+                           "div", kOk, kOk, kOk,
+                           "divbr", kTodo, kOk, kTodo,
+                           "editable", kOk, kOk, kOk,
+                           "editablebr", kTodo, kOk, kTodo,
+                           "textarea", kOk, kOk, kOk);
+      testTextBeforeOffset(12, BOUNDARY_WORD_END, "oneword", 0, 7, IDs);
+      testTextBeforeOffset(13, BOUNDARY_WORD_END, "\n\ntwo", 7, 12, IDs);
+      testTextBeforeOffset(18, BOUNDARY_WORD_END, "\n\ntwo", 7, 12, IDs);
+      testTextBeforeOffset(19, BOUNDARY_WORD_END, " words", 12, 18,
+                           "div", kOk, kOk, kOk,
                            "divbr", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "editablebr", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(18, BOUNDARY_WORD_END, "\n\ntwo", 7, 12,
-                           "div", kTodo, kTodo, kTodo,
-                           "divbr", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "editablebr", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(19, BOUNDARY_WORD_END, " words", 13, 18,
-                           "div", kTodo, kTodo, kTodo,
-                           "divbr", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
+                           "editable", kOk, kOk, kOk,
                            "editablebr", kTodo, kTodo, kTodo,
                            "textarea", kTodo, kTodo, kTodo);
 
       // BOUNDARY_LINE_START
       testTextBeforeOffset(0, BOUNDARY_LINE_START, "", 0, 0,
                            "div", kOk, kOk, kOk,
                            "divbr", kOk, kOk, kOk,
                            "editable", kOk, kOk, kOk,
@@ -379,66 +319,46 @@
       testTextAtOffset(9, BOUNDARY_CHAR, "t", 9, 10,
                        "div", kOk, kOk, kOk,
                        "divbr", kOk, kOk, kOk,
                        "editable", kOk, kOk, kOk,
                        "editablebr", kOk, kOk, kOk,
                        "textarea", kOk, kOk, kOk);
 
       // BOUNDARY_WORD_START
-      testTextAtOffset(0, BOUNDARY_WORD_START, "oneword\n\n", 0, 9,
-                       "div", kTodo, kOk, kTodo,
-                       "divbr", kOk, kOk, kOk,
-                       "editable", kTodo, kOk, kTodo,
-                       "editablebr", kOk, kOk, kOk,
-                       "textarea", kTodo, kOk, kTodo);
+      testTextAtOffset(0, BOUNDARY_WORD_START, "oneword\n\n", 0, 9, IDs);
       testTextAtOffset(8, BOUNDARY_WORD_START, "oneword\n\n", 0, 9,
-                       "div", kTodo, kTodo, kOk,
-                       "divbr", kOk, kOk, kOk,
-                       "editable", kTodo, kTodo, kOk,
-                       "editablebr", kOk, kOk, kOk,
-                       "textarea", kTodo, kTodo, kOk);
-      testTextAtOffset(9, BOUNDARY_WORD_START, "two ", 9, 13,
-                       "div", kTodo, kTodo, kTodo,
-                       "divbr", kOk, kOk, kOk,
-                       "editable", kTodo, kTodo, kTodo,
-                       "editablebr", kOk, kOk, kOk,
-                       "textarea", kTodo, kTodo, kTodo);
-      testTextAtOffset(13, BOUNDARY_WORD_START, "words\n", 13, 19,
                        "div", kOk, kOk, kOk,
-                       "divbr", kOk, kOk, kOk,
+                       "divbr", kTodo, kTodo, kTodo,
                        "editable", kOk, kOk, kOk,
-                       "editablebr", kOk, kOk, kOk,
+                       "editablebr", kTodo, kTodo, kTodo,
                        "textarea", kOk, kOk, kOk);
+      testTextAtOffset(9, BOUNDARY_WORD_START, "two ", 9, 13, IDs);
+      testTextAtOffset(13, BOUNDARY_WORD_START, "words\n", 13, 19, IDs);
 
       // BOUNDARY_WORD_END
       testTextAtOffset(0, BOUNDARY_WORD_END, "oneword", 0, 7,
-                       "div", kOk, kOk, kOk,
-                       "divbr", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "editablebr", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
+                       "div", kTodo, kOk, kTodo,
+                       "divbr", kTodo, kOk, kTodo,
+                       "editable", kTodo, kOk, kTodo,
+                       "editablebr", kTodo, kOk, kTodo,
+                       "textarea", kTodo, kOk, kTodo);
       testTextAtOffset(8, BOUNDARY_WORD_END, "\n\ntwo", 7, 12,
                        "div", kOk, kOk, kOk,
                        "divbr", kTodo, kTodo, kTodo,
                        "editable", kOk, kOk, kOk,
                        "editablebr", kTodo, kTodo, kTodo,
                        "textarea", kOk, kOk, kOk);
       testTextAtOffset(9, BOUNDARY_WORD_END, "\n\ntwo", 7, 12,
-                       "div", kTodo, kTodo, kOk,
+                       "div", kOk, kOk, kOk,
                        "divbr", kTodo, kTodo, kTodo,
-                       "editable", kTodo, kTodo, kOk,
+                       "editable", kOk, kOk, kOk,
                        "editablebr", kTodo, kTodo, kTodo,
-                       "textarea", kTodo, kTodo, kOk);
-      testTextAtOffset(12, BOUNDARY_WORD_END, "\n\ntwo", 7, 12,
-                       "div", kTodo, kTodo, kTodo,
-                       "divbr", kTodo, kTodo, kTodo,
-                       "editable", kTodo, kTodo, kTodo,
-                       "editablebr", kTodo, kTodo, kTodo,
-                       "textarea", kTodo, kTodo, kTodo);
+                       "textarea", kOk, kOk, kOk);
+      testTextAtOffset(12, BOUNDARY_WORD_END, "\n\ntwo", 7, 12, IDs);
       testTextAtOffset(13, BOUNDARY_WORD_END, " words", 12, 18,
                        "div", kOk, kOk, kOk,
                        "divbr", kOk, kOk, kOk,
                        "editable", kOk, kOk, kOk,
                        "editablebr", kOk, kOk, kOk,
                        "textarea", kOk, kOk, kOk);
 
       // BOUNDARY_LINE_START
@@ -512,21 +432,21 @@
                        "textarea", kOk, kOk, kOk);
       testTextAtOffset(17, BOUNDARY_LINE_END, "\ntwo words", 8, 18,
                        "div", kOk, kOk, kOk,
                        "divbr", kOk, kOk, kOk,
                        "editable", kOk, kOk, kOk,
                        "editablebr", kOk, kOk, kOk,
                        "textarea", kOk, kOk, kOk);
       testTextAtOffset(18, BOUNDARY_LINE_END, "\ntwo words", 8, 18,
-                       "div", kTodo, kTodo, kTodo,
-                       "divbr", kTodo, kTodo, kTodo,
-                       "editable", kTodo, kTodo, kTodo,
-                       "editablebr", kTodo, kTodo, kTodo,
-                       "textarea", kTodo, kTodo, kTodo);
+                       "div", kTodo, kOk, kTodo,
+                       "divbr", kTodo, kOk, kTodo,
+                       "editable", kTodo, kOk, kTodo,
+                       "editablebr", kTodo, kOk, kTodo,
+                       "textarea", kTodo, kOk, kTodo);
       testTextAtOffset(19, BOUNDARY_LINE_END, "\n", 18, 19,
                        "div", kTodo, kTodo, kTodo,
                        "divbr", kTodo, kTodo, kTodo,
                        "editable", kTodo, kTodo, kTodo,
                        "editablebr", kTodo, kTodo, kTodo,
                        "textarea", kTodo, kTodo, kTodo);
 
       SimpleTest.finish();
@@ -538,19 +458,30 @@
 </head>
 <body>
 
   <a target="_blank"
      title="nsIAccessibleText getText related functions test in multiline text"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=612331">
    Bug 612331
   </a>
+  <a target="_blank"
+     title="getTextAtOffset for word boundaries: beginning of a new life"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=853340">
+    Bug 853340
+  </a>
+  <a target="_blank"
+     title="getTextBeforeOffset for word boundaries: evolving"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=855732">
+    Bug 855732
+  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
+
   <div id="div">oneword
 
 two words
 </div>
   <div id="divbr">oneword<br/><br/>two words<br/></div>
   <div id="editable" contenteditable="true">oneword
 
 two words
--- a/accessible/tests/mochitest/text/test_singleline.html
+++ b/accessible/tests/mochitest/text/test_singleline.html
@@ -7,19 +7,19 @@
   <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="../text.js"></script>
   <script type="application/javascript">
     if (navigator.platform.startsWith("Mac")) {
-      SimpleTest.expectAssertions(0, 19);
+      SimpleTest.expectAssertions(0, 20);
     } else {
-      SimpleTest.expectAssertions(19);
+      SimpleTest.expectAssertions(20);
     }
 
     function doTest()
     {
       // __h__e__l__l__o__ __m__y__ __f__r__i__e__n__d__
       //  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
 
       ////////////////////////////////////////////////////////////////////////
@@ -100,19 +100,19 @@
                           "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kOk);
       testTextAfterOffset(14, BOUNDARY_WORD_START, "", 15, 15,
                           "input", kTodo, kTodo, kOk,
                           "div", kTodo, kTodo, kOk,
                           "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kOk);
       testTextAfterOffset(15, BOUNDARY_WORD_START, "", 15, 15,
-                          "input", kOk, kTodo, kTodo,
-                          "div", kOk, kTodo, kTodo,
-                          "editable", kOk, kTodo, kTodo,
+                          "input", kOk, kOk, kOk,
+                          "div", kOk, kOk, kOk,
+                          "editable", kOk, kOk, kOk,
                           "textarea", kTodo, kOk, kTodo);
 
       // BOUNDARY_WORD_END
       testTextAfterOffset(0, BOUNDARY_WORD_END, " my", 5, 8,
                           "input", kTodo, kTodo, kTodo,
                           "div", kTodo, kTodo, kTodo,
                           "editable", kTodo, kTodo, kTodo,
                           "textarea", kTodo, kTodo, kTodo);
@@ -152,19 +152,19 @@
                           "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kOk);
       testTextAfterOffset(14, BOUNDARY_WORD_END, "", 15, 15,
                           "input", kTodo, kTodo, kOk,
                           "div", kTodo, kTodo, kOk,
                           "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kOk);
       testTextAfterOffset(15, BOUNDARY_WORD_END, "", 15, 15,
-                          "input", kOk, kTodo, kTodo,
-                          "div", kOk, kTodo, kTodo,
-                          "editable", kOk, kTodo, kTodo,
+                          "input", kOk, kOk, kOk,
+                          "div", kOk, kOk, kOk,
+                          "editable", kOk, kOk, kOk,
                           "textarea", kTodo, kOk, kTodo);
 
       // BOUNDARY_LINE_START
       testTextAfterOffset(0, BOUNDARY_LINE_START, "", 15, 15,
                           "input", kTodo, kTodo, kOk,
                           "div", kTodo, kTodo, kOk,
                           "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kTodo);
@@ -174,157 +174,77 @@
                           "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kTodo);
       testTextAfterOffset(14, BOUNDARY_LINE_START, "", 15, 15,
                           "input", kTodo, kTodo, kOk,
                           "div", kTodo, kTodo, kOk,
                           "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kTodo);
       testTextAfterOffset(15, BOUNDARY_LINE_START, "", 15, 15,
-                          "input", undefined, undefined, undefined,
-                          "div", undefined, undefined, undefined,
-                          "editable", undefined, undefined, undefined,
-                          "textarea", kTodo, undefined, kTodo);
+                          "input", kOk, kOk, kOk,
+                          "div", kOk, kOk, kOk,
+                          "editable", kOk, kOk, kOk,
+                          "textarea", kTodo, kOk, kTodo);
 
       // BOUNDARY_LINE_END
       testTextAfterOffset(0, BOUNDARY_LINE_END, "", 15, 15,
                           "input", kTodo, kTodo, kOk,
                           "div", kTodo, kTodo, kOk,
                           "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kOk);
       testTextAfterOffset(1, BOUNDARY_LINE_END, "", 15, 15,
                           "input", kTodo, kTodo, kOk,
                           "div", kTodo, kTodo, kOk,
                           "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kOk);
       testTextAfterOffset(14, BOUNDARY_LINE_END, "", 15, 15,
-                          "input", kOk, kTodo, kTodo,
-                          "div", kOk, kTodo, kTodo,
-                          "editable", kOk, kTodo, kTodo,
+                          "input", kTodo, kTodo, kOk,
+                          "div", kTodo, kTodo, kOk,
+                          "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kOk);
       testTextAfterOffset(15, BOUNDARY_LINE_END, "", 15, 15,
                           "input", kOk, kTodo, kTodo,
                           "div", kOk, kTodo, kTodo,
                           "editable", kOk, kTodo, kTodo,
-                          "textarea", kOk, kTodo, kTodo);
+                          "textarea", kTodo, kOk, kTodo);
 
       ////////////////////////////////////////////////////////////////////////
       // getTextBeforeOffset
 
       var IDs = [ "input", "div", "editable", "textarea" ];
 
       // BOUNDARY_CHAR
       testCharBeforeOffset(IDs, 0, "", 0, 0);
       testCharBeforeOffset(IDs, 1, "h", 0, 1);
       testCharBeforeOffset(IDs, 14, "n", 13, 14);
       testCharBeforeOffset(IDs, 15, "d", 14, 15);
 
       // BOUNDARY_WORD_START
-      testTextBeforeOffset(0, BOUNDARY_WORD_START, "", 0, 0,
-                           "input", kOk, kOk, kOk,
-                           "div", kOk, kOk, kOk,
-                           "editable", kOk, kOk, kOk,
-                           "textarea", kOk, kOk, kOk);
-      testTextBeforeOffset(1, BOUNDARY_WORD_START, "", 0, 0,
-                           "input", kTodo, kOk, kTodo,
-                           "div", kTodo, kOk, kTodo,
-                           "editable", kTodo, kOk, kTodo,
-                           "textarea", kTodo, kOk, kTodo);
-      testTextBeforeOffset(5, BOUNDARY_WORD_START, "", 0, 0,
-                           "input", kTodo, kOk, kTodo,
-                           "div", kTodo, kOk, kTodo,
-                           "editable", kTodo, kOk, kTodo,
-                           "textarea", kTodo, kOk, kTodo);
-      testTextBeforeOffset(6, BOUNDARY_WORD_START, "hello ", 0, 6,
-                           "input", kOk, kOk, kOk,
-                           "div", kOk, kOk, kOk,
-                           "editable", kOk, kOk, kOk,
-                           "textarea", kOk, kOk, kOk);
-      testTextBeforeOffset(7, BOUNDARY_WORD_START, "hello ", 0, 6,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(8, BOUNDARY_WORD_START, "hello ", 0, 6,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(9, BOUNDARY_WORD_START, "my ", 6, 9,
-                           "input", kOk, kOk, kOk,
-                           "div", kOk, kOk, kOk,
-                           "editable", kOk, kOk, kOk,
-                           "textarea", kOk, kOk, kOk);
-      testTextBeforeOffset(10, BOUNDARY_WORD_START, "my ", 6, 9,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(14, BOUNDARY_WORD_START, "my ", 6, 9,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(15, BOUNDARY_WORD_START, "my ", 6, 9,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
+      testTextBeforeOffset(0, BOUNDARY_WORD_START, "", 0, 0, IDs);
+      testTextBeforeOffset(1, BOUNDARY_WORD_START, "", 0, 0, IDs);
+      testTextBeforeOffset(5, BOUNDARY_WORD_START, "", 0, 0, IDs);
+      testTextBeforeOffset(6, BOUNDARY_WORD_START, "hello ", 0, 6, IDs);
+      testTextBeforeOffset(7, BOUNDARY_WORD_START, "hello ", 0, 6, IDs);
+      testTextBeforeOffset(8, BOUNDARY_WORD_START, "hello ", 0, 6, IDs);
+      testTextBeforeOffset(9, BOUNDARY_WORD_START, "my ", 6, 9, IDs);
+      testTextBeforeOffset(10, BOUNDARY_WORD_START, "my ", 6, 9, IDs);
+      testTextBeforeOffset(14, BOUNDARY_WORD_START, "my ", 6, 9, IDs);
+      testTextBeforeOffset(15, BOUNDARY_WORD_START, "friend", 9, 15, IDs);
 
       // BOUNDARY_WORD_END
-      testTextBeforeOffset(0, BOUNDARY_WORD_END, "", 0, 0,
-                           "input", kOk, kOk, kOk,
-                           "div", kOk, kOk, kOk,
-                           "editable", kOk, kOk, kOk,
-                           "textarea", kOk, kOk, kOk);
-      testTextBeforeOffset(1, BOUNDARY_WORD_END, "", 0, 0,
-                           "input", kTodo, kOk, kTodo,
-                           "div", kTodo, kOk, kTodo,
-                           "editable", kTodo, kOk, kTodo,
-                           "textarea", kTodo, kOk, kTodo);
-      testTextBeforeOffset(5, BOUNDARY_WORD_END, "", 0, 0,
-                           "input", kTodo, kOk, kTodo,
-                           "div", kTodo, kOk, kTodo,
-                           "editable", kTodo, kOk, kTodo,
-                           "textarea", kTodo, kOk, kTodo);
-      testTextBeforeOffset(6, BOUNDARY_WORD_END, "hello ", 0, 6,
-                           "input", kTodo, kTodo, kOk,
-                           "div", kTodo, kTodo, kOk,
-                           "editable", kTodo, kTodo, kOk,
-                           "textarea", kTodo, kTodo, kOk);
-      testTextBeforeOffset(7, BOUNDARY_WORD_END, "hello ", 0, 6,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(8, BOUNDARY_WORD_END, "hello ", 0, 6,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(9, BOUNDARY_WORD_END, " my", 5, 8,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(10, BOUNDARY_WORD_END, " my", 5, 8,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(14, BOUNDARY_WORD_END, " my", 5, 8,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(15, BOUNDARY_WORD_END, " my", 5, 8,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
+      testTextBeforeOffset(0, BOUNDARY_WORD_END, "", 0, 0, IDs);
+      testTextBeforeOffset(1, BOUNDARY_WORD_END, "", 0, 0, IDs);
+      testTextBeforeOffset(5, BOUNDARY_WORD_END, "", 0, 0, IDs);
+      testTextBeforeOffset(6, BOUNDARY_WORD_END, "hello", 0, 5, IDs);
+      testTextBeforeOffset(7, BOUNDARY_WORD_END, "hello", 0, 5, IDs);
+      testTextBeforeOffset(8, BOUNDARY_WORD_END, "hello", 0, 5, IDs);
+      testTextBeforeOffset(9, BOUNDARY_WORD_END, " my", 5, 8, IDs);
+      testTextBeforeOffset(10, BOUNDARY_WORD_END, " my", 5, 8, IDs);
+      testTextBeforeOffset(14, BOUNDARY_WORD_END, " my", 5, 8, IDs);
+      testTextBeforeOffset(15, BOUNDARY_WORD_END, " my", 5, 8, IDs);
 
       // BOUNDARY_LINE_START
       testTextBeforeOffset(0, BOUNDARY_LINE_START, "", 0, 0,
                            "input", kOk, kOk, kOk,
                            "div", kOk, kOk, kOk,
                            "editable", kOk, kOk, kOk,
                            "textarea", kOk, kOk, kOk);
       testTextBeforeOffset(1, BOUNDARY_LINE_START, "", 0, 0,
@@ -350,25 +270,25 @@
                            "editable", kOk, kOk, kOk,
                            "textarea", kOk, kOk, kOk);
       testTextBeforeOffset(1, BOUNDARY_LINE_END, "", 0, 0,
                            "input", kTodo, kOk, kTodo,
                            "div", kTodo, kOk, kTodo,
                            "editable", kTodo, kOk, kTodo,
                            "textarea", kTodo, kOk, kTodo);
       testTextBeforeOffset(14, BOUNDARY_LINE_END, "", 0, 0,
-                           "input", kOk, kOk, kOk,
-                           "div", kOk, kOk, kOk,
-                           "editable", kOk, kOk, kOk,
+                           "input", kTodo, kOk, kTodo,
+                           "div", kTodo, kOk, kTodo,
+                           "editable", kTodo, kOk, kTodo,
                            "textarea", kTodo, kOk, kTodo);
       testTextBeforeOffset(15, BOUNDARY_LINE_END, "", 0, 0,
                            "input", kOk, kOk, kOk,
                            "div", kOk, kOk, kOk,
                            "editable", kOk, kOk, kOk,
-                           "textarea", kOk, kOk, kOk);
+                           "textarea", kTodo, kOk, kTodo);
 
       ////////////////////////////////////////////////////////////////////////
       // getTextAtOffset
 
       IDs = [ "input", "div", "editable", "textarea" ];
       regularIDs = [ "input", "div", "editable" ];
 
       // BOUNDARY_CHAR
@@ -376,135 +296,59 @@
       testCharAtOffset(IDs, 0, "h", 0, 1);
       testCharAtOffset(IDs, 1, "e", 1, 2);
       testCharAtOffset(IDs, 14, "d", 14, 15);
       testCharAtOffset(regularIDs, 15, "", 15, 15);
       testCharAtOffset("textarea", 15, "\n", 15, 16);
       testCharAtOffset("textarea", 16, "", 16, 16);
 
       // BOUNDARY_WORD_START
-      testTextAtOffset(0, BOUNDARY_WORD_START, "hello ", 0, 6,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(1, BOUNDARY_WORD_START, "hello ", 0, 6,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(5, BOUNDARY_WORD_START, "hello ", 0, 6,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(6, BOUNDARY_WORD_START, "my ", 6, 9,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(7, BOUNDARY_WORD_START, "my ", 6, 9,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(8, BOUNDARY_WORD_START, "my ", 6, 9,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(9, BOUNDARY_WORD_START, "friend", 9, 15,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(10, BOUNDARY_WORD_START, "friend", 9, 15,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(14, BOUNDARY_WORD_START, "friend", 9, 15,
+      testTextAtOffset(0, BOUNDARY_WORD_START, "hello ", 0, 6, IDs);
+      testTextAtOffset(1, BOUNDARY_WORD_START, "hello ", 0, 6, IDs);
+      testTextAtOffset(5, BOUNDARY_WORD_START, "hello ", 0, 6, IDs);
+      testTextAtOffset(6, BOUNDARY_WORD_START, "my ", 6, 9, IDs);
+      testTextAtOffset(7, BOUNDARY_WORD_START, "my ", 6, 9, IDs);
+      testTextAtOffset(8, BOUNDARY_WORD_START, "my ", 6, 9, IDs);
+      testTextAtOffset(9, BOUNDARY_WORD_START, "friend", 9, 15, IDs);
+      testTextAtOffset(10, BOUNDARY_WORD_START, "friend", 9, 15, IDs);
+      testTextAtOffset(14, BOUNDARY_WORD_START, "friend", 9, 15, IDs);
+      testTextAtOffset(15, BOUNDARY_WORD_START, "", 15, 15,
                        "input", kOk, kOk, kOk,
                        "div", kOk, kOk, kOk,
                        "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(15, BOUNDARY_WORD_START, "friend", 9, 15,
-                       "input", kTodo, kTodo, kTodo,
-                       "div", kTodo, kTodo, kTodo,
-                       "editable", kTodo, kTodo, kTodo,
-                       "textarea", kTodo, kTodo, kTodo);
+                       "textarea", kTodo, kTodo, kOk);
 
       // BOUNDARY_WORD_END
-      testTextAtOffset(0, BOUNDARY_WORD_END, "hello", 0, 5,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(1, BOUNDARY_WORD_END, "hello", 0, 5,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(5, BOUNDARY_WORD_END, "hello", 0, 5,
-                       "input", kTodo, kTodo, kTodo,
-                       "div", kTodo, kTodo, kTodo,
-                       "editable", kTodo, kTodo, kTodo,
-                       "textarea", kTodo, kTodo, kTodo);
-      testTextAtOffset(6, BOUNDARY_WORD_END, " my", 5, 8,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(7, BOUNDARY_WORD_END, " my", 5, 8,
-                        "input", kOk, kOk, kOk,
-                        "div", kOk, kOk, kOk,
-                        "editable", kOk, kOk, kOk,
-                        "textarea", kOk, kOk, kOk);
-      testTextAtOffset(8, BOUNDARY_WORD_END, " my", 5, 8,
-                       "input", kTodo, kTodo, kTodo,
-                       "div", kTodo, kTodo, kTodo,
-                       "editable", kTodo, kTodo, kTodo,
-                       "textarea", kTodo, kTodo, kTodo);
-      testTextAtOffset(9, BOUNDARY_WORD_END, " friend", 8, 15,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(10, BOUNDARY_WORD_END, " friend", 8, 15,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(14, BOUNDARY_WORD_END, " friend", 8, 15,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(15, BOUNDARY_WORD_END, " friend", 8, 15,
-                        "input", kTodo, kTodo, kTodo,
-                        "div", kTodo, kTodo, kTodo,
-                        "editable", kTodo, kTodo, kTodo,
-                        "textarea", kTodo, kTodo, kTodo);
+      testTextAtOffset(0, BOUNDARY_WORD_END, "", 0, 0, IDs);
+      testTextAtOffset(1, BOUNDARY_WORD_END, "hello", 0, 5, IDs);
+      testTextAtOffset(5, BOUNDARY_WORD_END, "hello", 0, 5, IDs);
+      testTextAtOffset(6, BOUNDARY_WORD_END, " my", 5, 8, IDs);
+      testTextAtOffset(7, BOUNDARY_WORD_END, " my", 5, 8, IDs);
+      testTextAtOffset(8, BOUNDARY_WORD_END, " my", 5, 8, IDs);
+      testTextAtOffset(9, BOUNDARY_WORD_END, " friend", 8, 15, IDs);
+      testTextAtOffset(10, BOUNDARY_WORD_END, " friend", 8, 15, IDs);
+      testTextAtOffset(14, BOUNDARY_WORD_END, " friend", 8, 15, IDs);
+      testTextAtOffset(15, BOUNDARY_WORD_END, " friend", 8, 15, IDs);
 
       // BOUNDARY_LINE_START
       testTextAtOffset(0, BOUNDARY_LINE_START, "hello my friend", 0, 15,
                        "input", kOk, kOk, kOk,
                        "div", kOk, kOk, kOk,
                        "editable", kOk, kOk, kOk,
                        "textarea", kTodo, kOk, kTodo);
       testTextAtOffset(1, BOUNDARY_LINE_START, "hello my friend", 0, 15,
                        "input", kOk, kOk, kOk,
                        "div", kOk, kOk, kOk,
                        "editable", kOk, kOk, kOk,
                        "textarea", kTodo, kOk, kTodo);
       testTextAtOffset(14, BOUNDARY_LINE_START, "hello my friend", 0, 15,
                        "input", kOk, kOk, kOk,
                        "div", kOk, kOk, kOk,
                        "editable", kOk, kOk, kOk,
-			       "textarea", kTodo, kOk, kTodo);
+                       "textarea", kTodo, kOk, kTodo);
       testTextAtOffset(15, BOUNDARY_LINE_START, "hello my friend", 0, 15,
 		       "input", kOk, kOk, kOk,
 		       "div", kOk, kOk, kOk,
 		       "editable", kOk, kOk, kOk,
 		       "textarea", kTodo, kOk, kTodo);
 
       // BOUNDARY_LINE_END
       testTextAtOffset(0, BOUNDARY_LINE_END, "hello my friend", 0, 15,
@@ -513,19 +357,19 @@
 		       "editable", kOk, kOk, kOk,
 		       "textarea", kOk, kOk, kOk);
       testTextAtOffset(1, BOUNDARY_LINE_END, "hello my friend", 0, 15,
 		       "input", kOk, kOk, kOk,
 		       "div", kOk, kOk, kOk,
 		       "editable", kOk, kOk, kOk,
 		       "textarea", kOk, kOk, kOk);
       testTextAtOffset(14, BOUNDARY_LINE_END, "hello my friend", 0, 15,
-		       "input", kTodo, kOk, kTodo,
-		       "div", kTodo, kOk, kTodo,
-		       "editable", kTodo, kOk, kTodo,
+		       "input", kOk, kOk, kOk,
+		       "div", kOk, kOk, kOk,
+		       "editable", kOk, kOk, kOk,
 		       "textarea", kOk, kOk, kOk);
       testTextAtOffset(15, BOUNDARY_LINE_END, "hello my friend", 0, 15,
 		       "input", kTodo, kOk, kTodo,
 		       "div", kTodo, kOk, kTodo,
 		       "editable", kTodo, kOk, kTodo,
 		       "textarea", kTodo, kOk, kTodo);
 
       SimpleTest.finish();
@@ -534,17 +378,29 @@
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
 <body>
 
   <a target="_blank"
      title="nsIAccessibleText getText related function tests for html:input,html:div and html:textarea"
-     href="https://bugzilla.mozilla.org/show_bug.cgi?id=452769">Mozilla Bug 452769</a>
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=452769">
+    Bug 452769
+  </a>
+  <a target="_blank"
+     title="getTextAtOffset for word boundaries: beginning of a new life"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=853340">
+    Bug 853340
+  </a>
+  <a target="_blank"
+     title="getTextBeforeOffset for word boundaries: evolving"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=855732">
+    Bug 855732
+  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <input id="input" value="hello my friend"/>
   <div id="div">hello my friend</div>
   <div id="editable" contenteditable="true">hello my friend</div>
--- a/accessible/tests/mochitest/text/test_whitespaces.html
+++ b/accessible/tests/mochitest/text/test_whitespaces.html
@@ -9,19 +9,19 @@
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <script type="application/javascript"
           src="../common.js"></script>
 
   <script type="application/javascript"
           src="../text.js"></script>
   <script type="application/javascript">
     if (navigator.platform.startsWith("Mac")) {
-      SimpleTest.expectAssertions(0, 8);
+      SimpleTest.expectAssertions(0, 3);
     } else {
-      SimpleTest.expectAssertions(8);
+      SimpleTest.expectAssertions(3);
     }
 
     function doTest()
     {
       // __B__r__a__v__e__ __S__i__r__ __ __R__o__b__i__n__ __ __ __r__a__n
       //  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21
 
       ////////////////////////////////////////////////////////////////////////
@@ -173,19 +173,19 @@
                           "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kOk);
       testTextAfterOffset(21, BOUNDARY_WORD_END, "", 22, 22,
                           "input", kTodo, kTodo, kOk,
                           "div", kTodo, kTodo, kOk,
                           "editable", kTodo, kTodo, kOk,
                           "textarea", kTodo, kTodo, kOk);
       testTextAfterOffset(22, BOUNDARY_WORD_END, "", 22, 22,
-                          "input", kOk, kTodo, kTodo,
-                          "div", kOk, kTodo, kTodo,
-                          "editable", kOk, kTodo, kTodo,
+                          "input", kOk, kOk, kOk,
+                          "div", kOk, kOk, kOk,
+                          "editable", kOk, kOk, kOk,
                           "textarea", kTodo, kOk, kTodo);
 
       ////////////////////////////////////////////////////////////////////////
       // getTextBeforeOffset
 
       var IDs = [ "input", "div", "editable", "textarea" ];
 
       // BOUNDARY_CHAR
@@ -193,173 +193,49 @@
       testCharBeforeOffset(IDs, 1, "B", 0, 1);
       testCharBeforeOffset(IDs, 6, " ", 5, 6);
       testCharBeforeOffset(IDs, 10, " ", 9, 10);
       testCharBeforeOffset(IDs, 11, " ", 10, 11);
       testCharBeforeOffset(IDs, 17, " ", 16, 17);
       testCharBeforeOffset(IDs, 19, " ", 18, 19);
 
       // BOUNDARY_WORD_START
-      testTextBeforeOffset(0, BOUNDARY_WORD_START, "", 0, 0,
-                           "input", kOk, kOk, kOk,
-                           "div", kOk, kOk, kOk,
-                           "editable", kOk, kOk, kOk,
-                           "textarea", kOk, kOk, kOk);
-      testTextBeforeOffset(1, BOUNDARY_WORD_START, "", 0, 0,
-                           "input", kTodo, kOk, kTodo,
-                           "div", kTodo, kOk, kTodo,
-                           "editable", kTodo, kOk, kTodo,
-                           "textarea", kTodo, kOk, kTodo);
-      testTextBeforeOffset(5, BOUNDARY_WORD_START, "", 0, 0,
-                           "input", kTodo, kOk, kTodo,
-                           "div", kTodo, kOk, kTodo,
-                           "editable", kTodo, kOk, kTodo,
-                           "textarea", kTodo, kOk, kTodo);
-      testTextBeforeOffset(6, BOUNDARY_WORD_START, "Brave ", 0, 6,
-                           "input", kOk, kOk, kOk,
-                           "div", kOk, kOk, kOk,
-                           "editable", kOk, kOk, kOk,
-                           "textarea", kOk, kOk, kOk);
-      testTextBeforeOffset(9, BOUNDARY_WORD_START, "Brave ", 0, 6,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(10, BOUNDARY_WORD_START, "Brave ", 0, 6,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(11, BOUNDARY_WORD_START, "Sir  ", 6, 11,
-                           "input", kOk, kOk, kOk,
-                           "div", kOk, kOk, kOk,
-                           "editable", kOk, kOk, kOk,
-                           "textarea", kOk, kOk, kOk);
-      testTextBeforeOffset(15, BOUNDARY_WORD_START, "Sir  ", 6, 11,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(16, BOUNDARY_WORD_START, "Sir  ", 6, 11,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(17, BOUNDARY_WORD_START, "Sir  ", 6, 11,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(18, BOUNDARY_WORD_START, "Sir  ", 6, 11,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(19, BOUNDARY_WORD_START, "Robin   ", 11, 19,
-                           "input", kOk, kOk, kOk,
-                           "div", kOk, kOk, kOk,
-                           "editable", kOk, kOk, kOk,
-                           "textarea", kOk, kOk, kOk);
-      testTextBeforeOffset(20, BOUNDARY_WORD_START, "Robin   ", 11, 19,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(21, BOUNDARY_WORD_START, "Robin   ", 11, 19,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
+      testTextBeforeOffset(0, BOUNDARY_WORD_START, "", 0, 0, IDs);
+      testTextBeforeOffset(1, BOUNDARY_WORD_START, "", 0, 0, IDs);
+      testTextBeforeOffset(5, BOUNDARY_WORD_START, "", 0, 0, IDs);
+      testTextBeforeOffset(6, BOUNDARY_WORD_START, "Brave ", 0, 6, IDs);
+      testTextBeforeOffset(9, BOUNDARY_WORD_START, "Brave ", 0, 6, IDs);
+      testTextBeforeOffset(10, BOUNDARY_WORD_START, "Brave ", 0, 6, IDs);
+      testTextBeforeOffset(11, BOUNDARY_WORD_START, "Sir  ", 6, 11, IDs);
+      testTextBeforeOffset(15, BOUNDARY_WORD_START, "Sir  ", 6, 11, IDs);
+      testTextBeforeOffset(16, BOUNDARY_WORD_START, "Sir  ", 6, 11, IDs);
+      testTextBeforeOffset(17, BOUNDARY_WORD_START, "Sir  ", 6, 11, IDs);
+      testTextBeforeOffset(18, BOUNDARY_WORD_START, "Sir  ", 6, 11, IDs);
+      testTextBeforeOffset(19, BOUNDARY_WORD_START, "Robin   ", 11, 19, IDs);
+      testTextBeforeOffset(20, BOUNDARY_WORD_START, "Robin   ", 11, 19, IDs);
+      testTextBeforeOffset(21, BOUNDARY_WORD_START, "Robin   ", 11, 19, IDs);
 
       // BOUNDARY_WORD_END
-      testTextBeforeOffset(0, BOUNDARY_WORD_END, "", 0, 0,
-                           "input", kOk, kOk, kOk,
-                           "div", kOk, kOk, kOk,
-                           "editable", kOk, kOk, kOk,
-                           "textarea", kOk, kOk, kOk);
-      testTextBeforeOffset(1, BOUNDARY_WORD_END, "", 0, 0,
-                           "input", kTodo, kOk, kTodo,
-                           "div", kTodo, kOk, kTodo,
-                           "editable", kTodo, kOk, kTodo,
-                           "textarea", kTodo, kOk, kTodo);
-      testTextBeforeOffset(4, BOUNDARY_WORD_END, "", 0, 0,
-                           "input", kTodo, kOk, kTodo,
-                           "div", kTodo, kOk, kTodo,
-                           "editable", kTodo, kOk, kTodo,
-                           "textarea", kTodo, kOk, kTodo);
-      testTextBeforeOffset(5, BOUNDARY_WORD_END, "", 0, 0,
-                           "input", kTodo, kOk, kTodo,
-                           "div", kTodo, kOk, kTodo,
-                           "editable", kTodo, kOk, kTodo,
-                           "textarea", kTodo, kOk, kTodo);
-      testTextBeforeOffset(6, BOUNDARY_WORD_END, "Brave", 0, 5,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(7, BOUNDARY_WORD_END, "Brave", 0, 5,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(8, BOUNDARY_WORD_END, "Brave", 0, 5,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(9, BOUNDARY_WORD_END, "Brave", 0, 5,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(10, BOUNDARY_WORD_END, " Sir", 5, 9,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(11, BOUNDARY_WORD_END, " Sir", 5, 9,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(15, BOUNDARY_WORD_END, " Sir", 5, 9,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(16, BOUNDARY_WORD_END, " Sir", 5, 9,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(17, BOUNDARY_WORD_END, "  Robin", 9, 16,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(18, BOUNDARY_WORD_END, "  Robin", 9, 16,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(19, BOUNDARY_WORD_END, "  Robin", 9, 16,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(21, BOUNDARY_WORD_END, "  Robin", 9, 16,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
-      testTextBeforeOffset(22, BOUNDARY_WORD_END, "  Robin", 9, 16,
-                           "input", kTodo, kTodo, kTodo,
-                           "div", kTodo, kTodo, kTodo,
-                           "editable", kTodo, kTodo, kTodo,
-                           "textarea", kTodo, kTodo, kTodo);
+      testTextBeforeOffset(0, BOUNDARY_WORD_END, "", 0, 0, IDs);
+      testTextBeforeOffset(1, BOUNDARY_WORD_END, "", 0, 0, IDs);
+      testTextBeforeOffset(4, BOUNDARY_WORD_END, "", 0, 0, IDs);
+      testTextBeforeOffset(5, BOUNDARY_WORD_END, "", 0, 0, IDs);
+      testTextBeforeOffset(6, BOUNDARY_WORD_END, "Brave", 0, 5, IDs);
+      testTextBeforeOffset(7, BOUNDARY_WORD_END, "Brave", 0, 5, IDs);
+      testTextBeforeOffset(8, BOUNDARY_WORD_END, "Brave", 0, 5, IDs);
+      testTextBeforeOffset(9, BOUNDARY_WORD_END, "Brave", 0, 5, IDs);
+      testTextBeforeOffset(10, BOUNDARY_WORD_END, " Sir", 5, 9, IDs);
+      testTextBeforeOffset(11, BOUNDARY_WORD_END, " Sir", 5, 9, IDs);
+      testTextBeforeOffset(15, BOUNDARY_WORD_END, " Sir", 5, 9, IDs);
+      testTextBeforeOffset(16, BOUNDARY_WORD_END, " Sir", 5, 9, IDs);
+      testTextBeforeOffset(17, BOUNDARY_WORD_END, "  Robin", 9, 16, IDs);
+      testTextBeforeOffset(18, BOUNDARY_WORD_END, "  Robin", 9, 16, IDs);
+      testTextBeforeOffset(19, BOUNDARY_WORD_END, "  Robin", 9, 16, IDs);
+      testTextBeforeOffset(21, BOUNDARY_WORD_END, "  Robin", 9, 16, IDs);
+      testTextBeforeOffset(22, BOUNDARY_WORD_END, "  Robin", 9, 16, IDs);
 
       ////////////////////////////////////////////////////////////////////////
       // getTextAtOffset
 
       // BOUNDARY_CHAR
       testTextAtOffset(0, BOUNDARY_CHAR, "B", 0, 1,
                        "input", kOk, kOk, kOk,
                        "div", kOk, kOk, kOk,
@@ -452,116 +328,64 @@
                        "div", kOk, kOk, kOk,
                        "editable", kOk, kOk, kOk,
                        "textarea", kTodo, kOk, kTodo);
       testTextAtOffset(21, BOUNDARY_WORD_START, "ran", 19, 22,
                        "input", kOk, kOk, kOk,
                        "div", kOk, kOk, kOk,
                        "editable", kOk, kOk, kOk,
                        "textarea", kTodo, kOk, kTodo);
-      testTextAtOffset(22, BOUNDARY_WORD_START, "ran", 19, 22,
-                       "input", kTodo, kTodo, kTodo,
-                       "div", kTodo, kTodo, kTodo,
-                       "editable", kTodo, kTodo, kTodo,
-                       "textarea", kTodo, kOk, kTodo);
-
-      // BOUNDARY_WORD_END
-      testTextAtOffset(0, BOUNDARY_WORD_END, "Brave", 0, 5,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(4, BOUNDARY_WORD_END, "Brave", 0, 5,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(5, BOUNDARY_WORD_END, "Brave", 0, 5,
-                       "input", kTodo, kTodo, kTodo,
-                       "div", kTodo, kTodo, kTodo,
-                       "editable", kTodo, kTodo, kTodo,
-                       "textarea", kTodo, kTodo, kTodo);
-      testTextAtOffset(6, BOUNDARY_WORD_END, " Sir", 5, 9,
-                        "input", kOk, kOk, kOk,
-                        "div", kOk, kOk, kOk,
-                        "editable", kOk, kOk, kOk,
-                        "textarea", kOk, kOk, kOk);
-      testTextAtOffset(8, BOUNDARY_WORD_END, " Sir", 5, 9,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(9, BOUNDARY_WORD_END, " Sir", 5, 9,
-                       "input", kTodo, kTodo, kTodo,
-                       "div", kTodo, kTodo, kTodo,
-                       "editable", kTodo, kTodo, kTodo,
-                       "textarea", kTodo, kTodo, kTodo);
-      testTextAtOffset(10, BOUNDARY_WORD_END, "  Robin", 9, 16,
+      testTextAtOffset(22, BOUNDARY_WORD_START, "", 22, 22,
                        "input", kOk, kOk, kOk,
                        "div", kOk, kOk, kOk,
                        "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(11, BOUNDARY_WORD_END, "  Robin", 9, 16,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(15, BOUNDARY_WORD_END, "  Robin", 9, 16,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(16, BOUNDARY_WORD_END, "  Robin", 9, 16,
-                       "input", kTodo, kTodo, kTodo,
-                       "div", kTodo, kTodo, kTodo,
-                       "editable", kTodo, kTodo, kTodo,
                        "textarea", kTodo, kTodo, kTodo);
-      testTextAtOffset(17, BOUNDARY_WORD_END, "   ran", 16, 22,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(18, BOUNDARY_WORD_END, "   ran", 16, 22,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(19, BOUNDARY_WORD_END, "   ran", 16, 22,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(20, BOUNDARY_WORD_END, "   ran", 16, 22,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(21, BOUNDARY_WORD_END, "   ran", 16, 22,
-                       "input", kOk, kOk, kOk,
-                       "div", kOk, kOk, kOk,
-                       "editable", kOk, kOk, kOk,
-                       "textarea", kOk, kOk, kOk);
-      testTextAtOffset(22, BOUNDARY_WORD_END, "   ran", 16, 22,
-                       "input", kTodo, kTodo, kTodo,
-                       "div", kTodo, kTodo, kTodo,
-                       "editable", kTodo, kTodo, kTodo,
-                       "textarea", kTodo, kTodo, kTodo);
+
+      // BOUNDARY_WORD_END
+      testTextAtOffset(0, BOUNDARY_WORD_END, "", 0, 0, IDs);
+      testTextAtOffset(4, BOUNDARY_WORD_END, "Brave", 0, 5, IDs);
+      testTextAtOffset(5, BOUNDARY_WORD_END, "Brave", 0, 5, IDs);
+      testTextAtOffset(6, BOUNDARY_WORD_END, " Sir", 5, 9, IDs);
+      testTextAtOffset(8, BOUNDARY_WORD_END, " Sir", 5, 9, IDs);
+      testTextAtOffset(9, BOUNDARY_WORD_END, " Sir", 5, 9, IDs);
+      testTextAtOffset(10, BOUNDARY_WORD_END, "  Robin", 9, 16, IDs);
+      testTextAtOffset(11, BOUNDARY_WORD_END, "  Robin", 9, 16, IDs);
+      testTextAtOffset(15, BOUNDARY_WORD_END, "  Robin", 9, 16, IDs);
+      testTextAtOffset(16, BOUNDARY_WORD_END, "  Robin", 9, 16, IDs);
+      testTextAtOffset(17, BOUNDARY_WORD_END, "   ran", 16, 22, IDs);
+      testTextAtOffset(18, BOUNDARY_WORD_END, "   ran", 16, 22, IDs);
+      testTextAtOffset(19, BOUNDARY_WORD_END, "   ran", 16, 22, IDs);
+      testTextAtOffset(20, BOUNDARY_WORD_END, "   ran", 16, 22, IDs);
+      testTextAtOffset(21, BOUNDARY_WORD_END, "   ran", 16, 22, IDs);
+      testTextAtOffset(22, BOUNDARY_WORD_END, "   ran", 16, 22, IDs);
 
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
 <body>
 
   <a target="_blank"
      title="getText... methods tests on string with whitespaces for plain text containers"
-     href="https://bugzilla.mozilla.org/show_bug.cgi?id=610568">Mozilla Bug 610568</a>
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=610568">
+    Bug 610568
+  </a>
+  <a target="_blank"
+     title="getTextAtOffset for word boundaries: beginning of a new life"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=853340">
+    Bug 853340
+  </a>
+  <a target="_blank"
+     title="getTextBeforeOffset for word boundaries: evolving"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=855732">
+    Bug 855732
+  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   <input id="input" value="Brave Sir  Robin   ran"/>
   <div id="div">Brave Sir  Robin   ran</div>
   <div id="editable" contenteditable="true">Brave Sir  Robin   ran</div>
   <textarea id="textarea" cols="300">Brave Sir  Robin   ran</textarea>
   </pre>
--- a/accessible/tests/mochitest/text/test_words.html
+++ b/accessible/tests/mochitest/text/test_words.html
@@ -10,17 +10,17 @@
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../text.js"></script>
   <script type="application/javascript">
     if (navigator.platform.startsWith("Mac")) {
       SimpleTest.expectAssertions(0, 1);
     } else {
-      SimpleTest.expectAssertions(1);
+      SimpleTest.expectAssertions(0, 1);
     }
 
     function doTest()
     {
       // "one two"
       testWords("div1", ["one", "two"]);
 
       // "one  two"
--- a/accessible/tests/mochitest/textattrs/moz.build
+++ b/accessible/tests/mochitest/textattrs/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/mochitest/textcaret/moz.build
+++ b/accessible/tests/mochitest/textcaret/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/mochitest/textselection/moz.build
+++ b/accessible/tests/mochitest/textselection/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/mochitest/tree/moz.build
+++ b/accessible/tests/mochitest/tree/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/mochitest/tree/test_filectrl.html
+++ b/accessible/tests/mochitest/tree/test_filectrl.html
@@ -17,21 +17,26 @@ https://bugzilla.mozilla.org/show_bug.cg
 
   <script type="application/javascript">
     function doTest()
     {
       var accTree = {
         role: ROLE_TEXT_CONTAINER,
         children: [
           {
-            role: ROLE_ENTRY
+            role: ROLE_PUSHBUTTON
           },
           {
-            role: ROLE_PUSHBUTTON
-          }
+            role: ROLE_LABEL,
+            children: [
+              {
+                role: ROLE_TEXT_LEAF,
+              }
+            ],
+          },
         ]
       };
       testAccessibleTree("filectrl", accTree);
 
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
--- a/accessible/tests/mochitest/tree/test_txtctrl.xul
+++ b/accessible/tests/mochitest/tree/test_txtctrl.xul
@@ -13,21 +13,16 @@
           src="../common.js" />
   <script type="application/javascript"
           src="../role.js" />
   <script type="application/javascript"
           src="../events.js" />
 
   <script type="application/javascript">
   <![CDATA[
-    if (navigator.platform.startsWith("Mac")) {
-      SimpleTest.expectAssertions(0, 1);
-    } else {
-      SimpleTest.expectAssertions(1);
-    }
     ////////////////////////////////////////////////////////////////////////////
     // Test
 
     function doTest()
     {
       ////////////////////
       // textbox
       ////////////////////
--- a/accessible/tests/mochitest/treeupdate/moz.build
+++ b/accessible/tests/mochitest/treeupdate/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/mochitest/value/moz.build
+++ b/accessible/tests/mochitest/value/moz.build
@@ -1,5 +1,6 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
--- a/accessible/tests/moz.build
+++ b/accessible/tests/moz.build
@@ -1,8 +1,9 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 DIRS += ['mochitest']
 
 MODULE = 'test_accessibility'
--- a/addon-sdk/moz.build
+++ b/addon-sdk/moz.build
@@ -1,7 +1,8 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 TEST_DIRS += ['test']
 
--- a/addon-sdk/source/app-extension/bootstrap.js
+++ b/addon-sdk/source/app-extension/bootstrap.js
@@ -15,17 +15,18 @@ const { classes: Cc, Constructor: CC, in
 const ioService = Cc['@mozilla.org/network/io-service;1'].
                   getService(Ci.nsIIOService);
 const resourceHandler = ioService.getProtocolHandler('resource').
                         QueryInterface(Ci.nsIResProtocolHandler);
 const systemPrincipal = CC('@mozilla.org/systemprincipal;1', 'nsIPrincipal')();
 const scriptLoader = Cc['@mozilla.org/moz/jssubscript-loader;1'].
                      getService(Ci.mozIJSSubScriptLoader);
 const prefService = Cc['@mozilla.org/preferences-service;1'].
-                    getService(Ci.nsIPrefService);
+                    getService(Ci.nsIPrefService).
+                    QueryInterface(Ci.nsIPrefBranch);
 const appInfo = Cc["@mozilla.org/xre/app-info;1"].
                 getService(Ci.nsIXULAppInfo);
 const vc = Cc["@mozilla.org/xpcom/version-comparator;1"].
            getService(Ci.nsIVersionComparator);
 
 
 const REASON = [ 'unknown', 'startup', 'shutdown', 'enable', 'disable',
                  'install', 'uninstall', 'upgrade', 'downgrade' ];
@@ -122,22 +123,31 @@ function startup(data, reasonCode) {
       return result;
     }, paths);
 
     // We need to map tests folder when we run sdk tests whose package name
     // is stripped
     if (name == 'addon-sdk')
       paths['tests/'] = prefixURI + name + '/tests/';
 
+    let useBundledSDK = options['force-use-bundled-sdk'];
+    if (!useBundledSDK) {
+      try {
+        useBundledSDK = prefService.getBoolPref("extensions.addon-sdk.useBundledSDK");
+      }
+      catch (e) {
+        // Pref doesn't exist, allow using Firefox shipped SDK
+      }
+    }
+
     // Starting with Firefox 21.0a1, we start using modules shipped into firefox
     // Still allow using modules from the xpi if the manifest tell us to do so.
     // And only try to look for sdk modules in xpi if the xpi actually ship them
     if (options['is-sdk-bundled'] &&
-        (vc.compare(appInfo.version, '21.0a1') < 0 ||
-         options['force-use-bundled-sdk'])) {
+        (vc.compare(appInfo.version, '21.0a1') < 0 || useBundledSDK)) {
       // Maps sdk module folders to their resource folder
       paths[''] = prefixURI + 'addon-sdk/lib/';
       // test.js is usually found in root commonjs or SDK_ROOT/lib/ folder,
       // so that it isn't shipped in the xpi. Keep a copy of it in sdk/ folder
       // until we no longer support SDK modules in XPI:
       paths['test'] = prefixURI + 'addon-sdk/lib/sdk/test.js';
     }
 
--- a/addon-sdk/source/app-extension/install.rdf
+++ b/addon-sdk/source/app-extension/install.rdf
@@ -12,18 +12,18 @@
     <em:type>2</em:type>
     <em:bootstrap>true</em:bootstrap>
     <em:unpack>false</em:unpack>
 
     <!-- Firefox -->
     <em:targetApplication>
       <Description>
         <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
-        <em:minVersion>18.0</em:minVersion>
-        <em:maxVersion>21.0a1</em:maxVersion>
+        <em:minVersion>19.0</em:minVersion>
+        <em:maxVersion>22.0a1</em:maxVersion>
       </Description>
     </em:targetApplication>
 
     <!-- Front End MetaData -->
     <em:name>Test App</em:name>
     <em:description>Harness for tests.</em:description>
     <em:creator>Mozilla Corporation</em:creator>
     <em:homepageURL></em:homepageURL>
--- a/addon-sdk/source/doc/dev-guide-source/credits.md
+++ b/addon-sdk/source/doc/dev-guide-source/credits.md
@@ -130,17 +130,17 @@ We'd like to thank our many Jetpack proj
 * Paul O’Shannessy
 * Les Orchard
 
 <!--end-->
 
 ### P ###
 
 * Robert Pankowecki
-* [Jamie Phelps](https://github.com/ongaeshi)
+* [Jamie Phelps](https://github.com/jxpx777)
 * [Alexandre Poirot](https://github.com/ochameau)
 * Nickolay Ponomarev
 
 <!--end-->
 
 ### R ###
 
 * Aza Raskin
--- a/addon-sdk/source/doc/dev-guide-source/guides/content-scripts/using-postmessage.md
+++ b/addon-sdk/source/doc/dev-guide-source/guides/content-scripts/using-postmessage.md
@@ -54,60 +54,16 @@ To simplify this most content modules pr
 argument to the constructor:
 
     panel = require("sdk/panel").Panel({
       onMessage: function(contentScriptMessage) {
         // Handle message from the content script
       }
     });
 
-## Timing Issues Using postMessage ##
-
-Content scripts are loaded according to the value of the
-[`contentScriptWhen`](dev-guide/guides/content-scripts/loading.html)
-option: until that point is reached, any attempt to send a message to
-the script using `postMessage()` will trigger an exception, probably
-this:
-
-<span class="aside">
-This is a generic message which is emitted whenever we try to
-send a message to a content script, but can't find the worker
-which is supposed to receive it.
-</span>
-
-<pre>
-Error: Couldn't find the worker to receive this message. The script may not be initialized yet, or may already have been unloaded.
-</pre>
-
-So code like this, where we create a panel and then
-synchronously send it a message using `postMessage()`, will not work:
-
-    var data = require("sdk/self").data;
-
-    var panel = require("sdk/panel").Panel({
-      contentURL: "http://www.bbc.co.uk/mobile/index.html",
-      contentScriptFile: data.url("panel.js")
-    });
-
-    panel.postMessage("hi from main.js");
-
-[`port.emit()`](dev-guide/guides/content-scripts/using-port.html)
-queues messages until the content script is ready to receive them,
-so the equivalent code using `port.emit()` will work:
-
-    var data = require("sdk/self").data;
-
-    var panel = require("sdk/panel").Panel({
-      contentURL: "http://www.bbc.co.uk/mobile/index.html",
-      contentScriptFile: data.url("panel.js")
-    });
-
-    panel.port.emit("hi from main.js");
-
-
 ## Message Events Versus User-Defined Events ##
 
 You can use message events as an alternative to user-defined events:
 
     var pageModScript = "window.addEventListener('mouseover', function(event) {" +
                         "  self.postMessage(event.target.toString());" +
                         "}, false);";
 
--- a/addon-sdk/source/doc/dev-guide-source/guides/events.md
+++ b/addon-sdk/source/doc/dev-guide-source/guides/events.md
@@ -46,41 +46,36 @@ It takes two parameters:
 Many event emitters may emit more than one type of event: for example, a browser
 window might emit both `open` and `close` events. The list of valid event types
 is specific to an event emitter and is included with its documentation.
 
 * **`listener`**: the listener itself. This is a function which will be called
 whenever the event occurs. The arguments that will be passed to the listener
 are specific to an event type and are documented with the event emitter.
 
-For example, the following add-on registers two listeners with the
-[`private-browsing`](modules/sdk/private-browsing.html) module to
-listen for the `start` and `stop` events, and logs a string to the console
-reporting the change:
-
-    var pb = require("sdk/private-browsing");
+For example, the following add-on registers a listener with the
+[`tabs`](modules/sdk/tabs.html) module to
+listen for the `ready` event, and logs a string to the console
+reporting the event:
 
-    pb.on("start", function() {
-      console.log("Private browsing is on");
-    });
+    var tabs = require("sdk/tabs");
 
-    pb.on("stop", function() {
-      console.log("Private browsing is off");
+    tabs.on("ready", function () {
+      console.log("tab loaded");
     });
 
 It is not possible to enumerate the set of listeners for a given event.
 
 The value of `this` in the listener function is the object that emitted
 the event.
 
 ### Adding Listeners in Constructors ###
 
-Event emitters may be modules, as is the case for the
-`private-browsing` events, or they may be objects returned by
-constructors.
+Event emitters may be modules, as is the case for the `ready` event
+above, or they may be objects returned by constructors.
 
 In the latter case the `options` object passed to the constructor typically
 defines properties whose names are the names of supported event types prefixed
 with "on": for example, "onOpen", "onReady" and so on. Then in the constructor
 you can assign a listener function to this property as an alternative to
 calling the object's `on()` method.
 
 For example: the [`widget`](modules/sdk/widget.html) object emits
@@ -121,33 +116,41 @@ widget's `on()` method:
 ## Removing Event Listeners ##
 
 Event listeners can be removed by calling `removeListener(type, listener)`,
 supplying the type of event and the listener to remove.
 
 The listener must have been previously been added using one of the methods
 described above.
 
-In the following add-on, we add two listeners to private-browsing's `start`
-event, enter and exit private browsing, then remove the first listener and
-enter private browsing again.
+In the following add-on, we add two listeners to the
+[`tabs` module's `ready` event](modules/sdk/tabs.html#ready).
+One of the handler functions removes the listener again.
 
-    var pb = require("sdk/private-browsing");
+Then we open two tabs.
+
+    var tabs = require("sdk/tabs");
 
     function listener1() {
       console.log("Listener 1");
-      pb.removeListener("start", listener1);
+      tabs.removeListener("ready", listener1);
     }
 
     function listener2() {
       console.log("Listener 2");
     }
 
-    pb.on("start", listener1);
-    pb.on("start", listener2);
+    tabs.on("ready", listener1);
+    tabs.on("ready", listener2);
+
+    tabs.open("https://www.mozilla.org");
+    tabs.open("https://www.mozilla.org");
+
+We should see output like this:
 
-    pb.activate();
-    pb.deactivate();
-    pb.activate();
+<pre>
+info: tabevents: Listener 1
+info: tabevents: Listener 2
+info: tabevents: Listener 2
+</pre>
 
-Removing listeners is optional since they will be removed in any case
-when the application or add-on is unloaded.
+Listeners will be removed automatically when the add-on is unloaded.
 
--- a/addon-sdk/source/doc/dev-guide-source/package-spec.md
+++ b/addon-sdk/source/doc/dev-guide-source/package-spec.md
@@ -1,125 +1,222 @@
 <!-- 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/. -->
 
-# Package Specification #
+# package.json #
+
+The "package.json" file contains metadata for your add-on.
+
+Some of its entries, such as [`icon`](dev-guide/package-spec.html#icon),
+[`name`](dev-guide/package-spec.html#name), and
+[`description`](dev-guide/package-spec.html#description), have
+direct analogues in the
+[install manifest](https://developer.mozilla.org/en-US/docs/Install_Manifests)
+format, and entries from package.json are written into the install
+manifest when the add-on is built using [`cfx xpi`](dev-guide/cfx-tool.html#cfx xpi).
 
-A *package* is a directory that, at minimum, contains a JSON file
-called `package.json`. This file is also referred to as the
-*package manifest*.
+Others, such as
+[`lib`](dev-guide/package-spec.html#lib),
+[`permissions`](dev-guide/package-spec.html#permissions),
+and [`preferences`](dev-guide/package-spec.html#preferences),
+represent instructions to the cfx tool itself to generate and include
+particular code and data structures in your add-on.
 
-## The Package Manifest ##
+The `package.json` file is initially generated in your add-on's root
+directory the first time you run
+[`cfx init`](dev-guide/cfx-tool.html#cfx init). It looks like this
+(assuming the add-on's directory is "my-addon"):
+
+<pre>
+{
+  "name": "my-addon",
+  "fullName": "my-addon",
+  "description": "a basic add-on",
+  "author": "",
+  "license": "MPL 2.0",
+  "version": "0.1"
+}
+</pre>
 
 `package.json` may contain the following keys:
 
-* `name` - the name of the package. The package system will only load
-  one package with a given name. This name cannot contain spaces or periods.
-  The name defaults to the name of the parent directory. If the package is
-  ever built as an XPI and the `fullName` key is not present, this is
-  used as the add-on's `em:name` element in its `install.rdf`.
+<table>
+
+<colgroup>
+  <col width="20%"></col>
+  <col width="80%"></col>
+</colgroup>
 
-* `fullName` - the full name of the package. It can contain spaces. If
-  the package is ever built as an XPI, this is used as the add-on's
-  `em:name` element in its `install.rdf`.
+<tr>
+  <td id="author"><code>author</code></td>
+  <td><p>The original author of the package. Defaults to an empty string.
+  It may include a optional URL in parentheses and an email
+  address in angle brackets.</p>
+  <p>This value will be used as the add-on's
+  <a href="https://developer.mozilla.org/en-US/docs/Install_Manifests#creator"><code>em:creator</code></a>
+  element in its "install.rdf".</p></td>
+</tr>
 
-* `description` - a String describing the package. If the package is
-  ever built as an XPI, this is used as the add-on's
-  `em:description` element in its `install.rdf`.
+<tr>
+  <td id="contributors"><code>contributors</code></td>
+  <td><p>An array of additional <a href="dev-guide/package-spec.html#author"><code>author</code></a>
+  strings.</p>
+  <p>These values will be used as the add-on's
+  <a href="https://developer.mozilla.org/en-US/docs/Install_Manifests#contributor"><code>em:contributor</code></a>
+  elements in its "install.rdf".</p></td>
+</tr>
 
-* `author` - the original author of the package. The author may be a
-  String including an optional URL in parentheses and optional email
-  address in angle brackets. If the package is ever built as an XPI,
-  this is used as the add-on's `em:creator` element in its
-  `install.rdf`.
+<tr>
+  <td id="dependencies"><code>dependencies</code></td>
+  <td><p>String or array of strings representing package
+  names that this add-on requires in order to function properly.</p></td>
+</tr>
 
-* `translators` - an Array of Strings consisted of translators of the package.
-
-* `contributors` - may be an Array of additional author Strings.
-
-* `homepage` - the URL of the package's website.
+<tr>
+  <td id="description"><code>description</code></td>
+  <td><p>The add-on's description. This defaults to the text
+  <code>"a basic add-on"</code>.</p>
+  <p>This value will be used as the add-on's
+  <a href="https://developer.mozilla.org/en-US/docs/Install_Manifests#description"><code>em:description</code></a>
+  element in its "install.rdf".</p></td>
+</tr>
 
-* `icon` - the relative path from the root of the package to a
-  PNG file containing the icon for the package. By default, this
-  is `icon.png`. If the package is built as an XPI, this is used
-  as the add-on's icon to display in the Add-on Manager's add-ons list.
-  This key maps on to the
-  [`iconURL` entry in the Install Manifest](https://developer.mozilla.org/en/install_manifests#iconURL),
-  so the icon may be up to 48x48 pixels in size.
+<tr>
+  <td id="fullName"><code>fullName</code></td>
+  <td><p>The full name of the package. It can contain spaces.<p></p>
+  If this key is present its value will be used as the add-on's
+  <a href="https://developer.mozilla.org/en-US/docs/Install_Manifests#name"><code>em:name</code></a>
+  element in its "install.rdf".</p></td>
+</tr>
+
+<tr>
+  <td id="harnessClassID"><code>harnessClassID</code></td>
+  <td><p>String in the <a href="https://developer.mozilla.org/en-US/docs/Generating_GUIDs">GUID format</a>.</p>
+  <p>This is used as a
+  <a href="https://developer.mozilla.org/en-US/docs/Creating_XPCOM_Components/An_Overview_of_XPCOM#CID"><code>classID</code></a>
+  of the "harness service" XPCOM component. Defaults to a random GUID generated by <code>cfx</code>.</p></td>
+</tr>
 
-* `icon64` - the relative path from the root of the package to a
-  PNG file containing the icon64 for the package. By default, this
-  is `icon64.png`. If the package is built as an XPI, this is used
-  as the add-on's icon to display in the Addon Manager's add-on details view.
-  This key maps on to the
-  [`icon64URL` entry in the Install Manifest](https://developer.mozilla.org/en/install_manifests#icon64URL),
-  so the icon should be 64x64 pixels in size.
+<tr>
+  <td id="homepage"><code>homepage</code></td>
+  <td><p>The URL of the add-on's website.</p>
+  <p>This value will be used as the add-on's
+  <a href="https://developer.mozilla.org/en-US/docs/Install_Manifests#homepageURL"><code>em:homepageURL</code></a>
+  element in its "install.rdf".</p></td>
+</tr>
 
-* `preferences` - *experimental*
-  An array of JSON objects that use the following keys `name`, `type`, `value`,
-  `title`, and `description`.  These JSON objects will be used to automatically
-  create a preferences interface for the addon in the Add-ons Manager.
-  For more information see the documentation of [simple-prefs](modules/sdk/simple-prefs.html).
+<tr>
+  <td id="icon"><code>icon</code></td>
+  <td><p>The relative path from the root of the add-on to a
+  PNG file containing the icon for the add-on. Defaults to
+  <code>"icon.png"</code>.</p>
+  <p>This value will be used as the add-on's
+  <a href="https://developer.mozilla.org/en-US/docs/Install_Manifests#iconURL"><code>em:iconURL</code></a>
+  element in its "install.rdf".</p>
+  <p>The icon may be up to 48x48 pixels in size.</p></td>
+</tr>
 
-* `license` - the name of the license as a String, with an optional
-  URL in parentheses.
-
-* `id` - a globally unique identifier for the package. When the package is
-   built as an XPI, this is used as the add-on's `em:id` element in its
-  `install.rdf`. See the
-  [Program ID page](dev-guide/guides/program-id.html).
+<tr>
+  <td id="icon64"><code>icon64</code></td>
+  <td><p>The relative path from the root of the add-on to a
+  PNG file containing the large icon for the add-on. Defaults to
+  <code>"icon64.png"</code>.</p>
+  <p>This value will be used as the add-on's
+  <a href="https://developer.mozilla.org/en-US/docs/Install_Manifests#icon64URL"><code>em:icon64URL</code></a>
+  element in its "install.rdf".</p>
+  <p>The icon may be up to 64x64 pixels in size.</p></td>
+</tr>
 
-* `version` - a String representing the version of the package. If the
-  package is ever built as an XPI, this is used as the add-on's
-  `em:version` element in its `install.rdf`.
+<tr>
+  <td id="id"><code>id</code></td>
+  <td><p>A globally unique identifier for the add-on.</p>
+  <p>This value will be used as the add-on's
+  <a href="https://developer.mozilla.org/en-US/docs/Install_Manifests#id"><code>em:id</code></a>
+  element in its "install.rdf".</p>
+  <p>See the <a href="dev-guide/guides/program-id.html">Program ID documentation</a>.</p></td>
+</tr>
 
-* `dependencies` - a String or Array of Strings representing package
-  names that this package requires in order to function properly.
+<tr>
+  <td id="lib"><code>lib</code></td>
+  <td><p>String representing the top-level module directory provided in
+  this add-on. Defaults to <code>"lib"</code>.</p></td>
+</tr>
 
-* `lib` - a String representing the top-level module directory provided in
-  this package. Defaults to `"lib"`.
-
-* `tests` - a String representing the top-level module directory containing
-  test suites for this package. Defaults to `"tests"`.
+<tr>
+  <td id="license"><code>license</code></td>
+  <td><p>The name of the license under which the add-on is distributed, with an optional
+  URL in parentheses. Defaults to <code>"MPL 2.0"</code>.</p></td>
+</tr>
 
-* `packages` - a String or Array of Strings representing paths to
-  directories containing additional packages, defaults to
-  `"packages"`.
-
-* `main` - a String representing the name of a program module that is
+<tr>
+  <td id="main"><code>main</code></td>
+  <td><p>String representing the name of a program module that is
   located in one of the top-level module directories specified by
-  `lib`. Defaults to `"main"`.
+  <a href="dev-guide/package-spec.html#lib"><code>lib</code></a>.
+  Defaults to <code>"main"</code>.</p></td>
+</tr>
 
-* `harnessClassID` - a String in the GUID format:
-  `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`, where `x` represents a single
-  hexadecimal digit. It is used as a `classID` (CID) of the "harness service"
-  XPCOM component. Defaults to a random GUID generated by `cfx`.
+<tr>
+  <td id="name"><code>name</code></td>
+  <td><p>The add-on's name. This name cannot contain spaces or periods, and
+  defaults to the name of the parent directory.</p><p>When the add-on is
+  built as an XPI, if the <a href="dev-guide/package-spec.html#fullName"><code>fullName</code></a>
+  key is not present, <code>name</code> is used as the add-on's
+  <a href="https://developer.mozilla.org/en-US/docs/Install_Manifests#name"><code>em:name</code></a>
+  element in its "install.rdf".</p></td>
+</tr>
+
+<tr>
+  <td id="packages"><code>packages</code></td>
+  <td><p>String or array of strings representing paths to
+  directories containing additional packages. Defaults to
+  <code>"packages"</code>.</p></td>
+</tr>
 
-* `permissions` - a set of permissions that the add-on needs.
-    * `private-browsing` - A Boolean indicating whether or not the
-      package supports private browsing.  If this value is not `true`
-      then the package will not see private windows.
+<tr>
+  <td id="permissions"><code>permissions</code></td>
+  <td><p>A set of permissions that the add-on needs.</p>
+    <p><strong><code>private-browsing</code></strong>: a boolean
+  indicating whether or not the
+  add-on supports private browsing. If this value is not <code>true</code>
+  or is omitted, then the add-on will not see any private windows or
+objects, such as tabs, that are associated with private windows. See the
+documentation for the
+<a href="modules/sdk/private-browsing.html"><code>private-browsing</code> module</a>.</p>
+  </td>
+</tr>
 
-## Documentation ##
-
-A package may optionally contain a
-[Markdown](http://daringfireball.net/projects/markdown/)-formatted file
-called `README.md` in its root directory. Package-browsing tools may display
-this file to developers.
+<tr>
+  <td id="preferences"><code>preferences</code></td>
+  <td><p>An array of JSON objects that use the following keys:
+  <code>name</code>,<code>type</code>, <code>value</code>,
+  <code>title</code>, and <code>description</code>.  These JSON objects will be used to
+  create a preferences interface for the add-on in the Add-ons Manager.</p>
+  <p>See the documentation for the
+  <a href="modules/sdk/simple-prefs.html"><code>simple-prefs</code> module</a>.</p></td>
+</tr>
 
-Additionally, Markdown files can be placed in an optional `docs`
-directory. When package-browsing tools are asked to show the
-documentation for a module, they will look in this directory for a
-`.md` file with the module's name. Thus, for instance, if a user
-browses to a module at `lib/foo/bar.js`, the package-browsing tool
-will look for a file at `docs/foo/bar.js` to represent the module's
-API documentation.
+<tr>
+  <td id="tests"><code>tests</code></td>
+  <td><p>String representing the top-level module directory containing
+  test suites for this package. Defaults to <code>"tests"</code>.</p></td>
+</tr>
 
-## Data Resources ##
+<tr>
+  <td id="translators"><code>translators</code></td>
+  <td><p>An array of strings listing translators of this add-on.</p>
+  <p>These values will be used as the add-on's
+  <a href="https://developer.mozilla.org/en-US/docs/Install_Manifests#translator"><code>em:translator</code></a>
+  elements in its "install.rdf".</p></td>
+</tr>
 
-Packages may optionally contain a directory called `data` into which
-arbitrary files may be placed, such as images or text files. The
-URL for these resources may be reached using the
-[self](modules/sdk/self.html) module.
+<tr>
+  <td id="version"><code>version</code></td>
+  <td><p>String representing the version of the add-on. Defaults to
+  <code>"0.1"</code>.</p>
+  <p>This value will be used as the add-on's
+  <a href="https://developer.mozilla.org/en-US/docs/Install_Manifests#version"><code>em:version</code></a>
+  element in its "install.rdf".</p></td>
+</tr>
 
-  [Markdown]: http://daringfireball.net/projects/markdown/
-  [non-bootstrapped XUL extension]: #guide/xul-extensions
+</table>
+
--- a/addon-sdk/source/doc/dev-guide-source/tutorials/annotator/overview.md
+++ b/addon-sdk/source/doc/dev-guide-source/tutorials/annotator/overview.md
@@ -45,18 +45,22 @@ elements they are associated with. It hi
 are found. When the user moves the mouse over an annotated element
 the matcher tells the main add-on code, which displays the annotation panel.
 
 ## Working with Data ##
 
 We'll use the `simple-storage` module to store annotations.
 
 Because we are recording potentially sensitive information, we want to prevent
-the user creating annotations when in private browsing mode, so we'll use the
-`private-browsing` module for that.
+the user creating annotations when in private browsing mode. The simplest way
+to do this is to omit the
+[`"private-browsing"` key](dev-guide/package-spec.html#permissions) from the
+add-on's "package.json" file. If we do this, then the add-on won't see any
+private windows, and the annotator's widget will not appear in any private
+windows.
 
 ## Getting Started ##
 
 
 Let's get started by creating a directory called "annotator". Navigate to it
 and type `cfx init`.
 
 Next, we will implement the
--- a/addon-sdk/source/doc/dev-guide-source/tutorials/annotator/storing.md
+++ b/addon-sdk/source/doc/dev-guide-source/tutorials/annotator/storing.md
@@ -272,98 +272,25 @@ Because we use a notification to alert t
 
 (It should be obvious that this is an incredibly unhelpful way to deal with the
 problem. A real add-on should give the user a chance to choose which data to
 keep, and prevent the user from adding any more data until the add-on is back
 under quota.)
 
 ## Respecting Private Browsing ##
 
-Since annotations record the user's browsing history we should prevent the user
-from creating annotations while the browser is in
-[Private Browsing](http://support.mozilla.com/en-US/kb/Private%20Browsing) mode.
-
-First let's import the `private-browsing` module into `main.js`:
-
-    var privateBrowsing = require('sdk/private-browsing');
-
-We already have a variable `annotatorIsOn` that we use to indicate whether the
-user can enter annotations. But we don't want to use that here, because we want
-to remember the underlying state so that when they exit Private Browsing the
-annotator is back in whichever state it was in before.
-
-So we'll implement a function defining that to enter annotations, the annotator
-must be active *and* Private Browsing must be off:
-
-    function canEnterAnnotations() {
-      return (annotatorIsOn && !privateBrowsing.isActive);
-    }
-
-Next, everywhere we previously used `annotatorIsOn` directly, we'll call this
-function instead:
-
-    function activateSelectors() {
-      selectors.forEach(
-        function (selector) {
-          selector.postMessage(canEnterAnnotations());
-      });
-    }
-<br>
-
-    function toggleActivation() {
-      annotatorIsOn = !annotatorIsOn;
-      activateSelectors();
-      return canEnterAnnotations();
-    }
-<br>
+Since annotations record the user's browsing history we should avoid recording
+annotations in private windows.
 
-    var selector = pageMod.PageMod({
-      include: ['*'],
-      contentScriptWhen: 'ready',
-      contentScriptFile: [data.url('jquery-1.4.2.min.js'),
-                          data.url('selector.js')],
-      onAttach: function(worker) {
-        worker.postMessage(canEnterAnnotations());
-        selectors.push(worker);
-        worker.port.on('show', function(data) {
-          annotationEditor.annotationAnchor = data;
-          annotationEditor.show();
-        });
-        worker.on('detach', function () {
-          detachWorker(this, selectors);
-        });
-      }
-    });
-
-We want to stop the user changing the underlying activation state when in
-Private Browsing mode, so we'll edit `toggleActivation` again:
+There's a very simple way to do this: do nothing. By omitting the
+[`"private-browsing"` key](dev-guide/package-spec.html#permissions) from the
+annotator's "package.json" file, the annotator opts out of private browsing
+altogether.
 
-    function toggleActivation() {
-      if (privateBrowsing.isActive) {
-        return false;
-      }
-      annotatorIsOn = !annotatorIsOn;
-      activateSelectors();
-      return canEnterAnnotations();
-    }
-
-Finally, inside the `main` function, we'll add the following code to handle
-changes in Private Browsing state by changing the icon and notifying the
-selectors:
+This means that its widget will not appear on any private windows and its
+selector and matcher content scripts won't run, so the user won't be able to
+enter any annotations in private windows.
 
-    privateBrowsing.on('start', function() {
-      widget.contentURL = data.url('widget/pencil-off.png');
-      activateSelectors();
-    });
-
-    privateBrowsing.on('stop', function() {
-      if (canEnterAnnotations()) {
-        widget.contentURL = data.url('widget/pencil-on.png');
-        activateSelectors();
-      }
-    });
-
-Try it: execute `cfx run`, and experiment with switching the annotator on and
-off while in and out of Private Browsing mode.
+Try it: execute cfx run and open a new private window: you should no longer
+see the annotator's widget.
 
 Now we can create and store annotations, the last piece is to
-[display them when the user loads the
-page](dev-guide/tutorials/annotator/displaying.html).
+[display them when the user loads the page](dev-guide/tutorials/annotator/displaying.html).
\ No newline at end of file
--- a/addon-sdk/source/doc/dev-guide-source/tutorials/event-targets.md
+++ b/addon-sdk/source/doc/dev-guide-source/tutorials/event-targets.md
@@ -5,17 +5,17 @@
 # Creating Event Targets #
 
 <span class="aside">This tutorial describes the use of low-level APIs.
 These APIs are still in active development, and we expect to make
 incompatible changes to them in future releases.</span>
 
 The [guide to event-driven programming with the SDK](dev-guide/guides/events.html)
 describes how to consume events: that is, how to listen to events generated
-by event targets. For example, you can listen to [`private-browsing`'s `start` event](modules/sdk/private-browsing.html#start) or the
+by event targets. For example, you can listen to the [`tabs` module's `ready` event](modules/sdk/tabs.html#ready) or the
 [`Panel` object's `show` event](modules/sdk/panel.html#show).
 
 With the SDK, it's also simple to implement your own event targets.
 This is especially useful if you want to
 [build your own modules](dev-guide/tutorials/reusable-modules.html),
 either to organize your add-on better or to enable other developers to
 reuse your code. If you use the SDK's event framework for your
 event targets, users of your module can listen for events using the SDK's
--- a/addon-sdk/source/doc/module-source/sdk/context-menu.md
+++ b/addon-sdk/source/doc/module-source/sdk/context-menu.md
@@ -1,21 +1,15 @@
 <!-- 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/. -->
 
 <!-- contributed by Drew Willcoxon [adw@mozilla.com]  -->
 <!-- edited by Noelle Murata [fiveinchpixie@gmail.com]  -->
 
-The `context-menu` module lets you add items to Firefox's page context menu.
-
-
-Introduction
-------------
-
 The `context-menu` API provides a simple, declarative way to add items to the
 page's context menu. You can add items that perform an action when clicked,
 submenus, and menu separators.
 
 Instead of manually adding items when particular contexts occur and then
 removing them when those contexts go away, you *bind* items to contexts, and the
 adding and removing is automatically handled for you. Items are bound to
 contexts in much the same way that event listeners are bound to events. When
@@ -391,16 +385,25 @@ This item implements the aforementioned 
                      '});'
     });
 
 The `"context"` listener gets the window's current selection, truncating it if
 it's too long, and includes it in the returned string. When the item is shown,
 its label will be "Search Google for `text`", where `text` is the truncated
 selection.
 
+## Private Windows ##
+
+If your add-on has not opted into private browsing, then any menus or
+menu items that you add will not appear in context menus belonging to
+private browser windows.
+
+To learn more about private windows, how to opt into private browsing, and how
+to support private browsing, refer to the
+[documentation for the `private-browsing` module](modules/sdk/private-browsing.html).
 
 More Examples
 -------------
 
 For conciseness, these examples create their content scripts as strings and use
 the `contentScript` property. In your own add-on, you will probably want to
 create your content scripts in separate files and pass their URLs using the
 `contentScriptFile` property. See
--- a/addon-sdk/source/doc/module-source/sdk/page-mod.md
+++ b/addon-sdk/source/doc/module-source/sdk/page-mod.md
@@ -254,16 +254,26 @@ The following add-on creates a widget wh
             'var divs = document.getElementsByTagName("div");' +
             'for (var i = 0; i < divs.length; ++i) {' +
               'divs[i].setAttribute("style", "border: solid red 1px;");' +
             '}'
         });
       }
     });
 
+## Private Windows ##
+
+If your add-on has not opted into private browsing, then your page-mods will
+not attach content scripts to documents loaded into private windows, even if
+their URLs match the pattern you have specified.
+
+To learn more about private windows, how to opt into private browsing, and how
+to support private browsing, refer to the
+[documentation for the `private-browsing` module](modules/sdk/private-browsing.html).
+
 <api name="PageMod">
 @class
 A page-mod object. Once created a page-mod will execute the supplied content
 scripts, and load any supplied stylesheets, in the context of any documents
 matching the pattern specified by the `include` property.
 
 <api name="PageMod">
 @constructor
--- a/addon-sdk/source/doc/module-source/sdk/panel.md
+++ b/addon-sdk/source/doc/module-source/sdk/panel.md
@@ -26,16 +26,25 @@ them.
 A panel's content is loaded as soon as it is created, before the panel is shown,
 and the content remains loaded when a panel is hidden, so it is possible
 to keep a panel around in the background, updating its content as appropriate
 in preparation for the next time it is shown.
 
 Your add-on can receive notifications when a panel is shown or hidden by
 listening to its `show` and `hide` events.
 
+Opening a panel will close an already opened panel.
+
+<div class="warning">
+If your add-on has
+<a href="modules/sdk/private-browsing.html#Opting into private browsing">opted into private browsing</a>,
+then you can't use panels in your add-on. This is due to a platform bug which we expect to
+be fixed in Firefox 21.
+</div>
+
 ## Panel Content ##
 
 The panel's content is specified as HTML, which is loaded from the URL
 supplied in the `contentURL` option to the panel's constructor.
 
 You can load remote HTML into the panel:
 
     var panel = require("sdk/panel").Panel({
@@ -371,16 +380,28 @@ The panel's default style is different f
 alt="OS X panel default style">
 
 This helps to ensure that the panel's style is consistent with the dialogs
 displayed by Firefox and other applications, but means you need to take care
 when applying your own styles. For example, if you set the panel's
 `background-color` property to `white` and do not set the `color` property,
 then the panel's text will be invisible on OS X although it looks fine on Ubuntu.
 
+## Private Browsing ##
+
+If your add-on has
+[opted into private browsing](modules/sdk/private-browsing.html#Opting into private browsing),
+then **you can't use panels in your add-on**. This is due to a platform bug which we expect to
+be fixed in Firefox 21.
+
+If your add-on has not opted into private browsing, and it calls `panel.show()`
+when the currently active window is a
+[private window](modules/sdk/private-browsing.html#Per-window private browsing),
+then the panel will not be shown.
+
 <api name="Panel">
 @class
 The Panel object represents a floating modal dialog that can by an add-on to
 present user interface content.
 
 Once a panel object has been created it can be shown and hidden using its
 `show()` and `hide()` methods. Once a panel is no longer needed it can be
 deactivated using `destroy()`.
@@ -395,16 +416,20 @@ add-on.
 @constructor
 Creates a panel.
 @param options {object}
   Options for the panel, with the following keys:
   @prop [width] {number}
     The width of the panel in pixels. Optional.
   @prop [height] {number}
     The height of the panel in pixels. Optional.
+  @prop [focus] {boolean}
+    Set to `false` to prevent taking the focus away when the panel is shown.
+    Only turn this off if necessary, to prevent accessibility issue.
+    Optional, default to `true`.
   @prop [contentURL] {string}
     The URL of the content to load in the panel.
   @prop [allow] {object}
     An optional object describing permissions for the content.  It should
     contain a single key named `script` whose value is a boolean that indicates
     whether or not to execute script in the content.  `script` defaults to true.
   @prop [contentScriptFile] {string,array}
     A local file URL or an array of local file URLs of content scripts to load.
@@ -467,16 +492,22 @@ Tells if the panel is currently shown or
 The height of the panel in pixels.
 </api>
 
 <api name="width">
 @property {number}
 The width of the panel in pixels.
 </api>
 
+<api name="focus">
+@property {boolean}
+Whether of not focus will be taken away when the panel is shown.
+This property is read-only.
+</api>
+
 <api name="contentURL">
 @property {string}
 The URL of content loaded into the panel.  This can point to
 local content loaded from your add-on's "data" directory or remote content.
 Setting it updates the panel's content immediately.
 </api>
 
 <api name="allow">
--- a/addon-sdk/source/doc/module-source/sdk/private-browsing.md
+++ b/addon-sdk/source/doc/module-source/sdk/private-browsing.md
@@ -1,95 +1,175 @@
 <!-- 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/. -->
 
 <!-- contributed by Paul O'Shannessy [paul@oshannessy.com]  -->
 <!-- edited by Noelle Murata [fiveinchpixie@gmail.com]  -->
 <!-- contributed by Irakli Gozalishvili [gozala@mozilla.com] -->
 
-The `private-browsing` module allows you to access Firefox's private browsing
-mode, detecting if it is active and when its state changes.
+## Per-window private browsing ##
+
+Firefox 20 introduces per-window private browsing. This means that private
+browsing status is a property of an individual browser window.
+
+The user enters
+private browsing by opening a new private browser window. When they do this,
+any existing non-private windows are kept open, so the user will typically
+have both private and non-private windows open at the same time.
+
+## Opting into private browsing ##
+
+Add-ons built using the SDK must opt into private browsing by setting the
+following key in their [`package.json`](dev-guide/package-spec.html) file:
+
+<pre>"permissions": {"private-browsing": true}</pre>
+
+If an add-on has not opted in, then the high-level SDK modules will not
+expose private windows, or objects (such as tabs) that are associated
+with private windows:
+
+* the [`windows`](modules/sdk/windows.html) module will not list any
+private browser windows, generate any events for private browser windows,
+or let the add-on open any private browser windows
+
+* the [`tabs`](modules/sdk/tabs.html) module will not list any tabs that
+belong to private browser windows, and the add-on won't receive any events
+for such tabs
+
+* any [`widgets`](modules/sdk/widget.html) will not be displayed in
+private browser windows
+
+* any menus or menu items created using the
+[`context-menu`](modules/sdk/context-menu.html) will not be shown in
+context menus that belong to private browser windows
 
-This module is available in all applications. However, only Firefox will ever
-transition into or out of private browsing mode. For all other applications,
-`pb.isActive` will always be `false`, and none of the events will be emitted.
+* the [`page-mod`](modules/sdk/page-mod.html) module will not attach
+content scripts to documents belonging to private browser windows
+
+* any [`panel`](modules/sdk/panel.html) objects will not be shown if the
+active window is a private browser window
+
+* the [`selection`](modules/sdk/selection.html) module will not include
+any selections made in private browser windows
+
+Add-ons that have opted in:
+
+* will see private windows, so they will need to
+use the `private-browsing` module to check whether objects are private,
+so as to avoid storing data derived from such objects.
+
+* will not be able to use panels in their code. This is due to a platform
+restriction which will be fixed in Firefox 21.
+
+Additionally, add-ons that use low-level modules such as
+[`window/utils`](modules/sdk/window/utils.html) may see private browser
+windows with certain functions, even if they have not explicitly opted
+into private browsing.
+
+## Respecting private browsing ##
+
+The `private-browsing` module exports a single function
+[`isPrivate()`](modules/sdk/private-browsing.html#isPrivate(object))
+that takes an object, which may be a
+[`BrowserWindow`](modules/sdk/windows.html#BrowserWindow),
+[`tab`](modules/sdk/tabs.html#Tab), or
+[`worker`](modules/sdk/content/worker.html#Worker),
+as an argument. It returns `true` only if the object is:
+
+* a private window, or
+* a tab belonging to a private window, or
+* a worker that's associated with a document hosted in a private window
 
-<div class="warning">
-The <a href="modules/sdk/private-browsing.html#activate()"><code>activate</code></a>
-and <a href="modules/sdk/private-browsing.html#deactivate()"><code>deactivate</code></a>
-functions, <a href="modules/sdk/private-browsing.html#isActive"><code>isActive</code></a>
-property, <a href="modules/sdk/private-browsing.html#start"><code>start</code></a>,
-and <a href="modules/sdk/private-browsing.html#stop"><code>stop</code></a>
-events are all
-now deprecated due to per-window private browsing. They will continue to work
-until version 1.13 of the SDK. From version 1.13 onwards they will still exist
-but will have no effect when called.
-</div>
+Add-ons can use this API to decide whether or not to store user data.
+For example, here's an add-on that stores the titles of tabs the user loads,
+and uses `isPrivate()` to exclude the titles of tabs that were loaded into
+private windows:
+
+    var simpleStorage = require("simple-storage");
+ 
+    if (!simpleStorage.storage.titles)
+      simpleStorage.storage.titles = [];
+ 
+    require("tabs").on("ready", function(tab) {
+      if (!require("private-browsing").isPrivate(tab)) {
+        console.log("storing...");
+        simpleStorage.storage.titles.push(tab.title);
+      }
+      else {
+        console.log("not storing, private data");
+      }
+    });
+
+Here's an add-on that uses a [page-mod](modules/sdk/page-mod.html) to log
+the content of pages loaded by the user, unless the page is private. In
+the handler for the page-mod's [`attach`](modules/sdk/page-mod.html#attach)
+event, it passes the worker into `isPrivate()`:
+
+    var pageMod = require("sdk/page-mod");
+    var privateBrowsing = require("sdk/private-browsing");
+
+    var loggingScript = "self.port.on('log-content', function() {" +
+                        "  console.log(document.body.innerHTML);" +
+                        "});";
 
-<api name="isActive">
-@property {boolean}
-  This read-only boolean is `true` if global private browsing mode is turned on.
+    function logPublicPageContent(worker) {
+      if (privateBrowsing.isPrivate(worker)) {
+        console.log("private window, doing nothing");
+      }
+      else {
+        worker.port.emit("log-content");
+      }
+    }
+
+    pageMod.PageMod({
+      include: "*",
+      contentScript: loggingScript,
+      onAttach: logPublicPageContent
+    });
+
+## Tracking private-browsing exit ##
+
+Sometimes it can be useful to cache some data from private windows while they
+are open, as long as you don't store it after the private browsing windows
+have been closed. For example, the "Downloads" window might want to display
+all downloads while there are still some private windows open, then clean out
+all the private data when all private windows have closed.
 
-  <div class="warning">
-  This property is deprecated. It will continue to work until version 1.13 of the SDK.
-  From version 1.13 onwards it will always return `false`.
-  </div>
-</api>
+To do this with the SDK, you can listen to the system event named
+"last-pb-context-exited":
+
+    var events = require("sdk/system/events");
+
+    function listener(event) {
+      console.log("last private window closed");
+    }
+
+    events.on("last-pb-context-exited", listener);
+
+## Working with Firefox 19 ##
+
+In Firefox 19, private browsing is a global property for the entire browser.
+When the user enters private browsing, the existing browsing session is
+suspended and a new blank window opens. This window is private, as are any
+other windows opened until the user chooses to exit private browsing, at which
+point all private windows are closed and the user is returned to the original
+non-private session.
+
+When running on Firefox 19, `isPrivate()` will return true if and only if
+the user has global private browsing enabled.
 
 <api name="isPrivate">
 @function
-  Returns `true` if the argument is a private window or tab.
-@param [thing] {any}
-  The thing to check if it is private, only handles windows and tabs at the moment.
-  Everything else returns `false` automatically.
-  In global private browsing mode, this method returns the same value as `isActive`.
-</api>
-
-<api name="activate">
-@function
-  Turns on global private browsing mode.
-
-  <div class="warning">
-  This function is deprecated. It will continue to work until version 1.13 of the SDK.
-  From version 1.13 onwards it will still exist but will have no effect when called.
-  </div>
-</api>
-
-<api name="deactivate">
-@function
-  Turns off global private browsing mode.
-
-  <div class="warning">
-  This function is deprecated. It will continue to work until version 1.13 of the SDK.
-  From version 1.13 onwards it will still exist but will have no effect when called.
-  </div>
-</api>
+Function to check whether the given object is private. It takes an
+object as an argument, and returns `true` only if the object is:
 
-<api name="start">
-@event
-Emitted immediately after global private browsing begins.
-
-    var pb = require("sdk/private-browsing");
-    pb.on("start", function() {
-      // Do something when the browser starts private browsing mode.
-    });
-
-  <div class="warning">
-  This event is deprecated. It will continue to work until version 1.13 of the SDK.
-  From version 1.13 onwards this event will not be emitted.
-  </div>
-</api>
+* a private [`BrowserWindow`](modules/sdk/windows.html#BrowserWindow) or
+* a [`tab`](modules/sdk/tabs.html#Tab) belonging to a private window, or
+* a [`worker`](modules/sdk/content/worker.html#Worker) that's associated
+with a document hosted in a private window
 
-<api name="stop">
-@event
-Emitted immediately after global private browsing ends.
-
-    var pb = require("sdk/private-browsing");
-    pb.on("stop", function() {
-      // Do something when the browser stops private browsing mode.
-    });
-
-  <div class="warning">
-  This event is deprecated. It will continue to work until version 1.13 of the SDK.
-  From version 1.13 onwards this event will not be emitted.
-  </div>
+@param [object] {any}
+  The object to check. This may be a
+[`BrowserWindow`](modules/sdk/windows.html#BrowserWindow),
+[`tab`](modules/sdk/tabs.html#Tab), or
+[`worker`](modules/sdk/content/worker.html#Worker).
 </api>
--- a/addon-sdk/source/doc/module-source/sdk/selection.md
+++ b/addon-sdk/source/doc/module-source/sdk/selection.md
@@ -25,16 +25,24 @@ To be notified when the user makes a sel
 
 Iterating Over Discontiguous Selections
 ---------------------------------------
 
 Discontiguous selections can be accessed by iterating over the `selection`
 module itself. Each iteration yields a `Selection` object from which `text`,
 `html`, and `isContiguous` properties can be accessed.
 
+## Private Windows ##
+
+If your add-on has not opted into private browsing, then you won't see any
+selections made in tabs that are hosted by private browser windows.
+
+To learn more about private windows, how to opt into private browsing, and how
+to support private browsing, refer to the
+[documentation for the `private-browsing` module](modules/sdk/private-browsing.html).
 
 Examples
 --------
 
 Log the current contiguous selection as text:
 
     var selection = require("sdk/selection");
     if (selection.text)
--- a/addon-sdk/source/doc/module-source/sdk/self.md
+++ b/addon-sdk/source/doc/module-source/sdk/self.md
@@ -48,18 +48,19 @@ startup
 upgrade
 downgrade
 </pre>
 
 </api>
 
 <api name="isPrivateBrowsingSupported">
 @property {boolean}
-This property indicates add-on's support for private browsing. It comes from the
-`private-browsing` property set in the `package.json` file in the main package.
+This property indicates whether or not the add-on supports private browsing.
+It comes from the [`private-browsing` key](dev-guide/package-spec.html#permissions)
+in the add-on's `package.json` file.
 </api>
 
 <api name="data">
 @property {object}
 The `data` object is used to access data that was bundled with the add-on.
 This data lives in the main package's `data/` directory, immediately below
 the `package.json` file. All files in this directory will be copied into the
 XPI and made available through the `data` object.
--- a/addon-sdk/source/doc/module-source/sdk/simple-storage.md
+++ b/addon-sdk/source/doc/module-source/sdk/simple-storage.md
@@ -167,43 +167,23 @@ data you remove is up to you.  For examp
       while (ss.quotaUsage > 1)
         ss.storage.myList.pop();
     });
 
 
 Private Browsing
 ----------------
 If your storage is related to your users' Web history, personal information, or
-other sensitive data, your add-on should respect [private browsing mode][SUMO].
-While private browsing mode is active, you should not store any sensitive data.
-
-Because any kind of data can be placed into simple storage, support for private
-browsing is not built into the module.  Instead, use the
-[`private-browsing`](modules/sdk/private-browsing.html) module to
-check private browsing status and respond accordingly.
-
-For example, the URLs your users visit should not be stored during private
-browsing.  If your add-on records the URL of the selected tab, here's how you
-might handle that:
+other sensitive data, your add-on should respect
+[private browsing](http://support.mozilla.com/en-US/kb/Private+Browsing).
 
-    ss.storage.history = [];
-    var privateBrowsing = require("sdk/private-browsing");
-    if (!privateBrowsing.isActive) {
-      var url = getSelectedTabURL();
-      ss.storage.history.push(url);
-    }
-
-For more information on supporting private browsing, see its [Mozilla Developer
-Network documentation][MDN].  While that page does not apply specifically to
-SDK-based add-ons (and its code samples don't apply at all), you should follow
-its guidance on best practices and policies.
-
-[SUMO]: http://support.mozilla.com/en-US/kb/Private+Browsing
-[MDN]: https://developer.mozilla.org/En/Supporting_private_browsing_mode
-
+To read about how to opt into private browsing mode and how to use the
+SDK to avoid storing user data associated with private windows, refer to the
+documentation for the
+[`private-browsing` module](modules/sdk/private-browsing.html).
 
 <api name="storage">
 @property {object}
   A persistent object private to your add-on.  Properties with array, boolean,
   number, object, null, and string values will be persisted.
 </api>
 
 <api name="quotaUsage">
--- a/addon-sdk/source/doc/module-source/sdk/system/events.md
+++ b/addon-sdk/source/doc/module-source/sdk/system/events.md
@@ -8,20 +8,22 @@ observer service, also known as
 You can find a list of events dispatched by firefox codebase
 [here](https://developer.mozilla.org/en-US/docs/Observer_Notifications).
 
 ## Example
 
     var events = require("sdk/system/events");
     var { Ci } = require("chrome");
 
-    events.on("http-on-modify-request", function (event) {
+    function listener(event) {
       var channel = event.subject.QueryInterface(Ci.nsIHttpChannel);
       channel.setRequestHeader("User-Agent", "MyBrowser/1.0", false);
-    });
+    }
+
+    events.on("http-on-modify-request", listener);
 
 <api name="emit">
 @function
   Send an event to observer service
 
 @param type {string}
   The event type.
 @param [event] {object}
--- a/addon-sdk/source/doc/module-source/sdk/tabs.md
+++ b/addon-sdk/source/doc/module-source/sdk/tabs.md
@@ -63,16 +63,28 @@ content:
       tab.attach({
         contentScript: 'self.postMessage(document.body.innerHTML);',
         onMessage: function (message) {
           console.log(message);
         }
       });
     });
 
+## Private Windows ##
+
+If your add-on has not opted into private browsing, then you won't see any
+tabs that are hosted by private browser windows.
+
+Tabs hosted by private browser windows won't be seen if you enumerate the
+`tabs` module itself, and you won't receive any events for them.
+
+To learn more about private windows, how to opt into private browsing, and how
+to support private browsing, refer to the
+[documentation for the `private-browsing` module](modules/sdk/private-browsing.html).
+
 <api name="activeTab">
 @property {Tab}
 
 The currently active tab in the active window. This property is read-only. To
 activate a `Tab` object, call its `activate` method.
 
 **Example**
 
@@ -135,18 +147,18 @@ This is a required property.
 If present and true, a new browser window will be opened and the URL will be
 opened in the first tab in that window. This is an optional property.
 
 @prop [inBackground] {boolean}
 If present and true, the new tab will be opened to the right of the active tab
 and will not be active. This is an optional property.
 
 @prop isPrivate {boolean}
-Boolean which will determine if a private tab should be opened.
-Private browsing mode must be supported in order to do this.
+Boolean which will determine whether the new tab should be private or not.
+If your add-on does not support private browsing this will have no effect.
 See the [private-browsing](modules/sdk/private-browsing.html) documentation for more information.
 
 @prop [isPinned] {boolean}
 If present and true, then the new tab will be pinned as an
 [app tab](http://support.mozilla.com/en-US/kb/what-are-app-tabs).
 
 @prop [onOpen] {function}
 A callback function that will be registered for 'open' event.
--- a/addon-sdk/source/doc/module-source/sdk/tabs/utils.md
+++ b/addon-sdk/source/doc/module-source/sdk/tabs/utils.md
@@ -34,18 +34,27 @@ Get the `tabbrowser`'s
 property.
 @param window {window}
 A browser window.
 @returns {tabContainer}
 </api>
 
 <api name="getTabs">
 @function
-Returns the tabs for the specified `window`, or the tabs
-across all the browser's windows if `window` is omitted.
+Returns the tabs for the specified `window`.
+
+If you omit `window`, this function will return tabs
+across all the browser's windows. However, if your add-on
+has not opted into private browsing, then the function will
+exclude all tabs that are hosted by private browser windows.
+
+To learn more about private windows, how to opt into private browsing, and how
+to support private browsing, refer to the
+[documentation for the `private-browsing` module](modules/sdk/private-browsing.html).
+
 @param window {nsIWindow}
 Optional.
 @returns {Array}
 An array of [`tab`](https://developer.mozilla.org/en-US/docs/XUL/tab)
 elements.
 </api>
 
 <api name="getActiveTab">
--- a/addon-sdk/source/doc/module-source/sdk/widget.md
+++ b/addon-sdk/source/doc/module-source/sdk/widget.md
@@ -341,16 +341,25 @@ listener, the panel will not be anchored
       onClick: function() {
         // Will not be anchored
         this.panel.show();
       }
     });
 
 See [bug 638142](https://bugzilla.mozilla.org/show_bug.cgi?id=638142).
 
+## Private Windows ##
+
+If your add-on has not opted into private browsing, then your widget will
+not appear in any private browser windows.
+
+To learn more about private windows, how to opt into private browsing, and how
+to support private browsing, refer to the
+[documentation for the `private-browsing` module](modules/sdk/private-browsing.html).
+
 ## Examples ##
 
 For conciseness, these examples create their content scripts as strings and use
 the `contentScript` property.  In your own add-ons, you will probably want to
 create your content scripts in separate files and pass their URLs using the
 `contentScriptFile` property.  See
 [Working with Content Scripts](dev-guide/guides/content-scripts/index.html) for more
 information.
@@ -680,16 +689,19 @@ attribute.
 
 @argument {WidgetView}
 The related `WidgetView` object.
 </api>
 
 <api name="click">
 @event
 This event is emitted when the widget is clicked.
+
+@argument {WidgetView}
+Listeners are passed a single argument which is the `WidgetView` that triggered the click event.
 </api>
 
 <api name="message">
 @event
 If you listen to this event you can receive message events from content
 scripts associated with this widget. When a content script posts a
 message using `self.postMessage()`, the message is delivered to the add-on
 code in the widget's `message` event.
--- a/addon-sdk/source/doc/module-source/sdk/window/utils.md
+++ b/addon-sdk/source/doc/module-source/sdk/window/utils.md
@@ -1,15 +1,30 @@
 <!-- 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/. -->
 
 The `window/utils` module provides helper functions for working with
 application windows.
 
+## Private Windows ##
+
+With this module your add-on will see private browser windows
+even if it has not explicitly opted into private browsing, so you need
+to take care not to store any user data derived from private browser windows.
+
+The exception is the [`windows()`](modules/sdk/window/utils.html#windows())
+function which returns an array of currently opened windows. Private windows
+will not be included in this list if your add-on has not opted into private
+browsing.
+
+To learn more about private windows, how to opt into private browsing, and how
+to support private browsing, refer to the
+[documentation for the `private-browsing` module](modules/sdk/private-browsing.html).
+
 <api name="getMostRecentBrowserWindow">
   @function
   Get the topmost browser window, as an
   [`nsIDOMWindow`](https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIDOMWindow) instance.
   @returns {nsIDOMWindow}
 </api>
 
 <api name="getInnerId">
@@ -164,16 +179,21 @@ element.
     documentation. Optional, defaults to: `{'chrome,all,dialog=no'}`.
   @returns {nsIDOMWindow}
 </api>
 
 <api name="windows">
   @function
   Returns an array of all currently opened windows.
   Note that these windows may still be loading.
+
+  If your add-on has not
+  [opted into private browsing](modules/sdk/private-browsing.html),
+  any private browser windows will not be included in the array.
+
   @returns {Array}
   Array of `nsIDOMWindow` instances.
 </api>
 
 <api name="isDocumentLoaded">
   @function
   Check if the given window's document is completely loaded.
   This means that its "load" event has been fired and all content
--- a/addon-sdk/source/doc/module-source/sdk/windows.md
+++ b/addon-sdk/source/doc/module-source/sdk/windows.md
@@ -1,40 +1,46 @@
 <!-- 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/. -->
 
 <!-- contributed by Felipe Gomes [felipc@gmail.com]  -->
 
+The `windows` module provides basic functions for working with browser
+windows. With this module, you can:
 
-The `windows` module provides easy access to browser windows, their
-tabs, and open/close related functions and events.
+* [enumerate the currently opened browser windows](modules/sdk/windows.html#browserWindows)
+* [open new browser windows](modules/sdk/windows.html#open(options))
+* [listen for common window events such as open and close](modules/sdk/windows.html#Events)
+
+## Private Windows ##
 
-This module currently only supports browser windows and does not provide
-access to non-browser windows such as the Bookmarks Library, preferences
-or other non-browser windows created via add-ons.
+If your add-on has not opted into private browsing, then you won't see any
+private browser windows. Private browser windows won't appear in the
+[`browserWindows`](modules/sdk/windows.html#browserWindows) property, you
+won't receive any window events, and you won't be able to open private 
+windows.
+
+To learn more about private windows, how to opt into private browsing, and how
+to support private browsing, refer to the
+[documentation for the `private-browsing` module](modules/sdk/private-browsing.html).
 
 <api name="browserWindows">
 @property {List}
-An object that contains various properties and methods to access
-functionality from browser windows, such as opening new windows, accessing
-their tabs or switching the current active window.
-
-`browserWindows` provides access to all the currently open browser windows:
+`browserWindows` provides access to all the currently open browser windows as
+[BrowserWindow](modules/sdk/windows.html#BrowserWindow) objects.
 
     var windows = require("sdk/windows");
     for each (var window in windows.browserWindows) {
       console.log(window.title);
     }
 
     console.log(windows.browserWindows.length);
 
-Object emits all the events listed under "Events" section.
-
-####Examples####
+This object emits all the events listed under the "Events" section:
 
     var windows = require("sdk/windows").browserWindows;
 
     // add a listener to the 'open' event
     windows.on('open', function(window) {
       myOpenWindows.push(window);
     });
 
@@ -114,18 +120,18 @@ as well as a callback for being notified
 If the only option being used is `url`, then a bare string URL can be passed to
 `open` instead of specifying it as a property of the `options` object.
 
 @prop url {string}
 String URL to be opened in the new window.
 This is a required property.
 
 @prop isPrivate {boolean}
-Boolean which will determine if a private window should be opened.
-Private browsing mode must be supported in order to do this.
+Boolean which will determine whether the new window should be private or not.
+If your add-on does not support private browsing this will have no effect.
 See the [private-browsing](modules/sdk/private-browsing.html) documentation for more information.
 
 @prop [onOpen] {function}
 A callback function that is called when the window has opened. This does not
 mean that the URL content has loaded, only that the window itself is fully
 functional and its properties can be accessed. This is an optional property.
 
 @prop [onClose] {function}
@@ -180,18 +186,17 @@ tabs in this window, not all tabs in all
 </api>
 
 <api name="isPrivateBrowsing">
 @property {boolean}
 Returns `true` if the window is in private browsing mode, and `false` otherwise.
 
 <div class="warning">
   This property is deprecated.
-  From version 1.14, please consider using following code instead:<br/>
-  <code>require("private-browsing").isPrivate(browserWindow)</code>
+  From version 1.14, use the <a href="modules/sdk/private-browsing.html#isPrivate()">private-browsing module's <code>isPrivate()</code></a> function instead.
 </div>
 
 </api>
 
 <api name="activate">
 @method
 Makes window active, which will focus that window and bring it to the
 foreground.
--- a/addon-sdk/source/examples/annotator/lib/main.js
+++ b/addon-sdk/source/examples/annotator/lib/main.js
@@ -3,17 +3,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 var widgets = require('widget');
 var pageMod = require('page-mod');
 var data = require('self').data;
 var panels = require('panel');
 var simpleStorage = require('simple-storage');
 var notifications = require("notifications");
-var privateBrowsing = require('private-browsing');
 
 /*
 Global variables
 * Boolean to indicate whether the add-on is switched on or not
 * Array for all workers associated with the 'selector' page mod
 * Array for all workers associated with the 'matcher' page mod
 */
 var annotatorIsOn = false;
@@ -28,23 +27,16 @@ Update the matchers: call this whenever 
 */
 function updateMatchers() {
   matchers.forEach(function (matcher) {
     matcher.postMessage(simpleStorage.storage.annotations);
   });
 }
 
 /*
-You can add annotations iff the add-on is on AND private browsing is off
-*/
-function canEnterAnnotations() {
-  return (annotatorIsOn && !privateBrowsing.isActive);
-}
-
-/*
 Constructor for an Annotation object
 */
 function Annotation(annotationText, anchor) {
   this.annotationText = annotationText;
   this.url = anchor[0];
   this.ancestorId = anchor[1];
   this.anchorText = anchor[2];
 }
@@ -61,31 +53,27 @@ function handleNewAnnotation(annotationT
 }
 
 /*
 Function to tell the selector page mod that the add-on has become (in)active
 */
 function activateSelectors() {
   selectors.forEach(
     function (selector) {
-      selector.postMessage(canEnterAnnotations());
+      selector.postMessage(annotatorIsOn);
   });
 }
 
 /*
 Toggle activation: update the on/off state and notify the selectors.
-Toggling activation is disabled when private browsing is on.
 */
 function toggleActivation() {
-  if (privateBrowsing.isActive) {
-    return false;
-  }
   annotatorIsOn = !annotatorIsOn;
   activateSelectors();
-  return canEnterAnnotations();
+  return annotatorIsOn;
 }
 
 function detachWorker(worker, workerArray) {
   var index = workerArray.indexOf(worker);
   if(index != -1) {
     workerArray.splice(index, 1);
   }
 }
@@ -133,17 +121,17 @@ When we receive this message we assign t
 display it.
 */
   var selector = pageMod.PageMod({
     include: ['*'],
     contentScriptWhen: 'ready',
     contentScriptFile: [data.url('jquery-1.4.2.min.js'),
                         data.url('selector.js')],
     onAttach: function(worker) {
-      worker.postMessage(canEnterAnnotations());
+      worker.postMessage(annotatorIsOn);
       selectors.push(worker);
       worker.port.on('show', function(data) {
         annotationEditor.annotationAnchor = data;
         annotationEditor.show();
       });
       worker.on('detach', function () {
         detachWorker(this, selectors);
       });
@@ -213,32 +201,16 @@ recent annotations until we are back in 
     notifications.notify({
       title: 'Storage space exceeded',
       text: 'Removing recent annotations'});
     while (simpleStorage.quotaUsage > 1)
       simpleStorage.storage.annotations.pop();
   });
 
 /*
-We listen for private browsing start/stop events to change the widget icon
-and to notify the selectors of the change in state.
-*/
-  privateBrowsing.on('start', function() {
-    widget.contentURL = data.url('widget/pencil-off.png');
-    activateSelectors();
-  });
-
-  privateBrowsing.on('stop', function() {
-    if (canEnterAnnotations()) {
-      widget.contentURL = data.url('widget/pencil-on.png');
-      activateSelectors();
-    }
-  });
-
-/*
 The matcher page-mod locates anchors on web pages and prepares for the
 annotation to be displayed.
 
 It is attached to all pages, and when it is attached we pass it the complete
 list of annotations. It looks for anchors in its page. If it finds one it
 highlights the anchor and binds mouseenter/mouseout events to 'show' and 'hide'
 messages to the add-on.
 
--- a/addon-sdk/source/lib/sdk/content/content-worker.js
+++ b/addon-sdk/source/lib/sdk/content/content-worker.js
@@ -219,17 +219,17 @@ const ContentWorker = Object.freeze({
     // (i.e. when it is removed from bfcache)
     pipe.on("detach", function clearTimeouts() {
       disableAllTimers();
       _timers = {};
       frozenTimers = [];
     });
   },
 
-  injectMessageAPI: function injectMessageAPI(exports, pipe) {
+  injectMessageAPI: function injectMessageAPI(exports, pipe, console) {
 
     let { eventEmitter: port, emit : portEmit } =
       ContentWorker.createEventEmitter(pipe.emit.bind(null, "event"));
     pipe.on("event", portEmit);
 
     let self = {
       port: port,
       postMessage: pipe.emit.bind(null, "message"),
@@ -288,17 +288,17 @@ const ContentWorker = Object.freeze({
   },
 
   inject: function (exports, chromeAPI, emitToChrome, options) {
     let { pipe, onChromeEvent, hasListenerFor } =
       ContentWorker.createPipe(emitToChrome);
 
     ContentWorker.injectConsole(exports, pipe);
     ContentWorker.injectTimers(exports, chromeAPI, pipe, exports.console);
-    ContentWorker.injectMessageAPI(exports, pipe);
+    ContentWorker.injectMessageAPI(exports, pipe, exports.console);
     if ( options !== undefined ) {
       ContentWorker.injectOptions(exports, options);
     }
 
     Object.freeze( exports.self );
 
     return {
       emitToContent: onChromeEvent,
--- a/addon-sdk/source/lib/sdk/content/worker.js
+++ b/addon-sdk/source/lib/sdk/content/worker.js
@@ -373,51 +373,57 @@ const WorkerSandbox = EventEmitter.compo
  * Message-passing facility for communication between code running
  * in the content and add-on process.
  * @see https://jetpack.mozillalabs.com/sdk/latest/docs/#module/api-utils/content/worker
  */
 const Worker = EventEmitter.compose({
   on: Trait.required,
   _removeAllListeners: Trait.required,
 
+  // List of messages fired before worker is initialized
+  get _earlyEvents() {
+    delete this._earlyEvents;
+    this._earlyEvents = [];
+    return this._earlyEvents;
+  },
+
   /**
    * Sends a message to the worker's global scope. Method takes single
    * argument, which represents data to be sent to the worker. The data may
    * be any primitive type value or `JSON`. Call of this method asynchronously
    * emits `message` event with data value in the global scope of this
    * symbiont.
    *
    * `message` event listeners can be set either by calling
    * `self.on` with a first argument string `"message"` or by
    * implementing `onMessage` function in the global scope of this worker.
    * @param {Number|String|JSON} data
    */
-  postMessage: function postMessage(data) {
-    if (!this._contentWorker)
-      throw new Error(ERR_DESTROYED);
-    if (this._frozen)
-      throw new Error(ERR_FROZEN);
-
-    this._contentWorker.emit("message", data);
+  postMessage: function (data) {
+    let args = ['message'].concat(Array.slice(arguments));
+    if (!this._inited) {
+      this._earlyEvents.push(args);
+      return;
+    }
+    processMessage.apply(this, args);
   },
 
   /**
    * EventEmitter, that behaves (calls listeners) asynchronously.
    * A way to send customized messages to / from the worker.
    * Events from in the worker can be observed / emitted via
    * worker.on / worker.emit.
    */
   get port() {
     // We generate dynamically this attribute as it needs to be accessible
     // before Worker.constructor gets called. (For ex: Panel)
 
     // create an event emitter that receive and send events from/to the worker
-    let self = this;
     this._port = EventEmitterTrait.create({
-      emit: function () self._emitEventToContent(Array.slice(arguments))
+      emit: this._emitEventToContent.bind(this)
     });
 
     // expose wrapped port, that exposes only public properties:
     // We need to destroy this getter in order to be able to set the
     // final value. We need to update only public port attribute as we never
     // try to access port attribute from private API.
     delete this._public.port;
     this._public.port = Cortex(this._port);
@@ -433,50 +439,32 @@ const Worker = EventEmitter.compose({
    * Allow access to _emit, in order to send event to port.
    */
   _port: null,
 
   /**
    * Emit a custom event to the content script,
    * i.e. emit this event on `self.port`
    */
-  _emitEventToContent: function _emitEventToContent(args) {
-    // We need to save events that are emitted before the worker is
-    // initialized
+  _emitEventToContent: function () {
+    let args = ['event'].concat(Array.slice(arguments));
     if (!this._inited) {
       this._earlyEvents.push(args);
       return;
     }
-
-    if (this._frozen)
-      throw new Error(ERR_FROZEN);
-
-    // We throw exception when the worker has been destroyed
-    if (!this._contentWorker) {
-      throw new Error(ERR_DESTROYED);
-    }
-
-    // Forward the event to the WorkerSandbox object
-    this._contentWorker.emit.apply(null, ["event"].concat(args));
+    processMessage.apply(this, args);
   },
 
   // Is worker connected to the content worker sandbox ?
   _inited: false,
 
   // Is worker being frozen? i.e related document is frozen in bfcache.
   // Content script should not be reachable if frozen.
   _frozen: true,
 
-  // List of custom events fired before worker is initialized
-  get _earlyEvents() {
-    delete this._earlyEvents;
-    this._earlyEvents = [];
-    return this._earlyEvents;
-  },
-
   constructor: function Worker(options) {
     options = options || {};
 
     if ('window' in options)
       this._window = options.window;
     if ('contentScriptFile' in options)
       this.contentScriptFile = options.contentScriptFile;
     if ('contentScriptOptions' in options)
@@ -520,19 +508,21 @@ const Worker = EventEmitter.compose({
 
     // will set this._contentWorker pointing to the private API:
     this._contentWorker = WorkerSandbox(this);
 
     // Mainly enable worker.port.emit to send event to the content worker
     this._inited = true;
     this._frozen = false;
 
-    // Flush all events that have been fired before the worker is initialized.
-    this._earlyEvents.forEach((function (args) this._emitEventToContent(args)).
-                              bind(this));
+    // Process all events and messages that were fired before the
+    // worker was initialized.
+    this._earlyEvents.forEach((function (args) {
+      processMessage.apply(this, args);
+    }).bind(this));
   },
 
   _documentUnload: function _documentUnload(subject, topic, data) {
     let innerWinID = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
     if (innerWinID != this._windowID) return false;
     this._workerCleanup();
     return true;
   },
@@ -585,17 +575,17 @@ const Worker = EventEmitter.compose({
       this._window.removeEventListener("pagehide", this._pageHide, true);
     }
     this._window = null;
     // This method may be called multiple times,
     // avoid dispatching `detach` event more than once
     if (this._windowID) {
       this._windowID = null;
       observers.remove("inner-window-destroyed", this._documentUnload);
-      this._earlyEvents.slice(0, this._earlyEvents.length);
+      this._earlyEvents.length = 0;
       this._emit("detach");
     }
   },
 
   /**
    * Receive an event from the content script that need to be sent to
    * worker.port. Provide a way for composed object to catch all events.
    */
@@ -617,9 +607,25 @@ const Worker = EventEmitter.compose({
   _window: null,
 
   /**
    * Flag to enable `addon` object injection in document. (bug 612726)
    * @type {Boolean}
    */
   _injectInDocument: false
 });
+
+/**
+ * Fired from postMessage and _emitEventToContent, or from the _earlyMessage
+ * queue when fired before the content is loaded. Sends arguments to
+ * contentWorker if able
+ */
+
+function processMessage () {
+  if (!this._contentWorker)
+    throw new Error(ERR_DESTROYED);
+  if (this._frozen)
+    throw new Error(ERR_FROZEN);
+
+  this._contentWorker.emit.apply(null, Array.slice(arguments));
+}
+
 exports.Worker = Worker;
--- a/addon-sdk/source/lib/sdk/deprecated/window-utils.js
+++ b/addon-sdk/source/lib/sdk/deprecated/window-utils.js
@@ -10,26 +10,26 @@ module.metadata = {
 const { Cc, Ci } = require('chrome');
 const { EventEmitter } = require('../deprecated/events');
 const { Trait } = require('../deprecated/traits');
 const { when } = require('../system/unload');
 const { getInnerId, getOuterId, windows, isDocumentLoaded, isBrowser,
         getMostRecentBrowserWindow, getMostRecentWindow } = require('../window/utils');
 const errors = require('../deprecated/errors');
 const { deprecateFunction } = require('../util/deprecate');
-const { ignoreWindow } = require('sdk/private-browsing/utils');
+const { ignoreWindow, isGlobalPBSupported } = require('sdk/private-browsing/utils');
 const { isPrivateBrowsingSupported } = require('../self');
 
 const windowWatcher = Cc['@mozilla.org/embedcomp/window-watcher;1'].
                        getService(Ci.nsIWindowWatcher);
 const appShellService = Cc['@mozilla.org/appshell/appShellService;1'].
                         getService(Ci.nsIAppShellService);
 
 // Bug 834961: ignore private windows when they are not supported
-function getWindows() windows(null, { includePrivate: isPrivateBrowsingSupported });
+function getWindows() windows(null, { includePrivate: isPrivateBrowsingSupported || isGlobalPBSupported });
 
 /**
  * An iterator for XUL windows currently in the application.
  *
  * @return A generator that yields XUL windows exposing the
  *         nsIDOMWindow interface.
  */
 function windowIterator() {
--- a/addon-sdk/source/lib/sdk/event/core.js
+++ b/addon-sdk/source/lib/sdk/event/core.js
@@ -89,30 +89,33 @@ function emit(target, type, message /*, 
  * This is very experimental feature that you should not use unless absolutely
  * need it. Also it may be removed at any point without any further notice.
  *
  * Creates lazy iterator of return values of listeners. You can think of it
  * as lazy array of return values of listeners for the `emit` with the given
  * arguments.
  */
 emit.lazy = function lazy(target, type, message /*, ...*/) {
-  let args = Array.slice(arguments, 2)
-  let listeners = observers(target, type).slice()
-  while (listeners.length) {
-    try {
-      yield listeners.shift().apply(target, args);
-    }
+  let args = Array.slice(arguments, 2);
+  let listeners = observers(target, type).slice();
+  let index = 0;
+  let count = listeners.length;
+
+  // If error event and there are no handlers then print error message
+  // into a console.
+  if (count === 0 && type === 'error') console.exception(message);
+  while (index < count) {
+    try { yield listeners[index].apply(target, args); }
     catch (error) {
       // If exception is not thrown by a error listener and error listener is
       // registered emit `error` event. Otherwise dump exception to the console.
-      if (type !== 'error' && observers(target, 'error').length)
-        emit(target, 'error', error);
-      else
-        console.exception(error);
+      if (type !== 'error') emit(target, 'error', error);
+      else console.exception(error);
     }
+    index = index + 1;
   }
 }
 exports.emit = emit;
 
 /**
  * Removes an event `listener` for the given event `type` on the given event
  * `target`. If no `listener` is passed removes all listeners of the given
  * `type`. If `type` is not passed removes all the listeners of the given
--- a/addon-sdk/source/lib/sdk/frame/hidden-frame.js
+++ b/addon-sdk/source/lib/sdk/frame/hidden-frame.js
@@ -16,20 +16,21 @@ const { Class } = require("../core/herit
 const { List, addListItem, removeListItem } = require("../util/list");
 const { EventTarget } = require("../event/target");
 const { emit } = require("../event/core");
 const { create: makeFrame } = require("./utils");
 const { defer } = require("../core/promise");
 const { when: unload } = require("../system/unload");
 const { validateOptions, getTypeOf } = require("../deprecated/api-utils");
 const { window } = require("../addon/window");
+const { fromIterator } = require("../util/array");
 
 // This cache is used to access friend properties between functions
 // without exposing them on the public API.
-let cache = [];
+let cache = new Set();
 let elements = new WeakMap();
 
 function contentLoaded(target) {
   var deferred = defer();
   target.addEventListener("DOMContentLoaded", function DOMContentLoaded(event) {
     // "DOMContentLoaded" events from nested frames propagate up to target,
     // ignore events unless it's DOMContentLoaded for the given target.
     if (event.target === target || event.target === target.contentDocument) {
@@ -70,30 +71,23 @@ var HiddenFrame = Class({
     return elements.get(this);
   },
   toString: function toString() {
     return "[object Frame]"
   }
 });
 exports.HiddenFrame = HiddenFrame
 
-function isFrameCached(frame) {
-  // Function returns `true` if frame was already cached.
-  return cache.some(function(value) {
-    return value === frame
-  })
-}
-
 function addHidenFrame(frame) {
   if (!(frame instanceof HiddenFrame))
     throw Error("The object to be added must be a HiddenFrame.");
 
   // This instance was already added.
-  if (isFrameCached(frame)) return frame;
-  else cache.push(frame);
+  if (cache.has(frame)) return frame;
+  else cache.add(frame);
 
   let element = makeFrame(window.document, {
     nodeName: "iframe",
     type: "content",
     allowJavascript: true,
     allowPlugins: true,
     allowAuth: true,
   });
@@ -106,19 +100,19 @@ function addHidenFrame(frame) {
   return frame;
 }
 exports.add = addHidenFrame
 
 function removeHiddenFrame(frame) {
   if (!(frame instanceof HiddenFrame))
     throw Error("The object to be removed must be a HiddenFrame.");
 
-  if (!isFrameCached(frame)) return;
+  if (!cache.has(frame)) return;
 
   // Remove from cache before calling in order to avoid loop
-  cache.splice(cache.indexOf(frame), 1);
+  cache.delete(frame);
   emit(frame, "unload")
   let element = frame.element
   if (element) element.parentNode.removeChild(element)
 }
 exports.remove = removeHiddenFrame;
 
-unload(function() cache.splice(0).forEach(removeHiddenFrame));
+unload(function() fromIterator(cache).forEach(removeHiddenFrame));
--- a/addon-sdk/source/lib/sdk/indexed-db.js
+++ b/addon-sdk/source/lib/sdk/indexed-db.js
@@ -53,12 +53,11 @@ exports.indexedDB = Object.freeze({
 
 exports.IDBKeyRange = IDBKeyRange;
 exports.DOMException = Ci.nsIDOMDOMException;
 exports.IDBCursor = Ci.nsIIDBCursor;
 exports.IDBTransaction = Ci.nsIIDBTransaction;
 exports.IDBOpenDBRequest = Ci.nsIIDBOpenDBRequest;
 exports.IDBVersionChangeEvent = Ci.nsIIDBVersionChangeEvent;
 exports.IDBDatabase = Ci.nsIIDBDatabase;
-exports.IDBFactory = Ci.nsIIDBFactory;
 exports.IDBIndex = Ci.nsIIDBIndex;
 exports.IDBObjectStore = Ci.nsIIDBObjectStore;
 exports.IDBRequest = Ci.nsIIDBRequest;
--- a/addon-sdk/source/lib/sdk/panel.js
+++ b/addon-sdk/source/lib/sdk/panel.js
@@ -12,26 +12,30 @@ module.metadata = {
   }
 };
 
 const { Ci } = require("chrome");
 const { validateOptions: valid } = require('./deprecated/api-utils');
 const { Symbiont } = require('./content/content');
 const { EventEmitter } = require('./deprecated/events');
 const { setTimeout } = require('./timers');
+const { on, off, emit } = require('./system/events');
 const runtime = require('./system/runtime');
 const { getDocShell } = require("./frame/utils");
 const { getWindow } = require('./panel/window');
 const { isPrivateBrowsingSupported } = require('./self');
 const { isWindowPBSupported } = require('./private-browsing/utils');
+const { getNodeView } = require('./view/core');
 
 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
       ON_SHOW = 'popupshown',
       ON_HIDE = 'popuphidden',
-      validNumber = { is: ['number', 'undefined', 'null'] };
+      validNumber = { is: ['number', 'undefined', 'null'] },
+      validBoolean = { is: ['boolean', 'undefined', 'null'] },
+      ADDON_ID = require('./self').id;
 
 if (isPrivateBrowsingSupported && isWindowPBSupported) {
   throw Error('The panel module cannot be used with per-window private browsing at the moment, see Bug 816257');
 }
 
 /**
  * Emits show and hide events.
  */
@@ -63,39 +67,49 @@ const Panel = Symbiont.resolve({
       .swapFrameLoaders(this._viewFrame);
     this.__frameLoadersSwapped = value;
   },
   __frameLoadersSwapped: false,
 
   constructor: function Panel(options) {
     this._onShow = this._onShow.bind(this);
     this._onHide = this._onHide.bind(this);
+    this._onAnyPanelShow = this._onAnyPanelShow.bind(this);
+    on('sdk-panel-show', this._onAnyPanelShow);
+
     this.on('inited', this._onSymbiontInit.bind(this));
     this.on('propertyChange', this._onChange.bind(this));
 
     options = options || {};
     if ('onShow' in options)
       this.on('show', options.onShow);
     if ('onHide' in options)
       this.on('hide', options.onHide);
     if ('width' in options)
       this.width = options.width;
     if ('height' in options)
       this.height = options.height;
     if ('contentURL' in options)
       this.contentURL = options.contentURL;
+    if ('focus' in options) {
+      var value = options.focus;
+      var validatedValue = valid({ $: value }, { $: validBoolean }).$;
+      this._focus =
+        (typeof validatedValue == 'boolean') ? validatedValue : this._focus;
+    }
 
     this._init(options);
   },
   _destructor: function _destructor() {
     this.hide();
     this._removeAllListeners('show');
     this._removeAllListeners('hide');
     this._removeAllListeners('propertyChange');
     this._removeAllListeners('inited');
+    off('sdk-panel-show', this._onAnyPanelShow);
     // defer cleanup to be performed after panel gets hidden
     this._xulPanel = null;
     this._symbiontDestructor(this);
     this._removeAllListeners();
   },
   destroy: function destroy() {
     this._destructor();
   },
@@ -104,33 +118,37 @@ const Panel = Symbiont.resolve({
   set width(value)
     this._width = valid({ $: value }, { $: validNumber }).$ || this._width,
   _width: 320,
   /* Public API: Panel.height */
   get height() this._height,
   set height(value)
     this._height =  valid({ $: value }, { $: validNumber }).$ || this._height,
   _height: 240,
+  /* Public API: Panel.focus */
+  get focus() this._focus,
+  _focus: true,
 
   /* Public API: Panel.isShowing */
   get isShowing() !!this._xulPanel && this._xulPanel.state == "open",
 
   /* Public API: Panel.show */
   show: function show(anchor) {
-    anchor = anchor || null;
+    anchor = anchor ? getNodeView(anchor) : null;
     let anchorWindow = getWindow(anchor);
 
     // If there is no open window, or the anchor is in a private window
     // then we will not be able to display the panel
     if (!anchorWindow) {
       return;
     }
 
     let document = anchorWindow.document;
     let xulPanel = this._xulPanel;
+    let panel = this;
     if (!xulPanel) {
       xulPanel = this._xulPanel = document.createElementNS(XUL_NS, 'panel');
       xulPanel.setAttribute("type", "arrow");
 
       // One anonymous node has a big padding that doesn't work well with
       // Jetpack, as we would like to display an iframe that completely fills
       // the panel.
       // -> Use a XBL wrapper with inner stylesheet to remove this padding.
@@ -160,17 +178,17 @@ const Panel = Symbiont.resolve({
 
       // Load an empty document in order to have an immediatly loaded iframe,
       // so swapFrameLoaders is going to work without having to wait for load.
       frame.setAttribute("src","data:;charset=utf-8,");
 
       xulPanel.appendChild(frame);
       document.getElementById("mainPopupSet").appendChild(xulPanel);
     }
-    let { width, height } = this, x, y, position;
+    let { width, height, focus } = this, x, y, position;
 
     if (!anchor) {
       // Open the popup in the middle of the window.
       x = document.documentElement.clientWidth / 2 - width / 2;
       y = document.documentElement.clientHeight / 2 - height / 2;
       position = null;
     }
     else {
@@ -205,23 +223,35 @@ const Panel = Symbiont.resolve({
       xulPanel.setAttribute("flip","both");
     }
 
     // Resize the iframe instead of using panel.sizeTo
     // because sizeTo doesn't work with arrow panels
     xulPanel.firstChild.style.width = width + "px";
     xulPanel.firstChild.style.height = height + "px";
 
+    // Only display xulPanel if Panel.hide() was not called
+    // after Panel.show(), but before xulPanel.openPopup
+    // was loaded
+    emit('sdk-panel-show', { data: ADDON_ID, subject: xulPanel });
+
+    // Prevent the panel from getting focus when showing up
+    // if focus is set to false
+    xulPanel.setAttribute("noautofocus",!focus);
+
     // Wait for the XBL binding to be constructed
     function waitForBinding() {
       if (!xulPanel.openPopup) {
         setTimeout(waitForBinding, 50);
         return;
       }
-      xulPanel.openPopup(anchor, position, x, y);
+
+      if (xulPanel.state !== 'hiding') {
+        xulPanel.openPopup(anchor, position, x, y);
+      }
     }
     waitForBinding();
 
     return this._public;
   },
   /* Public API: Panel.hide */
   hide: function hide() {
     // The popuphiding handler takes care of swapping back the frame loaders
@@ -284,16 +314,18 @@ const Panel = Symbiont.resolve({
   },
 
   /**
    * Retrieve computed text color style in order to apply to the iframe
    * document. As MacOS background is dark gray, we need to use skin's
    * text color.
    */
   _applyStyleToDocument: function _applyStyleToDocument() {
+    if (this._defaultStyleApplied)
+      return;
     try {
       let win = this._xulPanel.ownerDocument.defaultView;
       let node = win.document.getAnonymousElementByAttribute(
         this._xulPanel, "class", "panel-arrowcontent");
       if (!node) {
         // Before bug 764755, anonymous content was different:
         // TODO: Remove this when targeting FF16+
         node = win.document.getAnonymousElementByAttribute(
@@ -304,16 +336,17 @@ const Panel = Symbiont.resolve({
       let style = doc.createElement("style");
       style.textContent = "body { color: " + textColor + "; }";
       let container = doc.head ? doc.head : doc.documentElement;
 
       if (container.firstChild)
         container.insertBefore(style, container.firstChild);
       else
         container.appendChild(style);
+      this._defaultStyleApplied = true;
     }
     catch(e) {
       console.error("Unable to apply panel style");
       console.exception(e);
     }
   },
 
   /**
@@ -328,16 +361,26 @@ const Panel = Symbiont.resolve({
         this._frameLoadersSwapped = true;
         this._applyStyleToDocument();
         this._emit('show');
       }
     } catch(e) {
       this._emit('error', e);
     }
   },
+
+  /**
+   * When any panel is displayed, system-wide, close `this`
+   * panel unless it's the most recently displayed panel
+   */