Merge mozilla-central into Electrolysis.
authorBenjamin Smedberg <benjamin@smedbergs.us>
Fri, 18 Sep 2009 16:47:18 -0400
changeset 35930 d1e8ebf88247191f19da7af9c75af66133c64380
parent 35929 266e73341c6f2a024d47d948c538226c0a704e54 (current diff)
parent 32868 8150d919e280be1b3bc4ae87d12ba865f98f5e36 (diff)
child 35931 bb6f71e54625e5fd84ed8568a0286bd9e244ba6a
push id10694
push userbsmedberg@mozilla.com
push dateMon, 14 Dec 2009 15:23:10 +0000
treeherdermozilla-central@683dfdc4adf0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9.3a1pre
Merge mozilla-central into Electrolysis.
accessible/src/atk/nsXULTreeAccessibleWrap.cpp
accessible/src/atk/nsXULTreeAccessibleWrap.h
accessible/src/mac/nsXULTreeAccessibleWrap.h
accessible/src/msaa/nsXULTreeAccessibleWrap.cpp
accessible/src/msaa/nsXULTreeAccessibleWrap.h
accessible/src/other/nsXULTreeAccessibleWrap.h
accessible/src/xul/nsXULSelectAccessible.cpp
accessible/src/xul/nsXULSelectAccessible.h
accessible/tests/mochitest/test_aria_role_grid.html
accessible/tests/mochitest/test_elm_table.html
accessible/tests/mochitest/test_nsIAccessibleTable_listboxes.xul
accessible/tests/mochitest/test_relations_table.html
accessible/tests/mochitest/test_table_2.html
browser/app/profile/firefox.js
browser/base/content/aboutRights.xhtml
browser/base/content/browser-textZoom.js
browser/base/content/metaData.js
browser/base/content/metaData.xul
browser/installer/unix/packages-static
browser/installer/windows/packages-static
browser/locales/en-US/chrome/browser/aboutRights.dtd
browser/locales/en-US/chrome/browser/aboutRights.properties
browser/locales/en-US/chrome/browser/metaData.dtd
browser/locales/en-US/chrome/browser/metaData.properties
build/package/debian/TODO
build/package/debian/changelog
build/package/debian/control
build/package/debian/copyright.short
build/package/debian/files
build/package/debian/libnspr3-dev.dirs
build/package/debian/libnspr3.dirs
build/package/debian/libnspr3.postinst
build/package/debian/libnspr3.shlibs
build/package/debian/libnspr3.substvars
build/package/debian/menu
build/package/debian/mozilla-editor.dirs
build/package/debian/mozilla-editor.files
build/package/debian/mozilla-editor.substvars
build/package/debian/mozilla-mailnews.dirs
build/package/debian/mozilla-mailnews.files
build/package/debian/mozilla-mailnews.substvars
build/package/debian/mozilla.dirs
build/package/debian/mozilla.mime
build/package/debian/postinst.debhelper
build/package/debian/postrm.debhelper
build/package/debian/rules
build/package/debian/runner
build/package/debian/substvars
build/package/debian/testipv6
config/autoconf.mk.in
configure.in
content/base/src/Makefile.in
content/canvas/src/nsCanvasRenderingContextGL.cpp
content/canvas/src/nsCanvasRenderingContextGL.h
content/canvas/src/nsCanvasRenderingContextGLWeb20.cpp
content/events/test/test_bug299673.html
docshell/base/nsDocShell.cpp
dom/locales/en-US/chrome/webservices/security.properties
embedding/tests/apitest/apitest.cpp
embedding/tests/apitest/makefile.win
gfx/public/nsRegion.h
gfx/src/nsRegion.cpp
gfx/thebes/src/gfxPlatform.cpp
intl/chardet/tools/makefile.win
js/src/call.js
js/src/correct.sh
js/src/correct/check-3d-morph.js
js/src/correct/check-3d-raytrace.js
js/src/correct/check-access-binary-trees.js
js/src/correct/check-access-fannkuch.js
js/src/correct/check-access-nbody.js
js/src/correct/check-access-nsieve.js
js/src/correct/check-bitops-3bit-bits-in-byte.js
js/src/correct/check-bitops-bits-in-byte.js
js/src/correct/check-bitops-bitwise-and.js
js/src/correct/check-bitops-nsieve-bits.js
js/src/correct/check-controlflow-recursive.js
js/src/correct/check-date-format-tofte.js
js/src/correct/check-date-format-xparb.js
js/src/correct/check-mont.js
js/src/if.js
js/src/math-partial-sums.js
js/src/md5.js
js/src/trace-test/tests/allow_oom/testBug507425.js
js/src/trace-test/tests/slow/createMandelSet.js
js/src/xpconnect/shell/Makefile.in
js/src/xpconnect/shell/xpcshell.cpp
layout/build/nsLayoutStatics.cpp
media/libfishsound/bug481601.patch
media/liboggz/bounded_seek.patch
modules/lcms/AUTHORS
modules/lcms/COPYING
modules/lcms/Makefile.in
modules/lcms/NEWS
modules/lcms/README.1ST
modules/lcms/include/Makefile.in
modules/lcms/include/icc34.h
modules/lcms/include/lcms.h
modules/lcms/src/Makefile.in
modules/lcms/src/cmscam02.c
modules/lcms/src/cmscam97.c
modules/lcms/src/cmscgats.c
modules/lcms/src/cmscnvrt.c
modules/lcms/src/cmserr.c
modules/lcms/src/cmsgamma.c
modules/lcms/src/cmsgmt.c
modules/lcms/src/cmsintrp.c
modules/lcms/src/cmsio0.c
modules/lcms/src/cmsio1.c
modules/lcms/src/cmslut.c
modules/lcms/src/cmsmatsh.c
modules/lcms/src/cmsmtrx.c
modules/lcms/src/cmsnamed.c
modules/lcms/src/cmspack.c
modules/lcms/src/cmspcs.c
modules/lcms/src/cmsprecache.c
modules/lcms/src/cmsps2.c
modules/lcms/src/cmssamp.c
modules/lcms/src/cmsvirt.c
modules/lcms/src/cmswtpnt.c
modules/lcms/src/cmsxform.c
modules/lcms/src/lcms.def
modules/libjar/test/TestJarCache.cpp
modules/libjar/test/makefile.win
modules/libpr0n/public/imgILoad.idl
modules/libutil/Makefile.in
modules/libutil/public/Makefile.in
modules/libutil/public/nsTimer.h
modules/libutil/public/stopwatch.h
modules/libutil/src/Makefile.in
modules/libutil/src/stopwatch.cpp
modules/plugin/base/public/nsplugindefs.h
modules/plugin/base/src/Makefile.in
modules/plugin/base/src/extradefs.os2
modules/plugin/base/src/nsNPAPIPlugin.cpp
modules/plugin/base/src/nsNPAPIPlugin.h
modules/plugin/base/src/nsNPAPIPluginInstance.cpp
modules/plugin/base/src/nsNPAPIPluginInstance.h
modules/plugin/base/src/nsPluginHost.cpp
modules/plugin/base/src/nsPluginNativeWindowWin.cpp
modules/plugin/test/testplugin/nptest.cpp
netwerk/build.mk
netwerk/build/Makefile.in
netwerk/protocol/http/src/Makefile.in
toolkit/components/passwordmgr/test/test_0init.html
toolkit/content/tests/widgets/window_menuchecks.xul
toolkit/library/libxul-config.mk
toolkit/mozapps/update/test/unit/tail_update.js
toolkit/themes/pinstripe/global/20pct_transparent_pixel.png
toolkit/themes/pinstripe/global/icons/close.gif
toolkit/themes/pinstripe/global/icons/minimize.gif
toolkit/themes/pinstripe/global/icons/restore.gif
toolkit/themes/pinstripe/global/icons/round-button-active-leftcap.png
toolkit/themes/pinstripe/global/icons/round-button-active-middle.png
toolkit/themes/pinstripe/global/icons/round-button-active-right.png
toolkit/themes/pinstripe/global/icons/round-button-leftcap.png
toolkit/themes/pinstripe/global/icons/round-button-middle.png
toolkit/themes/pinstripe/global/icons/round-button-right.png
toolkit/toolkit-makefiles.sh
toolkit/toolkit-tiers.mk
toolkit/xre/Makefile.in
toolkit/xre/nsAppRunner.cpp
widget/public/nsIEventListener.h
widget/src/gtk2/nsIdleServiceOSSO.cpp
widget/src/gtk2/nsIdleServiceOSSO.h
widget/src/xpwidgets/Makefile.in
xpcom/base/nsAllocator.cpp
xpcom/base/nsGarbageCollector.c
xpcom/base/nsILeakDetector.idl
xpcom/base/nsLeakDetector.cpp
xpcom/base/nsLeakDetector.h
xpcom/build/Makefile.in
xpcom/build/malloc.c
xpcom/build/nsXPComInit.cpp
xpcom/obsolete/Makefile.in
xpcom/obsolete/component/Makefile.in
xpcom/obsolete/component/nsRegistry.cpp
xpcom/obsolete/component/nsRegistry.h
xpcom/obsolete/component/nsXPCOMObsolete.cpp
xpcom/obsolete/dlldeps-obs.cpp
xpcom/obsolete/nsFileSpec.cpp
xpcom/obsolete/nsFileSpec.h
xpcom/obsolete/nsFileSpecBeOS.cpp
xpcom/obsolete/nsFileSpecImpl.cpp
xpcom/obsolete/nsFileSpecImpl.h
xpcom/obsolete/nsFileSpecOS2.cpp
xpcom/obsolete/nsFileSpecUnix.cpp
xpcom/obsolete/nsFileSpecWin.cpp
xpcom/obsolete/nsFileStream.cpp
xpcom/obsolete/nsFileStream.h
xpcom/obsolete/nsIFileSpec.idl
xpcom/obsolete/nsIFileStream.cpp
xpcom/obsolete/nsIFileStream.h
xpcom/obsolete/nsIRegistry.idl
xpcom/obsolete/nsIRegistryUtils.h
xpcom/obsolete/nsXPCOMObsolete.cpp
xpcom/obsolete/xpcomobsolete.h
xpfe/browser/public/Makefile.in
xpfe/browser/public/nsIBrowserInstance.idl
xpfe/browser/src/nsBrowserInstance.cpp
xpfe/browser/src/nsBrowserInstance.h
--- a/Makefile.in
+++ b/Makefile.in
@@ -188,32 +188,32 @@ ifdef MOZ_CRASHREPORTER
 	$(PYTHON) $(topsrcdir)/toolkit/crashreporter/tools/symbolstore.py \
 	  $(MAKE_SYM_STORE_ARGS)                                          \
 	  $(foreach dir,$(SYM_STORE_SOURCE_DIRS),-s $(dir))               \
 	  $(DUMP_SYMS_BIN)                                                \
 	  $(DIST)/crashreporter-symbols                                   \
 	  $(MAKE_SYM_STORE_PATH) >                                        \
 	  $(DIST)/crashreporter-symbols/$(SYMBOL_INDEX_NAME)
 	echo packing symbols
-	mkdir -p $(topsrcdir)/../$(BUILDID)
 	cd $(DIST)/crashreporter-symbols && \
           zip -r9D ../"$(SYMBOL_ARCHIVE_BASENAME).zip" .
 endif # MOZ_CRASHREPORTER
 
 uploadsymbols:
 ifdef MOZ_CRASHREPORTER
 	$(SHELL) $(topsrcdir)/toolkit/crashreporter/tools/upload_symbols.sh "$(DIST)/$(SYMBOL_ARCHIVE_BASENAME).zip"
 endif
 
 ifeq ($(OS_ARCH),WINNT)
 signnss:
 ifdef MOZILLA_OFFICIAL
 	echo signing NSS libs
 	cd $(DIST)/bin; ./shlibsign.exe -v -i softokn3.dll
 	cd $(DIST)/bin; ./shlibsign.exe -v -i freebl3.dll
+	cd $(DIST)/bin; ./shlibsign.exe -v -i nssdbm3.dll
 endif # MOZILLA_OFFICIAL
 
 deliver: rebase signnss
 
 endif # WINNT
 
 ifneq (,$(wildcard $(DIST)/bin/application.ini))
 BUILDID = $(shell $(PYTHON) $(srcdir)/config/printconfigsetting.py $(DIST)/bin/application.ini App BuildID)
--- a/accessible/public/ia2/Makefile.in
+++ b/accessible/public/ia2/Makefile.in
@@ -63,16 +63,18 @@ MIDL_INTERFACES = \
   AccessibleApplication.idl \
   AccessibleComponent.idl \
   AccessibleEditableText.idl \
   AccessibleHyperlink.idl \
   AccessibleHypertext.idl \
   AccessibleImage.idl \
   AccessibleRelation.idl \
   AccessibleTable.idl \
+  AccessibleTable2.idl \
+  AccessibleTableCell.idl \
   AccessibleText.idl \
   AccessibleValue.idl \
   $(NULL)
 
 MIDL_ENUMS = \
   AccessibleEventId.idl \
   AccessibleRole.idl \
   AccessibleStates.idl \
--- a/accessible/public/nsIAccessibilityService.idl
+++ b/accessible/public/nsIAccessibilityService.idl
@@ -41,17 +41,17 @@
 
 interface nsIAccessibleEventListener;
 interface nsIDocument;
 interface nsIFrame;
 interface nsObjectFrame;
 interface nsIContent;
 interface nsITimer;
 
-[uuid(05481634-4700-45d6-8a0c-704f3a5abc00)]
+[uuid(6a58f7e8-587c-40dd-b684-dc3e54f1342a)]
 interface nsIAccessibilityService : nsIAccessibleRetrieval
 {
   nsIAccessible createOuterDocAccessible(in nsIDOMNode aNode);
   nsIAccessible createRootAccessible(in nsIPresShell aShell, in nsIDocument aDocument);
 
   nsIAccessible createHTML4ButtonAccessible(in nsIFrame aFrame);
   nsIAccessible createHyperTextAccessible(in nsIFrame aFrame);
   nsIAccessible createHTMLBRAccessible(in nsIFrame aFrame);
@@ -67,46 +67,47 @@ interface nsIAccessibilityService : nsIA
   nsIAccessible createHTMLLabelAccessible(in nsIFrame aFrame);
   nsIAccessible createHTMLListboxAccessible(in nsIDOMNode aNode, in nsIWeakReference aPresShell);
   nsIAccessible createHTMLMediaAccessible(in nsIFrame aFrame);
   nsIAccessible createHTMLObjectFrameAccessible(in nsObjectFrame aFrame);
   nsIAccessible createHTMLRadioButtonAccessible(in nsIFrame aFrame);
   nsIAccessible createHTMLSelectOptionAccessible(in nsIDOMNode aNode, in nsIAccessible aAccParent, in nsIWeakReference aPresShell);
   nsIAccessible createHTMLTableAccessible(in nsIFrame aFrame);
   nsIAccessible createHTMLTableCellAccessible(in nsIFrame aFrame);
-  nsIAccessible createHTMLTableHeadAccessible(in nsIDOMNode aDOMNode);
   nsIAccessible createHTMLTextAccessible(in nsIFrame aFrame);
   nsIAccessible createHTMLTextFieldAccessible(in nsIFrame aFrame);
   nsIAccessible createHTMLCaptionAccessible(in nsIFrame aFrame);
 
   nsIAccessible getAccessible(in nsIDOMNode aNode, in nsIPresShell aPresShell,                          
                               in nsIWeakReference aWeakShell, 
                               inout nsIFrame frameHint, out boolean aIsHidden);
 
   // For gtk+ native window accessible
   nsIAccessible addNativeRootAccessible(in voidPtr aAtkAccessible);
   void removeNativeRootAccessible(in nsIAccessible aRootAccessible);
 
   /**
-   * Invalidate the accessibility cache associated with aPresShell, for accessibles
-   * that were generated for aContainerContent and its subtree.
-   * The container content node for the change is passed in, rather than the
-   * changed presentation for the content node itself.
-   * @param aPresShell         The presShell where changes occured
-   * @param aChangeContent     The affected DOM content
-   * @param aEvent             The event from nsIAccessibleEvent that
-   *                           caused the change:
-   *                           Must be one of:
-   *                           EVENT_REORDER (change),
-   *                           EVENT_SHOW (make visible or create) or 
-   *                           EVENT_HIDE (destroy or hide)
+   * Used to describe sort of changes leading to accessible tree invalidation.
    */
-  void invalidateSubtreeFor(in nsIPresShell aPresShell,
-                            in nsIContent aChangedContent,
-                            in PRUint32 aEvent);
+  const unsigned long NODE_APPEND = 0x01;
+  const unsigned long NODE_REMOVE = 0x02;
+  const unsigned long NODE_SIGNIFICANT_CHANGE = 0x03;
+  const unsigned long FRAME_SHOW = 0x04;
+  const unsigned long FRAME_HIDE = 0x05;
+  const unsigned long FRAME_SIGNIFICANT_CHANGE = 0x06;
+
+  /**
+   * Invalidate the accessible tree when DOM tree or frame tree is changed.
+   *
+   * @param aPresShell   [in] the presShell where changes occured
+   * @param aContent     [in] the affected DOM content
+   * @param aChangeType  [in] the change type (see constants declared above)
+   */
+  void invalidateSubtreeFor(in nsIPresShell aPresShell, in nsIContent aContent,
+                            in PRUint32 aChangeType);
 
   /**
    *  An internal doc load event has occured. Handle the event and remove it from the list.
    *  @param aTimer      The timer created to handle this doc load event
    *  @param aClosure    The nsIWebProgress* for the load event
    *  @param aEventType  The type of load event, one of: nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START,
    *                                                     nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE or
    *                                                     nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED
--- a/accessible/public/nsIAccessibleEvent.idl
+++ b/accessible/public/nsIAccessibleEvent.idl
@@ -56,436 +56,413 @@ interface nsIDOMNode;
  * using code something like this:
  *   nsCOMPtr<nsIObserverService> observerService = 
  *     do_GetService("@mozilla.org/observer-service;1", &rv);
  *   if (NS_SUCCEEDED(rv)) 
  *     rv = observerService->AddObserver(this, "accessible-event", PR_TRUE);
  *
  * @status UNDER_REVIEW
  */
-[scriptable, uuid(ba448f0e-a761-48c8-a0f5-1f25e23d4fe4)]
+[scriptable, uuid(5713f093-1d67-4666-b9e2-516f410976bc)]
 interface nsIAccessibleEvent : nsISupports
 {
   /**
    * An object has been created.
    */
-  const unsigned long EVENT_DOM_CREATE = 0x0001;
+  const unsigned long EVENT_SHOW = 0x0001;
 
   /**
    * An object has been destroyed.
    */
-  const unsigned long EVENT_DOM_DESTROY = 0x0002;
-
-  /**
-   * An object's properties or content have changed significantly so that the
-   * type of object has really changed, and therefore the accessible should be 
-   * destroyed or recreated.
-   */
-  const unsigned long EVENT_DOM_SIGNIFICANT_CHANGE = 0x0003;
+  const unsigned long EVENT_HIDE = 0x0002;
 
   /**
-   * A hidden object is shown -- this is a layout occurance and is thus asynchronous
-   */
-  const unsigned long EVENT_ASYNCH_SHOW = 0x0004;
-
-  /**
-   * An object is hidden -- this is a layout occurance and is thus asynchronous
+   * An object's children have changed
    */
-  const unsigned long EVENT_ASYNCH_HIDE = 0x0005;
-
-  /**
-   * An object had a significant layout change which could affect
-   * the type of accessible object -- this is a layout occurance and is thus asynchronous
-   */
-  const unsigned long EVENT_ASYNCH_SIGNIFICANT_CHANGE = 0x0006;
+  const unsigned long EVENT_REORDER = 0x0003;
 
   /**
    * The active descendant of a component has changed. The active descendant
    * is used in objects with transient children.
    */
-  const unsigned long EVENT_ACTIVE_DECENDENT_CHANGED = 0x0007;
+  const unsigned long EVENT_ACTIVE_DECENDENT_CHANGED = 0x0004;
 
   /**
    * An object has received the keyboard focus.
    */
-  const unsigned long EVENT_FOCUS = 0x0008;
+  const unsigned long EVENT_FOCUS = 0x0005;
 
   /**
    * An object's state has changed.
    */
-  const unsigned long EVENT_STATE_CHANGE = 0x0009;
+  const unsigned long EVENT_STATE_CHANGE = 0x0006;
 
   /**
    * An object has changed location, shape, or size.
    */
-  const unsigned long EVENT_LOCATION_CHANGE = 0x000A;
+  const unsigned long EVENT_LOCATION_CHANGE = 0x0007;
 
   /**
    * An object's Name property has changed.
    */
-  const unsigned long EVENT_NAME_CHANGE = 0x000B;
+  const unsigned long EVENT_NAME_CHANGE = 0x0008;
 
   /**
    * An object's Description property has changed.
    */
-  const unsigned long EVENT_DESCRIPTION_CHANGE = 0x000C;
+  const unsigned long EVENT_DESCRIPTION_CHANGE = 0x0009;
 
   /**
    * An object's Value property has changed.
    */
-  const unsigned long EVENT_VALUE_CHANGE = 0x000D;
+  const unsigned long EVENT_VALUE_CHANGE = 0x000A;
 
   /**
    * An object's help has changed.
    */
-  const unsigned long EVENT_HELP_CHANGE = 0x000E;
+  const unsigned long EVENT_HELP_CHANGE = 0x000B;
 
   /**
    * An object's default action has changed.
    */
-  const unsigned long EVENT_DEFACTION_CHANGE = 0x000F;
+  const unsigned long EVENT_DEFACTION_CHANGE = 0x000C;
 
   /**
    * An object's action has changed.
    */
-  const unsigned long EVENT_ACTION_CHANGE = 0x0010;
+  const unsigned long EVENT_ACTION_CHANGE = 0x000D;
 
   /**
    * An object's keyboard shortcut has changed.
    */
-  const unsigned long EVENT_ACCELERATOR_CHANGE = 0x0011;
+  const unsigned long EVENT_ACCELERATOR_CHANGE = 0x000E;
 
   /**
    * The selection within a container object has changed.
    */
-  const unsigned long EVENT_SELECTION = 0x0012;
+  const unsigned long EVENT_SELECTION = 0x000F;
 
   /**
    * An item within a container object has been added to the selection.
    */
-  const unsigned long EVENT_SELECTION_ADD = 0x0013;
+  const unsigned long EVENT_SELECTION_ADD = 0x0010;
 
   /**
    * An item within a container object has been removed from the selection.
    */
-  const unsigned long EVENT_SELECTION_REMOVE = 0x0014;
+  const unsigned long EVENT_SELECTION_REMOVE = 0x0011;
 
   /**
    * Numerous selection changes have occurred within a container object.
    */
-  const unsigned long EVENT_SELECTION_WITHIN = 0x0015;
+  const unsigned long EVENT_SELECTION_WITHIN = 0x0012;
 
   /**
    * An alert has been generated. Server applications send this event when a
    * user needs to know that a user interface element has changed.
    */
-  const unsigned long EVENT_ALERT = 0x0016;
+  const unsigned long EVENT_ALERT = 0x0013;
 
   /**
    * The foreground window has changed.
    */
-  const unsigned long EVENT_FOREGROUND = 0x0017;
+  const unsigned long EVENT_FOREGROUND = 0x0014;
 
   /**
    * A menu item on the menu bar has been selected.
    */
-  const unsigned long EVENT_MENU_START = 0x0018;
+  const unsigned long EVENT_MENU_START = 0x0015;
 
   /**
    * A menu from the menu bar has been closed.
    */
-  const unsigned long EVENT_MENU_END = 0x0019;
+  const unsigned long EVENT_MENU_END = 0x0016;
 
   /**
    * A pop-up menu has been displayed.
    */
-  const unsigned long EVENT_MENUPOPUP_START = 0x001A;
+  const unsigned long EVENT_MENUPOPUP_START = 0x0017;
 
   /**
    * A pop-up menu has been closed.
    */
-  const unsigned long EVENT_MENUPOPUP_END = 0x001B;
+  const unsigned long EVENT_MENUPOPUP_END = 0x0018;
 
   /**
    * A window has received mouse capture.
    */
-  const unsigned long EVENT_CAPTURE_START = 0x001C;
+  const unsigned long EVENT_CAPTURE_START = 0x0019;
 
   /**
    * A window has lost mouse capture.
    */
-  const unsigned long EVENT_CAPTURE_END = 0x001D;
+  const unsigned long EVENT_CAPTURE_END = 0x001A;
 
   /**
    * A window is being moved or resized.
    */
-  const unsigned long EVENT_MOVESIZE_START = 0x001E;
+  const unsigned long EVENT_MOVESIZE_START = 0x001B;
 
   /**
   * The movement or resizing of a window has finished
   */
-  const unsigned long EVENT_MOVESIZE_END = 0x001F;
+  const unsigned long EVENT_MOVESIZE_END = 0x001C;
 
   /**
    * A window has entered context-sensitive Help mode
    */
-  const unsigned long EVENT_CONTEXTHELP_START = 0x0020;
+  const unsigned long EVENT_CONTEXTHELP_START = 0x001D;
 
   /**
    * A window has exited context-sensitive Help mode
    */
-  const unsigned long EVENT_CONTEXTHELP_END = 0x0021;
+  const unsigned long EVENT_CONTEXTHELP_END = 0x001E;
 
   /**
    * An application is about to enter drag-and-drop mode
    */
-  const unsigned long EVENT_DRAGDROP_START = 0x0022;
+  const unsigned long EVENT_DRAGDROP_START = 0x001F;
 
   /**
    * An application is about to exit drag-and-drop mode
    */
-  const unsigned long EVENT_DRAGDROP_END = 0x0023;
+  const unsigned long EVENT_DRAGDROP_END = 0x0020;
   
   /**
    * A dialog box has been displayed
    */
-  const unsigned long EVENT_DIALOG_START = 0x0024;
+  const unsigned long EVENT_DIALOG_START = 0x0021;
 
   /**
    * A dialog box has been closed
    */
-  const unsigned long EVENT_DIALOG_END = 0x0025;
+  const unsigned long EVENT_DIALOG_END = 0x0022;
 
   /**
    * Scrolling has started on a scroll bar
    */
-  const unsigned long EVENT_SCROLLING_START = 0x0026;
+  const unsigned long EVENT_SCROLLING_START = 0x0023;
 
   /**
    * Scrolling has ended on a scroll bar
    */
-  const unsigned long EVENT_SCROLLING_END = 0x0027;
+  const unsigned long EVENT_SCROLLING_END = 0x0024;
 
   /**
    * A window object is about to be minimized or maximized
    */
-  const unsigned long EVENT_MINIMIZE_START = 0x0028;
+  const unsigned long EVENT_MINIMIZE_START = 0x0025;
 
   /**
    * A window object has been minimized or maximized
    */
-  const unsigned long EVENT_MINIMIZE_END = 0x0029;
+  const unsigned long EVENT_MINIMIZE_END = 0x0026;
 
   /**
    * XXX:
    */
-  const unsigned long EVENT_DOCUMENT_LOAD_START = 0x002A;
+  const unsigned long EVENT_DOCUMENT_LOAD_START = 0x0027;
 
   /**
    * The loading of the document has completed.
    */
-  const unsigned long EVENT_DOCUMENT_LOAD_COMPLETE = 0x002B;
+  const unsigned long EVENT_DOCUMENT_LOAD_COMPLETE = 0x0028;
 
   /**
    * The document contents are being reloaded.
    */
-  const unsigned long EVENT_DOCUMENT_RELOAD = 0x002C;
+  const unsigned long EVENT_DOCUMENT_RELOAD = 0x0029;
 
   /**
    * The loading of the document was interrupted.
    */
-  const unsigned long EVENT_DOCUMENT_LOAD_STOPPED = 0x002D;
+  const unsigned long EVENT_DOCUMENT_LOAD_STOPPED = 0x002A;
 
   /**
    * The document wide attributes of the document object have changed.
    */
-  const unsigned long EVENT_DOCUMENT_ATTRIBUTES_CHANGED = 0x002E;
+  const unsigned long EVENT_DOCUMENT_ATTRIBUTES_CHANGED = 0x002B;
 
   /**
    * The contents of the document have changed.
    */
-  const unsigned long EVENT_DOCUMENT_CONTENT_CHANGED = 0x002F;
+  const unsigned long EVENT_DOCUMENT_CONTENT_CHANGED = 0x002C;
 
-  const unsigned long EVENT_PROPERTY_CHANGED = 0x0030;
-  const unsigned long EVENT_SELECTION_CHANGED = 0x0031;
+  const unsigned long EVENT_PROPERTY_CHANGED = 0x002D;
+  const unsigned long EVENT_SELECTION_CHANGED = 0x002E;
 
   /**
    * A text object's attributes changed.
    * Also see EVENT_OBJECT_ATTRIBUTE_CHANGED.
    */
-  const unsigned long EVENT_TEXT_ATTRIBUTE_CHANGED = 0x0032;
+  const unsigned long EVENT_TEXT_ATTRIBUTE_CHANGED = 0x002F;
 
   /**
    * The caret has moved to a new position.
    */
-  const unsigned long EVENT_TEXT_CARET_MOVED = 0x0033;
+  const unsigned long EVENT_TEXT_CARET_MOVED = 0x0030;
 
   /**
    * This event indicates general text changes, i.e. changes to text that is
    * exposed through the IAccessibleText and IAccessibleEditableText interfaces.
    */
-  const unsigned long EVENT_TEXT_CHANGED = 0x0034;
+  const unsigned long EVENT_TEXT_CHANGED = 0x0031;
 
   /**
    * Text was inserted.
    */
-  const unsigned long EVENT_TEXT_INSERTED = 0x0035;
+  const unsigned long EVENT_TEXT_INSERTED = 0x0032;
 
   /**
    * Text was removed.
    */
-  const unsigned long EVENT_TEXT_REMOVED = 0x0036;
+  const unsigned long EVENT_TEXT_REMOVED = 0x0033;
 
   /**
    * Text was updated.
    */
-  const unsigned long EVENT_TEXT_UPDATED = 0x0037;
+  const unsigned long EVENT_TEXT_UPDATED = 0x0034;
 
   /**
    * The text selection changed.
    */
-  const unsigned long EVENT_TEXT_SELECTION_CHANGED = 0x0038;
+  const unsigned long EVENT_TEXT_SELECTION_CHANGED = 0x0035;
 
   /**
    * A visibile data event indicates the change of the visual appearance
    * of an accessible object.  This includes for example most of the
    * attributes available via the IAccessibleComponent interface.
    */
-  const unsigned long EVENT_VISIBLE_DATA_CHANGED = 0x0039;
+  const unsigned long EVENT_VISIBLE_DATA_CHANGED = 0x0036;
 
   /**
    * The caret moved from one column to the next.
    */
-  const unsigned long EVENT_TEXT_COLUMN_CHANGED = 0x003A;
+  const unsigned long EVENT_TEXT_COLUMN_CHANGED = 0x0037;
 
   /**
    * The caret moved from one section to the next.
    */
-  const unsigned long EVENT_SECTION_CHANGED = 0x003B;
+  const unsigned long EVENT_SECTION_CHANGED = 0x0038;
 
   /**
    * A table caption changed.
    */
-  const unsigned long EVENT_TABLE_CAPTION_CHANGED = 0x003C;
+  const unsigned long EVENT_TABLE_CAPTION_CHANGED = 0x0039;
 
   /**
    * A table's data changed.
    */
-  const unsigned long EVENT_TABLE_MODEL_CHANGED = 0x003D;
+  const unsigned long EVENT_TABLE_MODEL_CHANGED = 0x003A;
 
   /**
    * A table's summary changed.
    */
-  const unsigned long EVENT_TABLE_SUMMARY_CHANGED = 0x003E;
+  const unsigned long EVENT_TABLE_SUMMARY_CHANGED = 0x003B;
 
   /**
    * A table's row description changed.
    */
-  const unsigned long EVENT_TABLE_ROW_DESCRIPTION_CHANGED = 0x003F;
+  const unsigned long EVENT_TABLE_ROW_DESCRIPTION_CHANGED = 0x003C;
 
   /**
    * A table's row header changed.
    */
-  const unsigned long EVENT_TABLE_ROW_HEADER_CHANGED = 0x0040;
+  const unsigned long EVENT_TABLE_ROW_HEADER_CHANGED = 0x003D;
 
-  const unsigned long EVENT_TABLE_ROW_INSERT = 0x0041;
-  const unsigned long EVENT_TABLE_ROW_DELETE = 0x0042;
-  const unsigned long EVENT_TABLE_ROW_REORDER = 0x0043;
+  const unsigned long EVENT_TABLE_ROW_INSERT = 0x003E;
+  const unsigned long EVENT_TABLE_ROW_DELETE = 0x003F;
+  const unsigned long EVENT_TABLE_ROW_REORDER = 0x0040;
 
   /**
    * A table's column description changed.
    */
-  const unsigned long EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED = 0x0044;
+  const unsigned long EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED = 0x0041;
 
   /**
    * A table's column header changed.
    */
-  const unsigned long EVENT_TABLE_COLUMN_HEADER_CHANGED = 0x0045;
+  const unsigned long EVENT_TABLE_COLUMN_HEADER_CHANGED = 0x0042;
 
-  const unsigned long EVENT_TABLE_COLUMN_INSERT = 0x0046;
-  const unsigned long EVENT_TABLE_COLUMN_DELETE = 0x0047;
-  const unsigned long EVENT_TABLE_COLUMN_REORDER = 0x0048;
+  const unsigned long EVENT_TABLE_COLUMN_INSERT = 0x0043;
+  const unsigned long EVENT_TABLE_COLUMN_DELETE = 0x0044;
+  const unsigned long EVENT_TABLE_COLUMN_REORDER = 0x0045;
 
-  const unsigned long EVENT_WINDOW_ACTIVATE = 0x0049;
-  const unsigned long EVENT_WINDOW_CREATE = 0x004A;
-  const unsigned long EVENT_WINDOW_DEACTIVATE = 0x004B;
-  const unsigned long EVENT_WINDOW_DESTROY = 0x004C;
-  const unsigned long EVENT_WINDOW_MAXIMIZE = 0x004D;
-  const unsigned long EVENT_WINDOW_MINIMIZE = 0x004E;
-  const unsigned long EVENT_WINDOW_RESIZE = 0x004F;
-  const unsigned long EVENT_WINDOW_RESTORE = 0x0050;
+  const unsigned long EVENT_WINDOW_ACTIVATE = 0x0046;
+  const unsigned long EVENT_WINDOW_CREATE = 0x0047;
+  const unsigned long EVENT_WINDOW_DEACTIVATE = 0x0048;
+  const unsigned long EVENT_WINDOW_DESTROY = 0x0049;
+  const unsigned long EVENT_WINDOW_MAXIMIZE = 0x004A;
+  const unsigned long EVENT_WINDOW_MINIMIZE = 0x004B;
+  const unsigned long EVENT_WINDOW_RESIZE = 0x004C;
+  const unsigned long EVENT_WINDOW_RESTORE = 0x004D;
 
   /**
    * The ending index of this link within the containing string has changed.
    */
-  const unsigned long EVENT_HYPERLINK_END_INDEX_CHANGED = 0x0051;
+  const unsigned long EVENT_HYPERLINK_END_INDEX_CHANGED = 0x004E;
 
   /**
    * The number of anchors assoicated with this hyperlink object has changed.
    */
-  const unsigned long EVENT_HYPERLINK_NUMBER_OF_ANCHORS_CHANGED = 0x0052;
+  const unsigned long EVENT_HYPERLINK_NUMBER_OF_ANCHORS_CHANGED = 0x004F;
 
   /**
    * The hyperlink selected state changed from selected to unselected or
    * from unselected to selected.
    */
-  const unsigned long EVENT_HYPERLINK_SELECTED_LINK_CHANGED = 0x0053;
+  const unsigned long EVENT_HYPERLINK_SELECTED_LINK_CHANGED = 0x0050;
 
   /**
    * One of the links associated with the hypertext object has been activated.
    */
-  const unsigned long EVENT_HYPERTEXT_LINK_ACTIVATED = 0x0054;
+  const unsigned long EVENT_HYPERTEXT_LINK_ACTIVATED = 0x0051;
 
   /**
    * One of the links associated with the hypertext object has been selected.
    */
-  const unsigned long EVENT_HYPERTEXT_LINK_SELECTED = 0x0055;
+  const unsigned long EVENT_HYPERTEXT_LINK_SELECTED = 0x0052;
 
   /**
    * The starting index of this link within the containing string has changed.
    */
-  const unsigned long EVENT_HYPERLINK_START_INDEX_CHANGED = 0x0056;
+  const unsigned long EVENT_HYPERLINK_START_INDEX_CHANGED = 0x0053;
 
   /**
    * Focus has changed from one hypertext object to another, or focus moved
    * from a non-hypertext object to a hypertext object, or focus moved from a
    * hypertext object to a non-hypertext object.
    */
-  const unsigned long EVENT_HYPERTEXT_CHANGED = 0x0057;
+  const unsigned long EVENT_HYPERTEXT_CHANGED = 0x0054;
 
   /**
    * The number of hyperlinks associated with a hypertext object changed.
    */
-  const unsigned long EVENT_HYPERTEXT_NLINKS_CHANGED = 0x0058;
+  const unsigned long EVENT_HYPERTEXT_NLINKS_CHANGED = 0x0055;
 
   /**
    * An object's attributes changed. Also see EVENT_TEXT_ATTRIBUTE_CHANGED.
    */
-  const unsigned long EVENT_OBJECT_ATTRIBUTE_CHANGED = 0x0059;
+  const unsigned long EVENT_OBJECT_ATTRIBUTE_CHANGED = 0x0056;
 
   /**
    * A slide changed in a presentation document or a page boundary was
    * crossed in a word processing document.
    */
-  const unsigned long EVENT_PAGE_CHANGED = 0x005A;
+  const unsigned long EVENT_PAGE_CHANGED = 0x0057;
 
   /**
    * Used internally in Gecko.
    */
-  const unsigned long EVENT_INTERNAL_LOAD = 0x005B;
-
-  /**
-   * An object's children have changed
-   */
-  const unsigned long EVENT_REORDER = 0x005C;
+  const unsigned long EVENT_INTERNAL_LOAD = 0x0058;
 
   /**
    * Help make sure event map does not get out-of-line.
    */
-  const unsigned long EVENT_LAST_ENTRY = 0x005D;
+  const unsigned long EVENT_LAST_ENTRY = 0x0059;
 
   /**
    * The type of event, based on the enumerated event values
    * defined in this interface.
    */
   readonly attribute unsigned long eventType;
   
   /**
@@ -510,18 +487,18 @@ interface nsIAccessibleEvent : nsISuppor
   /**
    * Returns true if the event was caused by explicit user input,
    * as opposed to purely originating from a timer or mouse movement
    */
   attribute boolean isFromUserInput;
 };
 
 
-[scriptable, uuid(444db51a-05fd-4576-8a64-32dbb2a83884)]
-interface nsIAccessibleStateChangeEvent : nsIAccessibleEvent
+[scriptable, uuid(9addd25d-8fa1-415e-94ec-6038f220d3e4)]
+interface nsIAccessibleStateChangeEvent : nsISupports
 {
   /**
    * Returns the state of accessible (see constants declared
    * in nsIAccessibleStates).
    */
   readonly attribute unsigned long state;
 
   /**
@@ -531,18 +508,18 @@ interface nsIAccessibleStateChangeEvent 
 
   /**
    * Returns true if the state is turned on.
    */
   boolean isEnabled();
 };
 
 
-[scriptable, uuid(50a1e151-8e5f-4bcc-aaaf-a4bed1190e93)]
-interface nsIAccessibleTextChangeEvent : nsIAccessibleEvent
+[scriptable, uuid(21e0f8bd-5638-4964-870b-3c8e944ac4c4)]
+interface nsIAccessibleTextChangeEvent : nsISupports
 {
   /**
    * Returns offset of changed text in accessible.
    */
   readonly attribute long start;
 
   /**
    * Returns length of changed text.
@@ -555,27 +532,27 @@ interface nsIAccessibleTextChangeEvent :
   boolean isInserted();
 
   /**
    * The inserted or removed text
    */
   readonly attribute DOMString modifiedText;
 };
 
-[scriptable, uuid(b9076dce-4cd3-4e3d-a7f6-7f33a7f40c31)]
-interface nsIAccessibleCaretMoveEvent: nsIAccessibleEvent
+[scriptable, uuid(5675c486-a230-4d85-a4bd-33670826d5ff)]
+interface nsIAccessibleCaretMoveEvent: nsISupports
 {
   /**
    * Return caret offset.
    */
   readonly attribute long caretOffset;
 };
 
-[scriptable, uuid(a9485c7b-5861-4695-8441-fab0235b205d)]
-interface nsIAccessibleTableChangeEvent: nsIAccessibleEvent
+[scriptable, uuid(df517997-ed52-4ea2-b310-2f8e0fe64572)]
+interface nsIAccessibleTableChangeEvent: nsISupports
 {
   /**
    * Return the row or column index.
    */
   readonly attribute long rowOrColIndex;
 
   /**
    * Return the number of rows or cols
--- a/accessible/public/nsIAccessibleTable.idl
+++ b/accessible/public/nsIAccessibleTable.idl
@@ -19,16 +19,17 @@
  * Netscape Communications Corporation.
  * Portions created by the Initial Developer are Copyright (C) 1999
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Paul Sandoz (paul.sandoz@sun.com)
  *   Bill Haneman (bill.haneman@sun.com)
  *   John Gaunt (jgaunt@netscape.com)
+ *   Alexander Surkov <surkov.alexander@gmail.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either of the GNU General Public License Version 2 or later (the "GPL"),
  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -37,225 +38,256 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsISupports.idl"
 
 interface nsIAccessible;
+interface nsIArray;
 
-[scriptable, uuid(dcc1e5c3-966e-45b2-b30a-839d35432b24)]
+[scriptable, uuid(035c0c0e-41e3-4985-8ad9-d9f14cdc667a)]
 interface nsIAccessibleTable : nsISupports
 {
   /**
-   * Returns the caption accessible for the table. For example, html:caption
+   * Return the caption accessible for the table. For example, html:caption
    * element of html:table element.
    */
-  readonly attribute nsIAccessible       caption;
+  readonly attribute nsIAccessible caption;
 
   /**
-   * Returns summary description for the table. For example, @summary attribute
-   * on html:element.
+   * Return summary description for the table. For example, @summary attribute
+   * on html:table element.
    */
-  readonly attribute AString             summary;
-
-  /**
-   * Returns columns count in the table.
-   * XXX: not very well named property.
-   */
-  readonly attribute long                columns;
+  readonly attribute AString summary;
 
   /**
-   * Returns table accessible containing column headers.
+   * Return columns count in the table.
    */
-  readonly attribute nsIAccessibleTable  columnHeader;
+  readonly attribute long columnCount;
 
   /**
-   * Returns rows count in the table.
-   * XXX: not very well named property.
+   * Return rows count in the table.
    */
-  readonly attribute long                rows;
+  readonly attribute long rowCount;
 
   /**
-   * Returns table accessible containing row headers.
-   */
-  readonly attribute nsIAccessibleTable  rowHeader;
-
-  /**
-   * Returns the accessible object at the specified row and column in the table.
+   * Return the accessible object at the specified row and column in the table.
    * If both row and column index are valid then the corresponding accessible
    * object is returned that represents the requested cell regardless of whether
    * the cell is currently visible (on the screen).
    *
-   * @param row - The row index for which to retrieve the cell.
-   * @param column - The column index for which to retrieve the cell.
+   * @param  rowIndex     [in] the row index to retrieve the cell at
+   * @param  columnIndex  [in] the column index to retrieve the cell at
    */
-  nsIAccessible cellRefAt(in long row, in long column);
+  nsIAccessible getCellAt(in long rowIndex, in long columnIndex);
 
   /**
-   * Translates the given row and column indices into the corresponding cell
+   * Translate the given row and column indices into the corresponding cell
    * index.
    *
-   * @param row - index of the row of the table for which to return the cell
-   *              index.
-   * @param column - index of the column of the table for which to return
-   *                 the cell index.
+   * @param  rowIndex    [in] the row index to return cell index at
+   * @param  columnIndex [in] the column index to return cell index at
    */
-  long getIndexAt(in long row, in long column);
+  long getCellIndexAt(in long rowIndex, in long columnIndex);
 
   /**
-   * Translates the given child index into the corresponding column index.
+   * Translate the given cell index into the corresponding column index.
    *
-   * @param index - index of the child of the table for which to return
-   *                the column index.
+   * @param  cellIndex  [in] index of the table cell to return column index for
    */
-  long getColumnAtIndex(in long index);
+  long getColumnIndexAt(in long cellIndex);
 
   /**
-   * Translates the given child index into the corresponding row index.
+   * Translate the given cell index into the corresponding row index.
    *
-   * @param index - index of the child of the table for which to return
-   *                the row index.
+   * @param cellIndex  [in] index of the table cell to return row index for
    */
-  long getRowAtIndex(in long index);
+  long getRowIndexAt(in long cellIndex);
 
   /**
-   * Returns the number of columns occupied by the accessible object
-   * at the specified row and column in the table. The result differs from 1
-   * if the specified cell spans multiple columns.
+   * Return the number of columns occupied by the accessible cell at
+   * the specified row and column in the table. The result differs from 1 if
+   * the specified cell spans multiple columns.
    *
-   * @param row - Row index of the accessible for which to return
-   *              the column extent.
-   * @param column - Column index of the accessible for which to return
-   *                 the column extent.
+   * @param  row     [in] row index of the cell to return the column extent for
+   * @param  column  [in] column index of the cell to return the column extent
+   *                  for
    */
   long getColumnExtentAt(in long row, in long column);
 
   /**
-   * Returns the number of rows occupied by the accessible oject
-   * at the specified row and column in the table. The result differs from 1
-   * if the specified cell spans multiple rows.
+   * Return the number of rows occupied by the accessible cell at the specified
+   * row and column in the table. The result differs from 1 if the specified
+   * cell spans multiple rows.
    *
-   * @param row  - Row index of the accessible for which to return
-   *               the column extent.
-   * @param column - Column index of the accessible for which to return
-   *                 the column extent.
+   * @param  row     [in] row index of the cell to return the column extent for
+   * @param  column  [in] column index of the cell to return the column extent
+   *                  for
    */
   long getRowExtentAt(in long row, in long column);
 
   /**
-   * Returns the description text of the specified column in the table.
-   * @param column - The index of the column for which to retrieve
-   *                 the description.
+   * Return the description text of the specified column in the table.
+   *
+   * @param  columnIndex  [in] the column index to retrieve description for
    */
-  AString getColumnDescription(in long column);
+  AString getColumnDescription(in long columnIndex);
 
   /**
-   * Returns the description text of the specified row in the table.
-   * @param row - The index of the row for which to retrieve the description.
+   * Return the description text of the specified row in the table.
+   *
+   * @param  rowIndex  [in] the row index to retrieve description for
    */
-  AString getRowDescription(in long row);
+  AString getRowDescription(in long rowIndex);
 
   /**
-   * Returns a boolean value indicating whether the specified column is
-   * completely selected.
+   * Return a boolean value indicating whether the specified column is
+   * selected, i.e. all cells within the column are selected.
    *
-   * @param column  - Index of the column for which to determine whether it is
-   *                   selected.
+   * @param  columnIndex  [in] the column index to determine if it's selected
    */
-  boolean isColumnSelected(in long column);
+  boolean isColumnSelected(in long columnIndex);
 
   /**
-   * Returns a boolean value indicating whether the specified row is completely
-   * selected.
+   * Return a boolean value indicating whether the specified row is selected,
+   * i.e. all cells within the row are selected.
    *
-   * @param row - Index of the row for which to determine whether it is
-   *              selected.
+   * @param  rowIndex  [in] the row index to determine whether it's selected
    */
-  boolean isRowSelected(in  long row);
+  boolean isRowSelected(in long rowIndex);
 
   /**
-   * Returns a boolean value indicating whether the specified cell is selected.
+   * Return a boolean value indicating whether the specified cell is selected.
    *
-   * @param row - Index of the row for the cell to determine whether it is
-   *              selected.
-   * @param column - Index of the column for the cell to determine whether it
-   *                 is selected.
+   * @param  rowIndex     [in] the row index of the cell
+   * @param  columnIndex  [in] the column index of the cell
    */
-  boolean isCellSelected(in long row, in long column);
+  boolean isCellSelected(in long rowIndex, in long columnIndex);
 
   /**
-   * Returns the total number of selected cells.
+   * Return the total number of selected cells.
    */
-  readonly attribute unsigned long selectedCellsCount;
+  readonly attribute unsigned long selectedCellCount;
 
   /**
-   * Returns the total number of selected columns.
+   * Return the total number of selected columns.
    */
-  readonly attribute unsigned long selectedColumnsCount;
+  readonly attribute unsigned long selectedColumnCount;
+
+  /**
+   * Return the total number of selected rows.
+   */
+  readonly attribute unsigned long selectedRowCount;
 
   /**
-   * Returns the total number of selected rows.
+   * Return an array of selected cells.
    */
-  readonly attribute unsigned long selectedRowsCount;
+  readonly attribute nsIArray selectedCells;
 
   /**
-   * Returns a list of cells indexes currently selected.
+   * Return an array of cell indices currently selected.
    *
-   * @param cellsSize - length of array
-   * @param cells - array of indexes of selected cells
+   * @param  cellsArraySize  [in] length of array
+   * @param  cellsArray      [in] array of indexes of selected cells
    */
-  void getSelectedCells(out unsigned long cellsSize,
-                        [retval, array, size_is(cellsSize)] out long cells);
+  void getSelectedCellIndices(out unsigned long cellsArraySize,
+                              [retval, array, size_is(cellsArraySize)] out long cellsArray);
 
   /**
-   * Returns a list of column indexes currently selected.
+   * Return an array of column indices currently selected.
    *
-   * @param columnsSize - Length of array
-   * @param columns - Array of indexes of selected columns
+   * @param  columnsArraySize  [in] length of array
+   * @param  columnsArray      [in] array of indices of selected columns
    */
-  void getSelectedColumns(out unsigned long columnsSize,
-                          [retval, array, size_is(columnsSize)] out long columns);
+  void getSelectedColumnIndices(out unsigned long columnsArraySize,
+                                [retval, array, size_is(columnsArraySize)] out long columnsArray);
 
   /**
-   * Returns a list of row indexes currently selected.
+   * Return an array of row indices currently selected.
    *
-   * @param rowsSize - Length of array
-   * @param rows - Array of indexes of selected rows
+   * @param  rowsArraySize  [in] Length of array
+   * @param  rowsArray      [in] array of indices of selected rows
    */
-  void getSelectedRows(out unsigned long rowsSize,
-                       [retval, array, size_is(rowsSize)] out long rows);
+  void getSelectedRowIndices(out unsigned long rowsArraySize,
+                             [retval, array, size_is(rowsArraySize)] out long rowsArray);
 
   /**
-   * Selects a row and unselects all previously selected rows.
+   * Select a row and unselects all previously selected rows.
    *
-   * @param row - Index of the row to be selected.
+   * @param  rowIndex  [in] the row index to select
    */
-  void selectRow(in long row);
+  void selectRow(in long rowIndex);
 
   /**
-   * Selects a column and unselects all previously selected columns.
+   * Select a column and unselects all previously selected columns.
    *
-   * @param column - Index of the column to be selected.
+   * @param  columnIndex  [in] the column index to select
    */
-  void selectColumn(in long column);
+  void selectColumn(in long columnIndex);
 
   /**
-   * Unselects one row, leaving other selected rows selected (if any).
+   * Unselect the given row, leaving other selected rows selected (if any).
    *
-   * @param row  - Index of the row to be selected.
+   * @param  rowIndex  [in] the row index to select
   */
-  void unselectRow(in long row);
+  void unselectRow(in long rowIndex);
 
   /**
-   * Unselects one column, leaving other selected columns selected (if any).
+   * Unselect the given column, leaving other selected columns selected (if any).
    *
-   * @param column - Index of the column to be selected.
+   * @param  columnIndex  [in] the column index to select
    */
-  void unselectColumn(in long column);
+  void unselectColumn(in long columnIndex);
 
   /**
    * Use heuristics to determine if table is most likely used for layout.
    */
   boolean isProbablyForLayout();
 };
 
+
+[scriptable, uuid(654e296d-fae6-452b-987d-746b20b9514b)]
+interface nsIAccessibleTableCell : nsISupports
+{
+  /**
+   * Return host table accessible.
+   */
+  readonly attribute nsIAccessibleTable table;
+
+  /**
+   * Return column index of this cell.
+   */
+  readonly attribute long columnIndex;
+
+  /**
+   * Return row index of this cell.
+   */
+  readonly attribute long rowIndex;
+
+  /**
+   * Return the number of columns occupied by this cell. The result differs
+   * from 1 if the specified cell spans multiple columns.
+   */
+  readonly attribute long columnExtent;
+
+  /**
+   * Return the number of rows occupied by this accessible cell. The result
+   * differs from 1 if the specified cell spans multiple rows.
+   */
+  readonly attribute long rowExtent;
+
+  /**
+   * Return an array of column header cells for this cell.
+   */
+  readonly attribute nsIArray columnHeaderCells;
+
+  /**
+   * Return an array of row header cells for this cell.
+   */
+  readonly attribute nsIArray rowHeaderCells;
+
+  /**
+   * Return a boolean value indicating whether this cell is selected.
+   */
+  boolean isSelected();
+};
--- a/accessible/src/atk/Makefile.in
+++ b/accessible/src/atk/Makefile.in
@@ -61,31 +61,26 @@ CPPSRCS = \
   nsMaiHyperlink.cpp \
   nsMaiInterfaceHypertext.cpp \
   nsMaiInterfaceHyperlinkImpl.cpp \
   nsMaiInterfaceTable.cpp \
   nsMaiInterfaceDocument.cpp \
   nsMaiInterfaceImage.cpp \
   $(NULL)
 
-ifdef MOZ_XUL
-CPPSRCS += \
-  nsXULTreeAccessibleWrap.cpp \
-  $(NULL)
-endif
-
 EXPORTS = \
   nsAccessNodeWrap.h \
   nsARIAGridAccessibleWrap.h \
   nsAccessibleWrap.h \
   nsDocAccessibleWrap.h \
   nsRootAccessibleWrap.h \
   nsTextAccessibleWrap.h \
   nsXULMenuAccessibleWrap.h \
-  nsXULTreeAccessibleWrap.h \
+  nsXULListboxAccessibleWrap.h \
+  nsXULTreeGridAccessibleWrap.h \
   nsHyperTextAccessibleWrap.h \
   nsHTMLImageAccessibleWrap.h \
   nsHTMLTableAccessibleWrap.h \
   nsAccessibleRelationWrap.h \
   $(NULL)
 
 # we want to force the creation of a static lib.
 FORCE_STATIC_LIB = 1
--- a/accessible/src/atk/nsARIAGridAccessibleWrap.h
+++ b/accessible/src/atk/nsARIAGridAccessibleWrap.h
@@ -39,11 +39,12 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _NSARIAGRIDACCESSIBLEWRAP_H
 #define _NSARIAGRIDACCESSIBLEWRAP_H
 
 #include "nsARIAGridAccessible.h"
 
 typedef class nsARIAGridAccessible nsARIAGridAccessibleWrap;
+typedef class nsARIAGridCellAccessible nsARIAGridCellAccessibleWrap;
 
 #endif
 
--- a/accessible/src/atk/nsAccessibleWrap.cpp
+++ b/accessible/src/atk/nsAccessibleWrap.cpp
@@ -1126,20 +1126,18 @@ nsAccessibleWrap::FirePlatformEvent(nsIA
     nsresult rv = aEvent->GetEventType(&type);
     NS_ENSURE_SUCCESS(rv, rv);
 
     AtkObject *atkObj = nsAccessibleWrap::GetAtkObject(accessible);
 
     // We don't create ATK objects for nsIAccessible plain text leaves,
     // just return NS_OK in such case
     if (!atkObj) {
-        NS_ASSERTION(type == nsIAccessibleEvent::EVENT_ASYNCH_SHOW ||
-                     type == nsIAccessibleEvent::EVENT_ASYNCH_HIDE ||
-                     type == nsIAccessibleEvent::EVENT_DOM_CREATE ||
-                     type == nsIAccessibleEvent::EVENT_DOM_DESTROY,
+        NS_ASSERTION(type == nsIAccessibleEvent::EVENT_SHOW ||
+                     type == nsIAccessibleEvent::EVENT_HIDE,
                      "Event other than SHOW and HIDE fired for plain text leaves");
         return NS_OK;
     }
 
     nsAccessibleWrap *accWrap = GetAccessibleWrap(atkObj);
     if (!accWrap) {
         return NS_OK; // Node is shut down
     }
@@ -1154,17 +1152,17 @@ nsAccessibleWrap::FirePlatformEvent(nsIA
 
     case nsIAccessibleEvent::EVENT_FOCUS:
       {
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_FOCUS\n"));
         nsRefPtr<nsRootAccessible> rootAccWrap = accWrap->GetRootAccessible();
         if (rootAccWrap && rootAccWrap->mActivated) {
             atk_focus_tracker_notify(atkObj);
             // Fire state change event for focus
-            nsCOMPtr<nsIAccessibleStateChangeEvent> stateChangeEvent =
+            nsCOMPtr<nsIAccessibleEvent> stateChangeEvent =
               new nsAccStateChangeEvent(accessible,
                                         nsIAccessibleStates::STATE_FOCUSED,
                                         PR_FALSE, PR_TRUE);
             return FireAtkStateChangeEvent(stateChangeEvent, atkObj);
         }
       } break;
 
     case nsIAccessibleEvent::EVENT_VALUE_CHANGE:
@@ -1303,22 +1301,20 @@ nsAccessibleWrap::FirePlatformEvent(nsIA
         g_signal_emit_by_name(atkObj, "column_reordered");
         break;
 
     case nsIAccessibleEvent::EVENT_SECTION_CHANGED:
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_SECTION_CHANGED\n"));
         g_signal_emit_by_name(atkObj, "visible_data_changed");
         break;
 
-    case nsIAccessibleEvent::EVENT_DOM_CREATE:
-    case nsIAccessibleEvent::EVENT_ASYNCH_SHOW:
+    case nsIAccessibleEvent::EVENT_SHOW:
         return FireAtkShowHideEvent(aEvent, atkObj, PR_TRUE);
 
-    case nsIAccessibleEvent::EVENT_DOM_DESTROY:
-    case nsIAccessibleEvent::EVENT_ASYNCH_HIDE:
+    case nsIAccessibleEvent::EVENT_HIDE:
         return FireAtkShowHideEvent(aEvent, atkObj, PR_FALSE);
 
         /*
          * Because dealing with menu is very different between nsIAccessible
          * and ATK, and the menu activity is important, specially transfer the
          * following two event.
          * Need more verification by AT test.
          */
@@ -1445,17 +1441,17 @@ nsAccessibleWrap::FireAtkTextChangedEven
 
     PRUint32 length = 0;
     event->GetLength(&length);
 
     PRBool isInserted;
     event->IsInserted(&isInserted);
 
     PRBool isFromUserInput;
-    event->GetIsFromUserInput(&isFromUserInput);
+    aEvent->GetIsFromUserInput(&isFromUserInput);
 
     char *signal_name = g_strconcat(isInserted ? "text_changed::insert" : "text_changed::delete",
                                     isFromUserInput ? "" : kNonUserInputEvent, NULL);
     g_signal_emit_by_name(aObject, signal_name, start, length);
     g_free (signal_name);
 
     return NS_OK;
 }
--- a/accessible/src/atk/nsHTMLTableAccessibleWrap.h
+++ b/accessible/src/atk/nsHTMLTableAccessibleWrap.h
@@ -39,13 +39,13 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _NSHTMLTABLEACCESSIBLEWRAP_H
 #define _NSHTMLTABLEACCESSIBLEWRAP_H
 
 #include "nsHTMLTableAccessible.h"
 
 typedef class nsHTMLTableAccessible nsHTMLTableAccessibleWrap;
-
-typedef class nsHTMLTableHeadAccessible nsHTMLTableHeadAccessibleWrap;
+typedef class nsHTMLTableCellAccessible nsHTMLTableCellAccessibleWrap;
+typedef class nsHTMLTableHeaderCellAccessible nsHTMLTableHeaderCellAccessibleWrap;
 
 #endif
 
--- a/accessible/src/atk/nsMaiInterfaceTable.cpp
+++ b/accessible/src/atk/nsMaiInterfaceTable.cpp
@@ -35,16 +35,18 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsMaiInterfaceTable.h"
 
+#include "nsArrayUtils.h"
+
 void
 tableInterfaceInitCB(AtkTableIface *aIface)
 
 {
     g_return_if_fail(aIface != NULL);
 
     aIface->ref_at = refAtCB;
     aIface->get_index_at = getIndexAtCB;
@@ -76,17 +78,17 @@ refAtCB(AtkTable *aTable, gint aRow, gin
         return nsnull;
 
     nsCOMPtr<nsIAccessibleTable> accTable;
     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
                             getter_AddRefs(accTable));
     NS_ENSURE_TRUE(accTable, nsnull);
 
     nsCOMPtr<nsIAccessible> cell;
-    nsresult rv = accTable->CellRefAt(aRow, aColumn,getter_AddRefs(cell));
+    nsresult rv = accTable->GetCellAt(aRow, aColumn,getter_AddRefs(cell));
     if (NS_FAILED(rv) || !cell)
         return nsnull;
 
     AtkObject *cellAtkObj = nsAccessibleWrap::GetAtkObject(cell);
     if (cellAtkObj) {
         g_object_ref(cellAtkObj);
     }
     return cellAtkObj;
@@ -100,17 +102,17 @@ getIndexAtCB(AtkTable *aTable, gint aRow
         return -1;
 
     nsCOMPtr<nsIAccessibleTable> accTable;
     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
                             getter_AddRefs(accTable));
     NS_ENSURE_TRUE(accTable, -1);
 
     PRInt32 index;
-    nsresult rv = accTable->GetIndexAt(aRow, aColumn, &index);
+    nsresult rv = accTable->GetCellIndexAt(aRow, aColumn, &index);
     NS_ENSURE_SUCCESS(rv, -1);
 
     return static_cast<gint>(index);
 }
 
 gint
 getColumnAtIndexCB(AtkTable *aTable, gint aIndex)
 {
@@ -119,17 +121,17 @@ getColumnAtIndexCB(AtkTable *aTable, gin
         return -1;
 
     nsCOMPtr<nsIAccessibleTable> accTable;
     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
                             getter_AddRefs(accTable));
     NS_ENSURE_TRUE(accTable, -1);
 
     PRInt32 col;
-    nsresult rv = accTable->GetColumnAtIndex(aIndex, &col);
+    nsresult rv = accTable->GetColumnIndexAt(aIndex, &col);
     NS_ENSURE_SUCCESS(rv, -1);
 
     return static_cast<gint>(col);
 }
 
 gint
 getRowAtIndexCB(AtkTable *aTable, gint aIndex)
 {
@@ -138,17 +140,17 @@ getRowAtIndexCB(AtkTable *aTable, gint a
         return -1;
 
     nsCOMPtr<nsIAccessibleTable> accTable;
     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
                             getter_AddRefs(accTable));
     NS_ENSURE_TRUE(accTable, -1);
 
     PRInt32 row;
-    nsresult rv = accTable->GetRowAtIndex(aIndex, &row);
+    nsresult rv = accTable->GetRowIndexAt(aIndex, &row);
     NS_ENSURE_SUCCESS(rv, -1);
 
     return static_cast<gint>(row);
 }
 
 gint
 getColumnCountCB(AtkTable *aTable)
 {
@@ -157,17 +159,17 @@ getColumnCountCB(AtkTable *aTable)
         return -1;
 
     nsCOMPtr<nsIAccessibleTable> accTable;
     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
                             getter_AddRefs(accTable));
     NS_ENSURE_TRUE(accTable, -1);
 
     PRInt32 count;
-    nsresult rv = accTable->GetColumns(&count);
+    nsresult rv = accTable->GetColumnCount(&count);
     NS_ENSURE_SUCCESS(rv, -1);
 
     return static_cast<gint>(count);
 }
 
 gint
 getRowCountCB(AtkTable *aTable)
 {
@@ -176,17 +178,17 @@ getRowCountCB(AtkTable *aTable)
         return -1;
 
     nsCOMPtr<nsIAccessibleTable> accTable;
     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
                             getter_AddRefs(accTable));
     NS_ENSURE_TRUE(accTable, -1);
 
     PRInt32 count;
-    nsresult rv = accTable->GetRows(&count);
+    nsresult rv = accTable->GetRowCount(&count);
     NS_ENSURE_SUCCESS(rv, -1);
 
     return static_cast<gint>(count);
 }
 
 gint
 getColumnExtentAtCB(AtkTable *aTable,
                     gint aRow, gint aColumn)
@@ -273,35 +275,44 @@ getColumnHeaderCB(AtkTable *aTable, gint
     if (!accWrap)
         return nsnull;
 
     nsCOMPtr<nsIAccessibleTable> accTable;
     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
                             getter_AddRefs(accTable));
     NS_ENSURE_TRUE(accTable, nsnull);
 
-    nsCOMPtr<nsIAccessibleTable> header;
-    nsresult rv = accTable->GetColumnHeader(getter_AddRefs(header));
-    NS_ENSURE_SUCCESS(rv, nsnull);
-    NS_ENSURE_TRUE(header, nsnull);
+    nsCOMPtr<nsIAccessible> accCell;
+    accTable->GetCellAt(0, aColumn, getter_AddRefs(accCell));
+    if (!accCell)
+        return nsnull;
+
+    // If the cell at the first row is column header then assume it is column
+    // header for all rows,
+    if (nsAccUtils::Role(accCell) == nsIAccessibleRole::ROLE_COLUMNHEADER)
+        return nsAccessibleWrap::GetAtkObject(accCell);
+
+    // otherwise get column header for the data cell at the first row.
+    nsCOMPtr<nsIAccessibleTableCell> accTableCell =
+        do_QueryInterface(accCell);
 
-    // Note: "table column header" has different definition between atk and mai
-    //
-    // 1. "getColumnHeaderCB" defined in AtkTableIface should return object
-    // whose role is "ATK_ROLE_TABLE_COLUMN_HEADER", which is implemented
-    // by nsXULTreeColumnItemAccessible.
-    //
-    // 2. "GetColumnHeader" defined in nsIAccessibleTable returns
-    // nsXULTreeColumnsAccessibleWrap, which exports nsIAccessibleTable and is
-    // "ROLE_LIST".
-    nsCOMPtr<nsIAccessible> accHeader;
-    header->CellRefAt(0, aColumn, getter_AddRefs(accHeader));
-    NS_ENSURE_TRUE(accHeader, nsnull);
+    if (accTableCell) {
+        nsCOMPtr<nsIArray> headerCells;
+        accTableCell->GetColumnHeaderCells(getter_AddRefs(headerCells));
+        if (headerCells) {
+            nsresult rv;
+            nsCOMPtr<nsIAccessible> accHeaderCell =
+                do_QueryElementAt(headerCells, 0, &rv);
+            NS_ENSURE_SUCCESS(rv, nsnull);
 
-    return nsAccessibleWrap::GetAtkObject(accHeader);
+            return nsAccessibleWrap::GetAtkObject(accHeaderCell);
+        }
+    }
+
+    return nsnull;
 }
 
 const gchar*
 getRowDescriptionCB(AtkTable *aTable, gint aRow)
 {
     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
     if (!accWrap)
         return nsnull;
@@ -325,24 +336,44 @@ getRowHeaderCB(AtkTable *aTable, gint aR
     if (!accWrap)
         return nsnull;
 
     nsCOMPtr<nsIAccessibleTable> accTable;
     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
                             getter_AddRefs(accTable));
     NS_ENSURE_TRUE(accTable, nsnull);
 
-    nsCOMPtr<nsIAccessibleTable> header;
-    nsresult rv = accTable->GetRowHeader(getter_AddRefs(header));
-    NS_ENSURE_SUCCESS(rv, nsnull);
+    nsCOMPtr<nsIAccessible> accCell;
+    accTable->GetCellAt(aRow, 0, getter_AddRefs(accCell));
+    if (!accCell)
+      return nsnull;
+
+    // If the cell at the first column is row header then assume it is row
+    // header for all columns,
+    if (nsAccUtils::Role(accCell) == nsIAccessibleRole::ROLE_ROWHEADER)
+        return nsAccessibleWrap::GetAtkObject(accCell);
+
+    // otherwise get row header for the data cell at the first column.
+    nsCOMPtr<nsIAccessibleTableCell> accTableCell =
+        do_QueryInterface(accCell);
 
-    nsCOMPtr<nsIAccessible> accHeader(do_QueryInterface(header));
-    NS_ENSURE_TRUE(accHeader, nsnull);
+    if (accTableCell) {
+      nsCOMPtr<nsIArray> headerCells;
+      accTableCell->GetRowHeaderCells(getter_AddRefs(headerCells));
+      if (headerCells) {
+        nsresult rv;
+        nsCOMPtr<nsIAccessible> accHeaderCell =
+            do_QueryElementAt(headerCells, 0, &rv);
+        NS_ENSURE_SUCCESS(rv, nsnull);
 
-    return nsAccessibleWrap::GetAtkObject(accHeader);
+        return nsAccessibleWrap::GetAtkObject(accHeaderCell);
+      }
+    }
+
+    return nsnull;
 }
 
 AtkObject*
 getSummaryCB(AtkTable *aTable)
 {
     // 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
@@ -359,17 +390,17 @@ getSelectedColumnsCB(AtkTable *aTable, g
 
     nsCOMPtr<nsIAccessibleTable> accTable;
     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
                             getter_AddRefs(accTable));
     NS_ENSURE_TRUE(accTable, 0);
 
     PRUint32 size = 0;
     PRInt32 *columns = NULL;
-    nsresult rv = accTable->GetSelectedColumns(&size, &columns);
+    nsresult rv = accTable->GetSelectedColumnIndices(&size, &columns);
     if (NS_FAILED(rv) || (size == 0) || !columns) {
         *aSelected = nsnull;
         return 0;
     }
 
     gint *atkColumns = g_new(gint, size);
     if (!atkColumns) {
         NS_WARNING("OUT OF MEMORY");
@@ -394,17 +425,17 @@ getSelectedRowsCB(AtkTable *aTable, gint
 
     nsCOMPtr<nsIAccessibleTable> accTable;
     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
                             getter_AddRefs(accTable));
     NS_ENSURE_TRUE(accTable, 0);
 
     PRUint32 size = 0;
     PRInt32 *rows = NULL;
-    nsresult rv = accTable->GetSelectedRows(&size, &rows);
+    nsresult rv = accTable->GetSelectedRowIndices(&size, &rows);
     if (NS_FAILED(rv) || (size == 0) || !rows) {
         *aSelected = nsnull;
         return 0;
     }
 
     gint *atkRows = g_new(gint, size);
     if (!atkRows) {
         NS_WARNING("OUT OF MEMORY");
new file mode 100644
--- /dev/null
+++ b/accessible/src/atk/nsXULListboxAccessibleWrap.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alexander Surkov <surkov.alexander@gmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __nsXULListboxAccessibleWrap_h__
+#define __nsXULListboxAccessibleWrap_h__
+
+#include "nsXULListboxAccessible.h"
+
+typedef class nsXULListboxAccessible nsXULListboxAccessibleWrap;
+typedef class nsXULListCellAccessible nsXULListCellAccessibleWrap;
+
+#endif
deleted file mode 100644
--- a/accessible/src/atk/nsXULTreeAccessibleWrap.cpp
+++ /dev/null
@@ -1,289 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Sun Microsystems, Inc.
- * Portions created by the Initial Developer are Copyright (C) 2002
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Pete Zha (pete.zha@sun.com)
- *   Kyle Yuan (kyle.yuan@sun.com)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "nsIDOMElement.h"
-#include "nsITreeSelection.h"
-#include "nsITreeColumns.h"
-#include "nsXULTreeAccessibleWrap.h"
-
-// --------------------------------------------------------
-// nsXULTreeAccessibleWrap Accessible
-// --------------------------------------------------------
-
-nsXULTreeGridAccessibleWrap::
-  nsXULTreeGridAccessibleWrap(nsIDOMNode *aDOMNode, nsIWeakReference *aShell):
-  nsXULTreeGridAccessible(aDOMNode, aShell)
-{
-}
-
-NS_IMETHODIMP
-nsXULTreeGridAccessibleWrap::GetColumnHeader(nsIAccessibleTable **aColumnHeader)
-{
-  nsresult rv = NS_OK;
-
-  nsCOMPtr<nsIAccessible> acc;
-  nsAccessible::GetFirstChild(getter_AddRefs(acc));
-  NS_ENSURE_TRUE(acc, NS_ERROR_FAILURE);
-
-  nsCOMPtr<nsIAccessibleTable> accTable(do_QueryInterface(acc, &rv));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  *aColumnHeader = accTable;
-  NS_IF_ADDREF(*aColumnHeader);
-
-  return rv;
-}
-
-NS_IMETHODIMP
-nsXULTreeGridAccessibleWrap::GetColumnDescription(PRInt32 aColumn, nsAString & _retval)
-{
-  nsCOMPtr<nsIAccessibleTable> columnHeader;
-  nsresult rv = GetColumnHeader(getter_AddRefs(columnHeader));
-  if (NS_SUCCEEDED(rv) && columnHeader) {
-    return columnHeader->GetColumnDescription(aColumn, _retval);
-  }
-  return NS_ERROR_FAILURE;
-}
-
-// --------------------------------------------------------
-// nsXULTreeColumnsAccessibleWrap Accessible
-// --------------------------------------------------------
-NS_IMPL_ISUPPORTS_INHERITED1(nsXULTreeColumnsAccessibleWrap, nsXULTreeColumnsAccessible, nsIAccessibleTable)
-
-nsXULTreeColumnsAccessibleWrap::nsXULTreeColumnsAccessibleWrap(nsIDOMNode *aDOMNode, nsIWeakReference *aShell):
-nsXULTreeColumnsAccessible(aDOMNode, aShell)
-{
-}
-
-NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetCaption(nsIAccessible **aCaption)
-{
-  *aCaption = nsnull;
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetSummary(nsAString &aSummary)
-{
-  aSummary.Truncate();
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetColumns(PRInt32 *aColumns)
-{
-  nsresult rv = GetChildCount(aColumns);
-  return *aColumns > 0 ? rv : NS_ERROR_FAILURE;
-}
-
-NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetColumnHeader(nsIAccessibleTable * *aColumnHeader)
-{
-  // Column header not supported.
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetRows(PRInt32 *aRows)
-{
-  NS_ENSURE_ARG_POINTER(aRows);
-
-  *aRows = 1;
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetRowHeader(nsIAccessibleTable * *aRowHeader)
-{
-  // Row header not supported.
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsXULTreeColumnsAccessibleWrap::GetSelectedCellsCount(PRUint32* aCount)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsXULTreeColumnsAccessibleWrap::GetSelectedColumnsCount(PRUint32* aCount)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsXULTreeColumnsAccessibleWrap::GetSelectedRowsCount(PRUint32* aCount)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsXULTreeColumnsAccessibleWrap::GetSelectedCells(PRUint32 *aNumCells,
-                                                 PRInt32 **aCells)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetSelectedColumns(PRUint32 *columnsSize, PRInt32 **columns)
-{
-  // Header can not be selected.
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetSelectedRows(PRUint32 *rowsSize, PRInt32 **rows)
-{
-  // Header can not be selected.
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::CellRefAt(PRInt32 aRow, PRInt32 aColumn, nsIAccessible **_retval)
-{
-  nsCOMPtr<nsIAccessible> next, temp;
-  GetFirstChild(getter_AddRefs(next));
-  NS_ENSURE_TRUE(next, NS_ERROR_FAILURE);
-
-  for (PRInt32 col = 0; col < aColumn; col++) {
-    next->GetNextSibling(getter_AddRefs(temp));
-    NS_ENSURE_TRUE(temp, NS_ERROR_FAILURE);
-
-    next = temp;
-  }
-
-  *_retval = next;
-  NS_IF_ADDREF(*_retval);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetIndexAt(PRInt32 aRow, PRInt32 aColumn, PRInt32 *_retval)
-{
-  NS_ENSURE_ARG_POINTER(_retval);
-
-  *_retval = aColumn;
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetColumnAtIndex(PRInt32 aIndex, PRInt32 *_retval)
-{
-  NS_ENSURE_ARG_POINTER(_retval);
-
-  *_retval = aIndex;
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetRowAtIndex(PRInt32 aIndex, PRInt32 *_retval)
-{
-  NS_ENSURE_ARG_POINTER(_retval);
-
-  *_retval = 0;
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetColumnExtentAt(PRInt32 aRow, PRInt32 aColumn, PRInt32 *_retval)
-{
-  NS_ENSURE_ARG_POINTER(_retval);
-
-  *_retval = 1;
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetRowExtentAt(PRInt32 aRow, PRInt32 aColumn, PRInt32 *_retval)
-{
-  NS_ENSURE_ARG_POINTER(_retval);
-
-  *_retval = 1;
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetColumnDescription(PRInt32 aColumn, nsAString & _retval)
-{
-  nsCOMPtr<nsIAccessible> column;  
-  nsresult rv = CellRefAt(0, aColumn, getter_AddRefs(column));
-  if (NS_SUCCEEDED(rv) && column) {
-    return column->GetName(_retval);
-  }
-  return NS_ERROR_FAILURE;
-}
-
-NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::GetRowDescription(PRInt32 aRow, nsAString & _retval)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::IsColumnSelected(PRInt32 aColumn, PRBool *_retval)
-{
-  // Header can not be selected.
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::IsRowSelected(PRInt32 aRow, PRBool *_retval)
-{
-  // Header can not be selected.
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::IsCellSelected(PRInt32 aRow, PRInt32 aColumn, PRBool *_retval)
-{
-  // Header can not be selected.
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsXULTreeColumnsAccessibleWrap::SelectRow(PRInt32 aRow)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsXULTreeColumnsAccessibleWrap::SelectColumn(PRInt32 aColumn)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsXULTreeColumnsAccessibleWrap::UnselectRow(PRInt32 aRow)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsXULTreeColumnsAccessibleWrap::UnselectColumn(PRInt32 aColumn)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP nsXULTreeColumnsAccessibleWrap::IsProbablyForLayout(PRBool *aIsProbablyForLayout)
-{
-  *aIsProbablyForLayout = PR_FALSE;
-  return NS_OK;
-}
rename from accessible/src/atk/nsXULTreeAccessibleWrap.h
rename to accessible/src/atk/nsXULTreeGridAccessibleWrap.h
--- a/accessible/src/atk/nsXULTreeAccessibleWrap.h
+++ b/accessible/src/atk/nsXULTreeGridAccessibleWrap.h
@@ -32,34 +32,18 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#ifndef __nsXULTreeAccessibleWrap_h__
-#define __nsXULTreeAccessibleWrap_h__
+#ifndef __nsXULTreeGridAccessibleWrap_h__
+#define __nsXULTreeGridAccessibleWrap_h__
 
 #include "nsXULTreeGridAccessible.h"
 
-class nsXULTreeGridAccessibleWrap : public nsXULTreeGridAccessible
-{
-public:
-  nsXULTreeGridAccessibleWrap(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
-
-  // nsIAccessibleTable
-  NS_IMETHOD GetColumnHeader(nsIAccessibleTable **aColumnHeader);
-  NS_IMETHOD GetColumnDescription(PRInt32 aColumn, nsAString& aDescription);
-};
-
-class nsXULTreeColumnsAccessibleWrap : public nsXULTreeColumnsAccessible,
-                                       public nsIAccessibleTable
-{
-public:
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSIACCESSIBLETABLE
-
-  nsXULTreeColumnsAccessibleWrap(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
-};
+typedef class nsXULTreeGridAccessible nsXULTreeGridAccessibleWrap;
+typedef class nsXULTreeGridCellAccessible nsXULTreeGridCellAccessibleWrap;
 
 #endif
+
--- a/accessible/src/base/nsARIAGridAccessible.cpp
+++ b/accessible/src/base/nsARIAGridAccessible.cpp
@@ -33,16 +33,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsARIAGridAccessible.h"
 
+#include "nsComponentManagerUtils.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsARIAGridAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // Constructor
@@ -84,160 +85,136 @@ nsARIAGridAccessible::GetSummary(nsAStri
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   // XXX: should be pointed by aria-describedby on grid?
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsARIAGridAccessible::GetColumns(PRInt32 *aColumns)
+nsARIAGridAccessible::GetColumnCount(PRInt32 *acolumnCount)
 {
-  NS_ENSURE_ARG_POINTER(aColumns);
-  *aColumns = 0;
+  NS_ENSURE_ARG_POINTER(acolumnCount);
+  *acolumnCount = 0;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIAccessible> row = GetNextRow();
   nsCOMPtr<nsIAccessible> cell;
   while ((cell = GetNextCellInRow(row, cell)))
-    (*aColumns)++;
+    (*acolumnCount)++;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsARIAGridAccessible::GetColumnHeader(nsIAccessibleTable **aColumnHeader)
+nsARIAGridAccessible::GetRowCount(PRInt32 *arowCount)
 {
-  NS_ENSURE_ARG_POINTER(aColumnHeader);
-  *aColumnHeader = nsnull;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  // XXX: what should we return here?
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsARIAGridAccessible::GetRows(PRInt32 *aRows)
-{
-  NS_ENSURE_ARG_POINTER(aRows);
-  *aRows = 0;
+  NS_ENSURE_ARG_POINTER(arowCount);
+  *arowCount = 0;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIAccessible> row;
   while ((row = GetNextRow(row)))
-    (*aRows)++;
+    (*arowCount)++;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsARIAGridAccessible::GetRowHeader(nsIAccessibleTable **aRowHeader)
-{
-  NS_ENSURE_ARG_POINTER(aRowHeader);
-  *aRowHeader = nsnull;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  // XXX: what should we return here?
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsARIAGridAccessible::CellRefAt(PRInt32 aRow, PRInt32 aColumn,
+nsARIAGridAccessible::GetCellAt(PRInt32 aRowIndex, PRInt32 aColumnIndex,
                                 nsIAccessible **aAccessible)
 {
   NS_ENSURE_ARG_POINTER(aAccessible);
   *aAccessible = nsnull;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsCOMPtr<nsIAccessible> row = GetRowAt(aRow);
+  nsCOMPtr<nsIAccessible> row = GetRowAt(aRowIndex);
   NS_ENSURE_ARG(row);
 
-  nsCOMPtr<nsIAccessible> cell = GetCellInRowAt(row, aColumn);
+  nsCOMPtr<nsIAccessible> cell = GetCellInRowAt(row, aColumnIndex);
   NS_ENSURE_ARG(cell);
 
   NS_ADDREF(*aAccessible = cell);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsARIAGridAccessible::GetIndexAt(PRInt32 aRow, PRInt32 aColumn, PRInt32 *aIndex)
+nsARIAGridAccessible::GetCellIndexAt(PRInt32 aRowIndex, PRInt32 aColumnIndex,
+                                     PRInt32 *aCellIndex)
 {
-  NS_ENSURE_ARG_POINTER(aIndex);
-  *aIndex = -1;
+  NS_ENSURE_ARG_POINTER(aCellIndex);
+  *aCellIndex = -1;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  NS_ENSURE_ARG(aRow >= 0 && aColumn >= 0);
+  NS_ENSURE_ARG(aRowIndex >= 0 && aColumnIndex >= 0);
 
   PRInt32 rowCount = 0;
-  GetRows(&rowCount);
-  NS_ENSURE_ARG(aRow < rowCount);
+  GetRowCount(&rowCount);
+  NS_ENSURE_ARG(aRowIndex < rowCount);
 
-  PRInt32 colCount = 0;
-  GetColumns(&colCount);
-  NS_ENSURE_ARG(aColumn < colCount);
+  PRInt32 colsCount = 0;
+  GetColumnCount(&colsCount);
+  NS_ENSURE_ARG(aColumnIndex < colsCount);
 
-  *aIndex = colCount * aRow + aColumn;
+  *aCellIndex = colsCount * aRowIndex + aColumnIndex;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsARIAGridAccessible::GetColumnAtIndex(PRInt32 aIndex, PRInt32 *aColumn)
+nsARIAGridAccessible::GetColumnIndexAt(PRInt32 aCellIndex,
+                                       PRInt32 *aColumnIndex)
 {
-  NS_ENSURE_ARG_POINTER(aColumn);
-  *aColumn = -1;
+  NS_ENSURE_ARG_POINTER(aColumnIndex);
+  *aColumnIndex = -1;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  NS_ENSURE_ARG(aIndex >= 0);
+  NS_ENSURE_ARG(aCellIndex >= 0);
 
   PRInt32 rowCount = 0;
-  GetRows(&rowCount);
-  
-  PRInt32 colCount = 0;
-  GetColumns(&colCount);
+  GetRowCount(&rowCount);
 
-  NS_ENSURE_ARG(aIndex < rowCount * colCount);
+  PRInt32 colsCount = 0;
+  GetColumnCount(&colsCount);
 
-  *aColumn = aIndex % colCount;
+  NS_ENSURE_ARG(aCellIndex < rowCount * colsCount);
+
+  *aColumnIndex = aCellIndex % colsCount;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsARIAGridAccessible::GetRowAtIndex(PRInt32 aIndex, PRInt32 *aRow)
+nsARIAGridAccessible::GetRowIndexAt(PRInt32 aCellIndex, PRInt32 *aRowIndex)
 {
-  NS_ENSURE_ARG_POINTER(aRow);
-  *aRow = -1;
+  NS_ENSURE_ARG_POINTER(aRowIndex);
+  *aRowIndex = -1;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  NS_ENSURE_ARG(aIndex >= 0);
+  NS_ENSURE_ARG(aCellIndex >= 0);
 
   PRInt32 rowCount = 0;
-  GetRows(&rowCount);
+  GetRowCount(&rowCount);
 
-  PRInt32 colCount = 0;
-  GetColumns(&colCount);
+  PRInt32 colsCount = 0;
+  GetColumnCount(&colsCount);
 
-  NS_ENSURE_ARG(aIndex < rowCount * colCount);
+  NS_ENSURE_ARG(aCellIndex < rowCount * colsCount);
 
-  *aRow = aIndex / colCount;
+  *aRowIndex = aCellIndex / colsCount;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsARIAGridAccessible::GetColumnExtentAt(PRInt32 aRow, PRInt32 aColumn,
                                         PRInt32 *aExtentCount)
 {
   NS_ENSURE_ARG_POINTER(aExtentCount);
@@ -308,22 +285,22 @@ nsARIAGridAccessible::IsColumnSelected(P
 
   NS_ENSURE_ARG(IsValidColumn(aColumn));
 
   nsCOMPtr<nsIAccessible> row = GetNextRow();
   if (!row)
     return NS_OK;
 
   do {
-    if (!IsARIASelected(row)) {
+    if (!nsAccUtils::IsARIASelected(row)) {
       nsCOMPtr<nsIAccessible> cell = GetCellInRowAt(row, aColumn);
       if (!cell) // Do not fail due to wrong markup
         return NS_OK;
       
-      if (!IsARIASelected(cell))
+      if (!nsAccUtils::IsARIASelected(cell))
         return NS_OK;
     }
   } while ((row = GetNextRow(row)));
 
   *aIsSelected = PR_TRUE;
   return NS_OK;
 }
 
@@ -334,20 +311,20 @@ nsARIAGridAccessible::IsRowSelected(PRIn
   *aIsSelected = PR_FALSE;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIAccessible> row = GetRowAt(aRow);
   NS_ENSURE_ARG(row);
 
-  if (!IsARIASelected(row)) {
+  if (!nsAccUtils::IsARIASelected(row)) {
     nsCOMPtr<nsIAccessible> cell;
     while ((cell = GetNextCellInRow(row, cell))) {
-      if (!IsARIASelected(cell))
+      if (!nsAccUtils::IsARIASelected(cell))
         return NS_OK;
     }
   }
 
   *aIsSelected = PR_TRUE;
   return NS_OK;
 }
 
@@ -359,129 +336,165 @@ nsARIAGridAccessible::IsCellSelected(PRI
   *aIsSelected = PR_FALSE;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIAccessible> row(GetRowAt(aRow));
   NS_ENSURE_ARG(row);
 
-  if (!IsARIASelected(row)) {
+  if (!nsAccUtils::IsARIASelected(row)) {
     nsCOMPtr<nsIAccessible> cell(GetCellInRowAt(row, aColumn));
     NS_ENSURE_ARG(cell);
 
-    if (!IsARIASelected(cell))
+    if (!nsAccUtils::IsARIASelected(cell))
       return NS_OK;
   }
 
   *aIsSelected = PR_TRUE;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsARIAGridAccessible::GetSelectedCellsCount(PRUint32* aCount)
+nsARIAGridAccessible::GetSelectedCellCount(PRUint32* aCount)
 {
   NS_ENSURE_ARG_POINTER(aCount);
   *aCount = 0;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   PRInt32 colCount = 0;
-  GetColumns(&colCount);
+  GetColumnCount(&colCount);
   
   nsCOMPtr<nsIAccessible> row;
   while ((row = GetNextRow(row))) {
-    if (IsARIASelected(row)) {
+    if (nsAccUtils::IsARIASelected(row)) {
       (*aCount) += colCount;
       continue;
     }
 
     nsCOMPtr<nsIAccessible> cell;
     while ((cell = GetNextCellInRow(row, cell))) {
-      if (IsARIASelected(cell))
+      if (nsAccUtils::IsARIASelected(cell))
         (*aCount)++;
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsARIAGridAccessible::GetSelectedColumnsCount(PRUint32* aCount)
+nsARIAGridAccessible::GetSelectedColumnCount(PRUint32* aCount)
 {
   return GetSelectedColumnsArray(aCount);
 }
 
 NS_IMETHODIMP
-nsARIAGridAccessible::GetSelectedRowsCount(PRUint32* aCount)
+nsARIAGridAccessible::GetSelectedRowCount(PRUint32* aCount)
 {
   NS_ENSURE_ARG_POINTER(aCount);
   *aCount = 0;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIAccessible> row;
   while ((row = GetNextRow(row))) {
-    if (IsARIASelected(row)) {
+    if (nsAccUtils::IsARIASelected(row)) {
       (*aCount)++;
       continue;
     }
 
     nsCOMPtr<nsIAccessible> cell = GetNextCellInRow(row);
     if (!cell)
       continue;
 
     PRBool isRowSelected = PR_TRUE;
     do {
-      if (!IsARIASelected(cell)) {
+      if (!nsAccUtils::IsARIASelected(cell)) {
         isRowSelected = PR_FALSE;
         break;
       }
     } while ((cell = GetNextCellInRow(row, cell)));
 
     if (isRowSelected)
       (*aCount)++;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsARIAGridAccessible::GetSelectedCells(PRUint32 *aCellsCount, PRInt32 **aCells)
+nsARIAGridAccessible::GetSelectedCells(nsIArray **aCells)
+{
+  NS_ENSURE_ARG_POINTER(aCells);
+  *aCells = nsnull;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsresult rv = NS_OK;
+  nsCOMPtr<nsIMutableArray> selCells =
+    do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCOMPtr<nsIAccessible> row;
+  while (row = GetNextRow(row)) {
+    if (nsAccUtils::IsARIASelected(row)) {
+      nsCOMPtr<nsIAccessible> cell;
+      while (cell = GetNextCellInRow(row, cell))
+        selCells->AppendElement(cell, PR_FALSE);
+
+      continue;
+    }
+
+    nsCOMPtr<nsIAccessible> cell;
+    while (cell = GetNextCellInRow(row, cell)) {
+      if (nsAccUtils::IsARIASelected(cell))
+        selCells->AppendElement(cell, PR_FALSE);
+    }
+  }
+
+  NS_ADDREF(*aCells = selCells);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsARIAGridAccessible::GetSelectedCellIndices(PRUint32 *aCellsCount,
+                                             PRInt32 **aCells)
 {
   NS_ENSURE_ARG_POINTER(aCellsCount);
   *aCellsCount = 0;
   NS_ENSURE_ARG_POINTER(aCells);
   *aCells = nsnull;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   PRInt32 rowCount = 0;
-  GetRows(&rowCount);
+  GetRowCount(&rowCount);
 
   PRInt32 colCount = 0;
-  GetColumns(&colCount);
+  GetColumnCount(&colCount);
 
   nsTArray<PRInt32> selCells(rowCount * colCount);
 
   nsCOMPtr<nsIAccessible> row;
   for (PRInt32 rowIdx = 0; row = GetNextRow(row); rowIdx++) {
-    if (IsARIASelected(row)) {
+    if (nsAccUtils::IsARIASelected(row)) {
       for (PRInt32 colIdx = 0; colIdx < colCount; colIdx++)
         selCells.AppendElement(rowIdx * colCount + colIdx);
 
       continue;
     }
 
     nsCOMPtr<nsIAccessible> cell;
     for (PRInt32 colIdx = 0; cell = GetNextCellInRow(row, cell); colIdx++) {
-      if (IsARIASelected(cell))
+      if (nsAccUtils::IsARIASelected(cell))
         selCells.AppendElement(rowIdx * colCount + colIdx);
     }
   }
 
   PRUint32 selCellsCount = selCells.Length();
   if (!selCellsCount)
     return NS_OK;
 
@@ -489,74 +502,75 @@ nsARIAGridAccessible::GetSelectedCells(P
     nsMemory::Clone(selCells.Elements(), selCellsCount * sizeof(PRInt32)));
   NS_ENSURE_TRUE(*aCells, NS_ERROR_OUT_OF_MEMORY);
 
   *aCellsCount = selCellsCount;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsARIAGridAccessible::GetSelectedColumns(PRUint32 *aColumnsCount,
-                                         PRInt32 **aColumns)
+nsARIAGridAccessible::GetSelectedColumnIndices(PRUint32 *acolumnCount,
+                                               PRInt32 **aColumns)
 {
   NS_ENSURE_ARG_POINTER(aColumns);
 
-  return GetSelectedColumnsArray(aColumnsCount, aColumns);
+  return GetSelectedColumnsArray(acolumnCount, aColumns);
 }
 
 NS_IMETHODIMP
-nsARIAGridAccessible::GetSelectedRows(PRUint32 *aRowsCount, PRInt32 **aRows)
+nsARIAGridAccessible::GetSelectedRowIndices(PRUint32 *arowCount,
+                                            PRInt32 **aRows)
 {
-  NS_ENSURE_ARG_POINTER(aRowsCount);
-  *aRowsCount = 0;
+  NS_ENSURE_ARG_POINTER(arowCount);
+  *arowCount = 0;
   NS_ENSURE_ARG_POINTER(aRows);
   *aRows = nsnull;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   PRInt32 rowCount = 0;
-  GetRows(&rowCount);
+  GetRowCount(&rowCount);
   if (!rowCount)
     return NS_OK;
 
   nsTArray<PRInt32> selRows(rowCount);
 
   nsCOMPtr<nsIAccessible> row;
   for (PRInt32 rowIdx = 0; row = GetNextRow(row); rowIdx++) {
-    if (IsARIASelected(row)) {
+    if (nsAccUtils::IsARIASelected(row)) {
       selRows.AppendElement(rowIdx);
       continue;
     }
 
     nsCOMPtr<nsIAccessible> cell = GetNextCellInRow(row);
     if (!cell)
       continue;
 
     PRBool isRowSelected = PR_TRUE;
     do {
-      if (!IsARIASelected(cell)) {
+      if (!nsAccUtils::IsARIASelected(cell)) {
         isRowSelected = PR_FALSE;
         break;
       }
     } while ((cell = GetNextCellInRow(row, cell)));
 
     if (isRowSelected)
       selRows.AppendElement(rowIdx);
   }
 
-  PRUint32 selRowsCount = selRows.Length();
-  if (!selRowsCount)
+  PRUint32 selrowCount = selRows.Length();
+  if (!selrowCount)
     return NS_OK;
 
   *aRows = static_cast<PRInt32*>(
-    nsMemory::Clone(selRows.Elements(), selRowsCount * sizeof(PRInt32)));
+    nsMemory::Clone(selRows.Elements(), selrowCount * sizeof(PRInt32)));
   NS_ENSURE_TRUE(*aRows, NS_ERROR_OUT_OF_MEMORY);
 
-  *aRowsCount = selRowsCount;
+  *arowCount = selrowCount;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsARIAGridAccessible::SelectRow(PRInt32 aRow)
 {
   NS_ENSURE_ARG(IsValidRow(aRow));
 
@@ -643,44 +657,44 @@ nsARIAGridAccessible::IsProbablyForLayou
 
 PRBool
 nsARIAGridAccessible::IsValidRow(PRInt32 aRow)
 {
   if (aRow < 0)
     return PR_FALSE;
   
   PRInt32 rowCount = 0;
-  GetRows(&rowCount);
+  GetRowCount(&rowCount);
   return aRow < rowCount;
 }
 
 PRBool
 nsARIAGridAccessible::IsValidColumn(PRInt32 aColumn)
 {
   if (aColumn < 0)
     return PR_FALSE;
 
   PRInt32 colCount = 0;
-  GetColumns(&colCount);
+  GetColumnCount(&colCount);
   return aColumn < colCount;
 }
 
 PRBool
 nsARIAGridAccessible::IsValidRowNColumn(PRInt32 aRow, PRInt32 aColumn)
 {
   if (aRow < 0 || aColumn < 0)
     return PR_FALSE;
   
   PRInt32 rowCount = 0;
-  GetRows(&rowCount);
+  GetRowCount(&rowCount);
   if (aRow >= rowCount)
     return PR_FALSE;
 
   PRInt32 colCount = 0;
-  GetColumns(&colCount);
+  GetColumnCount(&colCount);
   return aColumn < colCount;
 }
 
 already_AddRefed<nsIAccessible>
 nsARIAGridAccessible::GetRowAt(PRInt32 aRow)
 {
   PRInt32 rowIdx = aRow;
   nsCOMPtr<nsIAccessible> row(GetNextRow());
@@ -742,35 +756,16 @@ nsARIAGridAccessible::GetNextCellInRow(n
 
     nextCell->GetNextSibling(getter_AddRefs(tmpAcc));
     tmpAcc.swap(nextCell);
   }
 
   return nsnull;
 }
 
-PRBool
-nsARIAGridAccessible::IsARIASelected(nsIAccessible *aAccessible)
-{
-  nsRefPtr<nsAccessible> acc = nsAccUtils::QueryAccessible(aAccessible);
-  nsCOMPtr<nsIDOMNode> node;
-  acc->GetDOMNode(getter_AddRefs(node));
-  NS_ASSERTION(node, "No DOM node!");
-
-  if (node) {
-    nsCOMPtr<nsIContent> content(do_QueryInterface(node));
-    if (content->AttrValueIs(kNameSpaceID_None,
-                             nsAccessibilityAtoms::aria_selected,
-                             nsAccessibilityAtoms::_true, eCaseMatters))
-      return PR_TRUE;
-  }
-
-  return PR_FALSE;
-}
-
 nsresult
 nsARIAGridAccessible::SetARIASelected(nsIAccessible *aAccessible,
                                       PRBool aIsSelected, PRBool aNotify)
 {
   nsRefPtr<nsAccessible> acc = nsAccUtils::QueryAccessible(aAccessible);
   nsCOMPtr<nsIDOMNode> node;
   acc->GetDOMNode(getter_AddRefs(node));
   NS_ENSURE_STATE(node);
@@ -815,17 +810,17 @@ nsARIAGridAccessible::SetARIASelected(ns
   // siblings cells.
   if (role == nsIAccessibleRole::ROLE_GRID_CELL ||
       role == nsIAccessibleRole::ROLE_ROWHEADER ||
       role == nsIAccessibleRole::ROLE_COLUMNHEADER) {
     nsCOMPtr<nsIAccessible> row;
     aAccessible->GetParent(getter_AddRefs(row));
 
     if (nsAccUtils::Role(row) == nsIAccessibleRole::ROLE_ROW &&
-        IsARIASelected(row)) {
+        nsAccUtils::IsARIASelected(row)) {
       rv = SetARIASelected(row, PR_FALSE, PR_FALSE);
       NS_ENSURE_SUCCESS(rv, rv);
 
       nsCOMPtr<nsIAccessible> cell;
       while ((cell = GetNextCellInRow(row, cell))) {
         if (cell != aAccessible) {
           rv = SetARIASelected(cell, PR_TRUE, PR_FALSE);
           NS_ENSURE_SUCCESS(rv, rv);
@@ -833,71 +828,71 @@ nsARIAGridAccessible::SetARIASelected(ns
       }
     }
   }
 
   return NS_OK;
 }
 
 nsresult
-nsARIAGridAccessible::GetSelectedColumnsArray(PRUint32 *aColumnsCount,
+nsARIAGridAccessible::GetSelectedColumnsArray(PRUint32 *acolumnCount,
                                               PRInt32 **aColumns)
 {
-  NS_ENSURE_ARG_POINTER(aColumnsCount);
-  *aColumnsCount = 0;
+  NS_ENSURE_ARG_POINTER(acolumnCount);
+  *acolumnCount = 0;
   if (aColumns)
     *aColumns = nsnull;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIAccessible> row = GetNextRow();
   if (!row)
     return NS_OK;
 
   PRInt32 colCount = 0;
-  GetColumns(&colCount);
+  GetColumnCount(&colCount);
   if (!colCount)
     return NS_OK;
 
   PRInt32 selColCount = colCount;
 
   nsTArray<PRBool> isColSelArray(selColCount);
   isColSelArray.AppendElements(selColCount);
   for (PRInt32 i = 0; i < selColCount; i++)
     isColSelArray[i] = PR_TRUE;
 
   do {
-    if (IsARIASelected(row))
+    if (nsAccUtils::IsARIASelected(row))
       continue;
 
     PRInt32 colIdx = 0;
     nsCOMPtr<nsIAccessible> cell;
     for (colIdx = 0; cell = GetNextCellInRow(row, cell); colIdx++) {
       if (isColSelArray.SafeElementAt(colIdx, PR_FALSE) &&
-          !IsARIASelected(cell)) {
+          !nsAccUtils::IsARIASelected(cell)) {
         isColSelArray[colIdx] = PR_FALSE;
         selColCount--;
       }
     }
   } while ((row = GetNextRow(row)));
 
   if (!selColCount)
     return NS_OK;
 
   if (!aColumns) {
-    *aColumnsCount = selColCount;
+    *acolumnCount = selColCount;
     return NS_OK;
   }
 
   *aColumns = static_cast<PRInt32*>(
     nsMemory::Alloc(selColCount * sizeof(PRInt32)));
   NS_ENSURE_TRUE(*aColumns, NS_ERROR_OUT_OF_MEMORY);
 
-  *aColumnsCount = selColCount;
+  *acolumnCount = selColCount;
   for (PRInt32 colIdx = 0, idx = 0; colIdx < colCount; colIdx++) {
     if (isColSelArray[colIdx])
       (*aColumns)[idx++] = colIdx;
   }
 
   return NS_OK;
 }
 
@@ -914,18 +909,179 @@ nsARIAGridCellAccessible::nsARIAGridCell
                                                    nsIWeakReference* aShell) :
   nsHyperTextAccessibleWrap(aDomNode, aShell)
 {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsISupports
 
-NS_IMPL_ISUPPORTS_INHERITED0(nsARIAGridCellAccessible,
-                             nsHyperTextAccessible)
+NS_IMPL_ISUPPORTS_INHERITED1(nsARIAGridCellAccessible,
+                             nsHyperTextAccessible,
+                             nsIAccessibleTableCell)
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIAccessibleTableCell
+
+NS_IMETHODIMP
+nsARIAGridCellAccessible::GetTable(nsIAccessibleTable **aTable)
+{
+  NS_ENSURE_ARG_POINTER(aTable);
+  *aTable = nsnull;
+
+  nsCOMPtr<nsIAccessible> thisRow;
+  GetParent(getter_AddRefs(thisRow));
+  if (nsAccUtils::Role(thisRow) != nsIAccessibleRole::ROLE_ROW)
+    return NS_OK;
+
+  nsCOMPtr<nsIAccessible> table;
+  thisRow->GetParent(getter_AddRefs(table));
+  if (nsAccUtils::Role(table) != nsIAccessibleRole::ROLE_TABLE &&
+      nsAccUtils::Role(table) != nsIAccessibleRole::ROLE_TREE_TABLE)
+    return NS_OK;
+
+  CallQueryInterface(table, aTable);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsARIAGridCellAccessible::GetColumnIndex(PRInt32 *aColumnIndex)
+{
+  NS_ENSURE_ARG_POINTER(aColumnIndex);
+  *aColumnIndex = -1;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  *aColumnIndex = 0;
+
+  nsCOMPtr<nsIAccessible> prevCell, tmpAcc;
+  GetPreviousSibling(getter_AddRefs(prevCell));
+
+  while (prevCell) {
+    PRUint32 role = nsAccUtils::Role(prevCell);
+    if (role == nsIAccessibleRole::ROLE_GRID_CELL ||
+        role == nsIAccessibleRole::ROLE_ROWHEADER ||
+        role == nsIAccessibleRole::ROLE_COLUMNHEADER)
+      (*aColumnIndex)++;
+
+    prevCell->GetPreviousSibling(getter_AddRefs(tmpAcc));
+    tmpAcc.swap(prevCell);
+  }
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsARIAGridCellAccessible::GetRowIndex(PRInt32 *aRowIndex)
+{
+  NS_ENSURE_ARG_POINTER(aRowIndex);
+  *aRowIndex = -1;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsCOMPtr<nsIAccessible> row, prevRow;
+  GetParent(getter_AddRefs(row));
+
+  while (row) {
+    if (nsAccUtils::Role(row) == nsIAccessibleRole::ROLE_ROW)
+      (*aRowIndex)++;
+
+    row->GetPreviousSibling(getter_AddRefs(prevRow));
+    row.swap(prevRow);
+  }
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsARIAGridCellAccessible::GetColumnExtent(PRInt32 *aExtentCount)
+{
+  NS_ENSURE_ARG_POINTER(aExtentCount);
+  *aExtentCount = 0;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  *aExtentCount = 1;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsARIAGridCellAccessible::GetRowExtent(PRInt32 *aExtentCount)
+{
+  NS_ENSURE_ARG_POINTER(aExtentCount);
+  *aExtentCount = 0;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  *aExtentCount = 1;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsARIAGridCellAccessible::GetColumnHeaderCells(nsIArray **aHeaderCells)
+{
+  NS_ENSURE_ARG_POINTER(aHeaderCells);
+  *aHeaderCells = nsnull;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsCOMPtr<nsIAccessibleTable> table;
+  GetTable(getter_AddRefs(table));
+  if (!table)
+    return NS_OK;
+
+  return nsAccUtils::GetHeaderCellsFor(table, this,
+                                       nsAccUtils::eColumnHeaderCells,
+                                       aHeaderCells);
+}
+
+NS_IMETHODIMP
+nsARIAGridCellAccessible::GetRowHeaderCells(nsIArray **aHeaderCells)
+{
+  NS_ENSURE_ARG_POINTER(aHeaderCells);
+  *aHeaderCells = nsnull;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsCOMPtr<nsIAccessibleTable> table;
+  GetTable(getter_AddRefs(table));
+  if (!table)
+    return NS_OK;
+
+  return nsAccUtils::GetHeaderCellsFor(table, this,
+                                       nsAccUtils::eRowHeaderCells,
+                                       aHeaderCells);
+}
+
+NS_IMETHODIMP
+nsARIAGridCellAccessible::IsSelected(PRBool *aIsSelected)
+{
+  NS_ENSURE_ARG_POINTER(aIsSelected);
+  *aIsSelected = PR_FALSE;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsCOMPtr<nsIAccessible> row;
+  GetParent(getter_AddRefs(row));
+  if (nsAccUtils::Role(row) != nsIAccessibleRole::ROLE_ROW)
+    return NS_OK;
+
+  if (!nsAccUtils::IsARIASelected(row) && !nsAccUtils::IsARIASelected(this))
+    return NS_OK;
+
+  *aIsSelected = PR_TRUE;
+  return NS_OK;
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessible
 
 nsresult
 nsARIAGridCellAccessible::GetARIAState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   nsresult rv = nsHyperTextAccessibleWrap::GetARIAState(aState, aExtraState);
--- a/accessible/src/base/nsARIAGridAccessible.h
+++ b/accessible/src/base/nsARIAGridAccessible.h
@@ -99,49 +99,47 @@ protected:
    *
    * @param  aRow   [in] row accessible
    * @param  aCell  [in, optional] cell accessible
    */
   already_AddRefed<nsIAccessible> GetNextCellInRow(nsIAccessible *aRow,
                                                    nsIAccessible *aCell = nsnull);
 
   /**
-   * Return true if the DOM node of given accessible has aria-selected="true"
-   * attribute.
-   */
-  PRBool IsARIASelected(nsIAccessible *aAccessible);
-
-  /**
    * Set aria-selected attribute value on DOM node of the given accessible.
    *
    * @param  aAccessible  [in] accessible
    * @param  aIsSelected  [in] new value of aria-selected attribute
    * @param  aNotify      [in, optional] specifies if DOM should be notified
    *                       about attribute change (used internally).
    */
   nsresult SetARIASelected(nsIAccessible *aAccessible, PRBool aIsSelected,
                            PRBool aNotify = PR_TRUE);
 
   /**
-   * Helper method for GetSelectedColumnsCount and GetSelectedColumns.
+   * Helper method for GetSelectedColumnCount and GetSelectedColumns.
    */
-  nsresult GetSelectedColumnsArray(PRUint32 *aColumnsCount,
+  nsresult GetSelectedColumnsArray(PRUint32 *acolumnCount,
                                    PRInt32 **aColumns = nsnull);
 };
 
 
 /**
  * Accessible for ARIA gridcell and rowheader/columnheader.
  */
-class nsARIAGridCellAccessible : public nsHyperTextAccessibleWrap
+class nsARIAGridCellAccessible : public nsHyperTextAccessibleWrap,
+                                 public nsIAccessibleTableCell
 {
 public:
   nsARIAGridCellAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
+  // nsIAccessibleTableCell
+  NS_DECL_NSIACCESSIBLETABLECELL
+
   // nsAccessible
   virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState);
   virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
 };
 
 #endif
--- a/accessible/src/base/nsAccUtils.cpp
+++ b/accessible/src/base/nsAccUtils.cpp
@@ -51,16 +51,17 @@
 #include "nsAccessible.h"
 #include "nsARIAMap.h"
 #include "nsXULTreeGridAccessible.h"
 
 #include "nsIDOMXULContainerElement.h"
 #include "nsIDOMXULSelectCntrlEl.h"
 #include "nsIDOMXULSelectCntrlItemEl.h"
 #include "nsWhitespaceTokenizer.h"
+#include "nsComponentManagerUtils.h"
 
 void
 nsAccUtils::GetAccAttr(nsIPersistentProperties *aAttributes,
                        nsIAtom *aAttrName, nsAString& aAttrValue)
 {
   aAttrValue.Truncate();
 
   nsCAutoString attrName;
@@ -473,16 +474,35 @@ nsAccUtils::GetARIATreeItemParent(nsIAcc
     role = nsAccUtils::Role(prevAccessible);
   }
   if (role == nsIAccessibleRole::ROLE_OUTLINEITEM) {
     // Previous sibling of parent group is a tree item -- this is the conceptual tree item parent
     NS_ADDREF(*aTreeItemParentResult = prevAccessible);
   }
 }
 
+PRBool
+nsAccUtils::IsARIASelected(nsIAccessible *aAccessible)
+{
+  nsRefPtr<nsAccessible> acc = nsAccUtils::QueryAccessible(aAccessible);
+  nsCOMPtr<nsIDOMNode> node;
+  acc->GetDOMNode(getter_AddRefs(node));
+  NS_ASSERTION(node, "No DOM node!");
+
+  if (node) {
+    nsCOMPtr<nsIContent> content(do_QueryInterface(node));
+    if (content->AttrValueIs(kNameSpaceID_None,
+                             nsAccessibilityAtoms::aria_selected,
+                             nsAccessibilityAtoms::_true, eCaseMatters))
+      return PR_TRUE;
+  }
+
+  return PR_FALSE;
+}
+
 already_AddRefed<nsIAccessibleText>
 nsAccUtils::GetTextAccessibleFromSelection(nsISelection *aSelection,
                                            nsIDOMNode **aNode)
 {
   // Get accessible from selection's focus DOM point (the DOM point where
   // selection is ended).
 
   nsCOMPtr<nsIDOMNode> focusNode;
@@ -643,17 +663,20 @@ nsAccUtils::GetScreenCoordsForParent(nsI
   return nsIntPoint(parentRect.x, parentRect.y);
 }
 
 nsRoleMapEntry*
 nsAccUtils::GetRoleMapEntry(nsIDOMNode *aNode)
 {
   nsIContent *content = nsCoreUtils::GetRoleContent(aNode);
   nsAutoString roleString;
-  if (!content || !content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::role, roleString)) {
+  if (!content ||
+      !content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::role, roleString) ||
+      roleString.IsEmpty()) {
+    // We treat role="" as if the role attribute is absent (per aria spec:8.1.1)
     return nsnull;
   }
 
   nsWhitespaceTokenizer tokenizer(roleString);
   while (tokenizer.hasMoreTokens()) {
     // Do a binary search through table for the next role in role list
     NS_LossyConvertUTF16toASCII role(tokenizer.nextToken());
     PRUint32 low = 0;
@@ -669,17 +692,17 @@ nsAccUtils::GetRoleMapEntry(nsIDOMNode *
         high = index;
       }
       else {
         low = index + 1;
       }
     }
   }
 
-  // Always use some entry if there is a role string
+  // Always use some entry if there is a non-empty role string
   // To ensure an accessible object is created
   return &nsARIAMap::gLandmarkRoleMap;
 }
 
 PRUint32
 nsAccUtils::RoleInternal(nsIAccessible *aAcc)
 {
   PRUint32 role = nsIAccessibleRole::ROLE_NOTHING;
@@ -701,27 +724,29 @@ nsAccUtils::GetAttributeCharacteristics(
 {
     for (PRUint32 i = 0; i < nsARIAMap::gWAIUnivAttrMapLength; i++)
       if (*nsARIAMap::gWAIUnivAttrMap[i].attributeName == aAtom)
         return nsARIAMap::gWAIUnivAttrMap[i].characteristics;
 
     return 0;
 }
 
-void
+PRBool
 nsAccUtils::GetLiveAttrValue(PRUint32 aRule, nsAString& aValue)
 {
   switch (aRule) {
     case eOffLiveAttr:
       aValue = NS_LITERAL_STRING("off");
-      break;
+      return PR_TRUE;
     case ePoliteLiveAttr:
       aValue = NS_LITERAL_STRING("polite");
-      break;
+      return PR_TRUE;
   }
+
+  return PR_FALSE;
 }
 
 already_AddRefed<nsAccessible>
 nsAccUtils::QueryAccessible(nsIAccessible *aAccessible)
 {
   nsAccessible* acc = nsnull;
   if (aAccessible)
     CallQueryInterface(aAccessible, &acc);
@@ -902,8 +927,63 @@ nsAccUtils::GetMultiSelectFor(nsIDOMNode
     }
     state = State(accessible);
   }
 
   nsIAccessible *returnAccessible = nsnull;
   accessible.swap(returnAccessible);
   return returnAccessible;
 }
+
+nsresult
+nsAccUtils::GetHeaderCellsFor(nsIAccessibleTable *aTable,
+                              nsIAccessibleTableCell *aCell,
+                              PRInt32 aRowOrColHeaderCells, nsIArray **aCells)
+{
+  nsresult rv = NS_OK;
+  nsCOMPtr<nsIMutableArray> cells = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRInt32 rowIdx = -1;
+  rv = aCell->GetRowIndex(&rowIdx);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRInt32 colIdx = -1;
+  rv = aCell->GetColumnIndex(&colIdx);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRBool moveToLeft = aRowOrColHeaderCells == eRowHeaderCells;
+
+  // Move to the left or top to find row header cells or column header cells.
+  PRInt32 index = (moveToLeft ? colIdx : rowIdx) - 1;
+  for (; index >= 0; index--) {
+    PRInt32 curRowIdx = moveToLeft ? rowIdx : index;
+    PRInt32 curColIdx = moveToLeft ? index : colIdx;
+
+    nsCOMPtr<nsIAccessible> cell;
+    rv = aTable->GetCellAt(curRowIdx, curColIdx, getter_AddRefs(cell));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    nsCOMPtr<nsIAccessibleTableCell> tableCellAcc =
+      do_QueryInterface(cell);
+
+    PRInt32 origIdx = 1;
+    if (moveToLeft)
+      rv = tableCellAcc->GetColumnIndex(&origIdx);
+    else
+      rv = tableCellAcc->GetRowIndex(&origIdx);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    if (origIdx == index) {
+      // Append original header cells only.
+      PRUint32 role = Role(cell);
+      PRBool isHeader = moveToLeft ?
+        role == nsIAccessibleRole::ROLE_ROWHEADER :
+        role == nsIAccessibleRole::ROLE_COLUMNHEADER;
+
+      if (isHeader)
+        cells->AppendElement(cell, PR_FALSE);
+    }
+  }
+
+  NS_ADDREF(*aCells = cells);
+  return NS_OK;
+}
--- a/accessible/src/base/nsAccUtils.h
+++ b/accessible/src/base/nsAccUtils.h
@@ -175,16 +175,22 @@ public:
      * @param The tree item's parent, or null if none
      */
    static void
      GetARIATreeItemParent(nsIAccessible *aStartTreeItem,
                            nsIContent *aStartTreeItemContent,
                            nsIAccessible **aTreeItemParent);
 
   /**
+   * Return true if the DOM node of given accessible has aria-selected="true"
+   * attribute.
+   */
+  static PRBool IsARIASelected(nsIAccessible *aAccessible);
+
+  /**
    * Return text accessible containing focus point of the given selection.
    * Used for normal and misspelling selection changes processing.
    *
    * @param aSelection  [in] the given selection
    * @param aNode       [out, optional] the DOM node of text accessible
    * @return            text accessible
    */
   static already_AddRefed<nsIAccessibleText>
@@ -278,20 +284,25 @@ public:
    * 
    * @param aAtom  ARIA attribute
    * @return       A bitflag representing the attribute characteristics
    *               (see nsARIAMap.h for possible bit masks, prefixed "ARIA_")
    */
   static PRUint8 GetAttributeCharacteristics(nsIAtom* aAtom);
 
   /**
-   * Return the 'live' or 'container-live' object attribute value from the given
+   * Get the 'live' or 'container-live' object attribute value from the given
    * ELiveAttrRule constant.
+   *
+   * @param  aRule   [in] rule constant (see ELiveAttrRule in nsAccMap.h)
+   * @param  aValue  [out] object attribute value
+   *
+   * @return         true if object attribute should be exposed
    */
-  static void GetLiveAttrValue(PRUint32 aRule, nsAString& aValue);
+  static PRBool GetLiveAttrValue(PRUint32 aRule, nsAString& aValue);
 
   /**
    * Query DestinationType from the given SourceType.
    */
   template<class DestinationType, class SourceType> static inline
     already_AddRefed<DestinationType> QueryObject(SourceType *aObject)
   {
     DestinationType* object = nsnull;
@@ -419,21 +430,21 @@ public:
     return role != nsIAccessibleRole::ROLE_TEXT_LEAF &&
            role != nsIAccessibleRole::ROLE_WHITESPACE &&
            role != nsIAccessibleRole::ROLE_STATICTEXT;
   }
 
   /**
    * Return true if the given accessible hasn't children.
    */
-  static PRBool IsLeaf(nsIAccessible *aAcc)
+  static inline PRBool IsLeaf(nsIAccessible *aAcc)
   {
-    PRInt32 numChildren;
+    PRInt32 numChildren = 0;
     aAcc->GetChildCount(&numChildren);
-    return numChildren > 0;
+    return numChildren == 0;
   }
 
   /**
    * Return true if the given accessible can't have children. Used when exposing
    * to platform accessibility APIs, should the children be pruned off?
    */
   static PRBool MustPrune(nsIAccessible *aAccessible);
 
@@ -442,11 +453,37 @@ public:
    * the document's accessible tree.
    */
   static PRBool IsNodeRelevant(nsIDOMNode *aNode);
 
   /**
    * Return multiselectable parent for the given selectable accessible if any.
    */
   static already_AddRefed<nsIAccessible> GetMultiSelectFor(nsIDOMNode *aNode);
+
+  /**
+   * Search hint enum constants. Used by GetHeaderCellsFor() method.
+   */
+  enum {
+    // search for row header cells, left direction
+    eRowHeaderCells,
+    // search for column header cells, top direction
+    eColumnHeaderCells
+  };
+
+  /**
+   * Return an array of row or column header cells for the given cell.
+   *
+   * @param aTable                [in] table accessible
+   * @param aCell                 [in] cell accessible within the given table to
+   *                               get header cells
+   * @param aRowOrColHeaderCells  [in] specifies whether column or row header
+   *                               cells are returned (see enum constants
+   *                               above)
+   * @param aCells                [out] array of header cell accessibles
+   */
+  static nsresult GetHeaderCellsFor(nsIAccessibleTable *aTable,
+                                    nsIAccessibleTableCell *aCell,
+                                    PRInt32 aRowOrColHeaderCells,
+                                    nsIArray **aCells);
 };
 
 #endif
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -83,23 +83,24 @@
 #include "nsUnicharUtils.h"
 #include "nsIWebProgress.h"
 #include "nsNetError.h"
 #include "nsDocShellLoadTypes.h"
 
 #ifdef MOZ_XUL
 #include "nsXULAlertAccessible.h"
 #include "nsXULColorPickerAccessible.h"
+#include "nsXULComboboxAccessible.h"
 #include "nsXULFormControlAccessible.h"
+#include "nsXULListboxAccessibleWrap.h"
 #include "nsXULMenuAccessibleWrap.h"
-#include "nsXULSelectAccessible.h"
 #include "nsXULSliderAccessible.h"
 #include "nsXULTabAccessible.h"
 #include "nsXULTextAccessible.h"
-#include "nsXULTreeAccessibleWrap.h"
+#include "nsXULTreeGridAccessibleWrap.h"
 #endif
 
 // For native window support for object/embed/applet tags
 #ifdef XP_WIN
 #include "nsHTMLWin32ObjectAccessible.h"
 #endif
 
 #ifndef DISABLE_XFORMS_HOOKS
@@ -562,30 +563,25 @@ nsAccessibilityService::CreateHTMLAccess
            tag == nsAccessibilityAtoms::dt ||
            tag == nsAccessibilityAtoms::form ||
            tag == nsAccessibilityAtoms::h1 ||
            tag == nsAccessibilityAtoms::h2 ||
            tag == nsAccessibilityAtoms::h3 ||
            tag == nsAccessibilityAtoms::h4 ||
            tag == nsAccessibilityAtoms::h5 ||
            tag == nsAccessibilityAtoms::h6 ||
-#ifndef MOZ_ACCESSIBILITY_ATK
-           tag == nsAccessibilityAtoms::tbody ||
-           tag == nsAccessibilityAtoms::tfoot ||
-           tag == nsAccessibilityAtoms::thead ||
-#endif
            tag == nsAccessibilityAtoms::q) {
     return CreateHyperTextAccessible(aFrame, aAccessible);
   }
   else if (tag == nsAccessibilityAtoms::tr) {
     *aAccessible = new nsEnumRoleAccessible(aNode, aWeakShell,
                                             nsIAccessibleRole::ROLE_ROW);
   }
   else if (nsCoreUtils::IsHTMLTableHeader(content)) {
-    *aAccessible = new nsHTMLTableHeaderAccessible(aNode, aWeakShell);
+    *aAccessible = new nsHTMLTableHeaderCellAccessibleWrap(aNode, aWeakShell);
   }
 
   NS_IF_ADDREF(*aAccessible);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccessibilityService::CreateHTMLLIAccessible(nsIFrame *aFrame, 
@@ -832,56 +828,30 @@ nsAccessibilityService::CreateHTMLTableA
   if (! *_retval) 
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*_retval);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAccessibilityService::CreateHTMLTableHeadAccessible(nsIDOMNode *aDOMNode, nsIAccessible **_retval)
-{
-#ifndef MOZ_ACCESSIBILITY_ATK
-  *_retval = nsnull;
-  return NS_ERROR_FAILURE;
-#else
-  NS_ENSURE_ARG_POINTER(aDOMNode);
-
-  nsresult rv = NS_OK;
-
-  nsCOMPtr<nsIWeakReference> weakShell;
-  rv = GetShellFromNode(aDOMNode, getter_AddRefs(weakShell));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsHTMLTableHeadAccessibleWrap* accTableHead =
-    new nsHTMLTableHeadAccessibleWrap(aDOMNode, weakShell);
-
-  NS_ENSURE_TRUE(accTableHead, NS_ERROR_OUT_OF_MEMORY);
-
-  *_retval = static_cast<nsIAccessible *>(accTableHead);
-  NS_IF_ADDREF(*_retval);
-
-  return rv;
-#endif
-}
-
-NS_IMETHODIMP
-nsAccessibilityService::CreateHTMLTableCellAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
+nsAccessibilityService::CreateHTMLTableCellAccessible(nsIFrame *aFrame,
+                                                      nsIAccessible **aAccessible)
 {
   nsCOMPtr<nsIDOMNode> node;
   nsCOMPtr<nsIWeakReference> weakShell;
   nsresult rv = GetInfo(aFrame, getter_AddRefs(weakShell), getter_AddRefs(node));
   if (NS_FAILED(rv))
     return rv;
 
-  *_retval = new nsHTMLTableCellAccessible(node, weakShell);
-  if (! *_retval) 
+  *aAccessible = new nsHTMLTableCellAccessibleWrap(node, weakShell);
+  if (!*aAccessible) 
     return NS_ERROR_OUT_OF_MEMORY;
 
-  NS_ADDREF(*_retval);
+  NS_ADDREF(*aAccessible);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccessibilityService::CreateHTMLTextAccessible(nsIFrame *aFrame, nsIAccessible **_retval)
 {
   *_retval = nsnull;
 
@@ -1519,50 +1489,68 @@ NS_IMETHODIMP nsAccessibilityService::Ge
     nsIAtom *frameType = frame->GetType();
 
     PRBool partOfHTMLTable =
       frameType == nsAccessibilityAtoms::tableCaptionFrame ||
       frameType == nsAccessibilityAtoms::tableCellFrame ||
       frameType == nsAccessibilityAtoms::tableRowGroupFrame ||
       frameType == nsAccessibilityAtoms::tableRowFrame;
 
-    if (!roleMapEntry && partOfHTMLTable) {
+    if (partOfHTMLTable) {
       // Table-related frames don't get table-related roles
       // unless they are inside a table, but they may still get generic
       // accessibles
       nsIContent *tableContent = content;
       while ((tableContent = tableContent->GetParent()) != nsnull) {
         nsIFrame *tableFrame = aPresShell->GetPrimaryFrameFor(tableContent);
         if (!tableFrame)
           continue;
+
         if (tableFrame->GetType() == nsAccessibilityAtoms::tableOuterFrame) {
           nsCOMPtr<nsIDOMNode> tableNode(do_QueryInterface(tableContent));
           nsCOMPtr<nsIAccessible> tableAccessible;
-          GetAccessibleInShell(tableNode, aPresShell, getter_AddRefs(tableAccessible));
-          if (!tableAccessible && !content->IsFocusable()) {
+          GetAccessibleInShell(tableNode, aPresShell,
+                               getter_AddRefs(tableAccessible));
+
+          if (tableAccessible) {
+            if (!roleMapEntry) {
+              PRUint32 role = nsAccUtils::Role(tableAccessible);
+              if (role != nsIAccessibleRole::ROLE_TABLE &&
+                  role != nsIAccessibleRole::ROLE_TREE_TABLE) {
+                // No ARIA role and not in table: override role. For example,
+                // <table role="label"><td>content</td></table>
+                roleMapEntry = &nsARIAMap::gEmptyRoleMap;
+              }
+            }
+
+            break;
+          }
+
 #ifdef DEBUG
-            nsRoleMapEntry *tableRoleMapEntry =
-              nsAccUtils::GetRoleMapEntry(tableNode);
-            NS_ASSERTION(tableRoleMapEntry &&
-                         !nsCRT::strcmp(tableRoleMapEntry->roleString, "presentation"),
-                         "No accessible for parent table and it didn't have role of presentation");
+          nsRoleMapEntry *tableRoleMapEntry =
+            nsAccUtils::GetRoleMapEntry(tableNode);
+          NS_ASSERTION(tableRoleMapEntry &&
+                       !nsCRT::strcmp(tableRoleMapEntry->roleString, "presentation"),
+                       "No accessible for parent table and it didn't have role of presentation");
 #endif
-            // Table-related descendants of presentation table are also presentation
-            // Don't create accessibles for them unless they need to fire focus events
+
+          if (!roleMapEntry && !content->IsFocusable()) {
+            // Table-related descendants of presentation table are also
+            // presentation if they aren't focusable and have not explicit ARIA
+            // role (don't create accessibles for them unless they need to fire
+            // focus events).
             return NS_OK;
           }
-          if (tableAccessible &&
-              nsAccUtils::Role(tableAccessible) != nsIAccessibleRole::ROLE_TABLE) {
-            NS_ASSERTION(!roleMapEntry, "Should not be changing ARIA role, just overriding impl class role");
-            // Not in table: override role (roleMap entry was null).
-            roleMapEntry = &nsARIAMap::gEmptyRoleMap;
-          }
+
+          // otherwise create ARIA based accessible.
+          tryTagNameOrFrame = PR_FALSE;
           break;
         }
-        else if (tableContent->Tag() == nsAccessibilityAtoms::table) {
+
+        if (tableContent->Tag() == nsAccessibilityAtoms::table) {
           // Stop before we are fooled by any additional table ancestors
           // This table cell frameis part of a separate ancestor table.
           tryTagNameOrFrame = PR_FALSE;
           break;
         }
       }
 
       if (!tableContent)
@@ -1577,17 +1565,17 @@ NS_IMETHODIMP nsAccessibilityService::Ge
 
         if (roleMapEntry->role == nsIAccessibleRole::ROLE_TABLE ||
             roleMapEntry->role == nsIAccessibleRole::ROLE_TREE_TABLE) {
           newAcc = new nsARIAGridAccessibleWrap(aNode, aWeakShell);
 
         } else if (roleMapEntry->role == nsIAccessibleRole::ROLE_GRID_CELL ||
             roleMapEntry->role == nsIAccessibleRole::ROLE_ROWHEADER ||
             roleMapEntry->role == nsIAccessibleRole::ROLE_COLUMNHEADER) {
-          newAcc = new nsARIAGridCellAccessible(aNode, aWeakShell);
+          newAcc = new nsARIAGridCellAccessibleWrap(aNode, aWeakShell);
         }
       }
     }
 
     if (!newAcc && tryTagNameOrFrame) {
       // Prefer to use markup (mostly tag name, perhaps attributes) to
       // decide if and what kind of accessible to create.
       // The method creates accessibles for table related content too therefore
@@ -1823,20 +1811,20 @@ nsresult nsAccessibilityService::GetAcce
 
       *aAccessible = new nsHTMLImageAccessibleWrap(aNode, weakShell);
       break;
     }
     case nsIAccessibleProvider::XULLink:
       *aAccessible = new nsXULLinkAccessible(aNode, weakShell);
       break;
     case nsIAccessibleProvider::XULListbox:
-      *aAccessible = new nsXULListboxAccessible(aNode, weakShell);
+      *aAccessible = new nsXULListboxAccessibleWrap(aNode, weakShell);
       break;
     case nsIAccessibleProvider::XULListCell:
-      *aAccessible = new nsXULListCellAccessible(aNode, weakShell);
+      *aAccessible = new nsXULListCellAccessibleWrap(aNode, weakShell);
       break;
     case nsIAccessibleProvider::XULListHead:
       *aAccessible = new nsXULColumnsAccessible(aNode, weakShell);
       break;
     case nsIAccessibleProvider::XULListHeader:
       *aAccessible = new nsXULColumnItemAccessible(aNode, weakShell);
       break;
     case nsIAccessibleProvider::XULListitem:
@@ -1904,17 +1892,17 @@ nsresult nsAccessibilityService::GetAcce
       *aAccessible = new nsXULTextFieldAccessible(aNode, weakShell);
       break;
     case nsIAccessibleProvider::XULThumb:
       *aAccessible = new nsXULThumbAccessible(aNode, weakShell);
       break;
     case nsIAccessibleProvider::XULTree:
       return GetAccessibleForXULTree(aNode, weakShell, aAccessible);
     case nsIAccessibleProvider::XULTreeColumns:
-      *aAccessible = new nsXULTreeColumnsAccessibleWrap(aNode, weakShell);
+      *aAccessible = new nsXULTreeColumnsAccessible(aNode, weakShell);
       break;
     case nsIAccessibleProvider::XULTreeColumnItem:
       *aAccessible = new nsXULColumnItemAccessible(aNode, weakShell);
       break;
     case nsIAccessibleProvider::XULToolbar:
       *aAccessible = new nsXULToolbarAccessible(aNode, weakShell);
       break;
     case nsIAccessibleProvider::XULToolbarSeparator:
@@ -2037,35 +2025,37 @@ NS_IMETHODIMP nsAccessibilityService::Re
 
   return NS_OK;
 #else
   return NS_ERROR_NOT_IMPLEMENTED;
 #endif
 }
 
 // Called from layout when the frame tree owned by a node changes significantly
-NS_IMETHODIMP nsAccessibilityService::InvalidateSubtreeFor(nsIPresShell *aShell,
-                                                           nsIContent *aChangeContent,
-                                                           PRUint32 aEvent)
+NS_IMETHODIMP
+nsAccessibilityService::InvalidateSubtreeFor(nsIPresShell *aShell,
+                                             nsIContent *aChangeContent,
+                                             PRUint32 aChangeType)
 {
-  NS_ASSERTION(aEvent == nsIAccessibleEvent::EVENT_ASYNCH_SIGNIFICANT_CHANGE ||
-               aEvent == nsIAccessibleEvent::EVENT_ASYNCH_SHOW ||
-               aEvent == nsIAccessibleEvent::EVENT_ASYNCH_HIDE ||
-               aEvent == nsIAccessibleEvent::EVENT_DOM_SIGNIFICANT_CHANGE ||
-               aEvent == nsIAccessibleEvent::EVENT_DOM_CREATE ||
-               aEvent == nsIAccessibleEvent::EVENT_DOM_DESTROY,
+  NS_ASSERTION(aChangeType == nsIAccessibilityService::FRAME_SIGNIFICANT_CHANGE ||
+               aChangeType == nsIAccessibilityService::FRAME_SHOW ||
+               aChangeType == nsIAccessibilityService::FRAME_HIDE ||
+               aChangeType == nsIAccessibilityService::NODE_SIGNIFICANT_CHANGE ||
+               aChangeType == nsIAccessibilityService::NODE_APPEND ||
+               aChangeType == nsIAccessibilityService::NODE_REMOVE,
                "Incorrect aEvent passed in");
 
   NS_ENSURE_ARG_POINTER(aShell);
+
   nsCOMPtr<nsIAccessibleDocument> accessibleDoc =
     nsAccessNode::GetDocAccessibleFor(aShell->GetDocument());
   nsRefPtr<nsDocAccessible> docAcc =
     nsAccUtils::QueryAccessibleDocument(accessibleDoc);
   if (docAcc)
-    docAcc->InvalidateCacheSubtree(aChangeContent, aEvent);
+    docAcc->InvalidateCacheSubtree(aChangeContent, aChangeType);
 
   return NS_OK;
 }
 
 //////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////
 
 nsresult 
--- a/accessible/src/base/nsAccessibilityService.h
+++ b/accessible/src/base/nsAccessibilityService.h
@@ -293,22 +293,19 @@ static const char kRoleNames[][20] = {
 };
 
 /**
  * Map nsIAccessibleEvents constants to strings. Used by
  * nsIAccessibleRetrieval::getStringEventType() method.
  */
 static const char kEventTypeNames[][40] = {
   "unknown",                                 //
-  "DOM node create",                         // EVENT_DOM_CREATE
-  "DOM node destroy",                        // EVENT_DOM_DESTROY
-  "DOM node significant change",             // EVENT_DOM_SIGNIFICANT_CHANGE
-  "async show",                              // EVENT_ASYNCH_SHOW
-  "async hide",                              // EVENT_ASYNCH_HIDE
-  "async significant change",                // EVENT_ASYNCH_SIGNIFICANT_CHANGE
+  "show",                                    // EVENT_SHOW
+  "hide",                                    // EVENT_HIDE
+  "reorder",                                 // EVENT_REORDER
   "active decendent change",                 // EVENT_ACTIVE_DECENDENT_CHANGED
   "focus",                                   // EVENT_FOCUS
   "state change",                            // EVENT_STATE_CHANGE
   "location change",                         // EVENT_LOCATION_CHANGE
   "name changed",                            // EVENT_NAME_CHANGE
   "description change",                      // EVENT_DESCRIPTION_CHANGE
   "value change",                            // EVENT_VALUE_CHANGE
   "help change",                             // EVENT_HELP_CHANGE
@@ -383,18 +380,17 @@ static const char kEventTypeNames[][40] 
   "hyperlink selected link changed",         // EVENT_HYPERLINK_SELECTED_LINK_CHANGED
   "hypertext link activated",                // EVENT_HYPERTEXT_LINK_ACTIVATED
   "hypertext link selected",                 // EVENT_HYPERTEXT_LINK_SELECTED
   "hyperlink start index changed",           // EVENT_HYPERLINK_START_INDEX_CHANGED
   "hypertext changed",                       // EVENT_HYPERTEXT_CHANGED
   "hypertext links count changed",           // EVENT_HYPERTEXT_NLINKS_CHANGED
   "object attribute changed",                // EVENT_OBJECT_ATTRIBUTE_CHANGED
   "page changed",                            // EVENT_PAGE_CHANGED
-  "internal load",                           // EVENT_INTERNAL_LOAD
-  "reorder"                                  // EVENT_REORDER
+  "internal load"                            // EVENT_INTERNAL_LOAD
 };
 
 /**
  * Map nsIAccessibleRelation constants to strings. Used by
  * nsIAccessibleRetrieval::getStringRelationType() method.
  */
 static const char kRelationTypeNames[][20] = {
   "unknown",             // RELATION_NUL
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -1743,18 +1743,18 @@ nsAccessible::GetAttributes(nsIPersisten
   }
 
   // If there is no aria-live attribute then expose default value of 'live'
   // object attribute used for ARIA role of this accessible.
   if (mRoleMapEntry) {
     nsAutoString live;
     nsAccUtils::GetAccAttr(attributes, nsAccessibilityAtoms::live, live);
     if (live.IsEmpty()) {
-      nsAccUtils::GetLiveAttrValue(mRoleMapEntry->liveAttRule, live);
-      nsAccUtils::SetAccAttr(attributes, nsAccessibilityAtoms::live, live);
+      if (nsAccUtils::GetLiveAttrValue(mRoleMapEntry->liveAttRule, live))
+        nsAccUtils::SetAccAttr(attributes, nsAccessibilityAtoms::live, live);
     }
   }
 
   return NS_OK;
 }
 
 nsresult
 nsAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
@@ -2025,19 +2025,22 @@ nsAccessible::GetARIAState(PRUint32 *aSt
 
   PRUint32 index = 0;
   while (nsStateMapEntry::MapToStates(content, aState, aExtraState,
                                       nsARIAMap::gWAIUnivStateMap[index])) {
     ++ index;
   }
 
   if (mRoleMapEntry) {
-    // Once an ARIA role is used, default to not-readonly. This can be overridden
-    // by aria-readonly, or if the ARIA role is mapped to readonly by default
-    *aState &= ~nsIAccessibleStates::STATE_READONLY;
+
+    // We only force the readonly bit off if we have a real mapping for the aria
+    // role. This preserves the ability for screen readers to use readonly
+    // (primarily on the document) as the hint for creating a virtual buffer.
+    if (mRoleMapEntry->role != nsIAccessibleRole::ROLE_NOTHING)
+      *aState &= ~nsIAccessibleStates::STATE_READONLY;
 
     if (content->HasAttr(kNameSpaceID_None, content->GetIDAttributeName())) {
       // If has a role & ID and aria-activedescendant on the container, assume focusable
       nsIContent *ancestorContent = content;
       while ((ancestorContent = ancestorContent->GetParent()) != nsnull) {
         if (ancestorContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_activedescendant)) {
             // ancestor has activedescendant property, this content could be active
           *aState |= nsIAccessibleStates::STATE_FOCUSABLE;
--- a/accessible/src/base/nsAccessibleEventData.cpp
+++ b/accessible/src/base/nsAccessibleEventData.cpp
@@ -72,47 +72,46 @@ NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsAccEvent)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsAccEvent)
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccEvent. Constructors
 
 nsAccEvent::nsAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
-                       PRBool aIsAsynch, EEventRule aEventRule)
-  : mEventType(aEventType)
-  , mEventRule(aEventRule)
-  , mAccessible(aAccessible)
+                       PRBool aIsAsync, EEventRule aEventRule) :
+  mEventType(aEventType), mEventRule(aEventRule), mIsAsync(aIsAsync),
+  mAccessible(aAccessible)
 {
-  CaptureIsFromUserInput(aIsAsynch);
+  CaptureIsFromUserInput();
 }
 
 nsAccEvent::nsAccEvent(PRUint32 aEventType, nsIDOMNode *aDOMNode,
-                       PRBool aIsAsynch, EEventRule aEventRule)
-  : mEventType(aEventType)
-  , mEventRule(aEventRule)
-  , mDOMNode(aDOMNode)
+                       PRBool aIsAsync, EEventRule aEventRule) :
+  mEventType(aEventType), mEventRule(aEventRule), mIsAsync(aIsAsync),
+  mDOMNode(aDOMNode)
 {
-  CaptureIsFromUserInput(aIsAsynch);
+  CaptureIsFromUserInput();
 }
 
 void nsAccEvent::GetLastEventAttributes(nsIDOMNode *aNode,
                                         nsIPersistentProperties *aAttributes)
 {
   if (aNode == gLastEventNodeWeak) {
     // Only provide event-from-input for last event's node
     nsAutoString oldValueUnused;
     aAttributes->SetStringProperty(NS_LITERAL_CSTRING("event-from-input"),
                                    gLastEventFromUserInput ? NS_LITERAL_STRING("true") :
                                                              NS_LITERAL_STRING("false"),
                                    oldValueUnused);
   }
 }
 
-void nsAccEvent::CaptureIsFromUserInput(PRBool aIsAsynch)
+void
+nsAccEvent::CaptureIsFromUserInput()
 {
   nsCOMPtr<nsIDOMNode> eventNode;
   GetDOMNode(getter_AddRefs(eventNode));
   if (!eventNode) {
 #ifdef DEBUG
     // XXX: remove this hack during reorganization of 506907. Meanwhile we
     // want to get rid an assertion for application accessible events which
     // don't have DOM node (see bug 506206).
@@ -121,17 +120,17 @@ void nsAccEvent::CaptureIsFromUserInput(
 
     if (mAccessible != static_cast<nsIAccessible*>(applicationAcc.get()))
       NS_ASSERTION(eventNode, "There should always be a DOM node for an event");
 #endif
 
     return;
   }
 
-  if (!aIsAsynch) {
+  if (!mIsAsync) {
     PrepareForEvent(eventNode);
     mIsFromUserInput = gLastEventFromUserInput;
   }
   // For asynch, cannot calculate if from user input.
   // Don't reset global last input state here, do it
   // at the end of FlushPendingEvents()
 
   mIsFromUserInput = gLastEventFromUserInput;
@@ -303,107 +302,107 @@ nsAccEvent::GetAccessibleByNode()
   }
 #endif
 
   return accessible.forget();
 }
 
 /* static */
 void
-nsAccEvent::ApplyEventRules(nsCOMArray<nsIAccessibleEvent> &aEventsToFire)
+nsAccEvent::ApplyEventRules(nsTArray<nsCOMPtr<nsIAccessibleEvent> > &aEventsToFire)
 {
-  PRUint32 numQueuedEvents = aEventsToFire.Count();
-  for (PRInt32 tail = numQueuedEvents - 1; tail >= 0; tail --) {
-    nsRefPtr<nsAccEvent> tailEvent = GetAccEventPtr(aEventsToFire[tail]);
-    switch(tailEvent->mEventRule) {
-      case nsAccEvent::eCoalesceFromSameSubtree:
-      {
-        for (PRInt32 index = 0; index < tail; index ++) {
-          nsRefPtr<nsAccEvent> thisEvent = GetAccEventPtr(aEventsToFire[index]);
-          if (thisEvent->mEventType != tailEvent->mEventType)
-            continue; // Different type
+  PRUint32 numQueuedEvents = aEventsToFire.Length();
+  PRInt32 tail = numQueuedEvents - 1;
 
-          if (thisEvent->mEventRule == nsAccEvent::eAllowDupes ||
-              thisEvent->mEventRule == nsAccEvent::eDoNotEmit)
-            continue; //  Do not need to check
+  nsRefPtr<nsAccEvent> tailEvent = GetAccEventPtr(aEventsToFire[tail]);
+  switch(tailEvent->mEventRule) {
+    case nsAccEvent::eCoalesceFromSameSubtree:
+    {
+      for (PRInt32 index = 0; index < tail; index ++) {
+        nsRefPtr<nsAccEvent> thisEvent = GetAccEventPtr(aEventsToFire[index]);
+        if (thisEvent->mEventType != tailEvent->mEventType)
+          continue; // Different type
 
-          if (thisEvent->mDOMNode == tailEvent->mDOMNode) {
-            if (thisEvent->mEventType == nsIAccessibleEvent::EVENT_REORDER) {
-              CoalesceReorderEventsFromSameSource(thisEvent, tailEvent);
-              continue;
-            }
+        if (thisEvent->mEventRule == nsAccEvent::eAllowDupes ||
+            thisEvent->mEventRule == nsAccEvent::eDoNotEmit)
+          continue; //  Do not need to check
 
-            // Dupe
-            thisEvent->mEventRule = nsAccEvent::eDoNotEmit;
+        if (thisEvent->mDOMNode == tailEvent->mDOMNode) {
+          if (thisEvent->mEventType == nsIAccessibleEvent::EVENT_REORDER) {
+            CoalesceReorderEventsFromSameSource(thisEvent, tailEvent);
             continue;
           }
-          if (nsCoreUtils::IsAncestorOf(tailEvent->mDOMNode,
-                                        thisEvent->mDOMNode)) {
-            // thisDOMNode is a descendant of tailDOMNode
-            if (thisEvent->mEventType == nsIAccessibleEvent::EVENT_REORDER) {
-              CoalesceReorderEventsFromSameTree(tailEvent, thisEvent);
-              continue;
-            }
 
-            // Do not emit thisEvent, also apply this result to sibling
-            // nodes of thisDOMNode.
-            thisEvent->mEventRule = nsAccEvent::eDoNotEmit;
-            ApplyToSiblings(aEventsToFire, 0, index, thisEvent->mEventType,
-                            thisEvent->mDOMNode, nsAccEvent::eDoNotEmit);
+          // Dupe
+          thisEvent->mEventRule = nsAccEvent::eDoNotEmit;
+          continue;
+        }
+        if (nsCoreUtils::IsAncestorOf(tailEvent->mDOMNode,
+                                      thisEvent->mDOMNode)) {
+          // thisDOMNode is a descendant of tailDOMNode
+          if (thisEvent->mEventType == nsIAccessibleEvent::EVENT_REORDER) {
+            CoalesceReorderEventsFromSameTree(tailEvent, thisEvent);
             continue;
           }
-          if (nsCoreUtils::IsAncestorOf(thisEvent->mDOMNode,
-                                        tailEvent->mDOMNode)) {
-            // tailDOMNode is a descendant of thisDOMNode
-            if (thisEvent->mEventType == nsIAccessibleEvent::EVENT_REORDER) {
-              CoalesceReorderEventsFromSameTree(thisEvent, tailEvent);
-              continue;
-            }
 
-            // Do not emit tailEvent, also apply this result to sibling
-            // nodes of tailDOMNode.
-            tailEvent->mEventRule = nsAccEvent::eDoNotEmit;
-            ApplyToSiblings(aEventsToFire, 0, tail, tailEvent->mEventType,
-                            tailEvent->mDOMNode, nsAccEvent::eDoNotEmit);
-            break;
+          // Do not emit thisEvent, also apply this result to sibling
+          // nodes of thisDOMNode.
+          thisEvent->mEventRule = nsAccEvent::eDoNotEmit;
+          ApplyToSiblings(aEventsToFire, 0, index, thisEvent->mEventType,
+                          thisEvent->mDOMNode, nsAccEvent::eDoNotEmit);
+          continue;
+        }
+        if (nsCoreUtils::IsAncestorOf(thisEvent->mDOMNode,
+                                      tailEvent->mDOMNode)) {
+          // tailDOMNode is a descendant of thisDOMNode
+          if (thisEvent->mEventType == nsIAccessibleEvent::EVENT_REORDER) {
+            CoalesceReorderEventsFromSameTree(thisEvent, tailEvent);
+            continue;
           }
-        } // for (index)
+
+          // Do not emit tailEvent, also apply this result to sibling
+          // nodes of tailDOMNode.
+          tailEvent->mEventRule = nsAccEvent::eDoNotEmit;
+          ApplyToSiblings(aEventsToFire, 0, tail, tailEvent->mEventType,
+                          tailEvent->mDOMNode, nsAccEvent::eDoNotEmit);
+          break;
+        }
+      } // for (index)
 
-        if (tailEvent->mEventRule != nsAccEvent::eDoNotEmit) {
-          // Not in another event node's subtree, and no other event is in
-          // this event node's subtree.
-          // This event should be emitted
-          // Apply this result to sibling nodes of tailDOMNode
-          ApplyToSiblings(aEventsToFire, 0, tail, tailEvent->mEventType,
-                          tailEvent->mDOMNode, nsAccEvent::eAllowDupes);
-        }
-      } break; // case eCoalesceFromSameSubtree
+      if (tailEvent->mEventRule != nsAccEvent::eDoNotEmit) {
+        // Not in another event node's subtree, and no other event is in
+        // this event node's subtree.
+        // This event should be emitted
+        // Apply this result to sibling nodes of tailDOMNode
+        ApplyToSiblings(aEventsToFire, 0, tail, tailEvent->mEventType,
+                        tailEvent->mDOMNode, nsAccEvent::eAllowDupes);
+      }
+    } break; // case eCoalesceFromSameSubtree
 
-      case nsAccEvent::eRemoveDupes:
-      {
-        // Check for repeat events.
-        for (PRInt32 index = 0; index < tail; index ++) {
-          nsRefPtr<nsAccEvent> accEvent = GetAccEventPtr(aEventsToFire[index]);
-          if (accEvent->mEventType == tailEvent->mEventType &&
-              accEvent->mEventRule == tailEvent->mEventRule &&
-              accEvent->mDOMNode == tailEvent->mDOMNode) {
-            accEvent->mEventRule = nsAccEvent::eDoNotEmit;
-          }
+    case nsAccEvent::eRemoveDupes:
+    {
+      // Check for repeat events.
+      for (PRInt32 index = 0; index < tail; index ++) {
+        nsRefPtr<nsAccEvent> accEvent = GetAccEventPtr(aEventsToFire[index]);
+        if (accEvent->mEventType == tailEvent->mEventType &&
+            accEvent->mEventRule == tailEvent->mEventRule &&
+            accEvent->mDOMNode == tailEvent->mDOMNode) {
+          accEvent->mEventRule = nsAccEvent::eDoNotEmit;
         }
-      } break; // case eRemoveDupes
+      }
+    } break; // case eRemoveDupes
 
-      default:
-        break; // case eAllowDupes, eDoNotEmit
-    } // switch
-  } // for (tail)
+    default:
+      break; // case eAllowDupes, eDoNotEmit
+  } // switch
 }
 
 /* static */
 void
-nsAccEvent::ApplyToSiblings(nsCOMArray<nsIAccessibleEvent> &aEventsToFire,
+nsAccEvent::ApplyToSiblings(nsTArray<nsCOMPtr<nsIAccessibleEvent> > &aEventsToFire,
                             PRUint32 aStart, PRUint32 aEnd,
                              PRUint32 aEventType, nsIDOMNode* aDOMNode,
                              EEventRule aEventRule)
 {
   for (PRUint32 index = aStart; index < aEnd; index ++) {
     nsRefPtr<nsAccEvent> accEvent = GetAccEventPtr(aEventsToFire[index]);
     if (accEvent->mEventType == aEventType &&
         accEvent->mEventRule != nsAccEvent::eDoNotEmit &&
@@ -564,21 +563,23 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsAccTextCh
 
 nsAccTextChangeEvent::
   nsAccTextChangeEvent(nsIAccessible *aAccessible,
                        PRInt32 aStart, PRUint32 aLength, PRBool aIsInserted, PRBool aIsAsynch):
   nsAccEvent(aIsInserted ? nsIAccessibleEvent::EVENT_TEXT_INSERTED : nsIAccessibleEvent::EVENT_TEXT_REMOVED,
              aAccessible, aIsAsynch),
   mStart(aStart), mLength(aLength), mIsInserted(aIsInserted)
 {
+#ifdef XP_WIN
   nsCOMPtr<nsIAccessibleText> textAccessible = do_QueryInterface(aAccessible);
   NS_ASSERTION(textAccessible, "Should not be firing test change event for non-text accessible!!!");
   if (textAccessible) {
     textAccessible->GetText(aStart, aStart + aLength, mModifiedText);
   }
+#endif
 }
 
 NS_IMETHODIMP
 nsAccTextChangeEvent::GetStart(PRInt32 *aStart)
 {
   *aStart = mStart;
   return NS_OK;
 }
--- a/accessible/src/base/nsAccessibleEventData.h
+++ b/accessible/src/base/nsAccessibleEventData.h
@@ -100,21 +100,22 @@ public:
   NS_DECL_NSIACCESSIBLEEVENT
 
   static void GetLastEventAttributes(nsIDOMNode *aNode,
                                      nsIPersistentProperties *aAttributes);
 
 protected:
   already_AddRefed<nsIAccessible> GetAccessibleByNode();
 
-  void CaptureIsFromUserInput(PRBool aIsAsynch);
+  void CaptureIsFromUserInput();
   PRBool mIsFromUserInput;
 
   PRUint32 mEventType;
   EEventRule mEventRule;
+  PRPackedBool mIsAsync;
   nsCOMPtr<nsIAccessible> mAccessible;
   nsCOMPtr<nsIDOMNode> mDOMNode;
   nsCOMPtr<nsIAccessibleDocument> mDocAccessible;
 
 private:
   static PRBool gLastEventFromUserInput;
   static nsIDOMNode* gLastEventNodeWeak;
 
@@ -123,16 +124,20 @@ public:
     PRUint32 eventType;
     aAccEvent->GetEventType(&eventType);
     return eventType;
   }
   static EEventRule EventRule(nsIAccessibleEvent *aAccEvent) {
     nsRefPtr<nsAccEvent> accEvent = GetAccEventPtr(aAccEvent);
     return accEvent->mEventRule;
   }
+  static PRBool IsAsyncEvent(nsIAccessibleEvent *aAccEvent) {
+    nsRefPtr<nsAccEvent> accEvent = GetAccEventPtr(aAccEvent);
+    return accEvent->mIsAsync;
+  }
   static PRBool IsFromUserInput(nsIAccessibleEvent *aAccEvent) {
     PRBool isFromUserInput;
     aAccEvent->GetIsFromUserInput(&isFromUserInput);
     return isFromUserInput;
   }
 
   static void ResetLastInputState()
    {gLastEventFromUserInput = PR_FALSE; gLastEventNodeWeak = nsnull; }
@@ -159,17 +164,17 @@ public:
 
   /**
    * Apply event rules to pending events, this method is called in
    * FlushingPendingEvents().
    * Result of this method:
    *   Event rule of filtered events will be set to eDoNotEmit.
    *   Events with other event rule are good to emit.
    */
-  static void ApplyEventRules(nsCOMArray<nsIAccessibleEvent> &aEventsToFire);
+  static void ApplyEventRules(nsTArray<nsCOMPtr<nsIAccessibleEvent> > &aEventsToFire);
 
 private:
   static already_AddRefed<nsAccEvent> GetAccEventPtr(nsIAccessibleEvent *aAccEvent) {
     nsAccEvent* accEvent = nsnull;
     aAccEvent->QueryInterface(NS_GET_IID(nsAccEvent), (void**)&accEvent);
     return accEvent;
   }
 
@@ -178,17 +183,17 @@ private:
    * @param aEventsToFire    array of pending events
    * @param aStart           start index of pending events to be scanned
    * @param aEnd             end index to be scanned (not included)
    * @param aEventType       target event type
    * @param aDOMNode         target are siblings of this node
    * @param aEventRule       the event rule to be applied
    *                         (should be eDoNotEmit or eAllowDupes)
    */
-  static void ApplyToSiblings(nsCOMArray<nsIAccessibleEvent> &aEventsToFire,
+  static void ApplyToSiblings(nsTArray<nsCOMPtr<nsIAccessibleEvent> > &aEventsToFire,
                               PRUint32 aStart, PRUint32 aEnd,
                               PRUint32 aEventType, nsIDOMNode* aDOMNode,
                               EEventRule aEventRule);
 
   /**
    * Do not emit one of two given reorder events fired for the same DOM node.
    */
   static void CoalesceReorderEventsFromSameSource(nsAccEvent *aAccEvent1,
@@ -253,34 +258,32 @@ public:
   nsAccStateChangeEvent(nsIDOMNode *aNode,
                         PRUint32 aState, PRBool aIsExtraState,
                         PRBool aIsEnabled);
 
   nsAccStateChangeEvent(nsIDOMNode *aNode,
                         PRUint32 aState, PRBool aIsExtraState);
 
   NS_DECL_ISUPPORTS_INHERITED
-  NS_FORWARD_NSIACCESSIBLEEVENT(nsAccEvent::)
   NS_DECL_NSIACCESSIBLESTATECHANGEEVENT
 
 private:
   PRUint32 mState;
   PRBool mIsExtraState;
   PRBool mIsEnabled;
 };
 
 class nsAccTextChangeEvent: public nsAccEvent,
                             public nsIAccessibleTextChangeEvent
 {
 public:
   nsAccTextChangeEvent(nsIAccessible *aAccessible, PRInt32 aStart, PRUint32 aLength,
                        PRBool aIsInserted, PRBool aIsAsynch = PR_FALSE);
 
   NS_DECL_ISUPPORTS_INHERITED
-  NS_FORWARD_NSIACCESSIBLEEVENT(nsAccEvent::)
   NS_DECL_NSIACCESSIBLETEXTCHANGEEVENT
 
 private:
   PRInt32 mStart;
   PRUint32 mLength;
   PRBool mIsInserted;
   nsString mModifiedText;
 };
@@ -288,32 +291,30 @@ private:
 class nsAccCaretMoveEvent: public nsAccEvent,
                            public nsIAccessibleCaretMoveEvent
 {
 public:
   nsAccCaretMoveEvent(nsIAccessible *aAccessible, PRInt32 aCaretOffset);
   nsAccCaretMoveEvent(nsIDOMNode *aNode);
 
   NS_DECL_ISUPPORTS_INHERITED
-  NS_FORWARD_NSIACCESSIBLEEVENT(nsAccEvent::)
   NS_DECL_NSIACCESSIBLECARETMOVEEVENT
 
 private:
   PRInt32 mCaretOffset;
 };
 
 class nsAccTableChangeEvent : public nsAccEvent,
                               public nsIAccessibleTableChangeEvent {
 public:
   nsAccTableChangeEvent(nsIAccessible *aAccessible, PRUint32 aEventType,
                         PRInt32 aRowOrColIndex, PRInt32 aNumRowsOrCols,
                         PRBool aIsAsynch);
 
   NS_DECL_ISUPPORTS
-  NS_FORWARD_NSIACCESSIBLEEVENT(nsAccEvent::)
   NS_DECL_NSIACCESSIBLETABLECHANGEEVENT
 
 private:
   PRUint32 mRowOrColIndex;   // the start row/column after which the rows are inserted/deleted.
   PRUint32 mNumRowsOrCols;   // the number of inserted/deleted rows/columns
 };
 
 #endif
--- a/accessible/src/base/nsCaretAccessible.cpp
+++ b/accessible/src/base/nsCaretAccessible.cpp
@@ -264,17 +264,17 @@ nsCaretAccessible::NormalSelectionChange
     textAcc->GetSelectionCount(&selectionCount);   // Don't swallow similar events when selecting text
     if (!selectionCount) {
       return NS_OK;  // Swallow duplicate caret event
     }
   }
   mLastCaretOffset = caretOffset;
   mLastTextAccessible = textAcc;
 
-  nsCOMPtr<nsIAccessibleCaretMoveEvent> event =
+  nsCOMPtr<nsIAccessibleEvent> event =
     new nsAccCaretMoveEvent(textNode);
   NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
 
   return mRootAccessible->FireDelayedAccessibleEvent(event);
 }
 
 nsresult
 nsCaretAccessible::SpellcheckSelectionChanged(nsIDOMDocument *aDoc,
--- a/accessible/src/base/nsCoreUtils.cpp
+++ b/accessible/src/base/nsCoreUtils.cpp
@@ -1022,17 +1022,17 @@ nsCoreUtils::GetLastSensibleColumn(nsITr
   cols->GetLastColumn(getter_AddRefs(column));
   if (column && IsColumnHidden(column))
     return GetPreviousSensibleColumn(column);
 
   return column.forget();
 }
 
 PRUint32
-nsCoreUtils::GetSensibleColumnsCount(nsITreeBoxObject *aTree)
+nsCoreUtils::GetSensiblecolumnCount(nsITreeBoxObject *aTree)
 {
   PRUint32 count = 0;
 
   nsCOMPtr<nsITreeColumns> cols;
   aTree->GetColumns(getter_AddRefs(cols));
   if (!cols)
     return count;
 
--- a/accessible/src/base/nsCoreUtils.h
+++ b/accessible/src/base/nsCoreUtils.h
@@ -408,17 +408,17 @@ public:
    * Return last sensible column for the given tree box object.
    */
   static already_AddRefed<nsITreeColumn>
     GetLastSensibleColumn(nsITreeBoxObject *aTree);
 
   /**
    * Return sensible columns count for the given tree box object.
    */
-  static PRUint32 GetSensibleColumnsCount(nsITreeBoxObject *aTree);
+  static PRUint32 GetSensiblecolumnCount(nsITreeBoxObject *aTree);
 
   /**
    * Return sensible column at the given index for the given tree box object.
    */
   static already_AddRefed<nsITreeColumn>
     GetSensibleColumnAt(nsITreeBoxObject *aTree, PRUint32 aIndex);
 
   /**
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -81,17 +81,18 @@ PRUint32 nsDocAccessible::gLastFocusedAc
 nsIAtom *nsDocAccessible::gLastFocusedFrameType = nsnull;
 
 //-----------------------------------------------------
 // construction
 //-----------------------------------------------------
 nsDocAccessible::nsDocAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell):
   nsHyperTextAccessibleWrap(aDOMNode, aShell), mWnd(nsnull),
   mScrollPositionChangedTicks(0), mIsContentLoaded(PR_FALSE),
-  mIsLoadCompleteFired(PR_FALSE), mInFlushPendingEvents(PR_FALSE)
+  mIsLoadCompleteFired(PR_FALSE), mInFlushPendingEvents(PR_FALSE),
+  mFireEventTimerStarted(PR_FALSE)
 {
   // XXX aaronl should we use an algorithm for the initial cache size?
   mAccessNodeCache.Init(kDefaultCacheSize);
 
   // For GTK+ native window, we do nothing here.
   if (!mDOMNode)
     return;
 
@@ -148,22 +149,27 @@ ElementTraverser(const void *aKey, nsIAc
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mAccessNodeCache entry");
   cb->NoteXPCOMChild(aAccessNode);
   return PL_DHASH_NEXT;
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDocAccessible)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDocAccessible, nsAccessible)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mEventsToFire)
-  tmp->mAccessNodeCache.EnumerateRead(ElementTraverser, &cb); 
+  PRUint32 i, length = tmp->mEventsToFire.Length();
+  for (i = 0; i < length; ++i) {
+    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEventsToFire[i]");
+    cb.NoteXPCOMChild(tmp->mEventsToFire[i].get());
+  }
+
+  tmp->mAccessNodeCache.EnumerateRead(ElementTraverser, &cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDocAccessible, nsAccessible)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mEventsToFire)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(mEventsToFire)
   tmp->ClearCache(tmp->mAccessNodeCache);
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDocAccessible)
   NS_INTERFACE_MAP_STATIC_AMBIGUOUS(nsDocAccessible)
   NS_INTERFACE_MAP_ENTRY(nsIAccessibleDocument)
   NS_INTERFACE_MAP_ENTRY(nsIDocumentObserver)
   NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
@@ -647,27 +653,27 @@ nsDocAccessible::Shutdown()
   ClearCache(mAccessNodeCache);
 
   nsCOMPtr<nsIDocument> kungFuDeathGripDoc = mDocument;
   mDocument = nsnull;
 
   nsHyperTextAccessibleWrap::Shutdown();
 
   if (mFireEventTimer) {
-    // Doc being shut down before events fired,
+    // Doc being shut down before delayed events were processed.
     mFireEventTimer->Cancel();
     mFireEventTimer = nsnull;
-    if (mEventsToFire.Count() > 0 ) {
-      mEventsToFire.Clear();
-      // Make sure we release the kung fu death grip which is always
-      // there when there are still events left to be fired
-      // If FlushPendingEvents() is in call stack,
-      // kung fu death grip will be released there.
-      if (!mInFlushPendingEvents)
-        NS_RELEASE_THIS();
+    mEventsToFire.Clear();
+
+    if (mFireEventTimerStarted && !mInFlushPendingEvents) {
+      // Make sure we release the kung fu death grip which is always there when
+      // fire event timer was started but FlushPendingEvents() callback wasn't
+      // triggered yet. If FlushPendingEvents() is in call stack, kung fu death
+      // grip will be released there.
+      NS_RELEASE_THIS();
     }
   }
 
   // Remove from the cache after other parts of Shutdown(), so that Shutdown() procedures
   // can find the doc or root accessible in the cache if they need it.
   // We don't do this during ShutdownAccessibility() because that is already clearing the cache
   if (!nsAccessibilityService::gIsShutdown)
     gGlobalDocAccessibleCache.Remove(static_cast<void*>(kungFuDeathGripDoc));
@@ -924,41 +930,42 @@ nsDocAccessible::FireDocLoadEvents(PRUin
     if (acc) {
       // Make the parent forget about the old document as a child
       acc->InvalidateChildren();
     }
 
     if (sameTypeRoot != treeItem) {
       // Fire show/hide events to indicate frame/iframe content is new, rather than
       // doc load event which causes screen readers to act is if entire page is reloaded
-      InvalidateCacheSubtree(nsnull, nsIAccessibleEvent::EVENT_DOM_SIGNIFICANT_CHANGE);
+      InvalidateCacheSubtree(nsnull,
+                             nsIAccessibilityService::NODE_SIGNIFICANT_CHANGE);
     }
     // Fire STATE_CHANGE event for doc load finish if focus is in same doc tree
     if (gLastFocusedNode) {
       nsCOMPtr<nsIDocShellTreeItem> focusedTreeItem =
         nsCoreUtils::GetDocShellTreeItemFor(gLastFocusedNode);
       if (focusedTreeItem) {
         nsCOMPtr<nsIDocShellTreeItem> sameTypeRootOfFocus;
         focusedTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRootOfFocus));
         if (sameTypeRoot == sameTypeRootOfFocus) {
-          nsCOMPtr<nsIAccessibleStateChangeEvent> accEvent =
+          nsCOMPtr<nsIAccessibleEvent> accEvent =
             new nsAccStateChangeEvent(this, nsIAccessibleStates::STATE_BUSY, PR_FALSE, PR_FALSE);
           FireAccessibleEvent(accEvent);
           FireAnchorJumpEvent();
         }
       }
     }
   }
 
   if (sameTypeRoot == treeItem) {
     // Not a frame or iframe
     if (!isFinished) {
       // Fire state change event to set STATE_BUSY when document is loading. For
       // example, Window-Eyes expects to get it.
-      nsCOMPtr<nsIAccessibleStateChangeEvent> accEvent =
+      nsCOMPtr<nsIAccessibleEvent> accEvent =
         new nsAccStateChangeEvent(this, nsIAccessibleStates::STATE_BUSY,
                                   PR_FALSE, PR_TRUE);
       FireAccessibleEvent(accEvent);
     }
 
     nsAccUtils::FireAccEvent(aEventType, this);
   }
 }
@@ -1042,17 +1049,17 @@ NS_IMETHODIMP nsDocAccessible::ScrollPos
   return NS_OK;
 }
 
 NS_IMETHODIMP nsDocAccessible::Observe(nsISupports *aSubject, const char *aTopic,
                                        const PRUnichar *aData)
 {
   if (!nsCRT::strcmp(aTopic,"obs_documentCreated")) {    
     // State editable will now be set, readonly is now clear
-    nsCOMPtr<nsIAccessibleStateChangeEvent> event =
+    nsCOMPtr<nsIAccessibleEvent> event =
       new nsAccStateChangeEvent(this, nsIAccessibleStates::EXT_STATE_EDITABLE,
                                 PR_TRUE, PR_TRUE);
     FireAccessibleEvent(event);
   }
 
   return NS_OK;
 }
 
@@ -1134,34 +1141,40 @@ nsDocAccessible::AttributeChangedImpl(ns
   if (!targetNode || !nsAccUtils::IsNodeRelevant(targetNode))
     return;
 
   // Since we're in synchronous code, we can store whether the current attribute
   // change is from user input or not. If the attribute change causes an asynchronous
   // layout change, that event can use the last known user input state
   nsAccEvent::PrepareForEvent(targetNode);
 
-  // Universal boolean properties that don't require a role.
+  // Universal boolean properties that don't require a role. Fire the state
+  // change when disabled or aria-disabled attribute is set.
   if (aAttribute == nsAccessibilityAtoms::disabled ||
       aAttribute == nsAccessibilityAtoms::aria_disabled) {
-    // Fire the state change whether disabled attribute is
-    // set for XUL, HTML or ARIA namespace.
-    // Checking the namespace would not seem to gain us anything, because
-    // disabled really is going to mean the same thing in any namespace.
-    // We use the attribute instead of the disabled state bit because
-    // ARIA's aria-disabled does not affect the disabled state bit
-    nsCOMPtr<nsIAccessibleStateChangeEvent> enabledChangeEvent =
+
+    // Note. Checking the XUL or HTML namespace would not seem to gain us
+    // anything, because disabled attribute really is going to mean the same
+    // thing in any namespace.
+
+    // Note. We use the attribute instead of the disabled state bit because
+    // ARIA's aria-disabled does not affect the disabled state bit.
+
+    nsCOMPtr<nsIAccessibleEvent> enabledChangeEvent =
       new nsAccStateChangeEvent(targetNode,
                                 nsIAccessibleStates::EXT_STATE_ENABLED,
                                 PR_TRUE);
+
     FireDelayedAccessibleEvent(enabledChangeEvent);
-    nsCOMPtr<nsIAccessibleStateChangeEvent> sensitiveChangeEvent =
+
+    nsCOMPtr<nsIAccessibleEvent> sensitiveChangeEvent =
       new nsAccStateChangeEvent(targetNode,
                                 nsIAccessibleStates::EXT_STATE_SENSITIVE,
                                 PR_TRUE);
+
     FireDelayedAccessibleEvent(sensitiveChangeEvent);
     return;
   }
 
   // Check for namespaced ARIA attribute
   if (aNameSpaceID == kNameSpaceID_None) {
     // Check for hyphenated aria-foo property?
     const char* attributeName;
@@ -1172,26 +1185,27 @@ nsDocAccessible::AttributeChangedImpl(ns
   }
 
   if (aAttribute == nsAccessibilityAtoms::role ||
       aAttribute == nsAccessibilityAtoms::href ||
       aAttribute == nsAccessibilityAtoms::onclick) {
     // Not worth the expense to ensure which namespace these are in
     // It doesn't kill use to recreate the accessible even if the attribute was used
     // in the wrong namespace or an element that doesn't support it
-    InvalidateCacheSubtree(aContent, nsIAccessibleEvent::EVENT_DOM_SIGNIFICANT_CHANGE);
+    InvalidateCacheSubtree(aContent,
+                           nsIAccessibilityService::NODE_SIGNIFICANT_CHANGE);
     return;
   }
   
   if (aAttribute == nsAccessibilityAtoms::alt ||
       aAttribute == nsAccessibilityAtoms::title ||
       aAttribute == nsAccessibilityAtoms::aria_label ||
       aAttribute == nsAccessibilityAtoms::aria_labelledby) {
-    FireDelayedToolkitEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE,
-                            targetNode);
+    FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE,
+                               targetNode);
     return;
   }
 
   if (aAttribute == nsAccessibilityAtoms::selected ||
       aAttribute == nsAccessibilityAtoms::aria_selected) {
     // ARIA or XUL selection
     nsCOMPtr<nsIAccessible> multiSelect =
       nsAccUtils::GetMultiSelectFor(targetNode);
@@ -1203,62 +1217,62 @@ nsDocAccessible::AttributeChangedImpl(ns
     if (multiSelect) {
       // Need to find the right event to use here, SELECTION_WITHIN would
       // seem right but we had started using it for something else
       nsCOMPtr<nsIAccessNode> multiSelectAccessNode =
         do_QueryInterface(multiSelect);
       nsCOMPtr<nsIDOMNode> multiSelectDOMNode;
       multiSelectAccessNode->GetDOMNode(getter_AddRefs(multiSelectDOMNode));
       NS_ASSERTION(multiSelectDOMNode, "A new accessible without a DOM node!");
-      FireDelayedToolkitEvent(nsIAccessibleEvent::EVENT_SELECTION_WITHIN,
-                              multiSelectDOMNode,
-                              nsAccEvent::eAllowDupes);
+      FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_SELECTION_WITHIN,
+                                 multiSelectDOMNode,
+                                 nsAccEvent::eAllowDupes);
 
       static nsIContent::AttrValuesArray strings[] =
         {&nsAccessibilityAtoms::_empty, &nsAccessibilityAtoms::_false, nsnull};
       if (aContent->FindAttrValueIn(kNameSpaceID_None, aAttribute,
                                     strings, eCaseMatters) >= 0) {
-        FireDelayedToolkitEvent(nsIAccessibleEvent::EVENT_SELECTION_REMOVE,
-                                targetNode);
+        FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_SELECTION_REMOVE,
+                                   targetNode);
         return;
       }
 
-      FireDelayedToolkitEvent(nsIAccessibleEvent::EVENT_SELECTION_ADD,
-                                                  targetNode);
+      FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_SELECTION_ADD,
+                                 targetNode);
     }
   }
 
   if (aAttribute == nsAccessibilityAtoms::contenteditable) {
-    nsCOMPtr<nsIAccessibleStateChangeEvent> editableChangeEvent =
+    nsCOMPtr<nsIAccessibleEvent> editableChangeEvent =
       new nsAccStateChangeEvent(targetNode,
                                 nsIAccessibleStates::EXT_STATE_EDITABLE,
                                 PR_TRUE);
     FireDelayedAccessibleEvent(editableChangeEvent);
     return;
   }
 }
 
 void
 nsDocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute)
 {
   nsCOMPtr<nsIDOMNode> targetNode(do_QueryInterface(aContent));
   if (!targetNode)
     return;
 
   if (aAttribute == nsAccessibilityAtoms::aria_required) {
-    nsCOMPtr<nsIAccessibleStateChangeEvent> event =
+    nsCOMPtr<nsIAccessibleEvent> event =
       new nsAccStateChangeEvent(targetNode,
                                 nsIAccessibleStates::STATE_REQUIRED,
                                 PR_FALSE);
     FireDelayedAccessibleEvent(event);
     return;
   }
 
   if (aAttribute == nsAccessibilityAtoms::aria_invalid) {
-    nsCOMPtr<nsIAccessibleStateChangeEvent> event =
+    nsCOMPtr<nsIAccessibleEvent> event =
       new nsAccStateChangeEvent(targetNode,
                                 nsIAccessibleStates::STATE_INVALID,
                                 PR_FALSE);
     FireDelayedAccessibleEvent(event);
     return;
   }
 
   if (aAttribute == nsAccessibilityAtoms::aria_activedescendant) {
@@ -1282,88 +1296,90 @@ nsDocAccessible::ARIAAttributeChanged(ns
   }
 
   // The following ARIA attributes only take affect when dynamic content role is present
   if (aAttribute == nsAccessibilityAtoms::aria_checked ||
       aAttribute == nsAccessibilityAtoms::aria_pressed) {
     const PRUint32 kState = (aAttribute == nsAccessibilityAtoms::aria_checked) ?
                             nsIAccessibleStates::STATE_CHECKED : 
                             nsIAccessibleStates::STATE_PRESSED;
-    nsCOMPtr<nsIAccessibleStateChangeEvent> event =
+    nsCOMPtr<nsIAccessibleEvent> event =
       new nsAccStateChangeEvent(targetNode, kState, PR_FALSE);
     FireDelayedAccessibleEvent(event);
     if (targetNode == gLastFocusedNode) {
       // State changes for MIXED state currently only supported for focused item, because
       // otherwise we would need access to the old attribute value in this listener.
       // This is because we don't know if the previous value of aria-checked or aria-pressed was "mixed"
       // without caching that info.
       nsCOMPtr<nsIAccessible> accessible;
       event->GetAccessible(getter_AddRefs(accessible));
       if (accessible) {
         PRBool wasMixed = (gLastFocusedAccessiblesState & nsIAccessibleStates::STATE_MIXED) != 0;
         PRBool isMixed  =
           (nsAccUtils::State(accessible) & nsIAccessibleStates::STATE_MIXED) != 0;
         if (wasMixed != isMixed) {
-          nsCOMPtr<nsIAccessibleStateChangeEvent> event =
+          nsCOMPtr<nsIAccessibleEvent> event =
             new nsAccStateChangeEvent(targetNode,
                                       nsIAccessibleStates::STATE_MIXED,
                                       PR_FALSE, isMixed);
           FireDelayedAccessibleEvent(event);
         }
       }
     }
     return;
   }
 
   if (aAttribute == nsAccessibilityAtoms::aria_expanded) {
-    nsCOMPtr<nsIAccessibleStateChangeEvent> event =
+    nsCOMPtr<nsIAccessibleEvent> event =
       new nsAccStateChangeEvent(targetNode,
                                 nsIAccessibleStates::STATE_EXPANDED,
                                 PR_FALSE);
     FireDelayedAccessibleEvent(event);
     return;
   }
 
   if (aAttribute == nsAccessibilityAtoms::aria_readonly) {
-    nsCOMPtr<nsIAccessibleStateChangeEvent> event =
+    nsCOMPtr<nsIAccessibleEvent> event =
       new nsAccStateChangeEvent(targetNode,
                                 nsIAccessibleStates::STATE_READONLY,
                                 PR_FALSE);
     FireDelayedAccessibleEvent(event);
     return;
   }
 
   // Fire value change event whenever aria-valuetext is changed, or
   // when aria-valuenow is changed and aria-valuetext is empty
   if (aAttribute == nsAccessibilityAtoms::aria_valuetext ||      
       (aAttribute == nsAccessibilityAtoms::aria_valuenow &&
        (!aContent->HasAttr(kNameSpaceID_None,
            nsAccessibilityAtoms::aria_valuetext) ||
         aContent->AttrValueIs(kNameSpaceID_None,
             nsAccessibilityAtoms::aria_valuetext, nsAccessibilityAtoms::_empty,
             eCaseMatters)))) {
-    FireDelayedToolkitEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, targetNode);
+    FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE,
+                               targetNode);
     return;
   }
 
   if (aAttribute == nsAccessibilityAtoms::aria_multiselectable &&
       aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::role)) {
     // This affects whether the accessible supports nsIAccessibleSelectable.
     // COM says we cannot change what interfaces are supported on-the-fly,
     // so invalidate this object. A new one will be created on demand.
-    InvalidateCacheSubtree(aContent, nsIAccessibleEvent::EVENT_DOM_SIGNIFICANT_CHANGE);
+    InvalidateCacheSubtree(aContent,
+                           nsIAccessibilityService::NODE_SIGNIFICANT_CHANGE);
     return;
   }
 
   // For aria drag and drop changes we fire a generic attribute change event;
   // at least until native API comes up with a more meaningful event.
   if (aAttribute == nsAccessibilityAtoms::aria_grabbed ||
       aAttribute == nsAccessibilityAtoms::aria_dropeffect) {
-    FireDelayedToolkitEvent(nsIAccessibleEvent::EVENT_OBJECT_ATTRIBUTE_CHANGED,
-                           targetNode);
+    FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_OBJECT_ATTRIBUTE_CHANGED,
+                               targetNode);
   }
 }
 
 void nsDocAccessible::ContentAppended(nsIDocument *aDocument,
                                       nsIContent* aContainer,
                                       PRInt32 aNewIndexInContainer)
 {
   if ((!mIsContentLoaded || !mDocument) && mAccessNodeCache.Count() <= 1) {
@@ -1374,17 +1390,17 @@ void nsDocAccessible::ContentAppended(ns
 
   PRUint32 childCount = aContainer->GetChildCount();
   for (PRUint32 index = aNewIndexInContainer; index < childCount; index ++) {
     nsCOMPtr<nsIContent> child(aContainer->GetChildAt(index));
     // InvalidateCacheSubtree will not fire the EVENT_SHOW for the new node
     // unless an accessible can be created for the passed in node, which it
     // can't do unless the node is visible. The right thing happens there so
     // no need for an extra visibility check here.
-    InvalidateCacheSubtree(child, nsIAccessibleEvent::EVENT_DOM_CREATE);
+    InvalidateCacheSubtree(child, nsIAccessibilityService::NODE_APPEND);
   }
 }
 
 void nsDocAccessible::ContentStatesChanged(nsIDocument* aDocument,
                                            nsIContent* aContent1,
                                            nsIContent* aContent2,
                                            PRInt32 aStateMask)
 {
@@ -1413,28 +1429,29 @@ void nsDocAccessible::CharacterDataChang
 void
 nsDocAccessible::ContentInserted(nsIDocument *aDocument, nsIContent* aContainer,
                                  nsIContent* aChild, PRInt32 aIndexInContainer)
 {
   // InvalidateCacheSubtree will not fire the EVENT_SHOW for the new node
   // unless an accessible can be created for the passed in node, which it
   // can't do unless the node is visible. The right thing happens there so
   // no need for an extra visibility check here.
-  InvalidateCacheSubtree(aChild, nsIAccessibleEvent::EVENT_DOM_CREATE);
+  InvalidateCacheSubtree(aChild, nsIAccessibilityService::NODE_APPEND);
 }
 
 void
 nsDocAccessible::ContentRemoved(nsIDocument *aDocument, nsIContent* aContainer,
                                 nsIContent* aChild, PRInt32 aIndexInContainer)
 {
-  // Invalidate the subtree of the removed element.
-  // InvalidateCacheSubtree(aChild, nsIAccessibleEvent::EVENT_DOM_DESTROY);
-  // This is no longer needed, we get our notifications directly from content
-  // *before* the frame for the content is destroyed, or any other side effects occur.
-  // That allows us to correctly calculate the TEXT_REMOVED event if there is one.
+  // It's no needed to invalidate the subtree of the removed element,
+  // because we get notifications directly from content (see
+  // nsGenericElement::doRemoveChildAt) *before* the frame for the content is
+  // destroyed, or any other side effects occur . That allows us to correctly
+  // calculate the TEXT_REMOVED event if there is one and coalesce events from
+  // the same subtree.
 }
 
 void
 nsDocAccessible::ParentChainChanged(nsIContent *aContent)
 {
 }
 
 void
@@ -1500,27 +1517,27 @@ nsDocAccessible::FireTextChangeEventForT
     if (NS_FAILED(rv))
       return;
 
     rv = textAccessible->ContentToRenderedOffset(frame, start + length,
                                                  &renderedEndOffset);
     if (NS_FAILED(rv))
       return;
 
-    nsCOMPtr<nsIAccessibleTextChangeEvent> event =
+    nsCOMPtr<nsIAccessibleEvent> event =
       new nsAccTextChangeEvent(accessible, offset,
                                renderedEndOffset - renderedStartOffset,
                                aIsInserted, PR_FALSE);
     textAccessible->FireAccessibleEvent(event);
 
     FireValueChangeForTextFields(accessible);
   }
 }
 
-already_AddRefed<nsIAccessibleTextChangeEvent>
+already_AddRefed<nsIAccessibleEvent>
 nsDocAccessible::CreateTextChangeEventForNode(nsIAccessible *aContainerAccessible,
                                               nsIDOMNode *aChangeNode,
                                               nsIAccessible *aAccessibleForChangeNode,
                                               PRBool aIsInserting,
                                               PRBool aIsAsynch)
 {
   nsRefPtr<nsHyperTextAccessible> textAccessible;
   aContainerAccessible->QueryInterface(NS_GET_IID(nsHyperTextAccessible),
@@ -1580,132 +1597,161 @@ nsDocAccessible::CreateTextChangeEventFo
       }
     }
   }
 
   if (length <= 0) {
     return nsnull;
   }
 
-  nsIAccessibleTextChangeEvent *event =
+  nsIAccessibleEvent *event =
     new nsAccTextChangeEvent(aContainerAccessible, offset, length, aIsInserting, aIsAsynch);
   NS_IF_ADDREF(event);
 
   return event;
 }
   
-nsresult nsDocAccessible::FireDelayedToolkitEvent(PRUint32 aEvent,
-                                                  nsIDOMNode *aDOMNode,
-                                                  nsAccEvent::EEventRule aAllowDupes,
-                                                  PRBool aIsAsynch)
+nsresult
+nsDocAccessible::FireDelayedAccessibleEvent(PRUint32 aEventType,
+                                            nsIDOMNode *aDOMNode,
+                                            nsAccEvent::EEventRule aAllowDupes,
+                                            PRBool aIsAsynch)
 {
   nsCOMPtr<nsIAccessibleEvent> event =
-    new nsAccEvent(aEvent, aDOMNode, aIsAsynch, aAllowDupes);
+    new nsAccEvent(aEventType, aDOMNode, aIsAsynch, aAllowDupes);
   NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
 
   return FireDelayedAccessibleEvent(event);
 }
 
 nsresult
 nsDocAccessible::FireDelayedAccessibleEvent(nsIAccessibleEvent *aEvent)
 {
-  NS_ENSURE_TRUE(aEvent, NS_ERROR_FAILURE);
+  NS_ENSURE_ARG(aEvent);
+
+  mEventsToFire.AppendElement(aEvent);
+
+  // Filter events.
+  nsAccEvent::ApplyEventRules(mEventsToFire);
 
+  // Process events.
+  return PreparePendingEventsFlush();
+}
+
+nsresult
+nsDocAccessible::PreparePendingEventsFlush()
+{
+  nsresult rv = NS_OK;
+
+  // Create timer if we don't have it yet.
   if (!mFireEventTimer) {
-    // Do not yet have a timer going for firing another event.
-    mFireEventTimer = do_CreateInstance("@mozilla.org/timer;1");
-    NS_ENSURE_TRUE(mFireEventTimer, NS_ERROR_OUT_OF_MEMORY);
+    mFireEventTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
   }
 
-  mEventsToFire.AppendObject(aEvent);
-  if (mEventsToFire.Count() == 1) {
-    // This is be the first delayed event in queue, start timer
-    // so that event gets fired via FlushEventsCallback
-    NS_ADDREF_THIS(); // Kung fu death grip to prevent crash in callback
-    mFireEventTimer->InitWithFuncCallback(FlushEventsCallback,
-                                          this, 0, nsITimer::TYPE_ONE_SHOT);
+  // If there are delayed events in the queue and event timer wasn't started
+  // then initialize the timer so that delayed event will be processed in
+  // FlushPendingEvents.
+  if (mEventsToFire.Length() > 0 && !mFireEventTimerStarted) {
+
+    rv = mFireEventTimer->InitWithFuncCallback(FlushEventsCallback,
+                                               this, 0,
+                                               nsITimer::TYPE_ONE_SHOT);
+
+    if (NS_SUCCEEDED(rv)) {
+      // Kung fu death grip to prevent crash in callback.
+      NS_ADDREF_THIS();
+
+      mFireEventTimerStarted = PR_TRUE;
+    }
   }
 
-  return NS_OK;
+  return rv;
 }
 
 void
 nsDocAccessible::FlushPendingEvents()
 {
   mInFlushPendingEvents = PR_TRUE;
-  PRUint32 length = mEventsToFire.Count();
+
+  PRUint32 length = mEventsToFire.Length();
   NS_ASSERTION(length, "How did we get here without events to fire?");
   nsCOMPtr<nsIPresShell> presShell = GetPresShell();
   if (!presShell)
     length = 0; // The doc is now shut down, don't fire events in it anymore
   else {
     // Flush layout so that all the frame construction, reflow, and styles are
     // up-to-date. This will ensure we can get frames for the related nodes, as
     // well as get the most current information for calculating things like
     // visibility. We don't flush the display because we don't care about
     // painting. If no flush is necessary the method will simple return.
     presShell->FlushPendingNotifications(Flush_Layout);
+  }
 
-    // filter events
-    nsAccEvent::ApplyEventRules(mEventsToFire);
-  }
+  // Process only currently queued events. In the meantime, newly appended
+  // events will not be processed.
+  for (PRUint32 index = 0; index < length; index ++) {
   
-  for (PRUint32 index = 0; index < length; index ++) {
-    nsCOMPtr<nsIAccessibleEvent> accessibleEvent(
-      do_QueryInterface(mEventsToFire[index]));
+    // No presshell means the document was shut down duiring event handling
+    // by AT.
+    if (!mWeakShell)
+      break;
+
+    nsCOMPtr<nsIAccessibleEvent> accessibleEvent(mEventsToFire[index]);
 
     if (nsAccEvent::EventRule(accessibleEvent) == nsAccEvent::eDoNotEmit)
       continue;
 
     nsCOMPtr<nsIAccessible> accessible;
     accessibleEvent->GetAccessible(getter_AddRefs(accessible));
     nsCOMPtr<nsIDOMNode> domNode;
     accessibleEvent->GetDOMNode(getter_AddRefs(domNode));
     PRUint32 eventType = nsAccEvent::EventType(accessibleEvent);
     PRBool isFromUserInput = nsAccEvent::IsFromUserInput(accessibleEvent);
 
-    if (domNode == gLastFocusedNode &&
-        (eventType == nsIAccessibleEvent::EVENT_ASYNCH_HIDE || 
-        eventType == nsIAccessibleEvent::EVENT_ASYNCH_SHOW)) {
+    PRBool isAsync = nsAccEvent::IsAsyncEvent(accessibleEvent);
+    if (domNode == gLastFocusedNode && isAsync &&
+        (eventType == nsIAccessibleEvent::EVENT_SHOW ||
+         eventType == nsIAccessibleEvent::EVENT_HIDE)) {
       // If frame type didn't change for this event, then we don't actually need to invalidate
       // However, we only keep track of the old frame type for the focus, where it's very
       // important not to destroy and recreate the accessible for minor style changes,
       // such as a:focus { overflow: scroll; }
       nsCOMPtr<nsIContent> focusContent(do_QueryInterface(domNode));
       if (focusContent) {
         nsIFrame *focusFrame = presShell->GetRealPrimaryFrameFor(focusContent);
         nsIAtom *newFrameType =
           (focusFrame && focusFrame->GetStyleVisibility()->IsVisible()) ?
           focusFrame->GetType() : nsnull;
 
         if (newFrameType == gLastFocusedFrameType) {
           // Don't need to invalidate this current accessible, but can
           // just invalidate the children instead
-          FireShowHideEvents(domNode, PR_TRUE, eventType, PR_FALSE, isFromUserInput); 
+          FireShowHideEvents(domNode, PR_TRUE, eventType, eNormalEvent,
+                             isAsync, isFromUserInput); 
           continue;
         }
         gLastFocusedFrameType = newFrameType;
       }
     }
 
-    if (eventType == nsIAccessibleEvent::EVENT_DOM_CREATE || 
-        eventType == nsIAccessibleEvent::EVENT_ASYNCH_SHOW) {
+    if (eventType == nsIAccessibleEvent::EVENT_SHOW) {
 
       nsCOMPtr<nsIAccessible> containerAccessible;
       if (accessible)
         accessible->GetParent(getter_AddRefs(containerAccessible));
 
       if (!containerAccessible) {
         GetAccessibleInParentChain(domNode, PR_TRUE,
                                    getter_AddRefs(containerAccessible));
         if (!containerAccessible)
           containerAccessible = this;
       }
 
-      if (eventType == nsIAccessibleEvent::EVENT_ASYNCH_SHOW) {
+      if (isAsync) {
         // For asynch show, delayed invalidatation of parent's children
         nsRefPtr<nsAccessible> containerAcc =
           nsAccUtils::QueryAccessible(containerAccessible);
         if (containerAcc)
           containerAcc->InvalidateChildren();
 
         // Some show events in the subtree may have been removed to 
         // avoid firing redundant events. But, we still need to make sure any
@@ -1714,29 +1760,30 @@ nsDocAccessible::FlushPendingEvents()
       }
 
       // Also fire text changes if the node being created could affect the text in an nsIAccessibleText parent.
       // When a node is being made visible or is inserted, the text in an ancestor hyper text will gain characters
       // At this point we now have the frame and accessible for this node if there is one. That is why we
       // wait to fire this here, instead of in InvalidateCacheSubtree(), where we wouldn't be able to calculate
       // the offset, length and text for the text change.
       if (domNode && domNode != mDOMNode) {
-        nsCOMPtr<nsIAccessibleTextChangeEvent> textChangeEvent =
+        nsCOMPtr<nsIAccessibleEvent> textChangeEvent =
           CreateTextChangeEventForNode(containerAccessible, domNode, accessible, PR_TRUE, PR_TRUE);
         if (textChangeEvent) {
           nsAccEvent::PrepareForEvent(textChangeEvent, isFromUserInput);
           // XXX Queue them up and merge the text change events
           // XXX We need a way to ignore SplitNode and JoinNode() when they
           // do not affect the text within the hypertext
           FireAccessibleEvent(textChangeEvent);
         }
       }
 
       // Fire show/create events for this node or first accessible descendants of it
-      FireShowHideEvents(domNode, PR_FALSE, eventType, PR_FALSE, isFromUserInput); 
+      FireShowHideEvents(domNode, PR_FALSE, eventType, eNormalEvent, isAsync,
+                         isFromUserInput); 
       continue;
     }
 
     if (accessible) {
       if (eventType == nsIAccessibleEvent::EVENT_INTERNAL_LOAD) {
         nsRefPtr<nsDocAccessible> docAcc =
           nsAccUtils::QueryAccessibleDocument(accessible);
         NS_ASSERTION(docAcc, "No doc accessible for doc load event");
@@ -1755,17 +1802,17 @@ nsDocAccessible::FlushPendingEvents()
 #endif
 #ifdef DEBUG_CARET
           // Test caret line # -- fire an EVENT_ALERT on the focused node so we can watch the
           // line-number object attribute on it
           nsCOMPtr<nsIAccessible> accForFocus;
           GetAccService()->GetAccessibleFor(gLastFocusedNode, getter_AddRefs(accForFocus));
           nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_ALERT, accForFocus);
 #endif
-          nsCOMPtr<nsIAccessibleCaretMoveEvent> caretMoveEvent =
+          nsCOMPtr<nsIAccessibleEvent> caretMoveEvent =
             new nsAccCaretMoveEvent(accessible, caretOffset);
           if (!caretMoveEvent)
             break; // Out of memory, break out to release kung fu death grip
 
           FireAccessibleEvent(caretMoveEvent);
 
           PRInt32 selectionCount;
           accessibleText->GetSelectionCount(&selectionCount);
@@ -1787,34 +1834,46 @@ nsDocAccessible::FlushPendingEvents()
         }
       }
       else {
         // The input state was previously stored with the nsIAccessibleEvent,
         // so use that state now when firing the event
         nsAccEvent::PrepareForEvent(accessibleEvent);
         FireAccessibleEvent(accessibleEvent);
         // Post event processing
-        if (eventType == nsIAccessibleEvent::EVENT_ASYNCH_HIDE ||
-            eventType == nsIAccessibleEvent::EVENT_DOM_DESTROY) {
-          // Shutdown nsIAccessNode's or nsIAccessibles for any DOM nodes in this subtree
+        if (eventType == nsIAccessibleEvent::EVENT_HIDE) {
+          // Shutdown nsIAccessNode's or nsIAccessibles for any DOM nodes in
+          // this subtree.
           nsCOMPtr<nsIDOMNode> hidingNode;
           accessibleEvent->GetDOMNode(getter_AddRefs(hidingNode));
           if (hidingNode) {
             RefreshNodes(hidingNode); // Will this bite us with asynch events
           }
         }
       }
     }
   }
-  mEventsToFire.Clear(); // Clear out array
+
+  // Mark we are ready to start event processing timer again.
+  mFireEventTimerStarted = PR_FALSE;
+
+  // If the document accessible is alive then remove processed events from the
+  // queue (otherwise they were removed on shutdown already) and reinitialize
+  // queue processing callback if necessary (new events might occur duiring
+  // delayed event processing).
+  if (mWeakShell) {
+    mEventsToFire.RemoveElementsAt(0, length);
+    PreparePendingEventsFlush();
+  }
+
+  // After a flood of events, reset so that user input flag is off.
+  nsAccEvent::ResetLastInputState();
+
   mInFlushPendingEvents = PR_FALSE;
-  NS_RELEASE_THIS(); // Release kung fu death grip
-
-  // After a flood of events, reset so that user input flag is off
-  nsAccEvent::ResetLastInputState();
+  NS_RELEASE_THIS(); // Release kung fu death grip.
 }
 
 void nsDocAccessible::FlushEventsCallback(nsITimer *aTimer, void *aClosure)
 {
   nsDocAccessible *accessibleDoc = static_cast<nsDocAccessible*>(aClosure);
   NS_ASSERTION(accessibleDoc, "How did we get here without an accessible document?");
   if (accessibleDoc) {
     // A lot of crashes were happening here, so now we're reffing the doc
@@ -1927,37 +1986,37 @@ void nsDocAccessible::RefreshNodes(nsIDO
   accNode->Shutdown();
 
   // Remove from hash table as well
   mAccessNodeCache.Remove(uniqueID);
 }
 
 void
 nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
-                                        PRUint32 aChangeEventType)
+                                        PRUint32 aChangeType)
 {
-  PRBool isHiding = 
-    aChangeEventType == nsIAccessibleEvent::EVENT_ASYNCH_HIDE ||
-    aChangeEventType == nsIAccessibleEvent::EVENT_DOM_DESTROY;
+  PRBool isHiding =
+    aChangeType == nsIAccessibilityService::FRAME_HIDE ||
+    aChangeType == nsIAccessibilityService::NODE_REMOVE;
 
-  PRBool isShowing = 
-    aChangeEventType == nsIAccessibleEvent::EVENT_ASYNCH_SHOW ||
-    aChangeEventType == nsIAccessibleEvent::EVENT_DOM_CREATE;
+  PRBool isShowing =
+    aChangeType == nsIAccessibilityService::FRAME_SHOW ||
+    aChangeType == nsIAccessibilityService::NODE_APPEND;
 
-  PRBool isChanging = 
-    aChangeEventType == nsIAccessibleEvent::EVENT_DOM_SIGNIFICANT_CHANGE ||
-    aChangeEventType == nsIAccessibleEvent::EVENT_ASYNCH_SIGNIFICANT_CHANGE;
+  PRBool isChanging =
+    aChangeType == nsIAccessibilityService::NODE_SIGNIFICANT_CHANGE ||
+    aChangeType == nsIAccessibilityService::FRAME_SIGNIFICANT_CHANGE;
 
   NS_ASSERTION(isChanging || isHiding || isShowing,
                "Incorrect aChangeEventType passed in");
 
-  PRBool isAsynch = 
-    aChangeEventType == nsIAccessibleEvent::EVENT_ASYNCH_HIDE ||
-    aChangeEventType == nsIAccessibleEvent::EVENT_ASYNCH_SHOW ||
-    aChangeEventType == nsIAccessibleEvent::EVENT_ASYNCH_SIGNIFICANT_CHANGE;
+  PRBool isAsynch =
+    aChangeType == nsIAccessibilityService::FRAME_HIDE ||
+    aChangeType == nsIAccessibilityService::FRAME_SHOW ||
+    aChangeType == nsIAccessibilityService::FRAME_SIGNIFICANT_CHANGE;
 
   // Invalidate cache subtree
   // We have to check for accessibles for each dom node by traversing DOM tree
   // instead of just the accessible tree, although that would be faster
   // Otherwise we might miss the nsAccessNode's that are not nsAccessible's.
 
   NS_ENSURE_TRUE(mDOMNode,);
 
@@ -2007,44 +2066,38 @@ nsDocAccessible::InvalidateCacheSubtree(
   nsCOMPtr<nsIAccessNode> childAccessNode;
   GetCachedAccessNode(childNode, getter_AddRefs(childAccessNode));
   nsCOMPtr<nsIAccessible> childAccessible = do_QueryInterface(childAccessNode);
 
 #ifdef DEBUG_A11Y
   nsAutoString localName;
   childNode->GetLocalName(localName);
   const char *hasAccessible = childAccessible ? " (acc)" : "";
-  if (aChangeEventType == nsIAccessibleEvent::EVENT_ASYNCH_HIDE) {
+  if (aChangeType == nsIAccessibilityService::FRAME_HIDE)
     printf("[Hide %s %s]\n", NS_ConvertUTF16toUTF8(localName).get(), hasAccessible);
-  }
-  else if (aChangeEventType == nsIAccessibleEvent::EVENT_ASYNCH_SHOW) {
+  else if (aChangeType == nsIAccessibilityService::FRAME_SHOW)
     printf("[Show %s %s]\n", NS_ConvertUTF16toUTF8(localName).get(), hasAccessible);
-  }
-  else if (aChangeEventType == nsIAccessibleEvent::EVENT_ASYNCH_SIGNIFICANT_CHANGE) {
+  else if (aChangeType == nsIAccessibilityService::FRAME_SIGNIFICANT_CHANGE)
     printf("[Layout change %s %s]\n", NS_ConvertUTF16toUTF8(localName).get(), hasAccessible);
-  }
-  else if (aChangeEventType == nsIAccessibleEvent::EVENT_DOM_CREATE) {
+  else if (aChangeType == nsIAccessibleEvent::NODE_APPEND)
     printf("[Create %s %s]\n", NS_ConvertUTF16toUTF8(localName).get(), hasAccessible);
-  }
-  else if (aChangeEventType == nsIAccessibleEvent::EVENT_DOM_DESTROY) {
+  else if (aChangeType == nsIAccessibilityService::NODE_REMOVE)
     printf("[Destroy  %s %s]\n", NS_ConvertUTF16toUTF8(localName).get(), hasAccessible);
-  }
-  else if (aChangeEventType == nsIAccessibleEvent::EVENT_DOM_SIGNIFICANT_CHANGE) {
+  else if (aChangeEventType == nsIAccessibilityService::NODE_SIGNIFICANT_CHANGE)
     printf("[Type change %s %s]\n", NS_ConvertUTF16toUTF8(localName).get(), hasAccessible);
-  }
 #endif
 
   nsCOMPtr<nsIAccessible> containerAccessible;
   GetAccessibleInParentChain(childNode, PR_TRUE, getter_AddRefs(containerAccessible));
   if (!containerAccessible) {
     containerAccessible = this;
   }
 
   if (!isShowing) {
-    // Fire EVENT_ASYNCH_HIDE or EVENT_DOM_DESTROY
+    // Fire EVENT_HIDE.
     if (isHiding) {
       nsCOMPtr<nsIContent> content(do_QueryInterface(childNode));
       if (content) {
         nsIFrame *frame = presShell->GetPrimaryFrameFor(content);
         if (frame) {
           nsIFrame *frameParent = frame->GetParent();
           if (!frameParent || !frameParent->GetStyleVisibility()->IsVisible()) {
             // Ancestor already hidden or being hidden at the same time:
@@ -2053,31 +2106,31 @@ nsDocAccessible::InvalidateCacheSubtree(
             // which hides an entire subtree -- we get notified for each
             // node in the subtree and need to collate the hide events ourselves.
             return;
           }
         }
       }
     }
 
-    PRUint32 removalEventType = isAsynch ? nsIAccessibleEvent::EVENT_ASYNCH_HIDE :
-                                           nsIAccessibleEvent::EVENT_DOM_DESTROY;
-
     // Fire an event if the accessible existed for node being hidden, otherwise
-    // for the first line accessible descendants. Fire before the accessible(s) away.
-    nsresult rv = FireShowHideEvents(childNode, PR_FALSE, removalEventType, PR_TRUE, PR_FALSE);
+    // for the first line accessible descendants. Fire before the accessible(s)
+    // away.
+    nsresult rv = FireShowHideEvents(childNode, PR_FALSE,
+                                     nsIAccessibleEvent::EVENT_HIDE,
+                                     eDelayedEvent, isAsynch, PR_FALSE);
     NS_ENSURE_SUCCESS(rv,);
 
     if (childNode != mDOMNode) { // Fire text change unless the node being removed is for this doc
       // When a node is hidden or removed, the text in an ancestor hyper text will lose characters
       // At this point we still have the frame and accessible for this node if there was one
       // XXX Collate events when a range is deleted
       // XXX We need a way to ignore SplitNode and JoinNode() when they
       // do not affect the text within the hypertext
-      nsCOMPtr<nsIAccessibleTextChangeEvent> textChangeEvent =
+      nsCOMPtr<nsIAccessibleEvent> textChangeEvent =
         CreateTextChangeEventForNode(containerAccessible, childNode, childAccessible,
                                      PR_FALSE, isAsynch);
       if (textChangeEvent) {
         FireAccessibleEvent(textChangeEvent);
       }
     }
   }
 
@@ -2093,43 +2146,44 @@ nsDocAccessible::InvalidateCacheSubtree(
       // DOM already updated with new objects -- invalidate parent's children now
       // For asynch we must wait until layout updates before we invalidate the children
       nsRefPtr<nsAccessible> containerAcc =
         nsAccUtils::QueryAccessible(containerAccessible);
       if (containerAcc)
         containerAcc->InvalidateChildren();
 
     }
+
     // Fire EVENT_SHOW, EVENT_MENUPOPUP_START for newly visible content.
+
     // Fire after a short timer, because we want to make sure the view has been
     // updated to make this accessible content visible. If we don't wait,
     // the assistive technology may receive the event and then retrieve
     // nsIAccessibleStates::STATE_INVISIBLE for the event's accessible object.
-    PRUint32 additionEvent = isAsynch ? nsIAccessibleEvent::EVENT_ASYNCH_SHOW :
-                                        nsIAccessibleEvent::EVENT_DOM_CREATE;
-    FireDelayedToolkitEvent(additionEvent, childNode,
-                            nsAccEvent::eCoalesceFromSameSubtree,
-                            isAsynch);
+
+    FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_SHOW, childNode,
+                               nsAccEvent::eCoalesceFromSameSubtree,
+                               isAsynch);
 
     // Check to see change occured in an ARIA menu, and fire
     // an EVENT_MENUPOPUP_START if it did.
     nsRoleMapEntry *roleMapEntry = nsAccUtils::GetRoleMapEntry(childNode);
     if (roleMapEntry && roleMapEntry->role == nsIAccessibleRole::ROLE_MENUPOPUP) {
-      FireDelayedToolkitEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_START,
-                              childNode, nsAccEvent::eRemoveDupes,
-                              isAsynch);
+      FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_START,
+                                 childNode, nsAccEvent::eRemoveDupes,
+                                 isAsynch);
     }
 
     // Check to see if change occured inside an alert, and fire an EVENT_ALERT if it did
     nsIContent *ancestor = aChild;
     while (PR_TRUE) {
       if (roleMapEntry && roleMapEntry->role == nsIAccessibleRole::ROLE_ALERT) {
         nsCOMPtr<nsIDOMNode> alertNode(do_QueryInterface(ancestor));
-        FireDelayedToolkitEvent(nsIAccessibleEvent::EVENT_ALERT, alertNode,
-                                nsAccEvent::eRemoveDupes, isAsynch);
+        FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_ALERT, alertNode,
+                                   nsAccEvent::eRemoveDupes, isAsynch);
         break;
       }
       ancestor = ancestor->GetParent();
       nsCOMPtr<nsIDOMNode> ancestorNode = do_QueryInterface(ancestor);
       if (!ancestorNode) {
         break;
       }
       roleMapEntry = nsAccUtils::GetRoleMapEntry(ancestorNode);
@@ -2199,60 +2253,63 @@ nsDocAccessible::GetAccessibleInParentCh
       }
     }
   } while (!*aAccessible);
 
   return NS_OK;
 }
 
 nsresult
-nsDocAccessible::FireShowHideEvents(nsIDOMNode *aDOMNode, PRBool aAvoidOnThisNode, PRUint32 aEventType,
-                                    PRBool aDelay, PRBool aForceIsFromUserInput)
+nsDocAccessible::FireShowHideEvents(nsIDOMNode *aDOMNode,
+                                    PRBool aAvoidOnThisNode,
+                                    PRUint32 aEventType,
+                                    EEventFiringType aDelayedOrNormal,
+                                    PRBool aIsAsyncChange,
+                                    PRBool aForceIsFromUserInput)
 {
   NS_ENSURE_ARG(aDOMNode);
 
   nsCOMPtr<nsIAccessible> accessible;
   if (!aAvoidOnThisNode) {
-    if (aEventType == nsIAccessibleEvent::EVENT_ASYNCH_HIDE ||
-        aEventType == nsIAccessibleEvent::EVENT_DOM_DESTROY) {
+    if (aEventType == nsIAccessibleEvent::EVENT_HIDE) {
       // Don't allow creation for accessibles when nodes going away
       nsCOMPtr<nsIAccessNode> accessNode;
       GetCachedAccessNode(aDOMNode, getter_AddRefs(accessNode));
       accessible = do_QueryInterface(accessNode);
     } else {
       // Allow creation of new accessibles for show events
       GetAccService()->GetAttachedAccessibleFor(aDOMNode,
                                                 getter_AddRefs(accessible));
     }
   }
 
   if (accessible) {
-    // Found an accessible, so fire the show/hide on it and don't
-    // look further into this subtree
-    PRBool isAsynch = aEventType == nsIAccessibleEvent::EVENT_ASYNCH_HIDE ||
-                      aEventType == nsIAccessibleEvent::EVENT_ASYNCH_SHOW;
-
+    // Found an accessible, so fire the show/hide on it and don't look further
+    // into this subtree.
     nsCOMPtr<nsIAccessibleEvent> event =
-      new nsAccEvent(aEventType, accessible, isAsynch,
+      new nsAccEvent(aEventType, accessible, aIsAsyncChange,
                      nsAccEvent::eCoalesceFromSameSubtree);
     NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
+
     if (aForceIsFromUserInput) {
       nsAccEvent::PrepareForEvent(event, aForceIsFromUserInput);
     }
-    if (aDelay) {
+
+    if (aDelayedOrNormal == eDelayedEvent)
       return FireDelayedAccessibleEvent(event);
-    }
+
     return FireAccessibleEvent(event);
   }
 
   // Could not find accessible to show hide yet, so fire on any
   // accessible descendants in this subtree
   nsCOMPtr<nsINode> node(do_QueryInterface(aDOMNode));
   PRUint32 count = node->GetChildCount();
   for (PRUint32 index = 0; index < count; index++) {
     nsCOMPtr<nsIDOMNode> childNode = do_QueryInterface(node->GetChildAt(index));
     nsresult rv = FireShowHideEvents(childNode, PR_FALSE, aEventType,
-                                     aDelay, aForceIsFromUserInput);
+                                     aDelayedOrNormal, aIsAsyncChange,
+                                     aForceIsFromUserInput);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
--- a/accessible/src/base/nsDocAccessible.h
+++ b/accessible/src/base/nsDocAccessible.h
@@ -116,25 +116,25 @@ public:
   // nsIAccessibleText
   NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
 
   // nsDocAccessible
 
   /**
    * Non-virtual method to fire a delayed event after a 0 length timeout.
    *
-   * @param aEvent       [in] the nsIAccessibleEvent event type
+   * @param aEventType   [in] the nsIAccessibleEvent event type
    * @param aDOMNode     [in] DOM node the accesible event should be fired for
    * @param aAllowDupes  [in] rule to process an event (see EEventRule constants)
    * @param aIsAsynch    [in] set to PR_TRUE if this is not being called from
    *                      code synchronous with a DOM event
    */
-  nsresult FireDelayedToolkitEvent(PRUint32 aEvent, nsIDOMNode *aDOMNode,
-                                   nsAccEvent::EEventRule aAllowDupes = nsAccEvent::eRemoveDupes,
-                                   PRBool aIsAsynch = PR_FALSE);
+  nsresult FireDelayedAccessibleEvent(PRUint32 aEventType, nsIDOMNode *aDOMNode,
+                                      nsAccEvent::EEventRule aAllowDupes = nsAccEvent::eRemoveDupes,
+                                      PRBool aIsAsynch = PR_FALSE);
 
   /**
    * Fire accessible event after timeout.
    *
    * @param aEvent  [in] the event to fire
    */
   nsresult FireDelayedAccessibleEvent(nsIAccessibleEvent *aEvent);
 
@@ -161,21 +161,16 @@ public:
   void CacheAccessNode(void *aUniqueID, nsIAccessNode *aAccessNode);
 
   /**
    * Remove the given access node from document cache.
    */
   void RemoveAccessNodeFromCache(nsIAccessNode *aAccessNode);
 
   /**
-   * Fires pending events.
-   */
-  void FlushPendingEvents();
-
-  /**
    * Fire document load events.
    *
    * @param  aEventType  [in] nsIAccessibleEvent constant
    */
   virtual void FireDocLoadEvents(PRUint32 aEventType);
 
   /**
    * Process the case when anchor was clicked.
@@ -220,16 +215,26 @@ protected:
     /**
      * Fires accessible events when ARIA attribute is changed.
      *
      * @param aContent - node that attribute is changed for
      * @param aAttribute - changed attribute
      */
     void ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute);
 
+  /**
+   * Process delayed (pending) events resulted in normal events firing.
+   */
+  void FlushPendingEvents();
+
+  /**
+   * Start the timer to flush delayed (pending) events.
+   */
+  nsresult PreparePendingEventsFlush();
+
     /**
      * Fire text changed event for character data changed. The method is used
      * from nsIMutationObserver methods.
      *
      * @param aContent     the text node holding changed data
      * @param aInfo        info structure describing how the data was changed
      * @param aIsInserted  the flag pointed whether removed or inserted
      *                     characters should be cause of event
@@ -240,55 +245,71 @@ protected:
 
     /**
      * Create a text change event for a changed node
      * @param aContainerAccessible, the first accessible in the container
      * @param aChangeNode, the node that is being inserted or removed, or shown/hidden
      * @param aAccessibleForChangeNode, the accessible for that node, or nsnull if none exists
      * @param aIsInserting, is aChangeNode being created or shown (vs. removed or hidden)
      */
-    already_AddRefed<nsIAccessibleTextChangeEvent>
+    already_AddRefed<nsIAccessibleEvent>
     CreateTextChangeEventForNode(nsIAccessible *aContainerAccessible,
                                  nsIDOMNode *aChangeNode,
                                  nsIAccessible *aAccessibleForNode,
                                  PRBool aIsInserting,
                                  PRBool aIsAsynch);
 
-    /**
-     * Fire show/hide events for either the current node if it has an accessible,
-     * or the first-line accessible descendants of the given node.
-     *
-     * @param aDOMNode               the given node
-     * @param aEventType             event type to fire an event
-     * @param aAvoidOnThisNode       Call with PR_TRUE the first time to prevent event firing on root node for change
-     * @param aDelay                 whether to fire the event on a delay
-     * @param aForceIsFromUserInput  the event is known to be from user input
-     */
-    nsresult FireShowHideEvents(nsIDOMNode *aDOMNode, PRBool aAvoidOnThisNode, PRUint32 aEventType,
-                                PRBool aDelay, PRBool aForceIsFromUserInput);
+  /**
+   * Used to define should the event be fired on a delay.
+   */
+  enum EEventFiringType {
+    eNormalEvent,
+    eDelayedEvent
+  };
+
+  /**
+   * Fire show/hide events for either the current node if it has an accessible,
+   * or the first-line accessible descendants of the given node.
+   *
+   * @param aDOMNode               [in] the given node
+   * @param aAvoidOnThisNode       [in] call with PR_TRUE the first time to
+   *                                prevent event firing on root node for change
+   * @param aEventType             [in] event type to fire an event
+   * @param aDelayedOrNormal       [in] whether to fire the event on a delay
+   * @param aIsAsyncChange         [in] whether casual change is async
+   * @param aForceIsFromUserInput  [in] the event is known to be from user input
+   */
+  nsresult FireShowHideEvents(nsIDOMNode *aDOMNode, PRBool aAvoidOnThisNode,
+                              PRUint32 aEventType,
+                              EEventFiringType aDelayedOrNormal,
+                              PRBool aIsAsyncChange,
+                              PRBool aForceIsFromUserInput);
 
     /**
      * If the given accessible object is a ROLE_ENTRY, fire a value change event for it
      */
     void FireValueChangeForTextFields(nsIAccessible *aPossibleTextFieldAccessible);
 
     nsAccessNodeHashtable mAccessNodeCache;
     void *mWnd;
     nsCOMPtr<nsIDocument> mDocument;
     nsCOMPtr<nsITimer> mScrollWatchTimer;
     nsCOMPtr<nsITimer> mFireEventTimer;
     PRUint16 mScrollPositionChangedTicks; // Used for tracking scroll events
     PRPackedBool mIsContentLoaded;
     PRPackedBool mIsLoadCompleteFired;
-    nsCOMArray<nsIAccessibleEvent> mEventsToFire;
 
 protected:
     PRBool mIsAnchor;
     PRBool mIsAnchorJumped;
-    PRBool mInFlushPendingEvents;
+
+  PRBool mInFlushPendingEvents;
+  PRBool mFireEventTimerStarted;
+  nsTArray<nsCOMPtr<nsIAccessibleEvent> > mEventsToFire;
+
     static PRUint32 gLastFocusedAccessiblesState;
     static nsIAtom *gLastFocusedFrameType;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsDocAccessible,
                               NS_DOCACCESSIBLE_IMPL_CID)
 
 #endif  
--- a/accessible/src/base/nsRootAccessible.cpp
+++ b/accessible/src/base/nsRootAccessible.cpp
@@ -391,17 +391,18 @@ void nsRootAccessible::TryFireEarlyLoadE
       return;
     }
   }
   nsCOMPtr<nsIDocShellTreeItem> rootContentTreeItem;
   treeItem->GetSameTypeRootTreeItem(getter_AddRefs(rootContentTreeItem));
   NS_ASSERTION(rootContentTreeItem, "No root content tree item");
   if (rootContentTreeItem == treeItem) {
     // No frames or iframes, so we can fire the doc load finished event early
-    FireDelayedToolkitEvent(nsIAccessibleEvent::EVENT_INTERNAL_LOAD, aDocNode);
+    FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_INTERNAL_LOAD,
+                               aDocNode);
   }
 }
 
 PRBool nsRootAccessible::FireAccessibleFocusEvent(nsIAccessible *aAccessible,
                                                   nsIDOMNode *aNode,
                                                   nsIDOMEvent *aFocusEvent,
                                                   PRBool aForceEvent,
                                                   PRBool aIsAsynch)
@@ -533,19 +534,19 @@ PRBool nsRootAccessible::FireAccessibleF
     if (realFocusedNode != aNode || realFocusedNode == mDOMNode) {
       // Suppress document focus, because real DOM focus will be fired next,
       // and that's what we care about
       // Make sure we never fire focus for the nsRootAccessible (mDOMNode)
       return PR_FALSE;
     }
   }
 
-  FireDelayedToolkitEvent(nsIAccessibleEvent::EVENT_FOCUS,
-                          finalFocusNode, nsAccEvent::eRemoveDupes,
-                          aIsAsynch);
+  FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_FOCUS,
+                             finalFocusNode, nsAccEvent::eRemoveDupes,
+                             aIsAsynch);
 
   return PR_TRUE;
 }
 
 void nsRootAccessible::FireCurrentFocusEvent()
 {
   nsCOMPtr<nsIDOMNode> focusedNode = GetCurrentFocus();
   if (!focusedNode) {
@@ -678,33 +679,33 @@ nsresult nsRootAccessible::HandleEventWi
 
     // radiogroup in prefWindow is exposed as a list,
     // and panebutton is exposed as XULListitem in A11y.
     // nsXULListitemAccessible::GetStateInternal uses STATE_SELECTED in this case,
     // so we need to check nsIAccessibleStates::STATE_SELECTED also.
     PRBool isEnabled = (state & (nsIAccessibleStates::STATE_CHECKED |
                         nsIAccessibleStates::STATE_SELECTED)) != 0;
 
-    nsCOMPtr<nsIAccessibleStateChangeEvent> accEvent =
+    nsCOMPtr<nsIAccessibleEvent> accEvent =
       new nsAccStateChangeEvent(accessible, nsIAccessibleStates::STATE_CHECKED,
                                 PR_FALSE, isEnabled);
     acc->FireAccessibleEvent(accEvent);
 
     if (isEnabled)
       FireAccessibleFocusEvent(accessible, aTargetNode, aEvent);
 
     return NS_OK;
   }
 
   if (eventType.EqualsLiteral("CheckboxStateChange")) {
     PRUint32 state = nsAccUtils::State(accessible);
 
     PRBool isEnabled = !!(state & nsIAccessibleStates::STATE_CHECKED);
 
-    nsCOMPtr<nsIAccessibleStateChangeEvent> accEvent =
+    nsCOMPtr<nsIAccessibleEvent> accEvent =
       new nsAccStateChangeEvent(accessible,
                                 nsIAccessibleStates::STATE_CHECKED,
                                 PR_FALSE, isEnabled);
 
     return acc->FireAccessibleEvent(accEvent);
   }
 
   nsCOMPtr<nsIAccessible> treeItemAccessible;
@@ -730,17 +731,17 @@ nsresult nsRootAccessible::HandleEventWi
   }
 #endif
 
 #ifdef MOZ_XUL
   if (treeItemAccessible && eventType.EqualsLiteral("OpenStateChange")) {
     PRUint32 state = nsAccUtils::State(accessible); // collapsed/expanded changed
     PRBool isEnabled = (state & nsIAccessibleStates::STATE_EXPANDED) != 0;
 
-    nsCOMPtr<nsIAccessibleStateChangeEvent> accEvent =
+    nsCOMPtr<nsIAccessibleEvent> accEvent =
       new nsAccStateChangeEvent(accessible, nsIAccessibleStates::STATE_EXPANDED,
                                 PR_FALSE, isEnabled);
     return FireAccessibleEvent(accEvent);
   }
 
   if (treeItemAccessible && eventType.EqualsLiteral("select")) {
     // If multiselect tree, we should fire selectionadd or selection removed
     if (gLastFocusedNode == aTargetNode) {
@@ -888,17 +889,18 @@ nsresult nsRootAccessible::HandleEventWi
   }
   else if (eventType.EqualsLiteral("DOMMenuBarInactive")) {  // Always asynch, always from user input
     nsAccEvent::PrepareForEvent(aTargetNode, PR_TRUE);
     nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENU_END,
                              accessible, PR_TRUE);
     FireCurrentFocusEvent();
   }
   else if (eventType.EqualsLiteral("ValueChange")) {
-    FireDelayedToolkitEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, aTargetNode, nsAccEvent::eRemoveDupes);
+    FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE,
+                               aTargetNode, nsAccEvent::eRemoveDupes);
   }
 #ifdef DEBUG
   else if (eventType.EqualsLiteral("mouseover")) {
     nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_DRAGDROP_START,
                              accessible);
   }
 #endif
   return NS_OK;
@@ -1086,30 +1088,30 @@ nsRootAccessible::HandlePopupShownEvent(
                                     aAccessible);
   }
 
   if (role == nsIAccessibleRole::ROLE_TOOLTIP) {
     // There is a single <xul:tooltip> node which Mozilla moves around.
     // The accessible for it stays the same no matter where it moves. 
     // AT's expect to get an EVENT_SHOW for the tooltip. 
     // In event callback the tooltip's accessible will be ready.
-    return nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_ASYNCH_SHOW,
+    return nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_SHOW,
                                     aAccessible);
   }
 
   if (role == nsIAccessibleRole::ROLE_COMBOBOX_LIST) {
     // Fire expanded state change event for comboboxes and autocompeletes.
     nsCOMPtr<nsIAccessible> comboboxAcc;
     nsresult rv = aAccessible->GetParent(getter_AddRefs(comboboxAcc));
     NS_ENSURE_SUCCESS(rv, rv);
 
     PRUint32 comboboxRole = nsAccUtils::Role(comboboxAcc);
     if (comboboxRole == nsIAccessibleRole::ROLE_COMBOBOX ||
         comboboxRole == nsIAccessibleRole::ROLE_AUTOCOMPLETE) {
-      nsCOMPtr<nsIAccessibleStateChangeEvent> event =
+      nsCOMPtr<nsIAccessibleEvent> event =
         new nsAccStateChangeEvent(comboboxAcc,
                                   nsIAccessibleStates::STATE_EXPANDED,
                                   PR_FALSE, PR_TRUE);
       NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
 
       nsRefPtr<nsAccessible> acc(nsAccUtils::QueryAccessible(comboboxAcc));
       return acc->FireAccessibleEvent(event);
     }
@@ -1143,17 +1145,17 @@ nsRootAccessible::HandlePopupHidingEvent
 
   nsCOMPtr<nsIAccessible> comboboxAcc;
   nsresult rv = aAccessible->GetParent(getter_AddRefs(comboboxAcc));
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRUint32 comboboxRole = nsAccUtils::Role(comboboxAcc);
   if (comboboxRole == nsIAccessibleRole::ROLE_COMBOBOX ||
       comboboxRole == nsIAccessibleRole::ROLE_AUTOCOMPLETE) {
-    nsCOMPtr<nsIAccessibleStateChangeEvent> event =
+    nsCOMPtr<nsIAccessibleEvent> event =
       new nsAccStateChangeEvent(comboboxAcc,
                                 nsIAccessibleStates::STATE_EXPANDED,
                                 PR_FALSE, PR_FALSE);
     NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
 
     nsRefPtr<nsAccessible> acc(nsAccUtils::QueryAccessible(comboboxAcc));
     return acc->FireAccessibleEvent(event);
   }
--- a/accessible/src/html/Makefile.in
+++ b/accessible/src/html/Makefile.in
@@ -43,19 +43,16 @@ VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = accessibility
 LIBRARY_NAME = accessibility_html_s
 LIBXUL_LIBRARY = 1
 
 
-ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
-REQUIRES += editor
-endif
 
 CPPSRCS = \
   nsHTMLAreaAccessible.cpp \
   nsHTMLFormControlAccessible.cpp \
   nsHTMLImageAccessible.cpp \
   nsHTMLLinkAccessible.cpp \
   nsHTMLSelectAccessible.cpp \
   nsHTMLTableAccessible.cpp \
--- a/accessible/src/html/nsHTMLTableAccessible.cpp
+++ b/accessible/src/html/nsHTMLTableAccessible.cpp
@@ -15,17 +15,18 @@
  * The Original Code is mozilla.org code.
  *
  * The Initial Developer of the Original Code is
  * Netscape Communications Corporation.
  * Portions created by the Initial Developer are Copyright (C) 1998
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
- *   Author: Aaron Leventhal (aaronl@netscape.com)
+ *   Aaron Leventhal <aaronl@netscape.com> (original author)
+ *   Alexander Surkov <surkov.alexander@gmail.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either of the GNU General Public License Version 2 or later (the "GPL"),
  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -53,31 +54,39 @@
 #include "nsIDOMHTMLTableElement.h"
 #include "nsIDOMHTMLTableRowElement.h"
 #include "nsIDOMHTMLTableSectionElem.h"
 #include "nsIDocument.h"
 #include "nsIPresShell.h"
 #include "nsIServiceManager.h"
 #include "nsITableLayout.h"
 #include "nsITableCellLayout.h"
+#include "nsFrameSelection.h"
 #include "nsLayoutErrors.h"
+#include "nsArrayUtils.h"
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsHTMLTableCellAccessible implementation
-
-// nsISupports
+// nsHTMLTableCellAccessible
+////////////////////////////////////////////////////////////////////////////////
 
-NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLTableCellAccessible, nsHyperTextAccessible)
-
-nsHTMLTableCellAccessible::nsHTMLTableCellAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell):
-nsHyperTextAccessibleWrap(aDomNode, aShell)
-{ 
+nsHTMLTableCellAccessible::
+  nsHTMLTableCellAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell) :
+  nsHyperTextAccessibleWrap(aDomNode, aShell)
+{
 }
 
-// nsAccessible
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLTableCellAccessible: nsISupports implementation
+
+NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLTableCellAccessible,
+                             nsHyperTextAccessible,
+                             nsIAccessibleTableCell)
+
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLTableCellAccessible: nsAccessible implementation
 
 nsresult
 nsHTMLTableCellAccessible::GetRoleInternal(PRUint32 *aResult)
 {
   *aResult = nsIAccessibleRole::ROLE_CELL;
   return NS_OK;
 }
 
@@ -117,207 +126,266 @@ nsHTMLTableCellAccessible::GetAttributes
   if (!tableAcc)
     return NS_OK;
 
   PRInt32 rowIdx = -1, colIdx = -1;
   rv = GetCellIndexes(rowIdx, colIdx);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32 idx = -1;
-  rv = tableAcc->GetIndexAt(rowIdx, colIdx, &idx);
+  rv = tableAcc->GetCellIndexAt(rowIdx, colIdx, &idx);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoString stringIdx;
   stringIdx.AppendInt(idx);
   nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::tableCellIndex,
                          stringIdx);
   return NS_OK;
 }
 
-// nsIAccessible
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLTableCellAccessible: nsIAccessibleTableCell implementation
 
 NS_IMETHODIMP
-nsHTMLTableCellAccessible::GetRelationByType(PRUint32 aRelationType,
-                                             nsIAccessibleRelation **aRelation)
+nsHTMLTableCellAccessible::GetTable(nsIAccessibleTable **aTable)
 {
-  nsresult rv = nsHyperTextAccessibleWrap::GetRelationByType(aRelationType,
-                                                             aRelation);
-  NS_ENSURE_SUCCESS(rv, rv);
+  NS_ENSURE_ARG_POINTER(aTable);
+  *aTable = nsnull;
 
-  if (aRelationType != nsIAccessibleRelation::RELATION_DESCRIBED_BY)
+  if (IsDefunct())
     return NS_OK;
 
-  // 'described_by' relation from @headers attribute.
-  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
-  rv = nsRelUtils::AddTargetFromIDRefsAttr(aRelationType, aRelation,
-                                           content, nsAccessibilityAtoms::headers);
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsIAccessibleTable> table = GetTableAccessible();
+  table.swap(*aTable);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHTMLTableCellAccessible::GetColumnIndex(PRInt32 *aColumnIndex)
+{
+  NS_ENSURE_ARG_POINTER(aColumnIndex);
+  *aColumnIndex = -1;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsITableCellLayout* cellLayout = GetCellLayout();
+  NS_ENSURE_STATE(cellLayout);
+
+  return cellLayout->GetColIndex(*aColumnIndex);
+}
 
-  if (rv != NS_OK_NO_RELATION_TARGET)
-    return rv; // Do not calculate more relations.
+NS_IMETHODIMP
+nsHTMLTableCellAccessible::GetRowIndex(PRInt32 *aRowIndex)
+{
+  NS_ENSURE_ARG_POINTER(aRowIndex);
+  *aRowIndex = -1;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsITableCellLayout* cellLayout = GetCellLayout();
+  NS_ENSURE_STATE(cellLayout);
 
-  // 'described_by' relation from hierarchy (see 11.4.3 "Algorithm to find
-  // heading information" of w3c HTML 4.01)
-  return FindCellsForRelation(eHeadersForCell, aRelationType, aRelation);
+  return cellLayout->GetRowIndex(*aRowIndex);
+}
+
+NS_IMETHODIMP
+nsHTMLTableCellAccessible::GetColumnExtent(PRInt32 *aExtentCount)
+{
+  NS_ENSURE_ARG_POINTER(aExtentCount);
+  *aExtentCount = 1;
+
+  PRInt32 rowIdx = -1, colIdx = -1;
+  GetCellIndexes(rowIdx, colIdx);
+
+  nsCOMPtr<nsIAccessibleTable> table = GetTableAccessible();
+  NS_ENSURE_STATE(table);
+
+  return table->GetColumnExtentAt(rowIdx, colIdx, aExtentCount);
 }
 
-// nsHTMLTableCellAccessible
+NS_IMETHODIMP
+nsHTMLTableCellAccessible::GetRowExtent(PRInt32 *aExtentCount)
+{
+  NS_ENSURE_ARG_POINTER(aExtentCount);
+  *aExtentCount = 1;
+
+  PRInt32 rowIdx = -1, colIdx = -1;
+  GetCellIndexes(rowIdx, colIdx);
+
+  nsCOMPtr<nsIAccessibleTable> table = GetTableAccessible();
+  NS_ENSURE_STATE(table);
+
+  return table->GetRowExtentAt(rowIdx, colIdx, aExtentCount);
+}
+
+NS_IMETHODIMP
+nsHTMLTableCellAccessible::GetColumnHeaderCells(nsIArray **aHeaderCells)
+{
+  NS_ENSURE_ARG_POINTER(aHeaderCells);
+  *aHeaderCells = nsnull;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  return GetHeaderCells(nsAccUtils::eColumnHeaderCells, aHeaderCells);
+}
+
+NS_IMETHODIMP
+nsHTMLTableCellAccessible::GetRowHeaderCells(nsIArray **aHeaderCells)
+{
+  NS_ENSURE_ARG_POINTER(aHeaderCells);
+  *aHeaderCells = nsnull;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  return GetHeaderCells(nsAccUtils::eRowHeaderCells, aHeaderCells);
+}
+
+NS_IMETHODIMP
+nsHTMLTableCellAccessible::IsSelected(PRBool *aIsSelected)
+{
+  NS_ENSURE_ARG_POINTER(aIsSelected);
+  *aIsSelected = PR_FALSE;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  PRInt32 rowIdx = -1, colIdx = -1;
+  GetCellIndexes(rowIdx, colIdx);
+
+  nsCOMPtr<nsIAccessibleTable> table = GetTableAccessible();
+  NS_ENSURE_STATE(table);
+
+  return table->IsCellSelected(rowIdx, colIdx, aIsSelected);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLTableCellAccessible: protected implementation
 
 already_AddRefed<nsIAccessibleTable>
 nsHTMLTableCellAccessible::GetTableAccessible()
 {
-  nsCOMPtr<nsIAccessible> childAcc(this);
-
-  nsCOMPtr<nsIAccessible> parentAcc;
-  nsresult rv = childAcc->GetParent(getter_AddRefs(parentAcc));
-  if (NS_FAILED(rv))
-    return nsnull;
+  nsCOMPtr<nsIAccessible> childAcc(this), parentAcc;
+  childAcc->GetParent(getter_AddRefs(parentAcc));
 
   while (parentAcc) {
-    if (nsAccUtils::Role(parentAcc) == nsIAccessibleRole::ROLE_TABLE) {
-      // Table accessible must implement nsIAccessibleTable interface but if
-      // it isn't happen (for example because of ARIA usage).
-      if (!parentAcc)
-        return nsnull;
-
+    PRUint32 role = nsAccUtils::Role(parentAcc);
+    if (role == nsIAccessibleRole::ROLE_TABLE ||
+        role == nsIAccessibleRole::ROLE_TREE_TABLE) {
       nsIAccessibleTable* tableAcc = nsnull;
       CallQueryInterface(parentAcc, &tableAcc);
       return tableAcc;
     }
 
     parentAcc.swap(childAcc);
-    rv = childAcc->GetParent(getter_AddRefs(parentAcc));
-    if (NS_FAILED(rv))
-      return nsnull;
+    childAcc->GetParent(getter_AddRefs(parentAcc));
   }
 
   return nsnull;
 }
 
+nsITableCellLayout*
+nsHTMLTableCellAccessible::GetCellLayout()
+{
+  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
+  
+  nsCOMPtr<nsIPresShell> shell = GetPresShell();
+  if (!shell)
+    return nsnull;
+  
+  nsIFrame *frame = shell->GetPrimaryFrameFor(content);
+  NS_ASSERTION(frame, "The frame cannot be obtaied for HTML table cell.");
+  if (!frame)
+    return nsnull;
+  
+  nsITableCellLayout *cellLayout = do_QueryFrame(frame);
+  return cellLayout;
+}
+
 nsresult
 nsHTMLTableCellAccessible::GetCellIndexes(PRInt32& aRowIndex,
                                           PRInt32& aColIndex)
 {
-  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
-
-  nsCOMPtr<nsIPresShell> shell = GetPresShell();
-  NS_ENSURE_STATE(shell);
-
-  nsIFrame *frame = shell->GetPrimaryFrameFor(content);
-  NS_ASSERTION(frame, "The frame cannot be obtaied for HTML table cell.");
-  NS_ENSURE_STATE(frame);
-
-  nsITableCellLayout *cellLayout = do_QueryFrame(frame);
+  nsITableCellLayout *cellLayout = GetCellLayout();
   NS_ENSURE_STATE(cellLayout);
 
   return cellLayout->GetCellIndexes(aRowIndex, aColIndex);
 }
 
 nsresult
-nsHTMLTableCellAccessible::FindCellsForRelation(PRInt32 aSearchHint,
-                                                PRUint32 aRelationType,
-                                                nsIAccessibleRelation **aRelation)
+nsHTMLTableCellAccessible::GetHeaderCells(PRInt32 aRowOrColumnHeaderCell,
+                                          nsIArray **aHeaderCells)
 {
-  nsCOMPtr<nsIAccessibleTable> tableAcc(GetTableAccessible());
-  nsRefPtr<nsHTMLTableAccessible> nsTableAcc =
-    nsAccUtils::QueryAccessibleTable(tableAcc);
-  if (!nsTableAcc)
-    return NS_OK; // Do not fail because of wrong markup.
-
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
 
-  PRInt32 rowIdx = -1, colIdx = -1;
-  nsresult rv = GetCellIndexes(rowIdx, colIdx);
-  NS_ENSURE_SUCCESS(rv, rv);
+  // Get header cells from @header attribute.
+  nsCOMPtr<nsIArray> headerCellElms;
+  nsCoreUtils::GetElementsByIDRefsAttr(content, nsAccessibilityAtoms::headers,
+                                       getter_AddRefs(headerCellElms));
+
+  if (headerCellElms) {
+    nsresult rv = NS_OK;
+    nsCOMPtr<nsIMutableArray> headerCells =
+      do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
 
-  PRBool moveToTopLeft = aSearchHint == eHeadersForCell;
-  PRInt32 dir = (moveToTopLeft) ? -1 : 1;
-  PRInt32 bound = 0;
+    PRUint32 count = 0;
+    rv = headerCellElms->GetLength(&count);
+    if (NS_SUCCEEDED(rv) && count > 0) {
+      nsCOMPtr<nsIDOMNode> headerCellNode;
+      for (PRUint32 idx = 0; idx < count; idx++) {
+        headerCellNode = do_QueryElementAt(headerCellElms, idx, &rv);
+        nsCOMPtr<nsIAccessible> headerCell;
+        GetAccService()->GetAccessibleInWeakShell(headerCellNode, mWeakShell,
+                                                  getter_AddRefs(headerCell));
 
-  // left/right direction
-  if (aSearchHint != eCellsForColumnHeader) {
-    if (!moveToTopLeft) {
-      tableAcc->GetColumns(&bound);
-      bound--;
+        if (headerCell &&
+            (aRowOrColumnHeaderCell == nsAccUtils::eRowHeaderCells &&
+             nsAccUtils::Role(headerCell) == nsIAccessibleRole::ROLE_ROWHEADER ||
+             aRowOrColumnHeaderCell == nsAccUtils::eColumnHeaderCells &&
+             nsAccUtils::Role(headerCell) == nsIAccessibleRole::ROLE_COLUMNHEADER))
+          headerCells->AppendElement(headerCell, PR_FALSE);
+      }
     }
 
-    for (PRInt32 index = colIdx + dir; dir * index <= bound; index += dir) {
-      // Left direction means we look for the first columnheader. Right direction
-      // means we look for all cells underneath of columnheader.
-      nsIContent *cellContent = FindCell(nsTableAcc, content, rowIdx, index,
-                                         moveToTopLeft);
-
-      if (cellContent) {
-        nsRelUtils::AddTargetFromContent(aRelationType, aRelation, cellContent);
-        if (moveToTopLeft)
-          break;
-      }
-    }
+    NS_ADDREF(*aHeaderCells = headerCells);
+    return NS_OK;
   }
 
-  // up/down direction
-  if (aSearchHint != eCellsForRowHeader) {
-    if (!moveToTopLeft) {
-      tableAcc->GetRows(&bound);
-      bound--;
-    }
-
-    for (PRInt32 index = rowIdx + dir; dir * index <= bound; index += dir) {
-      // Left direction means we look for the first rowheader. Right direction
-      // means we look for all cells underneath of rowheader.
-      nsIContent *cellContent = FindCell(nsTableAcc, content, index, colIdx,
-                                         moveToTopLeft);
-
-      if (cellContent) {
-        nsRelUtils::AddTargetFromContent(aRelationType, aRelation, cellContent);
-        if (moveToTopLeft)
-          break;
-      }
-    }
+  // Otherwise calculate header cells from hierarchy (see 11.4.3 "Algorithm to
+  // find heading information" of w3c HTML 4.01).
+  nsCOMPtr<nsIAccessibleTable> table = GetTableAccessible();
+  if (table) {
+    return nsAccUtils::GetHeaderCellsFor(table, this, aRowOrColumnHeaderCell,
+                                         aHeaderCells);
   }
 
   return NS_OK;
 }
 
-nsIContent*
-nsHTMLTableCellAccessible::FindCell(nsHTMLTableAccessible *aTableAcc,
-                                    nsIContent *aAnchorCell,
-                                    PRInt32 aRowIdx, PRInt32 aColIdx,
-                                    PRInt32 aLookForHeader)
-{
-  nsCOMPtr<nsIDOMElement> cellElm;
-  aTableAcc->GetCellAt(aRowIdx, aColIdx, *getter_AddRefs(cellElm));
-  if (!cellElm)
-    return nsnull;
-
-  nsCOMPtr<nsIContent> cellContent(do_QueryInterface(cellElm));
-  if (aAnchorCell == cellContent) // colspan or rowspan case
-    return nsnull;
-
-  if (aLookForHeader) {
-    if (nsCoreUtils::IsHTMLTableHeader(cellContent))
-      return cellContent;
-
-    return nsnull;
-  }
-
-  return cellContent;
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLTableHeaderAccessible
+////////////////////////////////////////////////////////////////////////////////
 
-nsHTMLTableHeaderAccessible::
-  nsHTMLTableHeaderAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell):
+nsHTMLTableHeaderCellAccessible::
+  nsHTMLTableHeaderCellAccessible(nsIDOMNode* aDomNode,
+                                  nsIWeakReference* aShell) :
   nsHTMLTableCellAccessible(aDomNode, aShell)
 {
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLTableHeaderAccessible: nsAccessible implementation
+
 nsresult
-nsHTMLTableHeaderAccessible::GetRoleInternal(PRUint32 *aRole)
+nsHTMLTableHeaderCellAccessible::GetRoleInternal(PRUint32 *aRole)
 {
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
 
   // Check value of @scope attribute.
   static nsIContent::AttrValuesArray scopeValues[] =
     {&nsAccessibilityAtoms::col, &nsAccessibilityAtoms::row, nsnull};
   PRInt32 valueIdx = 
     content->FindAttrValueIn(kNameSpaceID_None, nsAccessibilityAtoms::scope,
@@ -360,69 +428,35 @@ nsHTMLTableHeaderAccessible::GetRoleInte
       
       return NS_OK;
     }
   }
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsHTMLTableHeaderAccessible::GetRelationByType(PRUint32 aRelationType,
-                                               nsIAccessibleRelation **aRelation)
-{
-  nsresult rv = nsHyperTextAccessibleWrap::
-    GetRelationByType(aRelationType, aRelation);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (aRelationType != nsIAccessibleRelation::RELATION_DESCRIPTION_FOR)
-    return rv;
-
-  // 'description_for' relation from @headers attribute placed on table cells.
-  nsCOMPtr<nsIAccessibleTable> tableAcc(GetTableAccessible());
-  if (!tableAcc)
-    return NS_OK;
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLTableAccessible
+////////////////////////////////////////////////////////////////////////////////
 
-  nsCOMPtr<nsIAccessNode> tableAccNode(do_QueryInterface(tableAcc));
-  nsCOMPtr<nsIDOMNode> tableNode;
-  tableAccNode->GetDOMNode(getter_AddRefs(tableNode));
-  nsCOMPtr<nsIContent> tableContent(do_QueryInterface(tableNode));
-  if (!tableContent)
-    return NS_OK;
-
-  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
-  rv = nsRelUtils::
-    AddTargetFromChildrenHavingIDRefsAttr(aRelationType, aRelation,
-                                          tableContent, content,
-                                          nsAccessibilityAtoms::headers);
-
-  if (rv != NS_OK_NO_RELATION_TARGET)
-    return rv; // Do not calculate more relations.
-
-  // 'description_for' relation from hierarchy.
-  PRUint32 role;
-  rv = GetRoleInternal(&role);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (role == nsIAccessibleRole::ROLE_COLUMNHEADER)
-    return FindCellsForRelation(eCellsForColumnHeader, aRelationType, aRelation);
-
-  return FindCellsForRelation(eCellsForRowHeader, aRelationType, aRelation);
+nsHTMLTableAccessible::
+  nsHTMLTableAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell) :
+  nsAccessibleWrap(aDomNode, aShell)
+{ 
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsHTMLTableAccessible
+// nsHTMLTableAccessible: nsISupports implementation
 
 NS_IMPL_ISUPPORTS_INHERITED2(nsHTMLTableAccessible, nsAccessible,
                              nsHTMLTableAccessible, nsIAccessibleTable)
 
-nsHTMLTableAccessible::nsHTMLTableAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell):
-nsAccessibleWrap(aDomNode, aShell)
-{ 
-}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLTableAccessible: nsAccessible implementation
 
 void nsHTMLTableAccessible::CacheChildren()
 {
   if (!mWeakShell) {
     // This node has been shut down
     mAccChildCount = eChildCountUninitialized;
     return;
   }
@@ -459,17 +493,16 @@ void nsHTMLTableAccessible::CacheChildre
         // we don't create accessibles for the other captions, since only the
         // first is actually visible
         break;
       }
     }
   }
 }
 
-/* unsigned long getRole (); */
 nsresult
 nsHTMLTableAccessible::GetRoleInternal(PRUint32 *aResult)
 {
   *aResult = nsIAccessibleRole::ROLE_TABLE;
   return NS_OK;
 }
 
 nsresult
@@ -513,16 +546,19 @@ nsHTMLTableAccessible::GetAttributesInte
     nsAutoString oldValueUnused;
     aAttributes->SetStringProperty(NS_LITERAL_CSTRING("layout-guess"),
                                    NS_LITERAL_STRING("true"), oldValueUnused);
   }
   
   return NS_OK;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLTableAccessible: nsIAccessible implementation
+
 NS_IMETHODIMP
 nsHTMLTableAccessible::GetRelationByType(PRUint32 aRelationType,
                                          nsIAccessibleRelation **aRelation)
 {
   nsresult rv = nsAccessibleWrap::GetRelationByType(aRelationType,
                                                     aRelation);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -530,16 +566,18 @@ nsHTMLTableAccessible::GetRelationByType
     nsCOMPtr<nsIAccessible> accCaption;
     GetCaption(getter_AddRefs(accCaption));
     return nsRelUtils::AddTarget(aRelationType, aRelation, accCaption);
   }
 
   return NS_OK;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLTableAccessible: nsIAccessibleTable implementation
 
 NS_IMETHODIMP
 nsHTMLTableAccessible::GetCaption(nsIAccessible **aCaption)
 {
   nsCOMPtr<nsIAccessible> firstChild;
   GetFirstChild(getter_AddRefs(firstChild));
   if (nsAccUtils::Role(firstChild) == nsIAccessibleRole::ROLE_CAPTION)
     NS_ADDREF(*aCaption = firstChild);
@@ -552,113 +590,73 @@ nsHTMLTableAccessible::GetSummary(nsAStr
 {
   nsCOMPtr<nsIDOMHTMLTableElement> table(do_QueryInterface(mDOMNode));
   NS_ENSURE_TRUE(table, NS_ERROR_FAILURE);
 
   return table->GetSummary(aSummary);
 }
 
 NS_IMETHODIMP
-nsHTMLTableAccessible::GetColumns(PRInt32 *aColumns)
+nsHTMLTableAccessible::GetColumnCount(PRInt32 *acolumnCount)
 {
-  nsITableLayout *tableLayout;
-  nsresult rv = GetTableLayout(&tableLayout);
-  NS_ENSURE_SUCCESS(rv, rv);
+  NS_ENSURE_ARG_POINTER(acolumnCount);
+  *acolumnCount = nsnull;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsITableLayout *tableLayout = GetTableLayout();
+  NS_ENSURE_STATE(tableLayout);
 
   PRInt32 rows;
-  return tableLayout->GetTableSize(rows, *aColumns);
+  return tableLayout->GetTableSize(rows, *acolumnCount);
 }
 
 NS_IMETHODIMP
-nsHTMLTableAccessible::GetColumnHeader(nsIAccessibleTable **aColumnHeader)
+nsHTMLTableAccessible::GetRowCount(PRInt32 *arowCount)
 {
-  nsresult rv = NS_OK;
-
-  nsCOMPtr<nsIDOMHTMLTableElement> table(do_QueryInterface(mDOMNode));
-  NS_ENSURE_TRUE(table, NS_ERROR_FAILURE);
-
-  nsCOMPtr<nsIDOMHTMLTableSectionElement> section;
-  rv = table->GetTHead(getter_AddRefs(section));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIAccessibilityService>
-    accService(do_GetService("@mozilla.org/accessibilityService;1"));
-  NS_ENSURE_TRUE(accService, NS_ERROR_FAILURE);
+  NS_ENSURE_ARG_POINTER(arowCount);
+  *arowCount = 0;
 
-  nsCOMPtr<nsIAccessible> accHead;
-  nsCOMPtr<nsIDOMNode> sectionNode(do_QueryInterface(section));
-  if (sectionNode) {
-    rv = accService->GetCachedAccessible(sectionNode, mWeakShell,
-                                         getter_AddRefs(accHead));
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  if (!accHead) {
-    accService->CreateHTMLTableHeadAccessible(section, getter_AddRefs(accHead));
-    NS_ENSURE_STATE(accHead);
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
 
-    nsRefPtr<nsAccessNode> accessNode = nsAccUtils::QueryAccessNode(accHead);
-    rv = accessNode->Init();
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
+  nsITableLayout *tableLayout = GetTableLayout();
+  NS_ENSURE_STATE(tableLayout);
 
-  nsCOMPtr<nsIAccessibleTable> accTableHead(do_QueryInterface(accHead));
-  NS_ENSURE_TRUE(accTableHead, NS_ERROR_FAILURE);
-
-  *aColumnHeader = accTableHead;
-  NS_IF_ADDREF(*aColumnHeader);
-
-  return rv;
+  PRInt32 columns;
+  return tableLayout->GetTableSize(*arowCount, columns);
 }
 
 NS_IMETHODIMP
-nsHTMLTableAccessible::GetRows(PRInt32 *aRows)
-{
-  nsITableLayout *tableLayout;
-  nsresult rv = GetTableLayout(&tableLayout);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  PRInt32 columns;
-  return tableLayout->GetTableSize(*aRows, columns);
-}
-
-NS_IMETHODIMP
-nsHTMLTableAccessible::GetRowHeader(nsIAccessibleTable **aRowHeader)
-{
-  // Can not implement because there is no row header in html table
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsHTMLTableAccessible::GetSelectedCellsCount(PRUint32* aCount)
+nsHTMLTableAccessible::GetSelectedCellCount(PRUint32* aCount)
 {
   NS_ENSURE_ARG_POINTER(aCount);
   *aCount = 0;
 
-  PRInt32 rowsCount = 0;
-  nsresult rv = GetRows(&rowsCount);
+  PRInt32 rowCount = 0;
+  nsresult rv = GetRowCount(&rowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRInt32 columnsCount = 0;
-  rv = GetColumns(&columnsCount);
+  PRInt32 columnCount = 0;
+  rv = GetColumnCount(&columnCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsITableLayout *tableLayout = nsnull;
-  rv = GetTableLayout(&tableLayout);
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsITableLayout *tableLayout = GetTableLayout();
+  NS_ENSURE_STATE(tableLayout);
 
   nsCOMPtr<nsIDOMElement> domElement;
   PRInt32 startRowIndex = 0, startColIndex = 0,
     rowSpan, colSpan, actualRowSpan, actualColSpan;
   PRBool isSelected = PR_FALSE;
 
   PRInt32 rowIndex;
-  for (rowIndex = 0; rowIndex < rowsCount; rowIndex++) {
+  for (rowIndex = 0; rowIndex < rowCount; rowIndex++) {
     PRInt32 columnIndex;
-    for (columnIndex = 0; columnIndex < columnsCount; columnIndex++) {
+    for (columnIndex = 0; columnIndex < columnCount; columnIndex++) {
       rv = tableLayout->GetCellDataAt(rowIndex, columnIndex,
                                       *getter_AddRefs(domElement),
                                       startRowIndex, startColIndex,
                                       rowSpan, colSpan,
                                       actualRowSpan, actualColSpan,
                                       isSelected);
 
       if (NS_SUCCEEDED(rv) && startRowIndex == rowIndex &&
@@ -667,95 +665,145 @@ nsHTMLTableAccessible::GetSelectedCellsC
       }
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHTMLTableAccessible::GetSelectedColumnsCount(PRUint32* aCount)
+nsHTMLTableAccessible::GetSelectedColumnCount(PRUint32* aCount)
 {
   NS_ENSURE_ARG_POINTER(aCount);
   *aCount = 0;
 
   PRInt32 count = 0;
-  nsresult rv = GetColumns(&count);
+  nsresult rv = GetColumnCount(&count);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32 index;
   for (index = 0; index < count; index++) {
     PRBool state = PR_FALSE;
     rv = IsColumnSelected(index, &state);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (state)
       (*aCount)++;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHTMLTableAccessible::GetSelectedRowsCount(PRUint32* aCount)
+nsHTMLTableAccessible::GetSelectedRowCount(PRUint32* aCount)
 {
   NS_ENSURE_ARG_POINTER(aCount);
   *aCount = 0;
 
   PRInt32 count = 0;
-  nsresult rv = GetRows(&count);
+  nsresult rv = GetRowCount(&count);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32 index;
   for (index = 0; index < count; index++) {
     PRBool state = PR_FALSE;
     rv = IsRowSelected(index, &state);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (state)
       (*aCount)++;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHTMLTableAccessible::GetSelectedCells(PRUint32 *aNumCells,
-                                        PRInt32 **aCells)
+nsHTMLTableAccessible::GetSelectedCells(nsIArray **aCells)
+{
+  NS_ENSURE_ARG_POINTER(aCells);
+  *aCells = nsnull;
+
+  PRInt32 rowCount = 0;
+  nsresult rv = GetRowCount(&rowCount);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRInt32 columnCount = 0;
+  rv = GetColumnCount(&columnCount);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsITableLayout *tableLayout = GetTableLayout();
+  NS_ENSURE_STATE(tableLayout);
+
+  nsCOMPtr<nsIMutableArray> selCells =
+    do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCOMPtr<nsIDOMElement> cellElement;
+  PRInt32 startRowIndex = 0, startColIndex = 0,
+    rowSpan, colSpan, actualRowSpan, actualColSpan;
+  PRBool isSelected = PR_FALSE;
+
+  PRInt32 rowIndex, index;
+  for (rowIndex = 0, index = 0; rowIndex < rowCount; rowIndex++) {
+    PRInt32 columnIndex;
+    for (columnIndex = 0; columnIndex < columnCount; columnIndex++, index++) {
+      rv = tableLayout->GetCellDataAt(rowIndex, columnIndex,
+                                      *getter_AddRefs(cellElement),
+                                      startRowIndex, startColIndex,
+                                      rowSpan, colSpan,
+                                      actualRowSpan, actualColSpan,
+                                      isSelected);
+
+      if (NS_SUCCEEDED(rv) && startRowIndex == rowIndex &&
+          startColIndex == columnIndex && isSelected) {
+        nsCOMPtr<nsIAccessible> cell;
+        GetAccService()->GetAccessibleInWeakShell(cellElement, mWeakShell,
+                                                  getter_AddRefs(cell));
+        selCells->AppendElement(cell, PR_FALSE);
+      }
+    }
+  }
+
+  NS_ADDREF(*aCells = selCells);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHTMLTableAccessible::GetSelectedCellIndices(PRUint32 *aNumCells,
+                                              PRInt32 **aCells)
 {
   NS_ENSURE_ARG_POINTER(aNumCells);
   *aNumCells = 0;
   NS_ENSURE_ARG_POINTER(aCells);
   *aCells = nsnull;
 
-  PRInt32 rowsCount = 0;
-  nsresult rv = GetRows(&rowsCount);
+  PRInt32 rowCount = 0;
+  nsresult rv = GetRowCount(&rowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRInt32 columnsCount = 0;
-  rv = GetColumns(&columnsCount);
+  PRInt32 columnCount = 0;
+  rv = GetColumnCount(&columnCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsITableLayout *tableLayout = nsnull;
-  rv = GetTableLayout(&tableLayout);
-  NS_ENSURE_SUCCESS(rv, rv);
-  
+  nsITableLayout *tableLayout = GetTableLayout();
+  NS_ENSURE_STATE(tableLayout);
+
   nsCOMPtr<nsIDOMElement> domElement;
   PRInt32 startRowIndex = 0, startColIndex = 0,
-  rowSpan, colSpan, actualRowSpan, actualColSpan;
+    rowSpan, colSpan, actualRowSpan, actualColSpan;
   PRBool isSelected = PR_FALSE;
 
-  PRInt32 cellsCount = columnsCount * rowsCount;
+  PRInt32 cellsCount = columnCount * rowCount;
   nsAutoArrayPtr<PRBool> states(new PRBool[cellsCount]);
   NS_ENSURE_TRUE(states, NS_ERROR_OUT_OF_MEMORY);
 
   PRInt32 rowIndex, index;
-  for (rowIndex = 0, index = 0; rowIndex < rowsCount; rowIndex++) {
+  for (rowIndex = 0, index = 0; rowIndex < rowCount; rowIndex++) {
     PRInt32 columnIndex;
-    for (columnIndex = 0; columnIndex < columnsCount; columnIndex++, index++) {
+    for (columnIndex = 0; columnIndex < columnCount; columnIndex++, index++) {
       rv = tableLayout->GetCellDataAt(rowIndex, columnIndex,
                                       *getter_AddRefs(domElement),
                                       startRowIndex, startColIndex,
                                       rowSpan, colSpan,
                                       actualRowSpan, actualColSpan,
                                       isSelected);
 
       if (NS_SUCCEEDED(rv) && startRowIndex == rowIndex &&
@@ -764,43 +812,43 @@ nsHTMLTableAccessible::GetSelectedCells(
         (*aNumCells)++;
       } else {
         states[index] = PR_FALSE;
       }
     }
   }
 
   PRInt32 *cellsArray =
-    (PRInt32 *)nsMemory::Alloc((*aNumCells) * sizeof(PRInt32));
+    static_cast<PRInt32*>(nsMemory::Alloc((*aNumCells) * sizeof(PRInt32)));
   NS_ENSURE_TRUE(cellsArray, NS_ERROR_OUT_OF_MEMORY);
 
   PRInt32 curr = 0;
-  for (rowIndex = 0, index = 0; rowIndex < rowsCount; rowIndex++) {
+  for (rowIndex = 0, index = 0; rowIndex < rowCount; rowIndex++) {
     PRInt32 columnIndex;
-    for (columnIndex = 0; columnIndex < columnsCount; columnIndex++, index++) {
+    for (columnIndex = 0; columnIndex < columnCount; columnIndex++, index++) {
       if (states[index]) {
         PRInt32 cellIndex = -1;
-        GetIndexAt(rowIndex, columnIndex, &cellIndex);
+        GetCellIndexAt(rowIndex, columnIndex, &cellIndex);
         cellsArray[curr++] = cellIndex;
       }
     }
   }
 
   *aCells = cellsArray;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHTMLTableAccessible::GetSelectedColumns(PRUint32 *aNumColumns,
-                                          PRInt32 **aColumns)
+nsHTMLTableAccessible::GetSelectedColumnIndices(PRUint32 *aNumColumns,
+                                                PRInt32 **aColumns)
 {
   nsresult rv = NS_OK;
 
   PRInt32 columnCount;
-  rv = GetColumns(&columnCount);
+  rv = GetColumnCount(&columnCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRBool *states = new PRBool[columnCount];
   NS_ENSURE_TRUE(states, NS_ERROR_OUT_OF_MEMORY);
 
   *aNumColumns = 0;
   PRInt32 index;
   for (index = 0; index < columnCount; index++) {
@@ -826,22 +874,23 @@ nsHTMLTableAccessible::GetSelectedColumn
   }
 
   delete []states;
   *aColumns = outArray;
   return rv;
 }
 
 NS_IMETHODIMP
-nsHTMLTableAccessible::GetSelectedRows(PRUint32 *aNumRows, PRInt32 **aRows)
+nsHTMLTableAccessible::GetSelectedRowIndices(PRUint32 *aNumRows,
+                                             PRInt32 **aRows)
 {
   nsresult rv = NS_OK;
 
   PRInt32 rowCount;
-  rv = GetRows(&rowCount);
+  rv = GetRowCount(&rowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRBool *states = new PRBool[rowCount];
   NS_ENSURE_TRUE(states, NS_ERROR_OUT_OF_MEMORY);
 
   *aNumRows = 0;
   PRInt32 index;
   for (index = 0; index < rowCount; index++) {
@@ -867,17 +916,17 @@ nsHTMLTableAccessible::GetSelectedRows(P
   }
 
   delete []states;
   *aRows = outArray;
   return rv;
 }
 
 NS_IMETHODIMP
-nsHTMLTableAccessible::CellRefAt(PRInt32 aRow, PRInt32 aColumn,
+nsHTMLTableAccessible::GetCellAt(PRInt32 aRow, PRInt32 aColumn,
                                  nsIAccessible **aTableCellAccessible)
 {
   NS_ENSURE_TRUE(IsValidRow(aRow) && IsValidColumn(aColumn), NS_ERROR_INVALID_ARG);
 
   nsresult rv = NS_OK;
 
   nsCOMPtr<nsIDOMElement> cellElement;
   rv = GetCellAt(aRow, aColumn, *getter_AddRefs(cellElement));
@@ -887,94 +936,102 @@ nsHTMLTableAccessible::CellRefAt(PRInt32
     accService(do_GetService("@mozilla.org/accessibilityService;1"));
   NS_ENSURE_TRUE(accService, NS_ERROR_FAILURE);
 
   return accService->GetAccessibleInWeakShell(cellElement, mWeakShell,
                                               aTableCellAccessible);
 }
 
 NS_IMETHODIMP
-nsHTMLTableAccessible::GetIndexAt(PRInt32 aRow, PRInt32 aColumn,
-                                  PRInt32 *aIndex)
+nsHTMLTableAccessible::GetCellIndexAt(PRInt32 aRow, PRInt32 aColumn,
+                                      PRInt32 *aIndex)
 {
   NS_ENSURE_ARG_POINTER(aIndex);
 
   NS_ENSURE_TRUE(IsValidRow(aRow) && IsValidColumn(aColumn), NS_ERROR_INVALID_ARG);
 
-  nsITableLayout *tableLayout = nsnull;
-  nsresult rv = GetTableLayout(&tableLayout);
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsITableLayout *tableLayout = GetTableLayout();
+  NS_ENSURE_STATE(tableLayout);
 
-  rv = tableLayout->GetIndexByRowAndColumn(aRow, aColumn, aIndex);
+  nsresult rv = tableLayout->GetIndexByRowAndColumn(aRow, aColumn, aIndex);
   if (rv == NS_TABLELAYOUT_CELL_NOT_FOUND)
     return NS_ERROR_INVALID_ARG;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHTMLTableAccessible::GetColumnAtIndex(PRInt32 aIndex, PRInt32 *aColumn)
+nsHTMLTableAccessible::GetColumnIndexAt(PRInt32 aIndex, PRInt32 *aColumn)
 {
   NS_ENSURE_ARG_POINTER(aColumn);
 
-  nsITableLayout *tableLayout = nsnull;
-  nsresult rv = GetTableLayout(&tableLayout);
-  NS_ENSURE_SUCCESS(rv, rv);
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsITableLayout *tableLayout = GetTableLayout();
+  NS_ENSURE_STATE(tableLayout);
 
   PRInt32 row;
   return tableLayout->GetRowAndColumnByIndex(aIndex, &row, aColumn);
 }
 
 NS_IMETHODIMP
-nsHTMLTableAccessible::GetRowAtIndex(PRInt32 aIndex, PRInt32 *aRow)
+nsHTMLTableAccessible::GetRowIndexAt(PRInt32 aIndex, PRInt32 *aRow)
 {
   NS_ENSURE_ARG_POINTER(aRow);
 
-  nsITableLayout *tableLayout = nsnull;
-  nsresult rv = GetTableLayout(&tableLayout);
-  NS_ENSURE_SUCCESS(rv, rv);
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsITableLayout *tableLayout = GetTableLayout();
+  NS_ENSURE_STATE(tableLayout);
 
   PRInt32 column;
   return tableLayout->GetRowAndColumnByIndex(aIndex, aRow, &column);
 }
 
 NS_IMETHODIMP
-nsHTMLTableAccessible::GetColumnExtentAt(PRInt32 aRow, PRInt32 aColumn,
-                                         PRInt32 *_retval)
+nsHTMLTableAccessible::GetColumnExtentAt(PRInt32 aRowIndex,
+                                         PRInt32 aColumnIndex,
+                                         PRInt32 *aExtentCount)
 {
-  NS_ENSURE_TRUE(IsValidRow(aRow) && IsValidColumn(aColumn), NS_ERROR_INVALID_ARG);
+  NS_ENSURE_TRUE(IsValidRow(aRowIndex) && IsValidColumn(aColumnIndex),
+                 NS_ERROR_INVALID_ARG);
 
-  nsresult rv = NS_OK;
+  nsITableLayout *tableLayout = GetTableLayout();
+  NS_ENSURE_STATE(tableLayout);
 
   nsCOMPtr<nsIDOMElement> domElement;
-  rv = GetCellAt(aRow, aColumn, *getter_AddRefs(domElement));
-  NS_ENSURE_SUCCESS(rv, rv);
+  PRInt32 startRowIndex, startColIndex, rowSpan, colSpan, actualRowSpan;
+  PRBool isSelected;
 
-  nsCOMPtr<nsIDOMHTMLTableCellElement> cell(do_QueryInterface(domElement));
-  NS_ENSURE_TRUE(cell, NS_ERROR_FAILURE);
-
-  return cell->GetColSpan(_retval);
+  return tableLayout->
+    GetCellDataAt(aRowIndex, aColumnIndex, *getter_AddRefs(domElement),
+                  startRowIndex, startColIndex, rowSpan, colSpan,
+                  actualRowSpan, *aExtentCount, isSelected);
 }
 
 NS_IMETHODIMP
-nsHTMLTableAccessible::GetRowExtentAt(PRInt32 aRow, PRInt32 aColumn,
-                                      PRInt32 *_retval)
+nsHTMLTableAccessible::GetRowExtentAt(PRInt32 aRowIndex, PRInt32 aColumnIndex,
+                                      PRInt32 *aExtentCount)
 {
-  NS_ENSURE_TRUE(IsValidRow(aRow) && IsValidColumn(aColumn), NS_ERROR_INVALID_ARG);
+  NS_ENSURE_TRUE(IsValidRow(aRowIndex) && IsValidColumn(aColumnIndex),
+                 NS_ERROR_INVALID_ARG);
 
-  nsresult rv = NS_OK;
+  nsITableLayout *tableLayout = GetTableLayout();
+  NS_ENSURE_STATE(tableLayout);
 
   nsCOMPtr<nsIDOMElement> domElement;
-  rv = GetCellAt(aRow, aColumn, *getter_AddRefs(domElement));
-  NS_ENSURE_SUCCESS(rv, rv);
+  PRInt32 startRowIndex, startColIndex, rowSpan, colSpan, actualColSpan;
+  PRBool isSelected;
 
-  nsCOMPtr<nsIDOMHTMLTableCellElement> cell(do_QueryInterface(domElement));
-  NS_ENSURE_TRUE(cell, NS_ERROR_FAILURE);
-
-  return cell->GetRowSpan(_retval);
+  return tableLayout->
+    GetCellDataAt(aRowIndex, aColumnIndex, *getter_AddRefs(domElement),
+                  startRowIndex, startColIndex, rowSpan, colSpan,
+                  *aExtentCount, actualColSpan, isSelected);
 }
 
 NS_IMETHODIMP
 nsHTMLTableAccessible::GetColumnDescription(PRInt32 aColumn, nsAString &_retval)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
@@ -989,17 +1046,17 @@ nsHTMLTableAccessible::IsColumnSelected(
 {
   NS_ENSURE_ARG_POINTER(_retval);
 
   NS_ENSURE_TRUE(IsValidColumn(aColumn), NS_ERROR_INVALID_ARG);
 
   nsresult rv = NS_OK;
 
   PRInt32 rows;
-  rv = GetRows(&rows);
+  rv = GetRowCount(&rows);
   NS_ENSURE_SUCCESS(rv, rv);
 
   for (PRInt32 index = 0; index < rows; index++) {
     rv = IsCellSelected(index, aColumn, _retval);
     NS_ENSURE_SUCCESS(rv, rv);
     if (!*_retval) {
       break;
     }
@@ -1013,17 +1070,17 @@ nsHTMLTableAccessible::IsRowSelected(PRI
 {
   NS_ENSURE_ARG_POINTER(_retval);
 
   NS_ENSURE_TRUE(IsValidRow(aRow), NS_ERROR_INVALID_ARG);
 
   nsresult rv = NS_OK;
 
   PRInt32 columns;
-  rv = GetColumns(&columns);
+  rv = GetColumnCount(&columns);
   NS_ENSURE_SUCCESS(rv, rv);
 
   for (PRInt32 index = 0; index < columns; index++) {
     rv = IsCellSelected(aRow, index, _retval);
     NS_ENSURE_SUCCESS(rv, rv);
     if (!*_retval) {
       break;
     }
@@ -1037,232 +1094,219 @@ nsHTMLTableAccessible::IsCellSelected(PR
                                       PRBool *aIsSelected)
 {
   NS_ENSURE_ARG_POINTER(aIsSelected);
   *aIsSelected = PR_FALSE;
 
   NS_ENSURE_TRUE(IsValidRow(aRow) && IsValidColumn(aColumn),
                  NS_ERROR_INVALID_ARG);
 
-  nsITableLayout *tableLayout = nsnull;
-  nsresult rv = GetTableLayout(&tableLayout);
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsITableLayout *tableLayout = GetTableLayout();
+  NS_ENSURE_STATE(tableLayout);
 
   nsCOMPtr<nsIDOMElement> domElement;
   PRInt32 startRowIndex = 0, startColIndex = 0,
           rowSpan, colSpan, actualRowSpan, actualColSpan;
 
-  rv = tableLayout->GetCellDataAt(aRow, aColumn, *getter_AddRefs(domElement),
-                                  startRowIndex, startColIndex,
-                                  rowSpan, colSpan,
-                                  actualRowSpan, actualColSpan, *aIsSelected);
+  nsresult rv = tableLayout->
+    GetCellDataAt(aRow, aColumn, *getter_AddRefs(domElement),
+                  startRowIndex, startColIndex, rowSpan, colSpan,
+                  actualRowSpan, actualColSpan, *aIsSelected);
 
   if (rv == NS_TABLELAYOUT_CELL_NOT_FOUND)
     return NS_ERROR_INVALID_ARG;
   return rv;
 }
 
 PRBool
 nsHTMLTableAccessible::IsValidColumn(PRInt32 aColumn)
 {
   PRInt32 colCount = 0;
-  nsresult rv = GetColumns(&colCount);
+  nsresult rv = GetColumnCount(&colCount);
   return NS_SUCCEEDED(rv) && (aColumn >= 0) && (aColumn < colCount);
 }
 
 PRBool
 nsHTMLTableAccessible::IsValidRow(PRInt32 aRow)
 {
   PRInt32 rowCount = 0;
-  nsresult rv = GetRows(&rowCount);
+  nsresult rv = GetRowCount(&rowCount);
   return NS_SUCCEEDED(rv) && (aRow >= 0) && (aRow < rowCount);
 }
 
 NS_IMETHODIMP
 nsHTMLTableAccessible::SelectRow(PRInt32 aRow)
 {
-  return SelectRowOrColumn(aRow, nsISelectionPrivate::TABLESELECTION_ROW,
-                           PR_TRUE);
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsresult rv =
+    RemoveRowsOrColumnsFromSelection(aRow,
+                                     nsISelectionPrivate::TABLESELECTION_ROW,
+                                     PR_TRUE);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return AddRowOrColumnToSelection(aRow,
+                                   nsISelectionPrivate::TABLESELECTION_ROW);
 }
 
 NS_IMETHODIMP
 nsHTMLTableAccessible::SelectColumn(PRInt32 aColumn)
 {
-  return SelectRowOrColumn(aColumn, nsISelectionPrivate::TABLESELECTION_COLUMN,
-                           PR_TRUE);
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsresult rv =
+    RemoveRowsOrColumnsFromSelection(aColumn,
+                                     nsISelectionPrivate::TABLESELECTION_COLUMN,
+                                     PR_TRUE);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return AddRowOrColumnToSelection(aColumn,
+                                   nsISelectionPrivate::TABLESELECTION_COLUMN);
 }
 
 NS_IMETHODIMP
 nsHTMLTableAccessible::UnselectRow(PRInt32 aRow)
 {
-  return SelectRowOrColumn(aRow, nsISelectionPrivate::TABLESELECTION_ROW,
-                           PR_FALSE);
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  return
+    RemoveRowsOrColumnsFromSelection(aRow,
+                                     nsISelectionPrivate::TABLESELECTION_ROW,
+                                     PR_FALSE);
 }
 
 NS_IMETHODIMP
 nsHTMLTableAccessible::UnselectColumn(PRInt32 aColumn)
 {
-  return SelectRowOrColumn(aColumn, nsISelectionPrivate::TABLESELECTION_COLUMN,
-                           PR_FALSE);
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  return
+    RemoveRowsOrColumnsFromSelection(aColumn,
+                                     nsISelectionPrivate::TABLESELECTION_COLUMN,
+                                     PR_FALSE);
 }
 
 nsresult
-nsHTMLTableAccessible::SelectRowOrColumn(PRInt32 aIndex, PRUint32 aTarget,
-                                         PRBool aDoSelect)
+nsHTMLTableAccessible::AddRowOrColumnToSelection(PRInt32 aIndex,
+                                                 PRUint32 aTarget)
 {
   PRBool doSelectRow = (aTarget == nsISelectionPrivate::TABLESELECTION_ROW);
 
-  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
-  if (!content)
-    return NS_OK;
+  nsITableLayout *tableLayout = GetTableLayout();
+  NS_ENSURE_STATE(tableLayout);
 
-  nsCOMPtr<nsIDocument> document = content->GetCurrentDoc();
-  NS_ENSURE_STATE(document);
+  nsCOMPtr<nsIDOMElement> cellElm;
+  PRInt32 startRowIdx, startColIdx, rowSpan, colSpan,
+    actualRowSpan, actualColSpan;
+  PRBool isSelected = PR_FALSE;
 
-  nsCOMPtr<nsISelectionController> selController(
-    do_QueryInterface(document->GetPrimaryShell()));
-  NS_ENSURE_STATE(selController);
+  nsresult rv = NS_OK;
+  PRInt32 count = 0;
+  if (doSelectRow)
+    rv = GetColumnCount(&count);
+  else
+    rv = GetRowCount(&count);
 
-  nsCOMPtr<nsISelection> selection;
-  selController->GetSelection(nsISelectionController::SELECTION_NORMAL,
-                              getter_AddRefs(selection));
-  NS_ENSURE_STATE(selection);
-
-  PRInt32 count = 0;
-  nsresult rv = doSelectRow ? GetColumns(&count) : GetRows(&count);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  for (PRInt32 index = 0; index < count; index++) {
-    nsCOMPtr<nsIDOMElement> cellElm;
-    PRInt32 column = doSelectRow ? index : aIndex;
-    PRInt32 row = doSelectRow ? aIndex : index;
-
-    rv = GetCellAt(row, column, *getter_AddRefs(cellElm));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    rv = SelectCell(selection, document, cellElm, aDoSelect);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-  
-  return NS_OK;
-}
-
-nsresult
-nsHTMLTableAccessible::SelectCell(nsISelection *aSelection,
-                                  nsIDocument *aDocument,
-                                  nsIDOMElement *aCellElement,
-                                  PRBool aDoSelect)
-{
-  if (aDoSelect) {
-    nsCOMPtr<nsIDOMDocumentRange> documentRange(do_QueryInterface(aDocument));
-    NS_ENSURE_STATE(documentRange);
-
-    nsCOMPtr<nsIDOMRange> range;
-    documentRange->CreateRange(getter_AddRefs(range));
+  nsCOMPtr<nsIPresShell> presShell(GetPresShell());
+  nsRefPtr<nsFrameSelection> tableSelection =
+    const_cast<nsFrameSelection*>(presShell->ConstFrameSelection());
 
-    nsCOMPtr<nsIDOMNode> cellNode(do_QueryInterface(aCellElement));
-    NS_ENSURE_STATE(cellNode);
-
-    range->SelectNode(cellNode);
-    return aSelection->AddRange(range);
-  }
-
-  nsCOMPtr<nsIContent> cell(do_QueryInterface(aCellElement));
-  NS_ENSURE_STATE(cell);
-
-  nsCOMPtr<nsIContent> cellParent = cell->GetParent();
-  NS_ENSURE_STATE(cellParent);
+  for (PRInt32 idx = 0; idx < count; idx++) {
+    PRInt32 rowIdx = doSelectRow ? aIndex : idx;
+    PRInt32 colIdx = doSelectRow ? idx : aIndex;
+    rv = tableLayout->GetCellDataAt(rowIdx, colIdx,
+                                    *getter_AddRefs(cellElm),
+                                    startRowIdx, startColIdx,
+                                    rowSpan, colSpan,
+                                    actualRowSpan, actualColSpan,
+                                    isSelected);      
 
-  PRInt32 offset = cellParent->IndexOf(cell);
-  NS_ENSURE_STATE(offset != -1);
-
-  nsCOMPtr<nsIDOMNode> parent(do_QueryInterface(cellParent));
-  NS_ENSURE_STATE(parent);
-
-  nsCOMPtr<nsISelection2> selection2(do_QueryInterface(aSelection));
-  NS_ENSURE_STATE(selection2);
-
-  nsCOMArray<nsIDOMRange> ranges;
-  nsresult rv = selection2->GetRangesForIntervalCOMArray(parent, offset,
-                                                         parent, offset,
-                                                         PR_TRUE, &ranges);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  for (PRInt32 i = 0; i < ranges.Count(); i ++)
-    aSelection->RemoveRange(ranges[i]);
+    if (NS_SUCCEEDED(rv) && !isSelected) {
+      nsCOMPtr<nsIContent> cellContent(do_QueryInterface(cellElm));
+      rv = tableSelection->SelectCellElement(cellContent);
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
+  }
 
   return NS_OK;
 }
 
 nsresult
-nsHTMLTableAccessible::GetTableNode(nsIDOMNode **_retval)
+nsHTMLTableAccessible::RemoveRowsOrColumnsFromSelection(PRInt32 aIndex,
+                                                        PRUint32 aTarget,
+                                                        PRBool aIsOuter)
 {
-  nsresult rv = NS_OK;
+  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
 
-  nsCOMPtr<nsIDOMHTMLTableElement> table(do_QueryInterface(mDOMNode));
-  if (table) {
-    *_retval = table;
-    NS_IF_ADDREF(*_retval);
-    return rv;
-  }
+  nsITableLayout *tableLayout = GetTableLayout();
+  NS_ENSURE_STATE(tableLayout);
+
+  nsCOMPtr<nsIPresShell> presShell(GetPresShell());
+  nsRefPtr<nsFrameSelection> tableSelection =
+    const_cast<nsFrameSelection*>(presShell->ConstFrameSelection());
+
+  PRBool doUnselectRow = (aTarget == nsISelectionPrivate::TABLESELECTION_ROW);
 
-  nsCOMPtr<nsIDOMHTMLTableSectionElement> section(do_QueryInterface(mDOMNode));
-  if (section) {
-    nsCOMPtr<nsIDOMNode> parent;
-    rv = section->GetParentNode(getter_AddRefs(parent));
-    NS_ENSURE_SUCCESS(rv, rv);
+  nsresult rv = NS_OK;
+  PRInt32 count = 0;
+  if (doUnselectRow)
+    rv = GetColumnCount(&count);
+  else
+    rv = GetRowCount(&count);
 
-    *_retval = parent;
-    NS_IF_ADDREF(*_retval);
-    return rv;
-  }
+  PRInt32 startRowIdx = doUnselectRow ? aIndex : 0;
+  PRInt32 endRowIdx = doUnselectRow ? aIndex : count - 1;
+  PRInt32 startColIdx = doUnselectRow ? 0 : aIndex;
+  PRInt32 endColIdx = doUnselectRow ? count - 1 : aIndex;
 
-  return NS_ERROR_FAILURE;
+  if (aIsOuter)
+    return tableSelection->RestrictCellsToSelection(content,
+                                                    startRowIdx, startColIdx, 
+                                                    endRowIdx, endColIdx);
+
+  return tableSelection->RemoveCellsFromSelection(content,
+                                                  startRowIdx, startColIdx, 
+                                                  endRowIdx, endColIdx);
 }
 
-nsresult
-nsHTMLTableAccessible::GetTableLayout(nsITableLayout **aTableLayout)
+nsITableLayout*
+nsHTMLTableAccessible::GetTableLayout()
 {
-  *aTableLayout = nsnull;
-
-  nsCOMPtr<nsIDOMNode> tableNode;
-  GetTableNode(getter_AddRefs(tableNode));
-  nsCOMPtr<nsIContent> tableContent(do_QueryInterface(tableNode));
-  if (!tableContent) {
-    return NS_ERROR_FAILURE; // Table shut down
-  }
-
+  nsCOMPtr<nsIContent> tableContent(do_QueryInterface(mDOMNode));
   nsCOMPtr<nsIPresShell> shell = GetPresShell();
-  NS_ENSURE_TRUE(shell, NS_ERROR_FAILURE);
 
   nsIFrame *frame = shell->GetPrimaryFrameFor(tableContent);
   if (!frame)
-    return NS_ERROR_FAILURE;
+    return nsnull;
 
-  *aTableLayout = do_QueryFrame(frame);
-  return (*aTableLayout) ? NS_OK : NS_NOINTERFACE;
+  nsITableLayout *tableLayout = do_QueryFrame(frame);
+  return tableLayout;
 }
 
 nsresult
 nsHTMLTableAccessible::GetCellAt(PRInt32        aRowIndex,
                                  PRInt32        aColIndex,
                                  nsIDOMElement* &aCell)
 {
   PRInt32 startRowIndex = 0, startColIndex = 0,
           rowSpan, colSpan, actualRowSpan, actualColSpan;
   PRBool isSelected;
 
-  nsITableLayout *tableLayout = nsnull;
-  nsresult rv = GetTableLayout(&tableLayout);
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsITableLayout *tableLayout = GetTableLayout();
+  NS_ENSURE_STATE(tableLayout);
 
-  rv = tableLayout->GetCellDataAt(aRowIndex, aColIndex, aCell,
-                                  startRowIndex, startColIndex,
-                                  rowSpan, colSpan,
-                                  actualRowSpan, actualColSpan, isSelected);
+  nsresult rv = tableLayout->
+    GetCellDataAt(aRowIndex, aColIndex, aCell, startRowIndex, startColIndex,
+                  rowSpan, colSpan, actualRowSpan, actualColSpan, isSelected);
 
   if (rv == NS_TABLELAYOUT_CELL_NOT_FOUND)
     return NS_ERROR_INVALID_ARG;
   return rv;
 }
 
 NS_IMETHODIMP nsHTMLTableAccessible::GetDescription(nsAString& aDescription)
 {
@@ -1355,21 +1399,19 @@ nsHTMLTableAccessible::IsProbablyForLayo
   { *aIsProbablyForLayout = isLayout; \
     mLayoutHeuristic = isLayout ? NS_LITERAL_STRING("layout table: ") : NS_LITERAL_STRING("data table: "); \
     mLayoutHeuristic += NS_LITERAL_STRING(heuristic); return NS_OK; }
 #else
 #define RETURN_LAYOUT_ANSWER(isLayout, heuristic) { *aIsProbablyForLayout = isLayout; return NS_OK; }
 #endif
 
   *aIsProbablyForLayout = PR_FALSE;
-  
-  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
-  if (!content) {
-    return NS_ERROR_FAILURE; // Table shut down
-  }
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIAccessible> docAccessible = do_QueryInterface(nsCOMPtr<nsIAccessibleDocument>(GetDocAccessible()));
   if (docAccessible) {
     PRUint32 state, extState;
     docAccessible->GetState(&state, &extState);
     if (extState & nsIAccessibleStates::EXT_STATE_EDITABLE) {  // Need to see all elements while document is being edited
       RETURN_LAYOUT_ANSWER(PR_FALSE, "In editable document");
     }
@@ -1378,16 +1420,17 @@ nsHTMLTableAccessible::IsProbablyForLayo
   // Check to see if an ARIA role overrides the role from native markup,
   // but for which we still expose table semantics (treegrid, for example).
   PRBool hasNonTableRole =
     (nsAccUtils::Role(this) != nsIAccessibleRole::ROLE_TABLE);
   if (hasNonTableRole) {
     RETURN_LAYOUT_ANSWER(PR_FALSE, "Has role attribute");
   }
 
+  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
   if (content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::role)) {
     // Role attribute is present, but overridden roles have already been dealt with.
     // Only landmarks and other roles that don't override the role from native
     // markup are left to deal with here.
     RETURN_LAYOUT_ANSWER(PR_FALSE, "Has role attribute, weak role, and role is table");
   }
   
   // Check for legitimate data table elements or attributes
@@ -1401,21 +1444,21 @@ nsHTMLTableAccessible::IsProbablyForLayo
     RETURN_LAYOUT_ANSWER(PR_FALSE, "Has caption, summary, th, thead, tfoot or colgroup -- legitimate table structures");
   }
   if (HasDescendant(NS_LITERAL_STRING("table"))) {
     RETURN_LAYOUT_ANSWER(PR_TRUE, "Has a nested table within it");
   }
   
   // If only 1 column or only 1 row, it's for layout
   PRInt32 columns, rows;
-  GetColumns(&columns);
+  GetColumnCount(&columns);
   if (columns <=1) {
     RETURN_LAYOUT_ANSWER(PR_TRUE, "Has only 1 column");
   }
-  GetRows(&rows);
+  GetRowCount(&rows);
   if (rows <=1) {
     RETURN_LAYOUT_ANSWER(PR_TRUE, "Has only 1 row");
   }
 
   // Check for many columns
   if (columns >= 5) {
     RETURN_LAYOUT_ANSWER(PR_FALSE, ">=5 columns");
   }
@@ -1515,68 +1558,20 @@ nsHTMLTableAccessible::IsProbablyForLayo
       HasDescendant(NS_LITERAL_STRING("applet")) ||
       HasDescendant(NS_LITERAL_STRING("iframe"))) {
     RETURN_LAYOUT_ANSWER(PR_TRUE, "Has no borders, and has iframe, object, applet or iframe, typical of advertisements");
   }
 
   RETURN_LAYOUT_ANSWER(PR_FALSE, "no layout factor strong enough, so will guess data");
 }
 
-// --------------------------------------------------------
-// nsHTMLTableHeadAccessible Accessible
-// --------------------------------------------------------
-NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLTableHeadAccessible, nsHTMLTableAccessible)
-
-nsHTMLTableHeadAccessible::nsHTMLTableHeadAccessible(nsIDOMNode *aDomNode, nsIWeakReference *aShell):
-nsHTMLTableAccessible(aDomNode, aShell)
-{
-}
-
-nsresult
-nsHTMLTableHeadAccessible::GetRoleInternal(PRUint32 *aRole)
-{
-  *aRole = nsIAccessibleRole::ROLE_COLUMNHEADER;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsHTMLTableHeadAccessible::GetCaption(nsIAccessible **aCaption)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsHTMLTableHeadAccessible::GetSummary(nsAString &aSummary)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsHTMLTableHeadAccessible::GetColumnHeader(nsIAccessibleTable **aColumnHeader)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsHTMLTableHeadAccessible::GetRows(PRInt32 *aRows)
-{
-  nsresult rv = NS_OK;
-
-  nsCOMPtr<nsIDOMHTMLTableSectionElement> head(do_QueryInterface(mDOMNode));
-  NS_ENSURE_TRUE(head, NS_ERROR_FAILURE);
-
-  nsCOMPtr<nsIDOMHTMLCollection> rows;
-  rv = head->GetRows(getter_AddRefs(rows));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return rows->GetLength((PRUint32 *)aRows);
-}
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLCaptionAccessible
+////////////////////////////////////////////////////////////////////////////////
 
 NS_IMETHODIMP
 nsHTMLCaptionAccessible::GetRelationByType(PRUint32 aRelationType,
                                            nsIAccessibleRelation **aRelation)
 {
   nsresult rv = nsHyperTextAccessible::GetRelationByType(aRelationType,
                                                          aRelation);
   NS_ENSURE_SUCCESS(rv, rv);
--- a/accessible/src/html/nsHTMLTableAccessible.h
+++ b/accessible/src/html/nsHTMLTableAccessible.h
@@ -34,104 +34,82 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _nsHTMLTableAccessible_H_
 #define _nsHTMLTableAccessible_H_
 
-#include "nsBaseWidgetAccessible.h"
+#include "nsHyperTextAccessibleWrap.h"
 #include "nsIAccessibleTable.h"
 
 class nsITableLayout;
+class nsITableCellLayout;
 
 /**
  * HTML table cell accessible (html:td).
  */
-class nsHTMLTableCellAccessible : public nsHyperTextAccessibleWrap
+class nsHTMLTableCellAccessible : public nsHyperTextAccessibleWrap,
+                                  public nsIAccessibleTableCell
 {
 public:
   nsHTMLTableCellAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  // nsIAccessible
-  NS_IMETHOD GetRelationByType(PRUint32 aRelationType,
-                               nsIAccessibleRelation **aRelation);
-  
+  // nsIAccessibleTableCell
+  NS_DECL_NSIACCESSIBLETABLECELL
+
   // nsAccessible
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
   virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
 
 protected:
-  already_AddRefed<nsIAccessibleTable> GetTableAccessible();
-  nsresult GetCellIndexes(PRInt32& aRowIdx, PRInt32& aColIdx);
-
   /**
-   * Search hint enum constants. Used by FindCellsForRelation method.
+   * Return host table accessible.
    */
-  enum {
-    // search for header cells, up-left direction search
-    eHeadersForCell,
-    // search for row header cell, right direction search
-    eCellsForRowHeader,
-    // search for column header cell, down direction search
-    eCellsForColumnHeader
-  };
+  already_AddRefed<nsIAccessibleTable> GetTableAccessible();
+  
+  /**
+   * Return nsITableCellLayout of the table cell frame.
+   */
+  nsITableCellLayout* GetCellLayout();
 
   /**
-   * Add found cells as relation targets.
-   *
-   * @param  aSearchHint    [in] enum constan defined above, defines an
-   *                         algorithm to search cells
-   * @param  aRelationType  [in] relation type
-   * @param  aRelation      [in, out] relation object
+   * Return row and column indices of the cell.
    */
-  nsresult FindCellsForRelation(PRInt32 aSearchHint, PRUint32 aRelationType,
-                                nsIAccessibleRelation **aRelation);
-
+  nsresult GetCellIndexes(PRInt32& aRowIdx, PRInt32& aColIdx);
+  
   /**
-   * Return the cell or header cell at the given row and column.
-   *
-   * @param  aTableAcc       [in] table accessible the search is prepared in
-   * @param  aAnchorCell     [in] anchor cell, found cell should be different
-   *                          from it
-   * @param  aRowIdx         [in] row index
-   * @param  aColIdx         [in] column index
-   * @param  aLookForHeader  [in] flag specifies if found cell must be a header
-   * @return                 found cell content
+   * Return an array of row or column header cells.
    */
-  nsIContent* FindCell(nsHTMLTableAccessible *aTableAcc, nsIContent *aAnchorCell,
-                       PRInt32 aRowIdx, PRInt32 aColIdx,
-                       PRInt32 aLookForHeader);
+  nsresult GetHeaderCells(PRInt32 aRowOrColumnHeaderCell,
+                          nsIArray **aHeaderCells);
 };
 
 
 /**
  * HTML table row/column header accessible (html:th or html:td@scope).
  */
-class nsHTMLTableHeaderAccessible : public nsHTMLTableCellAccessible
+class nsHTMLTableHeaderCellAccessible : public nsHTMLTableCellAccessible
 {
 public:
-  nsHTMLTableHeaderAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
+  nsHTMLTableHeaderCellAccessible(nsIDOMNode* aDomNode,
+                                  nsIWeakReference* aShell);
 
   // nsAccessible
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
-
-  // nsIAccessible
-  NS_IMETHOD GetRelationByType(PRUint32 aRelationType,
-                               nsIAccessibleRelation **aRelation);
 };
 
 
 /**
- * HTML table accessible.
+ * HTML table accessible (html:table).
  */
 
 // To turn on table debugging descriptions define SHOW_LAYOUT_HEURISTIC
 // This allow release trunk builds to be used by testers to refine the
 // data vs. layout heuristic
 // #define SHOW_LAYOUT_HEURISTIC
 
 #define NS_TABLEACCESSIBLE_IMPL_CID                     \
@@ -179,43 +157,50 @@ public:
     */
   PRBool IsValidRow(PRInt32 aRow);
 
   /**
    * Retun cell element at the given row and column index.
    */
   nsresult GetCellAt(PRInt32 aRowIndex, PRInt32 aColIndex,
                      nsIDOMElement* &aCell);
-protected:
 
   /**
-   * Selects or unselects row or column.
-   *
-   * @param aIndex - index of row or column to be selected
-   * @param aTarget - indicates what should be selected, either row or column
-   *                  (see nsISelectionPrivate)
-   * @param aDoSelect - indicates whether row or column should selected or
-   *                    unselected
+   * Return nsITableLayout for the frame of the accessible table.
    */
-  nsresult SelectRowOrColumn(PRInt32 aIndex, PRUint32 aTarget, PRBool aDoSelect);
+  nsITableLayout* GetTableLayout();
+
+protected:
+
+  // nsAccessible
+  virtual void CacheChildren();
+
+  // nsHTMLTableAccessible
 
   /**
-   * Selects or unselects the cell.
+   * Add row or column to selection.
    *
-   * @param aSelection - the selection of document
-   * @param aDocument - the document that contains the cell
-   * @param aCellElement - the cell of table
-   * @param aDoSelect - indicates whether cell should be selected or unselected
+   * @param aIndex   [in] index of row or column to be selected
+   * @param aTarget  [in] indicates what should be selected, either row or column
+   *                  (see nsISelectionPrivate)
    */
-  nsresult SelectCell(nsISelection *aSelection, nsIDocument *aDocument,
-                      nsIDOMElement *aCellElement, PRBool aDoSelect);
+  nsresult AddRowOrColumnToSelection(PRInt32 aIndex, PRUint32 aTarget);
 
-  virtual void CacheChildren();
-  nsresult GetTableNode(nsIDOMNode **_retval);
-  nsresult GetTableLayout(nsITableLayout **aLayoutObject);
+  /**
+   * Removes rows or columns at the given index or outside it from selection.
+   *
+   * @param  aIndex    [in] row or column index
+   * @param  aTarget   [in] indicates whether row or column should unselected
+   * @param  aIsOuter  [in] indicates whether all rows or column excepting
+   *                    the given one should be unselected or the given one
+   *                    should be unselected only
+   */
+  nsresult RemoveRowsOrColumnsFromSelection(PRInt32 aIndex,
+                                            PRUint32 aTarget,
+                                            PRBool aIsOuter);
 
   /**
    * Return true if table has an element with the given tag name.
    *
    * @param  aTagName     [in] tag name of searched element
    * @param  aAllowEmpty  [in, optional] points if found element can be empty
    *                       or contain whitespace text only.
    */
@@ -225,33 +210,19 @@ protected:
   nsString mLayoutHeuristic;
 #endif
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsHTMLTableAccessible,
                               NS_TABLEACCESSIBLE_IMPL_CID)
 
 
-class nsHTMLTableHeadAccessible : public nsHTMLTableAccessible
-{
-public:
-  NS_DECL_ISUPPORTS_INHERITED
-
-  nsHTMLTableHeadAccessible(nsIDOMNode *aDomNode, nsIWeakReference *aShell);
-
-  /* nsIAccessibleTable */
-  NS_IMETHOD GetCaption(nsIAccessible **aCaption);
-  NS_IMETHOD GetSummary(nsAString &aSummary);
-  NS_IMETHOD GetColumnHeader(nsIAccessibleTable **aColumnHeader);
-  NS_IMETHOD GetRows(PRInt32 *aRows);
-
-  // nsAccessible
-  virtual nsresult GetRoleInternal(PRUint32 *aRole);
-};
-
+/**
+ * HTML caption accessible (html:caption).
+ */
 class nsHTMLCaptionAccessible : public nsHyperTextAccessibleWrap
 {
 public:
   nsHTMLCaptionAccessible(nsIDOMNode *aDomNode, nsIWeakReference *aShell) :
     nsHyperTextAccessibleWrap(aDomNode, aShell) { }
 
   // nsIAccessible
   NS_IMETHOD GetRelationByType(PRUint32 aRelationType,
--- a/accessible/src/mac/Makefile.in
+++ b/accessible/src/mac/Makefile.in
@@ -60,17 +60,18 @@ CMMSRCS = nsAccessNodeWrap.mm \
 EXPORTS = \
   nsAccessNodeWrap.h \
   nsTextAccessibleWrap.h \
   nsAccessibleWrap.h \
   nsARIAGridAccessibleWrap.h \
   nsDocAccessibleWrap.h \
   nsRootAccessibleWrap.h \
   nsXULMenuAccessibleWrap.h \
-  nsXULTreeAccessibleWrap.h \
+  nsXULListboxAccessibleWrap.h \
+  nsXULTreeGridAccessibleWrap.h \
   nsHyperTextAccessibleWrap.h \
   nsHTMLImageAccessibleWrap.h \
   nsHTMLTableAccessibleWrap.h \
   nsAccessibleRelationWrap.h \
   nsApplicationAccessibleWrap.h \
   mozDocAccessible.h \
   mozAccessible.h \
   mozAccessibleWrapper.h \
--- a/accessible/src/mac/nsARIAGridAccessibleWrap.h
+++ b/accessible/src/mac/nsARIAGridAccessibleWrap.h
@@ -39,11 +39,12 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _NSARIAGRIDACCESSIBLEWRAP_H
 #define _NSARIAGRIDACCESSIBLEWRAP_H
 
 #include "nsARIAGridAccessible.h"
 
 typedef class nsARIAGridAccessible nsARIAGridAccessibleWrap;
+typedef class nsARIAGridCellAccessible nsARIAGridCellAccessibleWrap;
 
 #endif
 
--- a/accessible/src/mac/nsHTMLTableAccessibleWrap.h
+++ b/accessible/src/mac/nsHTMLTableAccessibleWrap.h
@@ -39,13 +39,13 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _NSHTMLTABLEACCESSIBLEWRAP_H
 #define _NSHTMLTABLEACCESSIBLEWRAP_H
 
 #include "nsHTMLTableAccessible.h"
 
 typedef class nsHTMLTableAccessible nsHTMLTableAccessibleWrap;
-
-typedef class nsHTMLTableHeadAccessible nsHTMLTableHeadAccessibleWrap;
+typedef class nsHTMLTableCellAccessible nsHTMLTableCellAccessibleWrap;
+typedef class nsHTMLTableHeaderCellAccessible nsHTMLTableHeaderCellAccessibleWrap;
 
 #endif
 
new file mode 100644
--- /dev/null
+++ b/accessible/src/mac/nsXULListboxAccessibleWrap.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alexander Surkov <surkov.alexander@gmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __nsXULListboxAccessibleWrap_h__
+#define __nsXULListboxAccessibleWrap_h__
+
+#include "nsXULListboxAccessible.h"
+
+typedef class nsXULListboxAccessible nsXULListboxAccessibleWrap;
+typedef class nsXULListCellAccessible nsXULListCellAccessibleWrap;
+
+#endif
rename from accessible/src/mac/nsXULTreeAccessibleWrap.h
rename to accessible/src/mac/nsXULTreeGridAccessibleWrap.h
--- a/accessible/src/mac/nsXULTreeAccessibleWrap.h
+++ b/accessible/src/mac/nsXULTreeGridAccessibleWrap.h
@@ -30,16 +30,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#ifndef __nsXULTreeAccessibleWrap_h__
-#define __nsXULTreeAccessibleWrap_h__
+#ifndef __nsXULTreeGridAccessibleWrap_h__
+#define __nsXULTreeGridAccessibleWrap_h__
 
 #include "nsXULTreeGridAccessible.h"
-typedef class nsXULTreeGridAccessible       nsXULTreeGridAccessibleWrap;
-typedef class nsXULTreeColumnsAccessible    nsXULTreeColumnsAccessibleWrap;
+
+typedef class nsXULTreeGridAccessible nsXULTreeGridAccessibleWrap;
+typedef class nsXULTreeGridCellAccessible nsXULTreeGridCellAccessibleWrap;
 
 #endif
--- a/accessible/src/msaa/CAccessibleHyperlink.cpp
+++ b/accessible/src/msaa/CAccessibleHyperlink.cpp
@@ -91,17 +91,17 @@ CAccessibleHyperlink::get_anchor(long aI
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   nsCOMPtr<nsIWinAccessNode> winAccessNode(do_QueryInterface(anchor));
   if (!winAccessNode)
     return E_FAIL;
 
   void *instancePtr = NULL;
-  rv =  winAccessNode->QueryNativeInterface(IID_IUnknown, &instancePtr);
+  rv = winAccessNode->QueryNativeInterface(IID_IUnknown, &instancePtr);
   if (NS_FAILED(rv))
     return E_FAIL;
 
   IUnknown *unknownPtr = static_cast<IUnknown*>(instancePtr);
   aAnchor->ppunkVal = &unknownPtr;
   aAnchor->vt = VT_UNKNOWN;
   return S_OK;
 
--- a/accessible/src/msaa/CAccessibleTable.cpp
+++ b/accessible/src/msaa/CAccessibleTable.cpp
@@ -37,21 +37,23 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "CAccessibleTable.h"
 
 #include "Accessible2.h"
 #include "AccessibleTable_i.c"
+#include "AccessibleTable2_i.c"
 
 #include "nsIAccessible.h"
 #include "nsIAccessibleTable.h"
 #include "nsIWinAccessNode.h"
 #include "nsAccessNodeWrap.h"
+#include "nsWinUtils.h"
 
 #include "nsCOMPtr.h"
 #include "nsString.h"
 
 #define CANT_QUERY_ASSERTION_MSG \
 "Subclass of CAccessibleTable doesn't implement nsIAccessibleTable"\
 
 // IUnknown
@@ -62,35 +64,42 @@ CAccessibleTable::QueryInterface(REFIID 
   *ppv = NULL;
 
   if (IID_IAccessibleTable == iid) {
     *ppv = static_cast<IAccessibleTable*>(this);
     (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
     return S_OK;
   }
 
+  if (IID_IAccessibleTable2 == iid) {
+    *ppv = static_cast<IAccessibleTable2*>(this);
+    (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
+    return S_OK;
+  }
+
   return E_NOINTERFACE;
 }
 
+////////////////////////////////////////////////////////////////////////////////
 // IAccessibleTable
 
 STDMETHODIMP
 CAccessibleTable::get_accessibleAt(long aRow, long aColumn,
                                    IUnknown **aAccessible)
 {
 __try {
   *aAccessible = NULL;
 
   nsCOMPtr<nsIAccessibleTable> tableAcc(do_QueryInterface(this));
   NS_ASSERTION(tableAcc, CANT_QUERY_ASSERTION_MSG);
   if (!tableAcc)
     return E_FAIL;
 
   nsCOMPtr<nsIAccessible> cell;
-  nsresult rv = tableAcc->CellRefAt(aRow, aColumn, getter_AddRefs(cell));
+  nsresult rv = tableAcc->GetCellAt(aRow, aColumn, getter_AddRefs(cell));
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   nsCOMPtr<nsIWinAccessNode> winAccessNode(do_QueryInterface(cell));
   if (!winAccessNode)
     return E_FAIL;
 
   void *instancePtr = NULL;
@@ -148,24 +157,25 @@ CAccessibleTable::get_childIndex(long aR
   *aChildIndex = 0;
 
   nsCOMPtr<nsIAccessibleTable> tableAcc(do_QueryInterface(this));
   NS_ASSERTION(tableAcc, CANT_QUERY_ASSERTION_MSG);
   if (!tableAcc)
     return E_FAIL;
 
   PRInt32 childIndex = 0;
-  nsresult rv = tableAcc->GetIndexAt(aRowIndex, aColumnIndex, &childIndex);
+  nsresult rv = tableAcc->GetCellIndexAt(aRowIndex, aColumnIndex, &childIndex);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   *aChildIndex = childIndex;
   return S_OK;
 
-} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(),
+                                                  GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 STDMETHODIMP
 CAccessibleTable::get_columnDescription(long aColumn, BSTR *aDescription)
 {
 __try {
   *aDescription = NULL;
@@ -215,131 +225,108 @@ CAccessibleTable::get_columnExtentAt(lon
 }
 
 STDMETHODIMP
 CAccessibleTable::get_columnHeader(IAccessibleTable **aAccessibleTable,
                                    long *aStartingRowIndex)
 {
 __try {
   *aAccessibleTable = NULL;
-
-  // XXX: starting row index is always 0.
-  *aStartingRowIndex = 0;
-
-  nsCOMPtr<nsIAccessibleTable> tableAcc(do_QueryInterface(this));
-  NS_ASSERTION(tableAcc, CANT_QUERY_ASSERTION_MSG);
-  if (!tableAcc)
-    return E_FAIL;
-
-  nsCOMPtr<nsIAccessibleTable> header;
-  nsresult rv = tableAcc->GetColumnHeader(getter_AddRefs(header));
-  if (NS_FAILED(rv))
-    return GetHRESULT(rv);
+  *aStartingRowIndex = -1;
 
-  if (!header)
-    return S_FALSE;
-
-  nsCOMPtr<nsIWinAccessNode> winAccessNode(do_QueryInterface(header));
-  if (!winAccessNode)
-    return E_FAIL;
-
-  void *instancePtr = NULL;
-  rv = winAccessNode->QueryNativeInterface(IID_IAccessibleTable, &instancePtr);
-  if (NS_FAILED(rv))
-    return GetHRESULT(rv);
-
-  *aAccessibleTable = static_cast<IAccessibleTable*>(instancePtr);
-  return S_OK;
-
-} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
-  return E_FAIL;
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(),
+                                                  GetExceptionInformation())) {}
+  return E_NOTIMPL;
 }
 
 STDMETHODIMP
 CAccessibleTable::get_columnIndex(long aChildIndex, long *aColumnIndex)
 {
 __try {
   *aColumnIndex = 0;
 
   nsCOMPtr<nsIAccessibleTable> tableAcc(do_QueryInterface(this));
   NS_ASSERTION(tableAcc, CANT_QUERY_ASSERTION_MSG);
   if (!tableAcc)
     return E_FAIL;
 
   PRInt32 columnIndex = 0;
-  nsresult rv = tableAcc->GetColumnAtIndex(aChildIndex, &columnIndex);
+  nsresult rv = tableAcc->GetColumnIndexAt(aChildIndex, &columnIndex);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   *aColumnIndex = columnIndex;
   return S_OK;
 
-} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(),
+                                                  GetExceptionInformation())) {}
   return E_FAIL;
 }
 
 STDMETHODIMP
 CAccessibleTable::get_nColumns(long *aColumnCount)
 {
 __try {
   *aColumnCount = 0;
 
   nsCOMPtr<nsIAccessibleTable> tableAcc(do_QueryInterface(this));
   NS_ASSERTION(tableAcc, CANT_QUERY_ASSERTION_MSG);
   if (!tableAcc)
     return E_FAIL;
 
   PRInt32 columnCount = 0;
-  nsresult rv = tableAcc->GetColumns(&columnCount);
+  nsresult rv = tableAcc->GetColumnCount(&columnCount);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   *aColumnCount = columnCount;
   return S_OK;
 
-} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(),
+                                                  GetExceptionInformation())) {}
   return E_FAIL;
 }
 
 STDMETHODIMP
 CAccessibleTable::get_nRows(long *aRowCount)
 {
 __try {
   *aRowCount = 0;
 
   nsCOMPtr<nsIAccessibleTable> tableAcc(do_QueryInterface(this));
   NS_ASSERTION(tableAcc, CANT_QUERY_ASSERTION_MSG);
   if (!tableAcc)
     return E_FAIL;
 
   PRInt32 rowCount = 0;
-  nsresult rv = tableAcc->GetRows(&rowCount);
+  nsresult rv = tableAcc->GetRowCount(&rowCount);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   *aRowCount = rowCount;
   return S_OK;
 
-} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(),
+                                                  GetExceptionInformation())) {}
   return E_FAIL;
 }
 
 STDMETHODIMP
 CAccessibleTable::get_nSelectedChildren(long *aChildCount)
 {
 __try {
   *aChildCount = 0;
 
   nsCOMPtr<nsIAccessibleTable> tableAcc(do_QueryInterface(this));
   NS_ASSERTION(tableAcc, CANT_QUERY_ASSERTION_MSG);
   if (!tableAcc)
     return E_FAIL;
 
   PRUint32 count = 0;
-  nsresult rv = tableAcc->GetSelectedCellsCount(&count);
+  nsresult rv = tableAcc->GetSelectedCellCount(&count);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   *aChildCount = count;
   return S_OK;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
@@ -352,17 +339,17 @@ CAccessibleTable::get_nSelectedColumns(l
   *aColumnCount = 0;
 
   nsCOMPtr<nsIAccessibleTable> tableAcc(do_QueryInterface(this));
   NS_ASSERTION(tableAcc, CANT_QUERY_ASSERTION_MSG);
   if (!tableAcc)
     return E_FAIL;
 
   PRUint32 count = 0;
-  nsresult rv = tableAcc->GetSelectedColumnsCount(&count);
+  nsresult rv = tableAcc->GetSelectedColumnCount(&count);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   *aColumnCount = count;
   return S_OK;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
@@ -375,17 +362,17 @@ CAccessibleTable::get_nSelectedRows(long
   *aRowCount = 0;
 
   nsCOMPtr<nsIAccessibleTable> tableAcc(do_QueryInterface(this));
   NS_ASSERTION(tableAcc, CANT_QUERY_ASSERTION_MSG);
   if (!tableAcc)
     return E_FAIL;
 
   PRUint32 count = 0;
-  nsresult rv = tableAcc->GetSelectedRowsCount(&count);
+  nsresult rv = tableAcc->GetSelectedRowCount(&count);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   *aRowCount = count;
   return S_OK;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
@@ -441,99 +428,79 @@ CAccessibleTable::get_rowExtentAt(long a
 }
 
 STDMETHODIMP
 CAccessibleTable::get_rowHeader(IAccessibleTable **aAccessibleTable,
                                 long *aStartingColumnIndex)
 {
 __try {
   *aAccessibleTable = NULL;
-
-  // XXX: starting column index is always 0.
-  *aStartingColumnIndex = 0;
-
-  nsCOMPtr<nsIAccessibleTable> tableAcc(do_QueryInterface(this));
-  NS_ASSERTION(tableAcc, CANT_QUERY_ASSERTION_MSG);
-  if (!tableAcc)
-    return E_FAIL;
-
-  nsCOMPtr<nsIAccessibleTable> header;
-  nsresult rv = tableAcc->GetRowHeader(getter_AddRefs(header));
-  if (NS_FAILED(rv))
-    return GetHRESULT(rv);
+  *aStartingColumnIndex = -1;
 
-  if (!header)
-    return S_FALSE;
-
-  nsCOMPtr<nsIWinAccessNode> winAccessNode(do_QueryInterface(header));
-  if (!winAccessNode)
-    return E_FAIL;
-
-  void *instancePtr = NULL;
-  rv = winAccessNode->QueryNativeInterface(IID_IAccessibleTable,
-                                           &instancePtr);
-  if (NS_FAILED(rv))
-    return GetHRESULT(rv);
-
-  *aAccessibleTable = static_cast<IAccessibleTable*>(instancePtr);
-  return S_OK;
-
-} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
-  return E_FAIL;
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(),
+                                                  GetExceptionInformation())) {}
+  return E_NOTIMPL;
 }
 
 STDMETHODIMP
 CAccessibleTable::get_rowIndex(long aChildIndex, long *aRowIndex)
 {
 __try {
   *aRowIndex = 0;
 
   nsCOMPtr<nsIAccessibleTable> tableAcc(do_QueryInterface(this));
   NS_ASSERTION(tableAcc, CANT_QUERY_ASSERTION_MSG);
   if (!tableAcc)
     return E_FAIL;
 
   PRInt32 rowIndex = 0;
-  nsresult rv = tableAcc->GetRowAtIndex(aChildIndex, &rowIndex);
+  nsresult rv = tableAcc->GetRowIndexAt(aChildIndex, &rowIndex);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   *aRowIndex = rowIndex;
   return S_OK;
 
-} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(),
+                                                  GetExceptionInformation())) {}
   return E_FAIL;
 }
 
 STDMETHODIMP
 CAccessibleTable::get_selectedChildren(long aMaxChildren, long **aChildren,
                                        long *aNChildren)
 {
 __try {
-  return GetSelectedItems(aMaxChildren, aChildren, aNChildren, ITEMSTYPE_CELLS);
-} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
+  return GetSelectedItems(aChildren, aNChildren, ITEMSTYPE_CELLS);
+
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(),
+                                                  GetExceptionInformation())) {}
   return E_FAIL;
 }
 
 STDMETHODIMP
 CAccessibleTable::get_selectedColumns(long aMaxColumns, long **aColumns,
                                       long *aNColumns)
 {
 __try {
-  return GetSelectedItems(aMaxColumns, aColumns, aNColumns, ITEMSTYPE_COLUMNS);
-} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
+  return GetSelectedItems(aColumns, aNColumns, ITEMSTYPE_COLUMNS);
+
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(),
+                                                  GetExceptionInformation())) {}
   return E_FAIL;
 }
 
 STDMETHODIMP
 CAccessibleTable::get_selectedRows(long aMaxRows, long **aRows, long *aNRows)
 {
 __try {
-  return GetSelectedItems(aMaxRows, aRows, aNRows, ITEMSTYPE_ROWS);
-} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
+  return GetSelectedItems(aRows, aNRows, ITEMSTYPE_ROWS);
+
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(),
+                                                  GetExceptionInformation())) {}
   return E_FAIL;
 }
 
 STDMETHODIMP
 CAccessibleTable::get_summary(IUnknown **aAccessible)
 {
 __try {
   *aAccessible = NULL;
@@ -695,22 +662,22 @@ CAccessibleTable::get_rowColumnExtentsAt
   *aIsSelected = false;
 
   nsCOMPtr<nsIAccessibleTable> tableAcc(do_QueryInterface(this));
   NS_ASSERTION(tableAcc, CANT_QUERY_ASSERTION_MSG);
   if (!tableAcc)
     return E_FAIL;
 
   PRInt32 row = -1;
-  nsresult rv = tableAcc->GetRowAtIndex(aIndex, &row);
+  nsresult rv = tableAcc->GetRowIndexAt(aIndex, &row);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   PRInt32 column = -1;
-  rv = tableAcc->GetColumnAtIndex(aIndex, &column);
+  rv = tableAcc->GetColumnIndexAt(aIndex, &column);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   PRInt32 rowExtents = 0;
   rv = tableAcc->GetRowExtentAt(row, column, &rowExtents);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
@@ -739,59 +706,117 @@ STDMETHODIMP
 CAccessibleTable::get_modelChange(IA2TableModelChange *aModelChange)
 {
 __try {
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_NOTIMPL;
 }
 
-// CAccessibleTable
+////////////////////////////////////////////////////////////////////////////////
+// IAccessibleTable2
+
+STDMETHODIMP
+CAccessibleTable::get_cellAt(long row, long column, IUnknown **cell)
+{
+  return get_accessibleAt(row, column, cell);
+}
+
+STDMETHODIMP
+CAccessibleTable::get_nSelectedCells(long *cellCount)
+{
+  return get_nSelectedChildren(cellCount);
+}
+
+STDMETHODIMP
+CAccessibleTable::get_selectedCells(IUnknown ***cells, long *nSelectedCells)
+{
+__try {
+  nsCOMPtr<nsIAccessibleTable> tableAcc(do_QueryInterface(this));
+  NS_ASSERTION(tableAcc, CANT_QUERY_ASSERTION_MSG);
+  if (!tableAcc)
+    return E_FAIL;
+
+  nsCOMPtr<nsIArray> geckoCells;
+  nsresult rv = tableAcc->GetSelectedCells(getter_AddRefs(geckoCells));
+  if (NS_FAILED(rv))
+    return GetHRESULT(rv);
+
+  return nsWinUtils::ConvertToIA2Array(geckoCells, cells, nSelectedCells);
+
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(),
+                                                  GetExceptionInformation())) {}
+
+  return E_FAIL;
+}
+
+STDMETHODIMP
+CAccessibleTable::get_selectedColumns(long **aColumns, long *aNColumns)
+{
+__try {
+  return GetSelectedItems(aColumns, aNColumns, ITEMSTYPE_COLUMNS);
+
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(),
+                                                  GetExceptionInformation())) {}
+  return E_FAIL;
+}
+
+STDMETHODIMP
+CAccessibleTable::get_selectedRows(long **aRows, long *aNRows)
+{
+__try {
+  return GetSelectedItems(aRows, aNRows, ITEMSTYPE_ROWS);
+
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(),
+                                                  GetExceptionInformation())) {}
+  return E_FAIL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// CAccessibleTable public
 
 HRESULT
-CAccessibleTable::GetSelectedItems(long aMaxItems, long **aItems,
-                                   long *aItemsCount, eItemsType aType)
+CAccessibleTable::GetSelectedItems(long **aItems, long *aItemsCount,
+                                   eItemsType aType)
 {
   *aItemsCount = 0;
 
   nsCOMPtr<nsIAccessibleTable> tableAcc(do_QueryInterface(this));
   NS_ASSERTION(tableAcc, CANT_QUERY_ASSERTION_MSG);
   if (!tableAcc)
     return E_FAIL;
 
   PRUint32 size = 0;
   PRInt32 *items = nsnull;
 
   nsresult rv = NS_OK;
   switch (aType) {
     case ITEMSTYPE_CELLS:
-      rv = tableAcc->GetSelectedCells(&size, &items);
+      rv = tableAcc->GetSelectedCellIndices(&size, &items);
       break;
     case ITEMSTYPE_COLUMNS:
-      rv = tableAcc->GetSelectedColumns(&size, &items);
+      rv = tableAcc->GetSelectedColumnIndices(&size, &items);
       break;
     case ITEMSTYPE_ROWS:
-      rv = tableAcc->GetSelectedRows(&size, &items);
+      rv = tableAcc->GetSelectedRowIndices(&size, &items);
       break;
     default:
       return E_FAIL;
   }
 
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   if (size == 0 || !items)
     return S_FALSE;
 
-  PRUint32 maxSize = size < static_cast<PRUint32>(aMaxItems) ? size : aMaxItems;
-  *aItemsCount = maxSize;
-
-  *aItems = static_cast<long*>(nsMemory::Alloc((maxSize) * sizeof(long)));
+  *aItems = static_cast<long*>(nsMemory::Alloc((size) * sizeof(long)));
   if (!*aItems)
     return E_OUTOFMEMORY;
 
-  for (PRUint32 index = 0; index < maxSize; ++index)
+  *aItemsCount = size;
+  for (PRUint32 index = 0; index < size; ++index)
     (*aItems)[index] = items[index];
 
   nsMemory::Free(items);
   return S_OK;
 }
 
--- a/accessible/src/msaa/CAccessibleTable.h
+++ b/accessible/src/msaa/CAccessibleTable.h
@@ -39,19 +39,21 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _ACCESSIBLE_TABLE_H
 #define _ACCESSIBLE_TABLE_H
 
 #include "nsISupports.h"
 
 #include "AccessibleTable.h"
+#include "AccessibleTable2.h"
 
 class CAccessibleTable: public nsISupports,
-                        public IAccessibleTable
+                        public IAccessibleTable,
+                        public IAccessibleTable2
 {
 public:
 
   // IUnknown
   STDMETHODIMP QueryInterface(REFIID, void**);
 
   // IAccessibleTable
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_accessibleAt(
@@ -165,21 +167,42 @@ public:
       /* [out] */ long *column,
       /* [out] */ long *rowExtents,
       /* [out] */ long *columnExtents,
       /* [retval][out] */ boolean *isSelected);
 
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_modelChange(
       /* [retval][out] */ IA2TableModelChange *modelChange);
 
+
+  // IAccessibleTable2
+
+  virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_cellAt(
+      /* [in] */ long row,
+      /* [in] */ long column,
+      /* [out, retval] */ IUnknown **cell);
+
+  virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_nSelectedCells(
+      /* [out, retval] */ long *cellCount);
+
+  virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_selectedCells(
+      /* [out, size_is(,*nSelectedCells,)] */ IUnknown ***cells,
+      /* [out, retval] */ long *nSelectedCells);
+
+  virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_selectedColumns(
+      /* [out, size_is(,*nColumns)] */ long **selectedColumns,
+      /* [out, retval] */ long *nColumns);
+
+  virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_selectedRows(
+      /* [out, size_is(,*nRows)] */ long **selectedRows, 
+      /* [out, retval] */ long *nRows);
+
 private:
   enum eItemsType {
     ITEMSTYPE_CELLS,
     ITEMSTYPE_COLUMNS,
     ITEMSTYPE_ROWS
   };
 
-  HRESULT GetSelectedItems(long aMaxItems, long **aItems, long *aItemsCount,
-                           eItemsType aType);
+  HRESULT GetSelectedItems(long **aItems, long *aItemsCount, eItemsType aType);
 };
 
 #endif
-
new file mode 100644
--- /dev/null
+++ b/accessible/src/msaa/CAccessibleTableCell.cpp
@@ -0,0 +1,341 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:expandtab:shiftwidth=2:tabstop=2:
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alexander Surkov <surkov.alexander@gmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "CAccessibleTableCell.h"
+
+#include "Accessible2.h"
+#include "AccessibleTable2_i.c"
+#include "AccessibleTableCell_i.c"
+
+#include "nsIAccessible.h"
+#include "nsIAccessibleTable.h"
+#include "nsIWinAccessNode.h"
+#include "nsAccessNodeWrap.h"
+#include "nsWinUtils.h"
+
+#include "nsCOMPtr.h"
+#include "nsString.h"
+
+#define TABLECELL_INTERFACE_UNSUPPORTED_MSG \
+"Subclass of CAccessibleTableCell doesn't implement nsIAccessibleTableCell"\
+
+// IUnknown
+
+STDMETHODIMP
+CAccessibleTableCell::QueryInterface(REFIID iid, void** ppv)
+{
+  *ppv = NULL;
+
+  if (IID_IAccessibleTableCell == iid) {
+    *ppv = static_cast<IAccessibleTableCell*>(this);
+    (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
+    return S_OK;
+  }
+
+  return E_NOINTERFACE;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// IAccessibleTableCell
+
+STDMETHODIMP
+CAccessibleTableCell::get_table(IUnknown **table)
+{
+__try {
+  nsCOMPtr<nsIAccessibleTableCell> tableCell(do_QueryInterface(this));
+  NS_ASSERTION(tableCell, TABLECELL_INTERFACE_UNSUPPORTED_MSG);
+  if (!tableCell)
+    return E_FAIL;
+
+  nsCOMPtr<nsIAccessibleTable> geckoTable;
+  nsresult rv = tableCell->GetTable(getter_AddRefs(geckoTable));
+  if (NS_FAILED(rv))
+    return GetHRESULT(rv);
+
+  nsCOMPtr<nsIWinAccessNode> winAccessNode = do_QueryInterface(geckoTable);
+  if (!winAccessNode)
+    return E_FAIL;
+
+  void *instancePtr = NULL;
+  rv = winAccessNode->QueryNativeInterface(IID_IUnknown, &instancePtr);
+  if (NS_FAILED(rv))
+    return GetHRESULT(rv);
+
+  *table = static_cast<IUnknown*>(instancePtr);
+  return S_OK;
+
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(),
+                                                  GetExceptionInformation())) {}
+
+  return E_FAIL;
+}
+
+STDMETHODIMP
+CAccessibleTableCell::get_columnExtent(long *nColumnsSpanned)
+{
+__try {
+  *nColumnsSpanned = 0;
+
+  nsCOMPtr<nsIAccessibleTableCell> tableCell(do_QueryInterface(this));
+  NS_ASSERTION(tableCell, TABLECELL_INTERFACE_UNSUPPORTED_MSG);
+  if (!tableCell)
+    return E_FAIL;
+
+  PRInt32 columnsSpanned = 0;
+  nsresult rv = tableCell->GetColumnExtent(&columnsSpanned);
+  if (NS_SUCCEEDED(rv)) {
+    *nColumnsSpanned = columnsSpanned;
+    return S_OK;
+  }
+
+  return GetHRESULT(rv);
+
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(),
+                                                  GetExceptionInformation())) {}
+
+  return E_FAIL;
+}
+
+STDMETHODIMP
+CAccessibleTableCell::get_columnHeaderCells(IUnknown ***cellAccessibles,
+                                            long *nColumnHeaderCells)
+{
+__try {
+  nsCOMPtr<nsIAccessibleTableCell> tableCell(do_QueryInterface(this));
+  NS_ASSERTION(tableCell, TABLECELL_INTERFACE_UNSUPPORTED_MSG);
+  if (!tableCell)
+    return E_FAIL;
+
+  nsCOMPtr<nsIArray> headerCells;
+  nsresult rv = tableCell->GetColumnHeaderCells(getter_AddRefs(headerCells));  
+  if (NS_FAILED(rv))
+    return GetHRESULT(rv);
+
+  return nsWinUtils::ConvertToIA2Array(headerCells, cellAccessibles,
+                                       nColumnHeaderCells);
+
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(),
+                                                  GetExceptionInformation())) {}
+
+  return E_FAIL;
+}
+
+STDMETHODIMP
+CAccessibleTableCell::get_columnIndex(long *columnIndex)
+{
+__try {
+  *columnIndex = -1;
+
+  nsCOMPtr<nsIAccessibleTableCell> tableCell(do_QueryInterface(this));
+  NS_ASSERTION(tableCell, TABLECELL_INTERFACE_UNSUPPORTED_MSG);
+  if (!tableCell)
+    return E_FAIL;
+
+  PRInt32 colIdx = -1;
+  nsresult rv = tableCell->GetColumnIndex(&colIdx);
+  if (NS_SUCCEEDED(rv)) {
+    *columnIndex = colIdx;
+    return S_OK;
+  }
+
+  return GetHRESULT(rv);
+
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(),
+                                                  GetExceptionInformation())) {}
+
+  return E_FAIL;
+}
+
+STDMETHODIMP
+CAccessibleTableCell::get_rowExtent(long *nRowsSpanned)
+{
+__try {
+  *nRowsSpanned = 0;
+
+  nsCOMPtr<nsIAccessibleTableCell> tableCell(do_QueryInterface(this));
+  NS_ASSERTION(tableCell, TABLECELL_INTERFACE_UNSUPPORTED_MSG);
+  if (!tableCell)
+    return E_FAIL;
+
+  PRInt32 rowsSpanned = 0;
+  nsresult rv = tableCell->GetRowExtent(&rowsSpanned);
+  if (NS_SUCCEEDED(rv)) {
+    *nRowsSpanned = rowsSpanned;
+    return S_OK;
+  }
+
+  return GetHRESULT(rv);
+
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(),
+                                                  GetExceptionInformation())) {}
+
+  return E_FAIL;
+}
+
+STDMETHODIMP
+CAccessibleTableCell::get_rowHeaderCells(IUnknown ***cellAccessibles,
+                                         long *nRowHeaderCells)
+{
+__try {
+  nsCOMPtr<nsIAccessibleTableCell> tableCell(do_QueryInterface(this));
+  NS_ASSERTION(tableCell, TABLECELL_INTERFACE_UNSUPPORTED_MSG);
+  if (!tableCell)
+    return E_FAIL;
+
+  nsCOMPtr<nsIArray> headerCells;
+  nsresult rv = tableCell->GetRowHeaderCells(getter_AddRefs(headerCells));  
+  if (NS_FAILED(rv))
+    return GetHRESULT(rv);
+
+  return nsWinUtils::ConvertToIA2Array(headerCells, cellAccessibles,
+                                       nRowHeaderCells);
+
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(),
+                                                  GetExceptionInformation())) {}
+
+  return E_FAIL;
+}
+
+STDMETHODIMP
+CAccessibleTableCell::get_rowIndex(long *rowIndex)
+{
+__try {
+  *rowIndex = -1;
+
+  nsCOMPtr<nsIAccessibleTableCell> tableCell(do_QueryInterface(this));
+  NS_ASSERTION(tableCell, TABLECELL_INTERFACE_UNSUPPORTED_MSG);
+  if (!tableCell)
+    return E_FAIL;
+
+  PRInt32 rowIdx = -1;
+  nsresult rv = tableCell->GetRowIndex(&rowIdx);
+  if (NS_SUCCEEDED(rv)) {
+    *rowIndex = rowIdx;
+    return S_OK;
+  }
+
+  return GetHRESULT(rv);
+
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(),
+                                                  GetExceptionInformation())) {}
+
+  return E_FAIL;
+}
+
+STDMETHODIMP
+CAccessibleTableCell::get_rowColumnExtents(long *row, long *column,
+                                           long *rowExtents,
+                                           long *columnExtents,
+                                           boolean *isSelected)
+{
+__try {
+  *row = 0;
+  *column = 0;
+  *rowExtents = 0;
+  *columnExtents = 0;
+  *isSelected = false;
+
+  nsCOMPtr<nsIAccessibleTableCell> tableCell(do_QueryInterface(this));
+  NS_ASSERTION(tableCell, TABLECELL_INTERFACE_UNSUPPORTED_MSG);
+  if (!tableCell)
+    return E_FAIL;
+
+  PRInt32 rowIdx = -1;
+  nsresult rv = tableCell->GetRowIndex(&rowIdx);
+  if (NS_FAILED(rv))
+    return GetHRESULT(rv);
+
+  PRInt32 columnIdx = -1;
+  rv = tableCell->GetColumnIndex(&columnIdx);
+  if (NS_FAILED(rv))
+    return GetHRESULT(rv);
+
+  PRInt32 spannedRows = 0;
+  rv = tableCell->GetRowExtent(&spannedRows);
+  if (NS_FAILED(rv))
+    return GetHRESULT(rv);
+
+  PRInt32 spannedColumns = 0;
+  rv = tableCell->GetColumnExtent(&spannedColumns);
+  if (NS_FAILED(rv))
+    return GetHRESULT(rv);
+
+  PRBool isSel = PR_FALSE;
+  rv = tableCell->IsSelected(&isSel);
+  if (NS_FAILED(rv))
+    return GetHRESULT(rv);
+
+  *row = rowIdx;
+  *column = columnIdx;
+  *rowExtents = spannedRows;
+  *columnExtents = spannedColumns;
+  *isSelected = isSel;
+  return S_OK;
+
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(),
+                                                  GetExceptionInformation())) {}
+  return E_FAIL;
+}
+
+STDMETHODIMP
+CAccessibleTableCell::get_isSelected(boolean *isSelected)
+{
+__try {
+  *isSelected = false;
+
+  nsCOMPtr<nsIAccessibleTableCell> tableCell(do_QueryInterface(this));
+  NS_ASSERTION(tableCell, TABLECELL_INTERFACE_UNSUPPORTED_MSG);
+  if (!tableCell)
+    return E_FAIL;
+
+  PRBool isSel = PR_FALSE;
+  nsresult rv = tableCell->IsSelected(&isSel);
+  if (NS_SUCCEEDED(rv)) {
+    *isSelected = isSel;
+    return S_OK;
+  }
+
+  return GetHRESULT(rv);
+
+} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(),
+                                                  GetExceptionInformation())) {}
+
+  return E_FAIL;
+}
new file mode 100644
--- /dev/null
+++ b/accessible/src/msaa/CAccessibleTableCell.h
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:expandtab:shiftwidth=2:tabstop=2:
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alexander Surkov <surkov.alexander@gmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef _ACCESSIBLE_TABLECELL_H
+#define _ACCESSIBLE_TABLECELL_H
+
+#include "nsISupports.h"
+
+#include "AccessibleTableCell.h"
+
+class CAccessibleTableCell: public nsISupports,
+                            public IAccessibleTableCell
+{
+public:
+
+  // IUnknown
+  STDMETHODIMP QueryInterface(REFIID, void**);
+
+  // IAccessibleTableCell
+
+  virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_table(
+      /* [out, retval] */ IUnknown **table);
+
+  virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_columnExtent(
+      /* [out, retval] */ long *nColumnsSpanned);
+
+  virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_columnHeaderCells(
+      /* [out, size_is(,*nColumnHeaderCells,)] */ IUnknown ***cellAccessibles,
+      /* [out, retval] */ long *nColumnHeaderCells);
+
+  virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_columnIndex(
+      /* [out, retval] */ long *columnIndex);
+
+  virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_rowExtent(
+      /* [out, retval] */ long *nRowsSpanned);
+
+  virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_rowHeaderCells(
+      /* [out, size_is(,*nRowHeaderCells,)] */ IUnknown ***cellAccessibles,
+      /* [out, retval] */ long *nRowHeaderCells);
+
+  virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_rowIndex(
+      /* [out, retval] */ long *rowIndex);
+
+  virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_rowColumnExtents(
+      /* [out] */ long *row,
+      /* [out] */ long *column,
+      /* [out] */ long *rowExtents,
+      /* [out] */ long *columnExtents,
+      /* [out, retval] */ boolean *isSelected);
+
+  virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_isSelected(
+      /* [out, retval] */ boolean *isSelected);
+};
+
+#endif
--- a/accessible/src/msaa/Makefile.in
+++ b/accessible/src/msaa/Makefile.in
@@ -50,56 +50,61 @@ CPPSRCS = \
   nsAccessNodeWrap.cpp \
   nsAccessibleWrap.cpp \
   nsTextAccessibleWrap.cpp \
   nsDocAccessibleWrap.cpp \
   nsRootAccessibleWrap.cpp \
   nsHTMLWin32ObjectAccessible.cpp \
   nsARIAGridAccessibleWrap.cpp \
   nsXULMenuAccessibleWrap.cpp \
-  nsXULTreeAccessibleWrap.cpp \
+  nsXULListboxAccessibleWrap.cpp \
+  nsXULTreeGridAccessibleWrap.cpp \
   nsHyperTextAccessibleWrap.cpp \
   nsHTMLImageAccessibleWrap.cpp \
   nsHTMLTableAccessibleWrap.cpp \
   nsAccessibleRelationWrap.cpp \
   nsApplicationAccessibleWrap.cpp \
+  nsWinUtils.cpp \
   CAccessibleAction.cpp \
   CAccessibleImage.cpp \
   CAccessibleComponent.cpp \
   CAccessibleText.cpp \
   CAccessibleEditableText.cpp \
   CAccessibleHyperlink.cpp \
   CAccessibleHypertext.cpp \
   CAccessibleTable.cpp \
+  CAccessibleTableCell.cpp \
   CAccessibleValue.cpp \
   $(NULL)
 
 EXPORTS = \
   nsAccessNodeWrap.h \
   nsAccessibleWrap.h \
   nsTextAccessibleWrap.h \
   nsDocAccessibleWrap.h \
   nsRootAccessibleWrap.h \
   nsHTMLWin32ObjectAccessible.h \
   nsARIAGridAccessibleWrap.h \
   nsXULMenuAccessibleWrap.h \
-  nsXULTreeAccessibleWrap.h \
+  nsXULListboxAccessibleWrap.h \
+  nsXULTreeGridAccessibleWrap.h \
   nsHyperTextAccessibleWrap.h \
   nsHTMLImageAccessibleWrap.h \
   nsHTMLTableAccessibleWrap.h \
   nsAccessibleRelationWrap.h \
   nsApplicationAccessibleWrap.h \
   CAccessibleAction.h \
   CAccessibleImage.h \
   CAccessibleComponent.h \
   CAccessibleText.h \
   CAccessibleEditableText.h \
   CAccessibleHyperlink.h \
   CAccessibleHypertext.h \
   CAccessibleTable.h \
+  CAccessibleTableCell.h \
   CAccessibleValue.h \
   $(NULL)
 
 # we don't want the shared lib, but we want to force the creation of a static lib.
 FORCE_STATIC_LIB = 1
 
 include $(topsrcdir)/config/rules.mk
 
--- a/accessible/src/msaa/nsARIAGridAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsARIAGridAccessibleWrap.cpp
@@ -35,14 +35,30 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsARIAGridAccessibleWrap.h"
 
+////////////////////////////////////////////////////////////////////////////////
+// nsARIAGridAccessibleWrap
+////////////////////////////////////////////////////////////////////////////////
+
 NS_IMPL_ISUPPORTS_INHERITED0(nsARIAGridAccessibleWrap,
                              nsARIAGridAccessible)
 
 IMPL_IUNKNOWN_INHERITED1(nsARIAGridAccessibleWrap,
                          nsAccessibleWrap,
-                         CAccessibleTable);
+                         CAccessibleTable)
+
+
+////////////////////////////////////////////////////////////////////////////////
+// nsARIAGridCellAccessibleWrap
+////////////////////////////////////////////////////////////////////////////////
+
+NS_IMPL_ISUPPORTS_INHERITED0(nsARIAGridCellAccessibleWrap,
+                             nsARIAGridCellAccessible)
+
+IMPL_IUNKNOWN_INHERITED1(nsARIAGridCellAccessibleWrap,
+                         nsHyperTextAccessibleWrap,
+                         CAccessibleTableCell)
--- a/accessible/src/msaa/nsARIAGridAccessibleWrap.h
+++ b/accessible/src/msaa/nsARIAGridAccessibleWrap.h
@@ -38,28 +38,47 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _NSARIAGRIDACCESSIBLEWRAP_H
 #define _NSARIAGRIDACCESSIBLEWRAP_H
 
 #include "nsARIAGridAccessible.h"
 #include "CAccessibleTable.h"
+#include "CAccessibleTableCell.h"
 
 /**
- * Accessible for ARIA grid and treegrid implementing IAccessibleTable
- * interface.
+ * IA2 wrapper class for nsARIAGridAccessible implementing IAccessibleTable and
+ * IAccessibleTable2 interfaces.
  */
 class nsARIAGridAccessibleWrap : public nsARIAGridAccessible,
                                  public CAccessibleTable
 {
 public:
   nsARIAGridAccessibleWrap(nsIDOMNode* aNode, nsIWeakReference* aShell) :
     nsARIAGridAccessible(aNode, aShell) {}
 
   // IUnknown
   DECL_IUNKNOWN_INHERITED
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 };
 
+/**
+ * IA2 wrapper class for nsARIAGridCellAccessible implementing
+ * IAccessibleTableCell interface.
+ */
+class nsARIAGridCellAccessibleWrap : public nsARIAGridCellAccessible,
+                                     public CAccessibleTableCell
+{
+public:
+  nsARIAGridCellAccessibleWrap(nsIDOMNode* aNode, nsIWeakReference* aShell) :
+    nsARIAGridCellAccessible(aNode, aShell) {}
+
+  // IUnknown
+  DECL_IUNKNOWN_INHERITED
+
+  // nsISupports
+  NS_DECL_ISUPPORTS_INHERITED
+};
+
 #endif
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -1683,18 +1683,17 @@ nsAccessibleWrap::FirePlatformEvent(nsIA
   }
  
   PRInt32 childID = GetChildIDFor(accessible); // get the id for the accessible
   if (!childID)
     return NS_OK; // Can't fire an event without a child ID
 
   // See if we're in a scrollable area with its own window
   nsCOMPtr<nsIAccessible> newAccessible;
-  if (eventType == nsIAccessibleEvent::EVENT_ASYNCH_HIDE ||
-      eventType == nsIAccessibleEvent::EVENT_DOM_DESTROY) {
+  if (eventType == nsIAccessibleEvent::EVENT_HIDE) {
     // Don't use frame from current accessible when we're hiding that
     // accessible.
     accessible->GetParent(getter_AddRefs(newAccessible));
   } else {
     newAccessible = accessible;
   }
 
   HWND hWnd = GetHWNDFor(newAccessible);
--- a/accessible/src/msaa/nsAccessibleWrap.h
+++ b/accessible/src/msaa/nsAccessibleWrap.h
@@ -65,16 +65,23 @@ Class::QueryInterface(REFIID iid, void**
   return hr;                                                                  \
 }                                                                             \
 
 #define IMPL_IUNKNOWN_QUERY_ENTRY(Class)                                      \
   hr = Class::QueryInterface(iid, ppv);                                       \
   if (SUCCEEDED(hr))                                                          \
     return hr;                                                                \
 
+#define IMPL_IUNKNOWN_QUERY_ENTRY_COND(Class, Cond)                           \
+  if (Cond) {                                                                 \
+    hr = Class::QueryInterface(iid, ppv);                                     \
+    if (SUCCEEDED(hr))                                                        \
+      return hr;                                                              \
+  }                                                                           \
+
 #define IMPL_IUNKNOWN_INHERITED0(Class, Super)                                \
   IMPL_IUNKNOWN_QUERY_HEAD(Class)                                             \
   IMPL_IUNKNOWN_QUERY_ENTRY(Super)                                            \
   IMPL_IUNKNOWN_QUERY_TAIL                                                    \
 
 #define IMPL_IUNKNOWN_INHERITED1(Class, Super, I1)                            \
   IMPL_IUNKNOWN_QUERY_HEAD(Class)                                             \
   IMPL_IUNKNOWN_QUERY_ENTRY(I1);                                              \
--- a/accessible/src/msaa/nsEventMap.h
+++ b/accessible/src/msaa/nsEventMap.h
@@ -44,22 +44,19 @@
 #endif
 #include "AccessibleEventId.h"
 
 const PRUint32 kEVENT_WIN_UNKNOWN = 0x00000000;
 const PRUint32 kEVENT_LAST_ENTRY  = 0xffffffff;
 
 static const PRUint32 gWinEventMap[] = {
   kEVENT_WIN_UNKNOWN,                                // nsIAccessibleEvent doesn't have 0 constant
-  EVENT_OBJECT_SHOW,                                 // nsIAccessibleEvent::EVENT_DOM_CREATE
-  EVENT_OBJECT_HIDE,                                 // nsIAccessibleEvent::EVENT_DOM_DESTROY
-  kEVENT_WIN_UNKNOWN,                                // nsIAccessibleEvent::EVENT_DOM_SIGNIFICANT_CHANGE
-  EVENT_OBJECT_SHOW,                                 // nsIAccessibleEvent::EVENT_ASYNCH_SHOW
-  EVENT_OBJECT_HIDE,                                 // nsIAccessibleEvent::EVENT_ASYNCH_HIDE
-  kEVENT_WIN_UNKNOWN,                                // nsIAccessibleEvent::EVENT_ASYNCH_LAYOUT_CHANGE
+  EVENT_OBJECT_SHOW,                                 // nsIAccessibleEvent::EVENT_SHOW
+  EVENT_OBJECT_HIDE,                                 // nsIAccessibleEvent::EVENT_HIDE
+  EVENT_OBJECT_REORDER,                              // nsIAccessibleEvent::EVENT_REORDER
   IA2_EVENT_ACTIVE_DECENDENT_CHANGED,                // nsIAccessibleEvent::EVENT_ACTIVE_DECENDENT_CHANGED
   EVENT_OBJECT_FOCUS,                                // nsIAccessibleEvent::EVENT_FOCUS
   EVENT_OBJECT_STATECHANGE,                          // nsIAccessibleEvent::EVENT_STATE_CHANGE
   EVENT_OBJECT_LOCATIONCHANGE,                       // nsIAccessibleEvent::EVENT_LOCATION_CHANGE
   EVENT_OBJECT_NAMECHANGE,                           // nsIAccessibleEvent::EVENT_NAME_CHANGE
   EVENT_OBJECT_DESCRIPTIONCHANGE,                    // nsIAccessibleEvent::EVENT_DESCRIPTION_CHANGE
   EVENT_OBJECT_VALUECHANGE,                          // nsIAccessibleEvent::EVENT_VALUE_CHANGE
   kEVENT_WIN_UNKNOWN,                                // nsIAccessibleEvent::EVENT_HELP_CHANGE
@@ -135,12 +132,11 @@ static const PRUint32 gWinEventMap[] = {
   IA2_EVENT_HYPERTEXT_LINK_ACTIVATED,                // nsIAccessibleEvent::EVENT_HYPERTEXT_LINK_ACTIVATED
   IA2_EVENT_HYPERTEXT_LINK_SELECTED,                 // nsIAccessibleEvent::EVENT_HYPERTEXT_LINK_SELECTED
   IA2_EVENT_HYPERLINK_START_INDEX_CHANGED,           // nsIAccessibleEvent::EVENT_HYPERLINK_START_INDEX_CHANGED
   IA2_EVENT_HYPERTEXT_CHANGED,                       // nsIAccessibleEvent::EVENT_HYPERTEXT_CHANGED
   IA2_EVENT_HYPERTEXT_NLINKS_CHANGED,                // nsIAccessibleEvent::EVENT_HYPERTEXT_NLINKS_CHANGED
   IA2_EVENT_OBJECT_ATTRIBUTE_CHANGED,                // nsIAccessibleEvent::EVENT_OBJECT_ATTRIBUTE_CHANGED
   IA2_EVENT_PAGE_CHANGED,                            // nsIAccessibleEvent::EVENT_PAGE_CHANGED
   kEVENT_WIN_UNKNOWN,                                // nsIAccessibleEvent::EVENT_INTERNAL_LOAD
-  EVENT_OBJECT_REORDER,                              // nsIAccessibleEvent::EVENT_REORDER
   kEVENT_LAST_ENTRY                                  // nsIAccessibleEvent::EVENT_LAST_ENTRY
 };
 
--- a/accessible/src/msaa/nsHTMLTableAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsHTMLTableAccessibleWrap.cpp
@@ -35,22 +35,42 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsHTMLTableAccessibleWrap.h"
 
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLTableAccessibleWrap
+////////////////////////////////////////////////////////////////////////////////
+
 NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLTableAccessibleWrap,
                              nsHTMLTableAccessible)
 
 IMPL_IUNKNOWN_INHERITED1(nsHTMLTableAccessibleWrap,
                          nsAccessibleWrap,
-                         CAccessibleTable);
+                         CAccessibleTable)
+
 
-NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLTableHeadAccessibleWrap,
-                             nsHTMLTableHeadAccessible)
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLTableCellAccessibleWrap
+////////////////////////////////////////////////////////////////////////////////
+
+NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLTableCellAccessibleWrap,
+                             nsHTMLTableCellAccessible)
 
-IMPL_IUNKNOWN_INHERITED1(nsHTMLTableHeadAccessibleWrap,
-                         nsAccessibleWrap,
-                         CAccessibleTable);
+IMPL_IUNKNOWN_INHERITED1(nsHTMLTableCellAccessibleWrap,
+                         nsHyperTextAccessibleWrap,
+                         CAccessibleTableCell)
+
 
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLTableCellAccessibleWrap
+////////////////////////////////////////////////////////////////////////////////
+
+NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLTableHeaderCellAccessibleWrap,
+                             nsHTMLTableHeaderCellAccessible)
+
+IMPL_IUNKNOWN_INHERITED1(nsHTMLTableHeaderCellAccessibleWrap,
+                         nsHyperTextAccessibleWrap,
+                         CAccessibleTableCell)
--- a/accessible/src/msaa/nsHTMLTableAccessibleWrap.h
+++ b/accessible/src/msaa/nsHTMLTableAccessibleWrap.h
@@ -37,38 +37,69 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _NSHTMLTABLEACCESSIBLEWRAP_H
 #define _NSHTMLTABLEACCESSIBLEWRAP_H
 
 #include "nsHTMLTableAccessible.h"
+
 #include "CAccessibleTable.h"
+#include "CAccessibleTableCell.h"
 
+/**
+ * IA2 wrapper class for nsHTMLTableAccessible implementing IAccessibleTable
+ * and IAccessibleTable2 interfaces.
+ */
 class nsHTMLTableAccessibleWrap : public nsHTMLTableAccessible,
                                   public CAccessibleTable
 {
 public:
   nsHTMLTableAccessibleWrap(nsIDOMNode* aNode, nsIWeakReference* aShell) :
     nsHTMLTableAccessible(aNode, aShell){}
 
   // IUnknown
   DECL_IUNKNOWN_INHERITED
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 };
 
-class nsHTMLTableHeadAccessibleWrap : public nsHTMLTableHeadAccessible,
-                                      public CAccessibleTable
+
+/**
+ * IA2 wrapper class for nsHTMLTableCellAccessible implementing
+ * IAccessibleTableCell interface.
+ */
+class nsHTMLTableCellAccessibleWrap : public nsHTMLTableCellAccessible,
+                                      public CAccessibleTableCell
 {
 public:
-  nsHTMLTableHeadAccessibleWrap(nsIDOMNode* aNode, nsIWeakReference* aShell) :
-    nsHTMLTableHeadAccessible(aNode, aShell){}
+  nsHTMLTableCellAccessibleWrap(nsIDOMNode* aNode, nsIWeakReference* aShell) :
+    nsHTMLTableCellAccessible(aNode, aShell) {}
+
+  // IUnknown
+  DECL_IUNKNOWN_INHERITED
+
+  // nsISupports
+  NS_DECL_ISUPPORTS_INHERITED
+};
+
+
+/**
+ * IA2 wrapper class for nsHTMLTableHeaderCellAccessible implementing
+ * IAccessibleTableCell interface.
+ */
+class nsHTMLTableHeaderCellAccessibleWrap : public nsHTMLTableHeaderCellAccessible,
+                                            public CAccessibleTableCell
+{
+public:
+  nsHTMLTableHeaderCellAccessibleWrap(nsIDOMNode* aNode,
+                                      nsIWeakReference* aShell) :
+    nsHTMLTableHeaderCellAccessible(aNode, aShell) {}
 
   // IUnknown
   DECL_IUNKNOWN_INHERITED
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 };
 
--- a/accessible/src/msaa/nsHyperTextAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsHyperTextAccessibleWrap.cpp
@@ -90,18 +90,20 @@ nsHyperTextAccessibleWrap::GetModifiedTe
   if (!gTextEvent)
     return NS_OK;
     
   PRBool isInserted;
   gTextEvent->IsInserted(&isInserted);
   if (aGetInsertedText != isInserted)
     return NS_OK;
 
+  nsCOMPtr<nsIAccessibleEvent> event(do_QueryInterface(gTextEvent));
+
   nsCOMPtr<nsIAccessible> targetAcc;
-  gTextEvent->GetAccessible(getter_AddRefs(targetAcc));
+  event->GetAccessible(getter_AddRefs(targetAcc));
   if (targetAcc != this)
     return NS_OK;
 
   PRInt32 offset;
   PRUint32 length;
 
   gTextEvent->GetStart(&offset);
   gTextEvent->GetLength(&length);
new file mode 100644
--- /dev/null
+++ b/accessible/src/msaa/nsWinUtils.cpp
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:expandtab:shiftwidth=2:tabstop=2:
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alexander Surkov <surkov.alexander@gmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsWinUtils.h"
+
+#include "nsAccessibleWrap.h"
+#include "nsIWinAccessNode.h"
+#include "nsArrayUtils.h"
+
+HRESULT
+nsWinUtils::ConvertToIA2Array(nsIArray *aGeckoArray, IUnknown ***aIA2Array,
+                              long *aIA2ArrayLen)
+{
+  *aIA2Array = NULL;
+  *aIA2ArrayLen = 0;
+
+  PRUint32 length = 0;
+  nsresult rv = aGeckoArray->GetLength(&length);
+  if (NS_FAILED(rv))
+    return GetHRESULT(rv);
+
+  *aIA2Array =
+    static_cast<IUnknown**>(nsMemory::Alloc((length) * sizeof(IUnknown*)));
+  if (!*aIA2Array)
+    return E_OUTOFMEMORY;
+
+  PRUint32 idx = 0;
+  for (; idx < length; ++idx) {
+    nsCOMPtr<nsIWinAccessNode> winAccessNode =
+      do_QueryElementAt(aGeckoArray, idx, &rv);
+    if (NS_FAILED(rv))
+      break;
+
+    void *instancePtr = NULL;
+    nsresult rv = winAccessNode->QueryNativeInterface(IID_IUnknown,
+                                                      &instancePtr);
+    if (NS_FAILED(rv))
+      break;
+
+    (*aIA2Array)[idx] = static_cast<IUnknown*>(instancePtr);
+  }
+
+  if (NS_FAILED(rv)) {
+    for (PRUint32 idx2 = 0; idx2 < idx; idx2++) {
+      (*aIA2Array)[idx2]->Release();
+      (*aIA2Array)[idx2] = NULL;
+    }
+
+    nsMemory::Free(*aIA2Array);
+    return GetHRESULT(rv);
+  }
+
+  *aIA2ArrayLen = length;
+  return S_OK;
+}
new file mode 100644
--- /dev/null
+++ b/accessible/src/msaa/nsWinUtils.h
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:expandtab:shiftwidth=2:tabstop=2:
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alexander Surkov <surkov.alexander@gmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsWinUtils_h_
+#define nsWinUtils_h_
+
+#include "Accessible2.h"
+
+#include "nsIArray.h"
+
+class nsWinUtils
+{
+public:
+  /**
+   * Convert nsIArray array of accessible objects to an array of IUnknown*
+   * objects used in IA2 methods.
+   */
+  static HRESULT ConvertToIA2Array(nsIArray *aCollection,
+                                   IUnknown ***aAccessibles, long *aCount);
+};
+
+#endif
+
new file mode 100644
--- /dev/null
+++ b/accessible/src/msaa/nsXULListboxAccessibleWrap.cpp
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alexander Surkov <surkov.alexander@gmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsXULListboxAccessibleWrap.h"
+
+////////////////////////////////////////////////////////////////////////////////
+// nsXULListboxAccessibleWrap
+////////////////////////////////////////////////////////////////////////////////
+
+nsXULListboxAccessibleWrap::
+  nsXULListboxAccessibleWrap(nsIDOMNode *aDOMNode, nsIWeakReference *aShell) :
+  nsXULListboxAccessible(aDOMNode, aShell)
+{
+}
+
+NS_IMPL_ISUPPORTS_INHERITED0(nsXULListboxAccessibleWrap,
+                             nsXULListboxAccessible)
+
+IMPL_IUNKNOWN_QUERY_HEAD(nsXULListboxAccessibleWrap)
+IMPL_IUNKNOWN_QUERY_ENTRY_COND(CAccessibleTable, IsMulticolumn());
+IMPL_IUNKNOWN_QUERY_ENTRY(nsAccessibleWrap)
+IMPL_IUNKNOWN_QUERY_TAIL
+
+
+////////////////////////////////////////////////////////////////////////////////
+// nsXULListCellAccessibleWrap
+////////////////////////////////////////////////////////////////////////////////
+
+nsXULListCellAccessibleWrap::
+  nsXULListCellAccessibleWrap(nsIDOMNode *aDOMNode, nsIWeakReference *aShell) :
+  nsXULListCellAccessible(aDOMNode, aShell)
+{
+}
+
+NS_IMPL_ISUPPORTS_INHERITED0(nsXULListCellAccessibleWrap,
+                             nsXULListCellAccessible)
+
+IMPL_IUNKNOWN_INHERITED1(nsXULListCellAccessibleWrap,
+                         nsHyperTextAccessibleWrap,
+                         CAccessibleTableCell)
new file mode 100644
--- /dev/null
+++ b/accessible/src/msaa/nsXULListboxAccessibleWrap.h
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Alexander Surkov <surkov.alexander@gmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __nsXULListboxAccessibleWrap_h__
+#define __nsXULListboxAccessibleWrap_h__
+
+#include "nsXULListboxAccessible.h"
+
+#include "CAccessibleTable.h"
+#include "CAccessibleTableCell.h"
+
+/**
+ * IA2 wrapper class for nsXULListboxAccessible class implementing
+ * IAccessibleTable and IAccessibleTable2 interfaces.
+ */
+class nsXULListboxAccessibleWrap : public nsXULListboxAccessible,
+                                   public CAccessibleTable
+{
+public:
+  nsXULListboxAccessibleWrap(nsIDOMNode *aDOMNode, nsIWeakReference *aShell);
+
+  // IUnknown
+  DECL_IUNKNOWN_INHERITED
+
+  // nsISupports
+  NS_DECL_ISUPPORTS_INHERITED
+};
+
+/**
+ * IA2 wrapper class for nsXULListCellAccessible class, implements
+ * IAccessibleTableCell interface.
+ */
+class nsXULListCellAccessibleWrap : public nsXULListCellAccessible,
+                                    public CAccessibleTableCell
+{
+public:
+  nsXULListCellAccessibleWrap(nsIDOMNode *aDOMNode, nsIWeakReference *aShell);
+
+  // IUnknown
+  DECL_IUNKNOWN_INHERITED
+
+  // nsISupports
+  NS_DECL_ISUPPORTS_INHERITED
+};
+
+#endif
rename from accessible/src/msaa/nsXULTreeAccessibleWrap.cpp
rename to accessible/src/msaa/nsXULTreeGridAccessibleWrap.cpp
--- a/accessible/src/msaa/nsXULTreeAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsXULTreeGridAccessibleWrap.cpp
@@ -32,26 +32,50 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#include "nsXULTreeAccessibleWrap.h"
+#include "nsXULTreeGridAccessibleWrap.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeGridAccessibleWrap
 ////////////////////////////////////////////////////////////////////////////////
 
 nsXULTreeGridAccessibleWrap::
   nsXULTreeGridAccessibleWrap(nsIDOMNode *aDOMNode, nsIWeakReference *aShell) :
   nsXULTreeGridAccessible(aDOMNode, aShell)
 {
 }
 
 NS_IMPL_ISUPPORTS_INHERITED0(nsXULTreeGridAccessibleWrap,
                              nsXULTreeGridAccessible)
 
 IMPL_IUNKNOWN_INHERITED1(nsXULTreeGridAccessibleWrap,
                          nsAccessibleWrap,
-                         CAccessibleTable);
+                         CAccessibleTable)
+
+
+////////////////////////////////////////////////////////////////////////////////
+// nsXULTreeGridCellAccessibleWrap
+////////////////////////////////////////////////////////////////////////////////
+
+nsXULTreeGridCellAccessibleWrap::
+  nsXULTreeGridCellAccessibleWrap(nsIDOMNode *aDOMNode,
+                                  nsIWeakReference *aShell,
+                                  nsXULTreeGridRowAccessible *aRowAcc,
+                                  nsITreeBoxObject *aTree,
+                                  nsITreeView *aTreeView,
+                                  PRInt32 aRow, nsITreeColumn* aColumn) :
+  nsXULTreeGridCellAccessible(aDOMNode, aShell, aRowAcc, aTree, aTreeView,
+                              aRow, aColumn)
+{
+}
+
+NS_IMPL_ISUPPORTS_INHERITED0(nsXULTreeGridCellAccessibleWrap,
+                             nsXULTreeGridCellAccessible)
+
+IMPL_IUNKNOWN_INHERITED1(nsXULTreeGridCellAccessibleWrap,
+                         nsAccessibleWrap,
+                         CAccessibleTableCell)
rename from accessible/src/msaa/nsXULTreeAccessibleWrap.h
rename to accessible/src/msaa/nsXULTreeGridAccessibleWrap.h
--- a/accessible/src/msaa/nsXULTreeAccessibleWrap.h
+++ b/accessible/src/msaa/nsXULTreeGridAccessibleWrap.h
@@ -32,35 +32,55 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete</