Bug 512424 - implement IAccessibleTable2, r=marcoz, davidb, sr=neil
authorAlexander Surkov <surkov.alexander@gmail.com>
Fri, 11 Sep 2009 09:07:56 +0800
changeset 32381 37b976412c043d9436b495730565f1068b0887d0
parent 32380 b11f8b61ce715ca875e5a42e7ea493f46a6d8c43
child 32382 9f811e15ca517c7805e27d5104f5f95b3d082e07
push idunknown
push userunknown
push dateunknown
reviewersmarcoz, davidb, neil
bugs512424
milestone1.9.3a1pre
Bug 512424 - implement IAccessibleTable2, r=marcoz, davidb, sr=neil
accessible/public/ia2/Makefile.in
accessible/public/nsIAccessibilityService.idl
accessible/public/nsIAccessibleTable.idl
accessible/src/atk/Makefile.in
accessible/src/atk/nsARIAGridAccessibleWrap.h
accessible/src/atk/nsHTMLTableAccessibleWrap.h
accessible/src/atk/nsMaiInterfaceTable.cpp
accessible/src/atk/nsXULListboxAccessibleWrap.h
accessible/src/atk/nsXULTreeAccessibleWrap.cpp
accessible/src/atk/nsXULTreeAccessibleWrap.h
accessible/src/atk/nsXULTreeGridAccessibleWrap.h
accessible/src/base/nsARIAGridAccessible.cpp
accessible/src/base/nsARIAGridAccessible.h
accessible/src/base/nsAccUtils.cpp
accessible/src/base/nsAccUtils.h
accessible/src/base/nsAccessibilityService.cpp
accessible/src/base/nsCoreUtils.cpp
accessible/src/base/nsCoreUtils.h
accessible/src/html/nsHTMLTableAccessible.cpp
accessible/src/html/nsHTMLTableAccessible.h
accessible/src/mac/Makefile.in
accessible/src/mac/nsARIAGridAccessibleWrap.h
accessible/src/mac/nsHTMLTableAccessibleWrap.h
accessible/src/mac/nsXULListboxAccessibleWrap.h
accessible/src/mac/nsXULTreeAccessibleWrap.h
accessible/src/mac/nsXULTreeGridAccessibleWrap.h
accessible/src/msaa/CAccessibleHyperlink.cpp
accessible/src/msaa/CAccessibleTable.cpp
accessible/src/msaa/CAccessibleTable.h
accessible/src/msaa/CAccessibleTableCell.cpp
accessible/src/msaa/CAccessibleTableCell.h
accessible/src/msaa/Makefile.in
accessible/src/msaa/nsARIAGridAccessibleWrap.cpp
accessible/src/msaa/nsARIAGridAccessibleWrap.h
accessible/src/msaa/nsAccessibleWrap.h
accessible/src/msaa/nsHTMLTableAccessibleWrap.cpp
accessible/src/msaa/nsHTMLTableAccessibleWrap.h
accessible/src/msaa/nsWinUtils.cpp
accessible/src/msaa/nsWinUtils.h
accessible/src/msaa/nsXULListboxAccessibleWrap.cpp
accessible/src/msaa/nsXULListboxAccessibleWrap.h
accessible/src/msaa/nsXULTreeAccessibleWrap.cpp
accessible/src/msaa/nsXULTreeAccessibleWrap.h
accessible/src/msaa/nsXULTreeGridAccessibleWrap.cpp
accessible/src/msaa/nsXULTreeGridAccessibleWrap.h
accessible/src/other/Makefile.in
accessible/src/other/nsARIAGridAccessibleWrap.h
accessible/src/other/nsHTMLTableAccessibleWrap.h
accessible/src/other/nsXULListboxAccessibleWrap.h
accessible/src/other/nsXULTreeAccessibleWrap.h
accessible/src/other/nsXULTreeGridAccessibleWrap.h
accessible/src/xul/Makefile.in
accessible/src/xul/nsXULComboboxAccessible.cpp
accessible/src/xul/nsXULComboboxAccessible.h
accessible/src/xul/nsXULFormControlAccessible.h
accessible/src/xul/nsXULListboxAccessible.cpp
accessible/src/xul/nsXULListboxAccessible.h
accessible/src/xul/nsXULSelectAccessible.cpp
accessible/src/xul/nsXULSelectAccessible.h
accessible/src/xul/nsXULTabAccessible.h
accessible/src/xul/nsXULTreeAccessible.cpp
accessible/src/xul/nsXULTreeAccessible.h
accessible/src/xul/nsXULTreeGridAccessible.cpp
accessible/src/xul/nsXULTreeGridAccessible.h
accessible/tests/mochitest/Makefile.in
accessible/tests/mochitest/common.js
accessible/tests/mochitest/grid.js
accessible/tests/mochitest/role.js
accessible/tests/mochitest/table.js
accessible/tests/mochitest/test_aria_role_grid.html
accessible/tests/mochitest/test_aria_roles.html
accessible/tests/mochitest/test_elm_listbox.xul
accessible/tests/mochitest/test_elm_table.html
accessible/tests/mochitest/test_elm_tree.xul
accessible/tests/mochitest/test_events_tree.xul
accessible/tests/mochitest/test_nsIAccessibleTable_listboxes.xul
accessible/tests/mochitest/test_relations_table.html
accessible/tests/mochitest/test_table_1.html
accessible/tests/mochitest/test_table_2.html
accessible/tests/mochitest/test_table_4.html
accessible/tests/mochitest/test_table_headers.html
accessible/tests/mochitest/test_table_headers_ariagrid.html
accessible/tests/mochitest/test_table_headers_listbox.xul
accessible/tests/mochitest/test_table_headers_tree.xul
accessible/tests/mochitest/test_table_indexes_listbox.xul
accessible/tests/mochitest/test_table_sels.html
accessible/tests/mochitest/test_table_sels_listbox.xul
accessible/tests/mochitest/test_table_struct.html
accessible/tests/mochitest/test_table_struct_ariagrid.html
accessible/tests/mochitest/test_table_struct_listbox.xul
accessible/tests/mochitest/test_table_struct_tree.xul
other-licenses/ia2/Accessible2.idl
other-licenses/ia2/AccessibleAction.idl
other-licenses/ia2/AccessibleApplication.idl
other-licenses/ia2/AccessibleComponent.idl
other-licenses/ia2/AccessibleEditableText.idl
other-licenses/ia2/AccessibleEventId.idl
other-licenses/ia2/AccessibleHyperlink.idl
other-licenses/ia2/AccessibleHypertext.idl
other-licenses/ia2/AccessibleImage.idl
other-licenses/ia2/AccessibleRelation.idl
other-licenses/ia2/AccessibleRole.idl
other-licenses/ia2/AccessibleStates.idl
other-licenses/ia2/AccessibleTable.idl
other-licenses/ia2/AccessibleTable2.idl
other-licenses/ia2/AccessibleTableCell.idl
other-licenses/ia2/AccessibleText.idl
other-licenses/ia2/AccessibleValue.idl
other-licenses/ia2/IA2CommonTypes.idl
other-licenses/ia2/IA2TypeLibrary.idl
toolkit/content/widgets/listbox.xml
--- 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(2fb528bc-33ec-4987-bbaa-21cab013f092)]
+[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,17 +67,16 @@ 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);
 
--- 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/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;
@@ -907,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>
@@ -447,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;
 
@@ -1577,17 +1547,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 +1793,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 +1874,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:
--- 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/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
@@ -55,30 +56,37 @@
 #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;
 }
 
@@ -118,54 +126,148 @@ 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));
@@ -188,137 +290,111 @@ nsHTMLTableCellAccessible::GetTableAcces
     rv = childAcc->GetParent(getter_AddRefs(parentAcc));
     if (NS_FAILED(rv))
       return nsnull;
   }
 
   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,
@@ -361,69 +437,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;
   }
@@ -460,17 +502,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
@@ -514,16 +555,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);
 
@@ -531,16 +575,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);
@@ -553,113 +599,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 &&
@@ -668,95 +674,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 &&
@@ -765,43 +821,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++) {
@@ -827,22 +883,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++) {
@@ -868,17 +925,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));
@@ -888,94 +945,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;
 }
 
@@ -990,17 +1055,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;
     }
@@ -1014,17 +1079,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;
     }
@@ -1038,47 +1103,46 @@ 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)
 {
   if (IsDefunct())
     return NS_ERROR_FAILURE;
@@ -1134,30 +1198,30 @@ nsHTMLTableAccessible::UnselectColumn(PR
 }
 
 nsresult
 nsHTMLTableAccessible::AddRowOrColumnToSelection(PRInt32 aIndex,
                                                  PRUint32 aTarget)
 {
   PRBool doSelectRow = (aTarget == nsISelectionPrivate::TABLESELECTION_ROW);
 
-  nsITableLayout *tableLayout = nsnull;
-  nsresult rv = GetTableLayout(&tableLayout);
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsITableLayout *tableLayout = GetTableLayout();
+  NS_ENSURE_STATE(tableLayout);
 
   nsCOMPtr<nsIDOMElement> cellElm;
   PRInt32 startRowIdx, startColIdx, rowSpan, colSpan,
     actualRowSpan, actualColSpan;
   PRBool isSelected = PR_FALSE;
 
+  nsresult rv = NS_OK;
   PRInt32 count = 0;
   if (doSelectRow)
-    rv = GetColumns(&count);
+    rv = GetColumnCount(&count);
   else
-    rv = GetRows(&count);
+    rv = GetRowCount(&count);
 
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIPresShell> presShell(GetPresShell());
   nsRefPtr<nsFrameSelection> tableSelection =
     const_cast<nsFrameSelection*>(presShell->ConstFrameSelection());
 
   for (PRInt32 idx = 0; idx < count; idx++) {
@@ -1182,113 +1246,76 @@ nsHTMLTableAccessible::AddRowOrColumnToS
 
 nsresult
 nsHTMLTableAccessible::RemoveRowsOrColumnsFromSelection(PRInt32 aIndex,
                                                         PRUint32 aTarget,
                                                         PRBool aIsOuter)
 {
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
 
-  nsITableLayout *tableLayout = nsnull;
-  nsresult rv = GetTableLayout(&tableLayout);
-  NS_ENSURE_SUCCESS(rv, 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);
 
+  nsresult rv = NS_OK;
   PRInt32 count = 0;
   if (doUnselectRow)
-    rv = GetColumns(&count);
+    rv = GetColumnCount(&count);
   else
-    rv = GetRows(&count);
+    rv = GetRowCount(&count);
 
   PRInt32 startRowIdx = doUnselectRow ? aIndex : 0;
   PRInt32 endRowIdx = doUnselectRow ? aIndex : count - 1;
   PRInt32 startColIdx = doUnselectRow ? 0 : aIndex;
   PRInt32 endColIdx = doUnselectRow ? count - 1 : aIndex;
 
   if (aIsOuter)
     return tableSelection->RestrictCellsToSelection(content,
                                                     startRowIdx, startColIdx, 
                                                     endRowIdx, endColIdx);
 
   return tableSelection->RemoveCellsFromSelection(content,
                                                   startRowIdx, startColIdx, 
                                                   endRowIdx, endColIdx);
 }
 
-nsresult
-nsHTMLTableAccessible::GetTableNode(nsIDOMNode **_retval)
+nsITableLayout*
+nsHTMLTableAccessible::GetTableLayout()
 {
-  nsresult rv = NS_OK;
-
-  nsCOMPtr<nsIDOMHTMLTableElement> table(do_QueryInterface(mDOMNode));
-  if (table) {
-    *_retval = table;
-    NS_IF_ADDREF(*_retval);
-    return rv;
-  }
-
-  nsCOMPtr<nsIDOMHTMLTableSectionElement> section(do_QueryInterface(mDOMNode));
-  if (section) {
-    nsCOMPtr<nsIDOMNode> parent;
-    rv = section->GetParentNode(getter_AddRefs(parent));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    *_retval = parent;
-    NS_IF_ADDREF(*_retval);
-    return rv;
-  }
-
-  return NS_ERROR_FAILURE;
-}
-
-nsresult
-nsHTMLTableAccessible::GetTableLayout(nsITableLayout **aTableLayout)
-{
-  *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)
 {
@@ -1381,21 +1408,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");
     }
@@ -1404,16 +1429,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
@@ -1427,21 +1453,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");
   }
@@ -1541,68 +1567,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,18 +157,29 @@ public:
     */
   PRBool IsValidRow(PRInt32 aRow);
 
   /**
    * Retun cell element at the given row and column index.
    */
   nsresult GetCellAt(PRInt32 aRowIndex, PRInt32 aColIndex,
                      nsIDOMElement* &aCell);
+
+  /**
+   * Return nsITableLayout for the frame of the accessible table.
+   */
+  nsITableLayout* GetTableLayout();
+
 protected:
 
+  // nsAccessible
+  virtual void CacheChildren();
+
+  // nsHTMLTableAccessible
+
   /**
    * Add row or column to selection.
    *
    * @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 AddRowOrColumnToSelection(PRInt32 aIndex, PRUint32 aTarget);
@@ -203,20 +192,16 @@ protected:
    * @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);
 
-  virtual void CacheChildren();
-  nsresult GetTableNode(nsIDOMNode **_retval);
-  nsresult GetTableLayout(nsITableLayout **aLayoutObject);
-
   /**
    * 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.
    */
   PRBool HasDescendant(const nsAString& aTagName, PRBool aAllowEmpty = PR_TRUE);
@@ -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.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/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
 };
 
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
  * 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"
 
 #include "CAccessibleTable.h"
-
-typedef class nsXULTreeColumnsAccessible   nsXULTreeColumnsAccessibleWrap;
+#include "CAccessibleTableCell.h"
 
 /**
- * IA2 wrapper of nsXULTreeGridAccessible class, implements IAccessibleTable
- * interface.
+ * IA2 wrapper class for nsXULTreeGridAccessible class implementing
+ * IAccessibleTable and IAccessibleTable2 interfaces.
  */
 class nsXULTreeGridAccessibleWrap : public nsXULTreeGridAccessible,
                                     public CAccessibleTable
 {
 public:
   nsXULTreeGridAccessibleWrap(nsIDOMNode *aDOMNode, nsIWeakReference *aShell);
-  virtual ~nsXULTreeGridAccessibleWrap() {}
+
+  // IUnknown
+  DECL_IUNKNOWN_INHERITED
+
+  // nsISupports
+  NS_DECL_ISUPPORTS_INHERITED
+};
+
+/**
+ * IA2 wrapper class for nsXULTreeGridCellAccessible class, implements
+ * IAccessibleTableCell interface.
+ */
+class nsXULTreeGridCellAccessibleWrap : public nsXULTreeGridCellAccessible,
+                                        public CAccessibleTableCell
+{
+public:
+  nsXULTreeGridCellAccessibleWrap(nsIDOMNode *aDOMNode,
+                                  nsIWeakReference *aShell,
+                                  nsXULTreeGridRowAccessible *aRowAcc,
+                                  nsITreeBoxObject *aTree,
+                                  nsITreeView *aTreeView,
+                                  PRInt32 aRow, nsITreeColumn* aColumn);
 
   // IUnknown
   DECL_IUNKNOWN_INHERITED
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 };
 
--- a/accessible/src/other/Makefile.in
+++ b/accessible/src/other/Makefile.in
@@ -55,17 +55,18 @@ CPPSRCS = \
 EXPORTS = \
   nsAccessNodeWrap.h \
   nsARIAGridAccessibleWrap.h \
   nsTextAccessibleWrap.h \
   nsAccessibleWrap.h \
   nsDocAccessibleWrap.h \
   nsRootAccessibleWrap.h \
   nsXULMenuAccessibleWrap.h \
-  nsXULTreeAccessibleWrap.h \
+  nsXULListboxAccessibleWrap.h \
+  nsXULTreeGridAccessibleWrap.h \
   nsHyperTextAccessibleWrap.h \
   nsHTMLImageAccessibleWrap.h \
   nsHTMLTableAccessibleWrap.h \
   nsAccessibleRelationWrap.h \
   nsApplicationAccessibleWrap.h \
   $(NULL)
 
 # we don't want the shared lib, but we want to force the creation of a static lib.
--- a/accessible/src/other/nsARIAGridAccessibleWrap.h
+++ b/accessible/src/other/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/other/nsHTMLTableAccessibleWrap.h
+++ b/accessible/src/other/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 nsHTMLTableCellHeaderAccessibleWrap;
 
 #endif
 
new file mode 100644
--- /dev/null
+++ b/accessible/src/other/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/other/nsXULTreeAccessibleWrap.h
rename to accessible/src/other/nsXULTreeGridAccessibleWrap.h
--- a/accessible/src/other/nsXULTreeAccessibleWrap.h
+++ b/accessible/src/other/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/xul/Makefile.in
+++ b/accessible/src/xul/Makefile.in
@@ -47,19 +47,20 @@ MODULE = accessibility
 LIBRARY_NAME = accessibility_xul_s
 LIBXUL_LIBRARY = 1
 
 
 
 CPPSRCS = \
   nsXULAlertAccessible.cpp \
   nsXULColorPickerAccessible.cpp \
+  nsXULComboboxAccessible.cpp \
   nsXULFormControlAccessible.cpp \
+  nsXULListboxAccessible.cpp \
   nsXULMenuAccessible.cpp \
-  nsXULSelectAccessible.cpp \
   nsXULSliderAccessible.cpp \
   nsXULTabAccessible.cpp \
   nsXULTextAccessible.cpp \
   nsXULTreeAccessible.cpp \
   nsXULTreeGridAccessible.cpp \
   $(NULL)
 
 # we don't want the shared lib, but we want to force the creation of a static lib.
new file mode 100644
--- /dev/null
+++ b/accessible/src/xul/nsXULComboboxAccessible.cpp
@@ -0,0 +1,237 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Aaron Leventhal <aaronl@netscape.com> (original author)
+ *   Kyle Yuan <kyle.yuan@sun.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
+ * 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 "nsXULComboboxAccessible.h"
+
+#include "nsIDOMXULMenuListElement.h"
+#include "nsIDOMXULSelectCntrlItemEl.h"
+#include "nsServiceManagerUtils.h"
+
+////////////////////////////////////////////////////////////////////////////////
+// nsXULComboboxAccessible
+////////////////////////////////////////////////////////////////////////////////
+
+nsXULComboboxAccessible::
+  nsXULComboboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell) :
+  nsAccessibleWrap(aDOMNode, aShell)
+{
+}
+
+nsresult
+nsXULComboboxAccessible::Init()
+{
+  nsresult rv = nsAccessibleWrap::Init();
+  nsXULMenupopupAccessible::GenerateMenu(mDOMNode);
+  return rv;
+}
+
+nsresult
+nsXULComboboxAccessible::GetRoleInternal(PRUint32 *aRole)
+{
+  nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
+  if (!content) {
+    return NS_ERROR_FAILURE;
+  }
+  if (content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::type,
+                           NS_LITERAL_STRING("autocomplete"), eIgnoreCase)) {
+    *aRole = nsIAccessibleRole::ROLE_AUTOCOMPLETE;
+  } else {
+    *aRole = nsIAccessibleRole::ROLE_COMBOBOX;
+  }
+  return NS_OK;
+}
+
+nsresult
+nsXULComboboxAccessible::GetStateInternal(PRUint32 *aState,
+                                          PRUint32 *aExtraState)
+{
+  // As a nsComboboxAccessible we can have the following states:
+  //     STATE_FOCUSED
+  //     STATE_FOCUSABLE
+  //     STATE_HASPOPUP
+  //     STATE_EXPANDED
+  //     STATE_COLLAPSED
+
+  // Get focus status from base class
+  nsresult rv = nsAccessible::GetStateInternal(aState, aExtraState);
+  NS_ENSURE_A11Y_SUCCESS(rv, rv);
+
+  nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mDOMNode));
+  if (menuList) {
+    PRBool isOpen;
+    menuList->GetOpen(&isOpen);
+    if (isOpen) {
+      *aState |= nsIAccessibleStates::STATE_EXPANDED;
+    }
+    else {
+      *aState |= nsIAccessibleStates::STATE_COLLAPSED;
+    }
+  }
+
+  *aState |= nsIAccessibleStates::STATE_HASPOPUP |
+             nsIAccessibleStates::STATE_FOCUSABLE;
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXULComboboxAccessible::GetValue(nsAString& aValue)
+{
+  aValue.Truncate();
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  // The value is the option or text shown entered in the combobox.
+  nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mDOMNode));
+  if (menuList)
+    return menuList->GetLabel(aValue);
+
+  return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsXULComboboxAccessible::GetDescription(nsAString& aDescription)
+{
+  aDescription.Truncate();
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  // Use description of currently focused option
+  nsCOMPtr<nsIDOMXULMenuListElement> menuListElm(do_QueryInterface(mDOMNode));
+  if (!menuListElm)
+    return NS_ERROR_FAILURE;
+
+  nsCOMPtr<nsIDOMXULSelectControlItemElement> focusedOptionItem;
+  menuListElm->GetSelectedItem(getter_AddRefs(focusedOptionItem));
+  nsCOMPtr<nsIDOMNode> focusedOptionNode(do_QueryInterface(focusedOptionItem));
+  if (focusedOptionNode) {
+    nsCOMPtr<nsIAccessible> focusedOption;
+    GetAccService()->GetAccessibleInWeakShell(focusedOptionNode, mWeakShell, 
+                                              getter_AddRefs(focusedOption));
+    NS_ENSURE_TRUE(focusedOption, NS_ERROR_FAILURE);
+
+    return focusedOption->GetDescription(aDescription);
+  }
+
+  return NS_OK;
+}
+
+PRBool
+nsXULComboboxAccessible::GetAllowsAnonChildAccessibles()
+{
+  nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
+  NS_ASSERTION(content, "No content during accessible tree building!");
+  if (!content)
+    return PR_FALSE;
+
+  if (content->NodeInfo()->Equals(nsAccessibilityAtoms::textbox, kNameSpaceID_XUL) ||
+      content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::editable,
+                           nsAccessibilityAtoms::_true, eIgnoreCase)) {
+    // Both the XUL <textbox type="autocomplete"> and <menulist editable="true"> widgets
+    // use nsXULComboboxAccessible. We need to walk the anonymous children for these
+    // so that the entry field is a child
+    return PR_TRUE;
+  }
+
+  // Argument of PR_FALSE indicates we don't walk anonymous children for
+  // menuitems
+  return PR_FALSE;
+}
+
+NS_IMETHODIMP
+nsXULComboboxAccessible::GetNumActions(PRUint8 *aNumActions)
+{
+  NS_ENSURE_ARG_POINTER(aNumActions);
+
+  // Just one action (click).
+  *aNumActions = 1;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXULComboboxAccessible::DoAction(PRUint8 aIndex)
+{
+  if (aIndex != nsXULComboboxAccessible::eAction_Click) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  // Programmaticaly toggle the combo box.
+  nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mDOMNode));
+  if (!menuList) {
+    return NS_ERROR_FAILURE;
+  }
+  PRBool isDroppedDown;
+  menuList->GetOpen(&isDroppedDown);
+  return menuList->SetOpen(!isDroppedDown);
+}
+
+NS_IMETHODIMP
+nsXULComboboxAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
+{
+  if (aIndex != nsXULComboboxAccessible::eAction_Click) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  // Our action name is the reverse of our state:
+  //     if we are close -> open is our name.
+  //     if we are open -> close is our name.
+  // Uses the frame to get the state, updated on every click.
+
+  nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mDOMNode));
+  if (!menuList) {
+    return NS_ERROR_FAILURE;
+  }
+  PRBool isDroppedDown;
+  menuList->GetOpen(&isDroppedDown);
+  if (isDroppedDown)
+    aName.AssignLiteral("close"); 
+  else
+    aName.AssignLiteral("open"); 
+
+  return NS_OK;
+}
new file mode 100644
--- /dev/null
+++ b/accessible/src/xul/nsXULComboboxAccessible.h
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   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
+ * 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 __nsXULComboboxAccessible_h__
+#define __nsXULComboboxAccessible_h__
+
+#include "nsCOMPtr.h"
+#include "nsXULMenuAccessible.h"
+
+/**
+ * Used for XUL comboboxes like xul:menulist and autocomplete textbox.
+ */
+class nsXULComboboxAccessible : public nsAccessibleWrap
+{
+public:
+  enum { eAction_Click = 0 };
+
+  nsXULComboboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
+
+  // nsIAccessible
+  NS_IMETHOD GetValue(nsAString& aValue);
+  NS_IMETHOD GetDescription(nsAString& aDescription);
+  NS_IMETHOD DoAction(PRUint8 aIndex);
+  NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
+  NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
+
+  // nsAccessNode
+  virtual nsresult Init();
+
+  // nsAccessible
+  virtual nsresult GetRoleInternal(PRUint32 *aRole);
+  virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
+  virtual PRBool GetAllowsAnonChildAccessibles();
+};
+
+#endif
--- a/accessible/src/xul/nsXULFormControlAccessible.h
+++ b/accessible/src/xul/nsXULFormControlAccessible.h
@@ -38,17 +38,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _nsXULFormControlAccessible_H_
 #define _nsXULFormControlAccessible_H_
 
 // NOTE: alphabetically ordered
 #include "nsAccessibleWrap.h"
 #include "nsFormControlAccessible.h"
-#include "nsXULSelectAccessible.h"
+#include "nsXULMenuAccessible.h"
 #include "nsHyperTextAccessibleWrap.h"
 
 class nsXULButtonAccessible : public nsAccessibleWrap
 // Don't inherit from nsFormControlAccessible - it doesn't allow children and a button can have a dropmarker child
 {
 public:
   enum { eAction_Click = 0 };
   nsXULButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
rename from accessible/src/xul/nsXULSelectAccessible.cpp
rename to accessible/src/xul/nsXULListboxAccessible.cpp
--- a/accessible/src/xul/nsXULSelectAccessible.cpp
+++ b/accessible/src/xul/nsXULListboxAccessible.cpp
@@ -15,47 +15,44 @@
  * 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):
- *   Original Author: Eric Vaughan (evaughan@netscape.com)
- *   Kyle Yuan (kyle.yuan@sun.com)
+ *   Aaron Leventhal <aaronl@netscape.com> (original author)
+ *   Kyle Yuan <kyle.yuan@sun.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
  * 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 "nsXULSelectAccessible.h"
-#include "nsAccessibilityService.h"
-#include "nsIContent.h"
-#include "nsIDOMXULMenuListElement.h"
+#include "nsXULListboxAccessible.h"
+
 #include "nsIDOMXULPopupElement.h"
 #include "nsIDOMXULMultSelectCntrlEl.h"
 #include "nsIDOMXULSelectCntrlItemEl.h"
-#include "nsIDOMXULTextboxElement.h"
-#include "nsIPresShell.h"
-#include "nsIServiceManager.h"
-#include "nsCaseTreatment.h"
+#include "nsServiceManagerUtils.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULColumnsAccessible
+////////////////////////////////////////////////////////////////////////////////
 
 nsXULColumnsAccessible::
   nsXULColumnsAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell) :
   nsAccessibleWrap(aDOMNode, aShell)
 {
 }
 
 nsresult
@@ -82,18 +79,20 @@ nsXULColumnsAccessible::GetStateInternal
   *aState = nsIAccessibleStates::STATE_READONLY;
 
   if (aExtraState)
     *aExtraState = 0;
 
   return NS_OK;
 }
 
+
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULColumnItemAccessible
+////////////////////////////////////////////////////////////////////////////////
 
 nsXULColumnItemAccessible::
   nsXULColumnItemAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell) :
   nsLeafAccessible(aDOMNode, aShell)
 {
 }
 
 nsresult
@@ -148,16 +147,17 @@ nsXULColumnItemAccessible::DoAction(PRUi
   if (aIndex != eAction_Click)
     return NS_ERROR_INVALID_ARG;
 
   return DoCommand();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULListboxAccessible
+////////////////////////////////////////////////////////////////////////////////
 
 nsXULListboxAccessible::
   nsXULListboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell) :
   nsXULSelectableAccessible(aDOMNode, aShell)
 {
 }
 
 NS_IMPL_ADDREF_INHERITED(nsXULListboxAccessible, nsXULSelectableAccessible)
@@ -165,33 +165,33 @@ NS_IMPL_RELEASE_INHERITED(nsXULListboxAc
 
 nsresult
 nsXULListboxAccessible::QueryInterface(REFNSIID aIID, void** aInstancePtr)
 {
   nsresult rv = nsXULSelectableAccessible::QueryInterface(aIID, aInstancePtr);
   if (*aInstancePtr)
     return rv;
 
-  if (aIID.Equals(NS_GET_IID(nsIAccessibleTable)) && IsTree()) {
+  if (aIID.Equals(NS_GET_IID(nsIAccessibleTable)) && IsMulticolumn()) {
     *aInstancePtr = static_cast<nsIAccessibleTable*>(this);
     NS_ADDREF_THIS();
     return NS_OK;
   }
 
   return NS_ERROR_NO_INTERFACE;
 }
 
 PRBool
-nsXULListboxAccessible::IsTree()
+nsXULListboxAccessible::IsMulticolumn()
 {
   PRInt32 numColumns = 0;
-  nsresult rv = GetColumns(&numColumns);
+  nsresult rv = GetColumnCount(&numColumns);
   if (NS_FAILED(rv))
     return PR_FALSE;
-  
+
   return numColumns > 1;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULListboxAccessible. nsIAccessible
 
 nsresult
 nsXULListboxAccessible::GetStateInternal(PRUint32 *aState,
@@ -245,17 +245,17 @@ nsXULListboxAccessible::GetRoleInternal(
     nsCOMPtr<nsIDOMXULPopupElement> xulPopup =
       do_QueryInterface(content->GetParent());
     if (xulPopup) {
       *aRole = nsIAccessibleRole::ROLE_COMBOBOX_LIST;
       return NS_OK;
     }
   }
 
-  if (IsTree())
+  if (IsMulticolumn())
     *aRole = nsIAccessibleRole::ROLE_TABLE;
   else
     *aRole = nsIAccessibleRole::ROLE_LISTBOX;
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -274,22 +274,22 @@ NS_IMETHODIMP
 nsXULListboxAccessible::GetSummary(nsAString &aSummary)
 {
   aSummary.Truncate();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULListboxAccessible::GetColumns(PRInt32 *aNumColumns)
+nsXULListboxAccessible::GetColumnCount(PRInt32 *aColumnsCout)
 {
-  NS_ENSURE_ARG_POINTER(aNumColumns);
-  *aNumColumns = 0;
+  NS_ENSURE_ARG_POINTER(aColumnsCout);
+  *aColumnsCout = 0;
 
-  if (!mDOMNode)
+  if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
 
   nsCOMPtr<nsIContent> headContent;
   PRUint32 count = content->GetChildCount();
 
   for (PRUint32 index = 0; index < count; ++index) {
@@ -313,129 +313,113 @@ nsXULListboxAccessible::GetColumns(PRInt
     NS_ENSURE_STATE(childContent);
 
     if (childContent->NodeInfo()->Equals(nsAccessibilityAtoms::listcol,
                                          kNameSpaceID_XUL)) {
       columnCount++;
     }
   }
 
-  *aNumColumns = columnCount;
+  *aColumnsCout = columnCount;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULListboxAccessible::GetColumnHeader(nsIAccessibleTable **aColumnHeader)
+nsXULListboxAccessible::GetRowCount(PRInt32 *arowCount)
 {
-  NS_ENSURE_ARG_POINTER(aColumnHeader);
-  *aColumnHeader = nsnull;
-
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
+  NS_ENSURE_ARG_POINTER(arowCount);
+  *arowCount = 0;
 
-NS_IMETHODIMP
-nsXULListboxAccessible::GetRows(PRInt32 *aNumRows)
-{
-  NS_ENSURE_ARG_POINTER(aNumRows);
-  *aNumRows = 0;
-
-  if (!mDOMNode)
+  if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIDOMXULSelectControlElement> element(do_QueryInterface(mDOMNode));
   NS_ENSURE_STATE(element);
 
   PRUint32 itemCount = 0;
   nsresult rv = element->GetItemCount(&itemCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aNumRows = itemCount;
+  *arowCount = itemCount;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULListboxAccessible::GetRowHeader(nsIAccessibleTable **aRowHeader)
-{
-  NS_ENSURE_ARG_POINTER(aRowHeader);
-  *aRowHeader = nsnull;
-
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsXULListboxAccessible::CellRefAt(PRInt32 aRow, PRInt32 aColumn,
+nsXULListboxAccessible::GetCellAt(PRInt32 aRow, PRInt32 aColumn,
                                   nsIAccessible **aAccessibleCell)
 {
   NS_ENSURE_ARG_POINTER(aAccessibleCell);
   *aAccessibleCell = nsnull;
 
   if (IsDefunct())
     return NS_OK;
 
   nsCOMPtr<nsIDOMXULSelectControlElement> control =
     do_QueryInterface(mDOMNode);
 
   nsCOMPtr<nsIDOMXULSelectControlItemElement> item;
   control->GetItemAtIndex(aRow, getter_AddRefs(item));
   NS_ENSURE_TRUE(item, NS_ERROR_INVALID_ARG);
 
+  nsCOMPtr<nsIDOMNode> itemNode(do_QueryInterface(item));
+
   nsCOMPtr<nsIAccessible> accessibleRow;
-  GetAccService()->GetAccessibleInWeakShell(item, mWeakShell,
+  GetAccService()->GetAccessibleInWeakShell(itemNode, mWeakShell,
                                             getter_AddRefs(accessibleRow));
   NS_ENSURE_STATE(accessibleRow);
 
   nsresult rv = accessibleRow->GetChildAt(aColumn, aAccessibleCell);
   NS_ENSURE_SUCCESS(rv, NS_ERROR_INVALID_ARG);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULListboxAccessible::GetIndexAt(PRInt32 aRow, PRInt32 aColumn,
-                                   PRInt32 *aIndex)
+nsXULListboxAccessible::GetCellIndexAt(PRInt32 aRow, PRInt32 aColumn,
+                                       PRInt32 *aIndex)
 {
   NS_ENSURE_ARG_POINTER(aIndex);
   *aIndex = -1;
 
   PRInt32 rowCount = 0;
-  nsresult rv = GetRows(&rowCount);
+  nsresult rv = GetRowCount(&rowCount);
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(0 <= aRow && aRow <= rowCount, NS_ERROR_INVALID_ARG);
 
   PRInt32 columnCount = 0;
-  rv = GetColumns(&columnCount);
+  rv = GetColumnCount(&columnCount);
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(0 <= aColumn && aColumn <= columnCount, NS_ERROR_INVALID_ARG);
 
   *aIndex = aRow * columnCount + aColumn;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULListboxAccessible::GetColumnAtIndex(PRInt32 aIndex, PRInt32 *aColumn)
+nsXULListboxAccessible::GetColumnIndexAt(PRInt32 aIndex, PRInt32 *aColumn)
 {
   NS_ENSURE_ARG_POINTER(aColumn);
   *aColumn = -1;
 
   PRInt32 columnCount = 0;
-  nsresult rv = GetColumns(&columnCount);
+  nsresult rv = GetColumnCount(&columnCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   *aColumn = aIndex % columnCount;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULListboxAccessible::GetRowAtIndex(PRInt32 aIndex, PRInt32 *aRow)
+nsXULListboxAccessible::GetRowIndexAt(PRInt32 aIndex, PRInt32 *aRow)
 {
   NS_ENSURE_ARG_POINTER(aRow);
   *aRow = -1;
 
   PRInt32 columnCount = 0;
-  nsresult rv = GetColumns(&columnCount);
+  nsresult rv = GetColumnCount(&columnCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   *aRow = aIndex / columnCount;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULListboxAccessible::GetColumnExtentAt(PRInt32 aRow, PRInt32 aColumn,
@@ -481,25 +465,25 @@ nsXULListboxAccessible::IsColumnSelected
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
     do_QueryInterface(mDOMNode);
   NS_ASSERTION(control,
                "Doesn't implement nsIDOMXULMultiSelectControlElement.");
 
-  PRInt32 selectedRowsCount = 0;
-  nsresult rv = control->GetSelectedCount(&selectedRowsCount);
+  PRInt32 selectedrowCount = 0;
+  nsresult rv = control->GetSelectedCount(&selectedrowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRInt32 rowsCount = 0;
-  rv = GetRows(&rowsCount);
+  PRInt32 rowCount = 0;
+  rv = GetRowCount(&rowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aIsSelected = (selectedRowsCount == rowsCount);
+  *aIsSelected = (selectedrowCount == rowCount);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULListboxAccessible::IsRowSelected(PRInt32 aRow, PRBool *aIsSelected)
 {
   NS_ENSURE_ARG_POINTER(aIsSelected);
   *aIsSelected = PR_FALSE;
@@ -515,24 +499,24 @@ nsXULListboxAccessible::IsRowSelected(PR
   nsCOMPtr<nsIDOMXULSelectControlItemElement> item;
   control->GetItemAtIndex(aRow, getter_AddRefs(item));
   NS_ENSURE_TRUE(item, NS_ERROR_INVALID_ARG);
 
   return item->GetSelected(aIsSelected);
 }
 
 NS_IMETHODIMP
-nsXULListboxAccessible::IsCellSelected(PRInt32 aRow, PRInt32 aColumn,
+nsXULListboxAccessible::IsCellSelected(PRInt32 aRowIndex, PRInt32 aColumnIndex,
                                        PRBool *aIsSelected)
 {
-  return IsRowSelected(aRow, aIsSelected);
+  return IsRowSelected(aRowIndex, aIsSelected);
 }
 
 NS_IMETHODIMP
-nsXULListboxAccessible::GetSelectedCellsCount(PRUint32* aCount)
+nsXULListboxAccessible::GetSelectedCellCount(PRUint32* aCount)
 {
   NS_ENSURE_ARG_POINTER(aCount);
   *aCount = 0;
 
   nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
     do_QueryInterface(mDOMNode);
   NS_ASSERTION(control,
                "Doesn't implement nsIDOMXULMultiSelectControlElement.");
@@ -544,109 +528,163 @@ nsXULListboxAccessible::GetSelectedCells
 
   PRUint32 selectedItemsCount = 0;
   nsresult rv = selectedItems->GetLength(&selectedItemsCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!selectedItemsCount)
     return NS_OK;
 
-  PRInt32 columnsCount = 0;
-  rv = GetColumns(&columnsCount);
+  PRInt32 columnCount = 0;
+  rv = GetColumnCount(&columnCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aCount = selectedItemsCount * columnsCount;
+  *aCount = selectedItemsCount * columnCount;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULListboxAccessible::GetSelectedColumnsCount(PRUint32* aCount)
+nsXULListboxAccessible::GetSelectedColumnCount(PRUint32* aCount)
 {
   NS_ENSURE_ARG_POINTER(aCount);
   *aCount = 0;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
-  do_QueryInterface(mDOMNode);
+    do_QueryInterface(mDOMNode);
   NS_ASSERTION(control,
                "Doesn't implement nsIDOMXULMultiSelectControlElement.");
 
-  PRInt32 selectedRowsCount = 0;
-  nsresult rv = control->GetSelectedCount(&selectedRowsCount);
+  PRInt32 selectedrowCount = 0;
+  nsresult rv = control->GetSelectedCount(&selectedrowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRInt32 rowsCount = 0;
-  rv = GetRows(&rowsCount);
+  PRInt32 rowCount = 0;
+  rv = GetRowCount(&rowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (selectedRowsCount != rowsCount)
+  if (selectedrowCount != rowCount)
     return NS_OK;
 
-  PRInt32 columnsCount = 0;
-  rv = GetColumns(&columnsCount);
+  PRInt32 columnCount = 0;
+  rv = GetColumnCount(&columnCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aCount = columnsCount;
+  *aCount = columnCount;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULListboxAccessible::GetSelectedRowsCount(PRUint32* aCount)
+nsXULListboxAccessible::GetSelectedRowCount(PRUint32* aCount)
 {
   NS_ENSURE_ARG_POINTER(aCount);
   *aCount = 0;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
     do_QueryInterface(mDOMNode);
   NS_ASSERTION(control,
                "Doesn't implement nsIDOMXULMultiSelectControlElement.");
 
-  PRInt32 selectedRowsCount = 0;
-  nsresult rv = control->GetSelectedCount(&selectedRowsCount);
+  PRInt32 selectedrowCount = 0;
+  nsresult rv = control->GetSelectedCount(&selectedrowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aCount = selectedRowsCount;
+  *aCount = selectedrowCount;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULListboxAccessible::GetSelectedCells(PRUint32 *aNumCells, PRInt32 **aCells)
+nsXULListboxAccessible::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<nsIDOMXULMultiSelectControlElement> control =
+    do_QueryInterface(mDOMNode);
+  NS_ASSERTION(control,
+               "Doesn't implement nsIDOMXULMultiSelectControlElement.");
+
+  nsCOMPtr<nsIDOMNodeList> selectedItems;
+  control->GetSelectedItems(getter_AddRefs(selectedItems));
+  if (!selectedItems)
+    return NS_OK;
+
+  PRUint32 selectedItemsCount = 0;
+  rv = selectedItems->GetLength(&selectedItemsCount);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRUint32 index = 0;
+  for (; index < selectedItemsCount; index++) {
+    nsCOMPtr<nsIDOMNode> itemNode;
+    selectedItems->Item(index, getter_AddRefs(itemNode));
+    nsCOMPtr<nsIAccessible> item;
+    GetAccService()->GetAccessibleInWeakShell(itemNode, mWeakShell,
+                                              getter_AddRefs(item));
+
+    if (item) {
+      nsCOMPtr<nsIAccessible> cell, nextCell;
+      item->GetFirstChild(getter_AddRefs(cell));
+      while (cell) {
+        if (nsAccUtils::Role(cell) == nsIAccessibleRole::ROLE_CELL)
+          selCells->AppendElement(cell, PR_FALSE);
+
+        cell->GetNextSibling(getter_AddRefs(nextCell));
+        nextCell.swap(cell);
+      }
+    }
+  }
+
+  NS_ADDREF(*aCells = selCells);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXULListboxAccessible::GetSelectedCellIndices(PRUint32 *aNumCells,
+                                               PRInt32 **aCells)
 {
   NS_ENSURE_ARG_POINTER(aNumCells);
   *aNumCells = 0;
   NS_ENSURE_ARG_POINTER(aCells);
   *aCells = nsnull;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
-  
+
   nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
     do_QueryInterface(mDOMNode);
   NS_ASSERTION(control,
                "Doesn't implement nsIDOMXULMultiSelectControlElement.");
 
   nsCOMPtr<nsIDOMNodeList> selectedItems;
   control->GetSelectedItems(getter_AddRefs(selectedItems));
   if (!selectedItems)
     return NS_OK;
 
   PRUint32 selectedItemsCount = 0;
   nsresult rv = selectedItems->GetLength(&selectedItemsCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRInt32 columnsCount = 0;
-  rv = GetColumns(&columnsCount);
+  PRInt32 columnCount = 0;
+  rv = GetColumnCount(&columnCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRUint32 cellsCount = selectedItemsCount * columnsCount;
+  PRUint32 cellsCount = selectedItemsCount * columnCount;
 
   PRInt32 *cellsIdxArray =
     static_cast<PRInt32*>(nsMemory::Alloc((cellsCount) * sizeof(PRInt32)));
   NS_ENSURE_TRUE(cellsIdxArray, NS_ERROR_OUT_OF_MEMORY);
 
   PRUint32 index = 0, cellsIdx = 0;
   for (; index < selectedItemsCount; index++) {
     nsCOMPtr<nsIDOMNode> itemNode;
@@ -654,63 +692,64 @@ nsXULListboxAccessible::GetSelectedCells
     nsCOMPtr<nsIDOMXULSelectControlItemElement> item =
       do_QueryInterface(itemNode);
 
     if (item) {
       PRInt32 itemIdx = -1;
       control->GetIndexOfItem(item, &itemIdx);
       if (itemIdx != -1) {
         PRInt32 colIdx = 0;
-        for (; colIdx < columnsCount; colIdx++)
-          cellsIdxArray[cellsIdx++] = itemIdx * columnsCount + colIdx;
+        for (; colIdx < columnCount; colIdx++)
+          cellsIdxArray[cellsIdx++] = itemIdx * columnCount + colIdx;
       }
     }
   }
 
   *aNumCells = cellsCount;
   *aCells = cellsIdxArray;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULListboxAccessible::GetSelectedColumns(PRUint32 *aNumColumns,
-                                           PRInt32 **aColumns)
+nsXULListboxAccessible::GetSelectedColumnIndices(PRUint32 *aNumColumns,
+                                                 PRInt32 **aColumns)
 {
   NS_ENSURE_ARG_POINTER(aNumColumns);
   *aNumColumns = 0;
   NS_ENSURE_ARG_POINTER(aColumns);
   *aColumns = nsnull;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  PRUint32 columnsCount = 0;
-  nsresult rv = GetSelectedColumnsCount(&columnsCount);
+  PRUint32 columnCount = 0;
+  nsresult rv = GetSelectedColumnCount(&columnCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (!columnsCount)
+  if (!columnCount)
     return NS_OK;
 
   PRInt32 *colsIdxArray =
-    static_cast<PRInt32*>(nsMemory::Alloc((columnsCount) * sizeof(PRInt32)));
+    static_cast<PRInt32*>(nsMemory::Alloc((columnCount) * sizeof(PRInt32)));
   NS_ENSURE_TRUE(colsIdxArray, NS_ERROR_OUT_OF_MEMORY);
 
   PRUint32 colIdx = 0;
-  for (; colIdx < columnsCount; colIdx++)
+  for (; colIdx < columnCount; colIdx++)
     colsIdxArray[colIdx] = colIdx;
 
-  *aNumColumns = columnsCount;
+  *aNumColumns = columnCount;
   *aColumns = colsIdxArray;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULListboxAccessible::GetSelectedRows(PRUint32 *aNumRows, PRInt32 **aRows)
+nsXULListboxAccessible::GetSelectedRowIndices(PRUint32 *aNumRows,
+                                              PRInt32 **aRows)
 {
   NS_ENSURE_ARG_POINTER(aNumRows);
   *aNumRows = 0;
   NS_ENSURE_ARG_POINTER(aRows);
   *aRows = nsnull;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
@@ -759,17 +798,17 @@ nsXULListboxAccessible::GetSelectedRows(
 
 NS_IMETHODIMP
 nsXULListboxAccessible::SelectRow(PRInt32 aRow)
 {
   if (IsDefunct())
     return NS_ERROR_FAILURE;
   
   nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
-  do_QueryInterface(mDOMNode);
+    do_QueryInterface(mDOMNode);
   NS_ASSERTION(control,
                "Doesn't implement nsIDOMXULMultiSelectControlElement.");
 
   nsCOMPtr<nsIDOMXULSelectControlItemElement> item;
   control->GetItemAtIndex(aRow, getter_AddRefs(item));
   NS_ENSURE_TRUE(item, NS_ERROR_INVALID_ARG);
 
   return control->SelectItem(item);
@@ -813,23 +852,24 @@ nsXULListboxAccessible::IsProbablyForLay
   NS_ENSURE_ARG_POINTER(aIsProbablyForLayout);
   *aIsProbablyForLayout = PR_FALSE;
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULListitemAccessible
+////////////////////////////////////////////////////////////////////////////////
 
 nsXULListitemAccessible::
   nsXULListitemAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell) :
   nsXULMenuitemAccessible(aDOMNode, aShell)
 {
   mIsCheckbox = PR_FALSE;
-  nsCOMPtr<nsIDOMElement> listItem (do_QueryInterface(mDOMNode));
+  nsCOMPtr<nsIDOMElement> listItem(do_QueryInterface(mDOMNode));
   if (listItem) {
     nsAutoString typeString;
     nsresult res = listItem->GetAttribute(NS_LITERAL_STRING("type"), typeString);
     if (NS_SUCCEEDED(res) && typeString.Equals(NS_LITERAL_STRING("checkbox")))
       mIsCheckbox = PR_TRUE;
   }
 }
 
@@ -921,17 +961,20 @@ nsXULListitemAccessible::GetStateInterna
     return NS_OK_DEFUNCT_OBJECT;
   }
 
   if (aExtraState)
     *aExtraState = 0;
 
   *aState = nsIAccessibleStates::STATE_FOCUSABLE |
             nsIAccessibleStates::STATE_SELECTABLE;
-  nsCOMPtr<nsIDOMXULSelectControlItemElement> listItem (do_QueryInterface(mDOMNode));
+
+  nsCOMPtr<nsIDOMXULSelectControlItemElement> listItem =
+    do_QueryInterface(mDOMNode);
+
   if (listItem) {
     PRBool isSelected;
     listItem->GetSelected(&isSelected);
     if (isSelected)
       *aState |= nsIAccessibleStates::STATE_SELECTED;
 
     if (gLastFocusedNode == mDOMNode) {
       *aState |= nsIAccessibleStates::STATE_FOCUSED;
@@ -977,204 +1020,258 @@ nsXULListitemAccessible::GetAttributesIn
   nsresult rv = nsAccessible::GetAttributesInternal(aAttributes);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAccUtils::SetAccAttrsForXULSelectControlItem(mDOMNode, aAttributes);
   return NS_OK;
 }
 
 
-
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULListCellAccessible
+////////////////////////////////////////////////////////////////////////////////
+
 nsXULListCellAccessible::
   nsXULListCellAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell):
   nsHyperTextAccessibleWrap(aDOMNode, aShell)
 {
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// nsISupports
+
+NS_IMPL_ISUPPORTS_INHERITED1(nsXULListCellAccessible,
+                             nsHyperTextAccessible,
+                             nsIAccessibleTableCell)
+
+////////////////////////////////////////////////////////////////////////////////
+// nsXULListCellAccessible: nsIAccessibleTableCell implementation
+
+NS_IMETHODIMP
+nsXULListCellAccessible::GetTable(nsIAccessibleTable **aTable)
+{
+  NS_ENSURE_ARG_POINTER(aTable);
+  *aTable = nsnull;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  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)
+    return NS_OK;
+
+  CallQueryInterface(table, aTable);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXULListCellAccessible::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_CELL ||
+        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
+nsXULListCellAccessible::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
+nsXULListCellAccessible::GetColumnExtent(PRInt32 *aExtentCount)
+{
+  NS_ENSURE_ARG_POINTER(aExtentCount);
+  *aExtentCount = 0;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  *aExtentCount = 1;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXULListCellAccessible::GetRowExtent(PRInt32 *aExtentCount)
+{
+  NS_ENSURE_ARG_POINTER(aExtentCount);
+  *aExtentCount = 0;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  *aExtentCount = 1;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXULListCellAccessible::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;
+
+  // Get column header cell from XUL listhead.
+  nsCOMPtr<nsIAccessible> tableAcc(do_QueryInterface(table));
+
+  nsCOMPtr<nsIAccessible> list, nextChild;
+  tableAcc->GetFirstChild(getter_AddRefs(list));
+  while (list) {
+    if (nsAccUtils::Role(list) == nsIAccessibleRole::ROLE_LIST)
+      break;
+
+    list->GetNextSibling(getter_AddRefs(nextChild));
+    nextChild.swap(list);
+  }
+
+  if (list) {
+    PRInt32 colIdx = -1;
+    GetColumnIndex(&colIdx);
+
+    nsCOMPtr<nsIAccessible> headerCell;
+    list->GetChildAt(colIdx, getter_AddRefs(headerCell));
+
+    if (headerCell) {
+      nsresult rv = NS_OK;
+      nsCOMPtr<nsIMutableArray> headerCells =
+        do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      headerCells->AppendElement(headerCell, PR_FALSE);
+      NS_ADDREF(*aHeaderCells = headerCells);
+      return NS_OK;
+    }
+  }
+
+  // No column header cell from XUL markup, try to get it from ARIA markup.
+  return nsAccUtils::GetHeaderCellsFor(table, this,
+                                       nsAccUtils::eColumnHeaderCells,
+                                       aHeaderCells);
+}
+
+NS_IMETHODIMP
+nsXULListCellAccessible::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;
+
+  // Calculate row header cells from ARIA markup.
+  return nsAccUtils::GetHeaderCellsFor(table, this,
+                                       nsAccUtils::eRowHeaderCells,
+                                       aHeaderCells);
+}
+
+NS_IMETHODIMP
+nsXULListCellAccessible::IsSelected(PRBool *aIsSelected)
+{
+  NS_ENSURE_ARG_POINTER(aIsSelected);
+  *aIsSelected = PR_FALSE;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsCOMPtr<nsIAccessibleTable> table;
+  GetTable(getter_AddRefs(table));
+  if (!table)
+    return NS_OK;
+
+  PRInt32 rowIdx = -1;
+  GetRowIndex(&rowIdx);
+
+  return table->IsRowSelected(rowIdx, aIsSelected);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsXULListCellAccessible. nsAccessible implementation
+
 nsresult
 nsXULListCellAccessible::GetRoleInternal(PRUint32 *aRole)
 {
   *aRole = nsIAccessibleRole::ROLE_CELL;
   return NS_OK;
 }
 
-/** ------------------------------------------------------ */
-/**  Finally, the Combobox widgets                         */
-/** ------------------------------------------------------ */
-
-/** ----- nsXULComboboxAccessible ----- */
-
-/** Constructor */
-nsXULComboboxAccessible::nsXULComboboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell):
-nsAccessibleWrap(aDOMNode, aShell)
+nsresult
+nsXULListCellAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
 {
-}
+  NS_ENSURE_ARG_POINTER(aAttributes);
 
-nsresult
-nsXULComboboxAccessible::Init()
-{
-  nsresult rv = nsAccessibleWrap::Init();
-  nsXULMenupopupAccessible::GenerateMenu(mDOMNode);
-  return rv;
-}
-
-/** We are a combobox */
-nsresult
-nsXULComboboxAccessible::GetRoleInternal(PRUint32 *aRole)
-{
-  nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
-  if (!content) {
+  if (IsDefunct())
     return NS_ERROR_FAILURE;
-  }
-  if (content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::type,
-                           NS_LITERAL_STRING("autocomplete"), eIgnoreCase)) {
-    *aRole = nsIAccessibleRole::ROLE_AUTOCOMPLETE;
-  } else {
-    *aRole = nsIAccessibleRole::ROLE_COMBOBOX;
-  }
-  return NS_OK;
-}
+
+  // "table-cell-index" attribute
+  nsCOMPtr<nsIAccessibleTable> table;
+  GetTable(getter_AddRefs(table));
 
-/**
-  * As a nsComboboxAccessible we can have the following states:
-  *     STATE_FOCUSED
-  *     STATE_FOCUSABLE
-  *     STATE_HASPOPUP
-  *     STATE_EXPANDED
-  *     STATE_COLLAPSED
-  */
-nsresult
-nsXULComboboxAccessible::GetStateInternal(PRUint32 *aState,
-                                          PRUint32 *aExtraState)
-{
-  // Get focus status from base class
-  nsresult rv = nsAccessible::GetStateInternal(aState, aExtraState);
-  NS_ENSURE_A11Y_SUCCESS(rv, rv);
+  PRInt32 rowIdx = -1;
+  GetRowIndex(&rowIdx);
+  PRInt32 colIdx = -1;
+  GetColumnIndex(&colIdx);
 
-  nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mDOMNode));
-  if (menuList) {
-    PRBool isOpen;
-    menuList->GetOpen(&isOpen);
-    if (isOpen) {
-      *aState |= nsIAccessibleStates::STATE_EXPANDED;
-    }
-    else {
-      *aState |= nsIAccessibleStates::STATE_COLLAPSED;
-    }
-  }
+  PRInt32 cellIdx = -1;
+  table->GetCellIndexAt(rowIdx, colIdx, &cellIdx);
 
-  *aState |= nsIAccessibleStates::STATE_HASPOPUP |
-             nsIAccessibleStates::STATE_FOCUSABLE;
+  nsAutoString stringIdx;
+  stringIdx.AppendInt(cellIdx);
+  nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::tableCellIndex,
+                         stringIdx);
 
   return NS_OK;
 }
-
-NS_IMETHODIMP nsXULComboboxAccessible::GetValue(nsAString& _retval)
-{
-  _retval.Truncate();
-
-  // The MSAA/ATK value is the option or text shown entered in the combobox
-  nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mDOMNode));
-  if (menuList) {
-    return menuList->GetLabel(_retval);
-  }
-  return NS_ERROR_FAILURE;
-}
-
-NS_IMETHODIMP nsXULComboboxAccessible::GetDescription(nsAString& aDescription)
-{
-  // Use description of currently focused option
-  aDescription.Truncate();
-  nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mDOMNode));
-  if (!menuList) {
-    return NS_ERROR_FAILURE;  // Shut down
-  }
-  nsCOMPtr<nsIDOMXULSelectControlItemElement> focusedOption;
-  menuList->GetSelectedItem(getter_AddRefs(focusedOption));
-  nsCOMPtr<nsIDOMNode> focusedOptionNode(do_QueryInterface(focusedOption));
-  if (focusedOptionNode) {
-    nsCOMPtr<nsIAccessibilityService> accService = 
-      do_GetService("@mozilla.org/accessibilityService;1");
-    NS_ENSURE_TRUE(accService, NS_ERROR_FAILURE);
-    nsCOMPtr<nsIAccessible> focusedOptionAccessible;
-    accService->GetAccessibleInWeakShell(focusedOptionNode, mWeakShell, 
-                                        getter_AddRefs(focusedOptionAccessible));
-    NS_ENSURE_TRUE(focusedOptionAccessible, NS_ERROR_FAILURE);
-    return focusedOptionAccessible->GetDescription(aDescription);
-  }
-  return NS_OK;
-}
-
-PRBool
-nsXULComboboxAccessible::GetAllowsAnonChildAccessibles()
-{
-  nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
-  NS_ASSERTION(content, "No content during accessible tree building!");
-  if (!content)
-    return PR_FALSE;
-
-  if (content->NodeInfo()->Equals(nsAccessibilityAtoms::textbox, kNameSpaceID_XUL) ||
-      content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::editable,
-                           nsAccessibilityAtoms::_true, eIgnoreCase)) {
-    // Both the XUL <textbox type="autocomplete"> and <menulist editable="true"> widgets
-    // use nsXULComboboxAccessible. We need to walk the anonymous children for these
-    // so that the entry field is a child
-    return PR_TRUE;
-  }
-
-  // Argument of PR_FALSE indicates we don't walk anonymous children for
-  // menuitems
-  return PR_FALSE;
-}
-
-/** Just one action ( click ). */
-NS_IMETHODIMP nsXULComboboxAccessible::GetNumActions(PRUint8 *aNumActions)
-{
-  *aNumActions = 1;
-  return NS_OK;
-}
-
-/**
-  * Programmaticaly toggle the combo box
-  */
-NS_IMETHODIMP nsXULComboboxAccessible::DoAction(PRUint8 aIndex)
-{
-  if (aIndex != nsXULComboboxAccessible::eAction_Click) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mDOMNode));
-  if (!menuList) {
-    return NS_ERROR_FAILURE;
-  }
-  PRBool isDroppedDown;
-  menuList->GetOpen(&isDroppedDown);
-  return menuList->SetOpen(!isDroppedDown);
-}
-
-/**
-  * Our action name is the reverse of our state: 
-  *     if we are closed -> open is our name.
-  *     if we are open -> closed is our name.
-  * Uses the frame to get the state, updated on every click
-  */
-NS_IMETHODIMP nsXULComboboxAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
-{
-  if (aIndex != nsXULComboboxAccessible::eAction_Click) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mDOMNode));
-  if (!menuList) {
-    return NS_ERROR_FAILURE;
-  }
-  PRBool isDroppedDown;
-  menuList->GetOpen(&isDroppedDown);
-  if (isDroppedDown)
-    aName.AssignLiteral("close"); 
-  else
-    aName.AssignLiteral("open"); 
-
-  return NS_OK;
-}
-
rename from accessible/src/xul/nsXULSelectAccessible.h
rename to accessible/src/xul/nsXULListboxAccessible.h
--- a/accessible/src/xul/nsXULSelectAccessible.h
+++ b/accessible/src/xul/nsXULListboxAccessible.h
@@ -15,33 +15,35 @@
  * 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):
- *   Kyle Yuan (kyle.yuan@sun.com)
+ *   Aaron Leventhal <aaronl@netscape.com> (original author)
+ *   Kyle Yuan <kyle.yuan@sun.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
  * 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 __nsXULSelectAccessible_h__
-#define __nsXULSelectAccessible_h__
+#ifndef __nsXULListboxAccessible_h__
+#define __nsXULListboxAccessible_h__
 
 #include "nsIAccessibleTable.h"
 
 #include "nsCOMPtr.h"
 #include "nsXULMenuAccessible.h"
 #include "nsBaseWidgetAccessible.h"
 
 class nsIWeakReference;
@@ -76,35 +78,16 @@ public:
 
   // nsAccessible
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
 
   enum { eAction_Click = 0 };
 };
 
-/**
-  * Listboxes (xul:listbox) and Comboboxes (xul:menulist) are made up of a
-  * number of different widgets, some of which are shared between the two.
-  * This file contains all of the widgets for both of them, for XUL only.
-  *
-  *  Listbox:
-  *     - nsXULListboxAccessible
-  *        - nsXULSelectOptionAccessible
-  *
-  *  Comboboxes:
-  *     - nsXULComboboxAccessible      <menulist />
-  *        - nsXULMenuAccessible          <menupopup />
-  *           - nsXULMenuitemAccessible(s)   <menuitem />
-  */
-
-/** ------------------------------------------------------ */
-/**  First, the common widgets                             */
-/** ------------------------------------------------------ */
-
 /*
  * A class the represents the XUL Listbox widget.
  */
 class nsXULListboxAccessible : public nsXULSelectableAccessible,
                                public nsIAccessibleTable
 {
 public:
   nsXULListboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
@@ -116,17 +99,17 @@ public:
   // nsIAccessible
   NS_IMETHOD GetValue(nsAString& aValue);
 
   // nsAccessible
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
 
 protected:
-  PRBool IsTree();
+  PRBool IsMulticolumn();
 };
 
 /**
   * Listitems -- used in listboxes 
   */
 class nsXULListitemAccessible : public nsXULMenuitemAccessible
 {
 public:
@@ -154,49 +137,26 @@ protected:
 
 private:
   PRBool mIsCheckbox;
 };
 
 /**
  * Class represents xul:listcell.
  */
-class nsXULListCellAccessible : public nsHyperTextAccessibleWrap
+class nsXULListCellAccessible : public nsHyperTextAccessibleWrap,
+                                public nsIAccessibleTableCell
 {
 public:
   nsXULListCellAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
 
+  // nsISupports
+  NS_DECL_ISUPPORTS_INHERITED
+
+  // nsIAccessibleTableCell
+  NS_DECL_NSIACCESSIBLETABLECELL
+
   // nsAccessible
+  virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
 };
 
-/** ------------------------------------------------------ */
-/**  Finally, the Combobox widgets                         */
-/** ------------------------------------------------------ */
-
-/*
- * A class the represents the XUL Combobox widget.
- */
-class nsXULComboboxAccessible : public nsAccessibleWrap
-{
-public:
-  enum { eAction_Click = 0 };
-
-  nsXULComboboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
-  virtual ~nsXULComboboxAccessible() {}
-
-  // nsIAccessible
-  NS_IMETHOD GetValue(nsAString& _retval);
-  NS_IMETHOD GetDescription(nsAString& aDescription);
-  NS_IMETHOD DoAction(PRUint8 index);
-  NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
-  NS_IMETHOD GetActionName(PRUint8 index, nsAString& aName);
-
-  // nsAccessNode
-  virtual nsresult Init();
-
-  // nsAccessible
-  virtual nsresult GetRoleInternal(PRUint32 *aRole);
-  virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
-  virtual PRBool GetAllowsAnonChildAccessibles();
-};
-
 #endif
--- a/accessible/src/xul/nsXULTabAccessible.h
+++ b/accessible/src/xul/nsXULTabAccessible.h
@@ -36,17 +36,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _nsXULTabAccessible_H_
 #define _nsXULTabAccessible_H_
 
 // NOTE: alphabetically ordered
 #include "nsBaseWidgetAccessible.h"
-#include "nsXULSelectAccessible.h"
+#include "nsXULMenuAccessible.h"
 
 /**
  * An individual tab, xul:tab element
  */
 class nsXULTabAccessible : public nsLeafAccessible
 {
 public:
   enum { eAction_Switch = 0 };
--- a/accessible/src/xul/nsXULTreeAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeAccessible.cpp
@@ -796,19 +796,19 @@ nsXULTreeItemAccessibleBase::GetNextSibl
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   nsRefPtr<nsXULTreeAccessible> treeAcc =
     nsAccUtils::QueryAccessibleTree(mParent);
   NS_ENSURE_STATE(treeAcc);
 
-  PRInt32 rowsCount = 0;
-  mTreeView->GetRowCount(&rowsCount);
-  if (mRow + 1 >= rowsCount)
+  PRInt32 rowCount = 0;
+  mTreeView->GetRowCount(&rowCount);
+  if (mRow + 1 >= rowCount)
     return NS_OK;
 
   treeAcc->GetTreeItemAccessible(mRow + 1, aNextSibling);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTreeItemAccessibleBase::GetPreviousSibling(nsIAccessible **aPreviousSibling)
--- a/accessible/src/xul/nsXULTreeAccessible.h
+++ b/accessible/src/xul/nsXULTreeAccessible.h
@@ -36,17 +36,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 #ifndef __nsXULTreeAccessible_h__
 #define __nsXULTreeAccessible_h__
 
 #include "nsITreeBoxObject.h"
 #include "nsITreeView.h"
 #include "nsITreeColumns.h"
-#include "nsXULSelectAccessible.h"
+#include "nsXULListboxAccessible.h"
 
 /*
  * A class the represents the XUL Tree widget.
  */
 const PRUint32 kMaxTreeColumns = 100;
 const PRUint32 kDefaultTreeCacheSize = 256;
 
 /**
--- a/accessible/src/xul/nsXULTreeGridAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeGridAccessible.cpp
@@ -31,19 +31,20 @@
  * 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 "nsXULTreeGridAccessible.h"
+#include "nsXULTreeGridAccessibleWrap.h"
 
 #include "nsITreeSelection.h"
+#include "nsServiceManagerUtils.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 // Internal static functions
 ////////////////////////////////////////////////////////////////////////////////
 
 static PLDHashOperator
 ElementTraverser(const void *aKey, nsIAccessNode *aAccessNode,
                  void *aUserArg)
@@ -89,251 +90,275 @@ nsXULTreeGridAccessible::GetCaption(nsIA
 NS_IMETHODIMP
 nsXULTreeGridAccessible::GetSummary(nsAString &aSummary)
 {
   aSummary.Truncate();
   return IsDefunct() ? NS_ERROR_FAILURE : NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULTreeGridAccessible::GetColumns(PRInt32 *aColumnsCount)
+nsXULTreeGridAccessible::GetColumnCount(PRInt32 *acolumnCount)
 {
-  NS_ENSURE_ARG_POINTER(aColumnsCount);
-  *aColumnsCount = 0;
+  NS_ENSURE_ARG_POINTER(acolumnCount);
+  *acolumnCount = 0;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  *aColumnsCount = nsCoreUtils::GetSensibleColumnsCount(mTree);
+  *acolumnCount = nsCoreUtils::GetSensiblecolumnCount(mTree);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULTreeGridAccessible::GetColumnHeader(nsIAccessibleTable **aColumnHeader)
+nsXULTreeGridAccessible::GetRowCount(PRInt32 *arowCount)
 {
-  NS_ENSURE_ARG_POINTER(aColumnHeader);
-  *aColumnHeader = nsnull;
-
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsXULTreeGridAccessible::GetRows(PRInt32 *aRowsCount)
-{
-  NS_ENSURE_ARG_POINTER(aRowsCount);
-  *aRowsCount = nsnull;
+  NS_ENSURE_ARG_POINTER(arowCount);
+  *arowCount = nsnull;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  return mTreeView->GetRowCount(aRowsCount);
+  return mTreeView->GetRowCount(arowCount);
 }
 
 NS_IMETHODIMP
-nsXULTreeGridAccessible::GetRowHeader(nsIAccessibleTable **aRowHeader)
-{
-  NS_ENSURE_ARG_POINTER(aRowHeader);
-  *aRowHeader = nsnull;
-
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsXULTreeGridAccessible::GetSelectedCellsCount(PRUint32* aCount)
+nsXULTreeGridAccessible::GetSelectedCellCount(PRUint32* aCount)
 {
   NS_ENSURE_ARG_POINTER(aCount);
   *aCount = 0;
 
-  PRUint32 selectedRowsCount = 0;
-  nsresult rv = GetSelectedRowsCount(&selectedRowsCount);
+  PRUint32 selectedrowCount = 0;
+  nsresult rv = GetSelectedRowCount(&selectedrowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRInt32 columnsCount = 0;
-  rv = GetColumns(&columnsCount);
+  PRInt32 columnCount = 0;
+  rv = GetColumnCount(&columnCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aCount = selectedRowsCount * columnsCount;
+  *aCount = selectedrowCount * columnCount;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULTreeGridAccessible::GetSelectedColumnsCount(PRUint32* aCount)
+nsXULTreeGridAccessible::GetSelectedColumnCount(PRUint32* aCount)
 {
   NS_ENSURE_ARG_POINTER(aCount);
   *aCount = 0;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   // If all the row has been selected, then all the columns are selected,
   // because we can't select a column alone.
 
-  PRInt32 rowsCount = 0;
-  nsresult rv = GetRows(&rowsCount);
+  PRInt32 rowCount = 0;
+  nsresult rv = GetRowCount(&rowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRInt32 selectedRowsCount = 0;
-  rv = GetSelectionCount(&selectedRowsCount);
+  PRInt32 selectedrowCount = 0;
+  rv = GetSelectionCount(&selectedrowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (rowsCount == selectedRowsCount) {
-    PRInt32 columnsCount = 0;
-    rv = GetColumns(&columnsCount);
+  if (rowCount == selectedrowCount) {
+    PRInt32 columnCount = 0;
+    rv = GetColumnCount(&columnCount);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    *aCount = columnsCount;
+    *aCount = columnCount;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULTreeGridAccessible::GetSelectedRowsCount(PRUint32* aCount)
+nsXULTreeGridAccessible::GetSelectedRowCount(PRUint32* aCount)
 {
   NS_ENSURE_ARG_POINTER(aCount);
   *aCount = 0;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  PRInt32 selectedRowsCount = 0;
-  nsresult rv = GetSelectionCount(&selectedRowsCount);
+  PRInt32 selectedrowCount = 0;
+  nsresult rv = GetSelectionCount(&selectedrowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aCount = selectedRowsCount;
+  *aCount = selectedrowCount;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULTreeGridAccessible::GetSelectedCells(PRUint32 *aCellsCount,
-                                          PRInt32 **aCells)
+nsXULTreeGridAccessible::GetSelectedCells(nsIArray **aCells)
+{
+  NS_ENSURE_ARG_POINTER(aCells);
+  *aCells = nsnull;
+
+  nsCOMPtr<nsIMutableArray> selCells = do_CreateInstance(NS_ARRAY_CONTRACTID);
+  NS_ENSURE_TRUE(selCells, NS_ERROR_FAILURE);
+
+  PRInt32 selectedrowCount = 0;
+  nsresult rv = GetSelectionCount(&selectedrowCount);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRInt32 columnCount = 0;
+  rv = GetColumnCount(&columnCount);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCOMPtr<nsITreeSelection> selection;
+  rv = mTreeView->GetSelection(getter_AddRefs(selection));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRInt32 rowCount = 0;
+  rv = GetRowCount(&rowCount);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRBool isSelected;
+  for (PRInt32 rowIdx = 0; rowIdx < rowCount; rowIdx++) {
+    selection->IsSelected(rowIdx, &isSelected);
+    if (isSelected) {
+      for (PRInt32 colIdx = 0; colIdx < columnCount; colIdx++) {
+        nsCOMPtr<nsIAccessible> cell;
+        GetCellAt(rowIdx, colIdx, getter_AddRefs(cell));
+        selCells->AppendElement(cell, PR_FALSE);
+      }
+    }
+  }
+
+  NS_ADDREF(*aCells = selCells);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXULTreeGridAccessible::GetSelectedCellIndices(PRUint32 *aCellsCount,
+                                                PRInt32 **aCells)
 {
   NS_ENSURE_ARG_POINTER(aCellsCount);
   *aCellsCount = 0;
   NS_ENSURE_ARG_POINTER(aCells);
   *aCells = nsnull;
 
-  PRInt32 selectedRowsCount = 0;
-  nsresult rv = GetSelectionCount(&selectedRowsCount);
+  PRInt32 selectedrowCount = 0;
+  nsresult rv = GetSelectionCount(&selectedrowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRInt32 columnsCount = 0;
-  rv = GetColumns(&columnsCount);
+  PRInt32 columnCount = 0;
+  rv = GetColumnCount(&columnCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRInt32 selectedCellsCount = selectedRowsCount * columnsCount;
+  PRInt32 selectedCellCount = selectedrowCount * columnCount;
   PRInt32* outArray = static_cast<PRInt32*>(
-    nsMemory::Alloc(selectedCellsCount * sizeof(PRInt32)));
+    nsMemory::Alloc(selectedCellCount * sizeof(PRInt32)));
   NS_ENSURE_TRUE(outArray, NS_ERROR_OUT_OF_MEMORY);
 
   nsCOMPtr<nsITreeSelection> selection;
   rv = mTreeView->GetSelection(getter_AddRefs(selection));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRInt32 rowsCount = 0;
-  rv = GetRows(&rowsCount);
+  PRInt32 rowCount = 0;
+  rv = GetRowCount(&rowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRBool isSelected;
-  for (PRInt32 rowIdx = 0, arrayIdx = 0; rowIdx < rowsCount; rowIdx++) {
+  for (PRInt32 rowIdx = 0, arrayIdx = 0; rowIdx < rowCount; rowIdx++) {
     selection->IsSelected(rowIdx, &isSelected);
     if (isSelected) {
-      for (PRInt32 colIdx = 0; colIdx < columnsCount; colIdx++)
-        outArray[arrayIdx++] = rowIdx * columnsCount + colIdx;
+      for (PRInt32 colIdx = 0; colIdx < columnCount; colIdx++)
+        outArray[arrayIdx++] = rowIdx * columnCount + colIdx;
     }
   }
 
-  *aCellsCount = selectedCellsCount;
+  *aCellsCount = selectedCellCount;
   *aCells = outArray;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULTreeGridAccessible::GetSelectedColumns(PRUint32 *aColumnsCount,
-                                            PRInt32 **aColumns)
+nsXULTreeGridAccessible::GetSelectedColumnIndices(PRUint32 *acolumnCount,
+                                                  PRInt32 **aColumns)
 {
-  NS_ENSURE_ARG_POINTER(aColumnsCount);
-  *aColumnsCount = 0;
+  NS_ENSURE_ARG_POINTER(acolumnCount);
+  *acolumnCount = 0;
   NS_ENSURE_ARG_POINTER(aColumns);
   *aColumns = nsnull;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   // If all the row has been selected, then all the columns are selected.
   // Because we can't select a column alone.
 
-  PRInt32 rowsCount = 0;
-  nsresult rv = GetRows(&rowsCount);
+  PRInt32 rowCount = 0;
+  nsresult rv = GetRowCount(&rowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRInt32 selectedRowsCount = 0;
-  rv = GetSelectionCount(&selectedRowsCount);
+  PRInt32 selectedrowCount = 0;
+  rv = GetSelectionCount(&selectedrowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (rowsCount != selectedRowsCount)
+  if (rowCount != selectedrowCount)
     return NS_OK;
 
-  PRInt32 columnsCount = 0;
-  rv = GetColumns(&columnsCount);
+  PRInt32 columnCount = 0;
+  rv = GetColumnCount(&columnCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32* outArray = static_cast<PRInt32*>(
-    nsMemory::Alloc(columnsCount * sizeof(PRInt32)));
+    nsMemory::Alloc(columnCount * sizeof(PRInt32)));
   NS_ENSURE_TRUE(outArray, NS_ERROR_OUT_OF_MEMORY);
 
-  for (PRInt32 colIdx = 0; colIdx < columnsCount; colIdx++)
+  for (PRInt32 colIdx = 0; colIdx < columnCount; colIdx++)
     outArray[colIdx] = colIdx;
 
-  *aColumnsCount = columnsCount;
+  *acolumnCount = columnCount;
   *aColumns = outArray;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULTreeGridAccessible::GetSelectedRows(PRUint32 *aRowsCount, PRInt32 **aRows)
+nsXULTreeGridAccessible::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 selectedRowsCount = 0;
-  nsresult rv = GetSelectionCount(&selectedRowsCount);
+  PRInt32 selectedrowCount = 0;
+  nsresult rv = GetSelectionCount(&selectedrowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32* outArray = static_cast<PRInt32*>(
-    nsMemory::Alloc(selectedRowsCount * sizeof(PRInt32)));
+    nsMemory::Alloc(selectedrowCount * sizeof(PRInt32)));
   NS_ENSURE_TRUE(outArray, NS_ERROR_OUT_OF_MEMORY);
 
   nsCOMPtr<nsITreeSelection> selection;
   rv = mTreeView->GetSelection(getter_AddRefs(selection));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRInt32 rowsCount = 0;
-  rv = GetRows(&rowsCount);
+  PRInt32 rowCount = 0;
+  rv = GetRowCount(&rowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRBool isSelected;
-  for (PRInt32 rowIdx = 0, arrayIdx = 0; rowIdx < rowsCount; rowIdx++) {
+  for (PRInt32 rowIdx = 0, arrayIdx = 0; rowIdx < rowCount; rowIdx++) {
     selection->IsSelected(rowIdx, &isSelected);
     if (isSelected)
       outArray[arrayIdx++] = rowIdx;
   }
 
-  *aRowsCount = selectedRowsCount;
+  *arowCount = selectedrowCount;
   *aRows = outArray;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULTreeGridAccessible::CellRefAt(PRInt32 aRowIndex, PRInt32 aColumnIndex,
+nsXULTreeGridAccessible::GetCellAt(PRInt32 aRowIndex, PRInt32 aColumnIndex,
                                    nsIAccessible **aCell)
 {
   NS_ENSURE_ARG_POINTER(aCell);
   *aCell = nsnull;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
@@ -350,59 +375,59 @@ nsXULTreeGridAccessible::CellRefAt(PRInt
   nsRefPtr<nsXULTreeItemAccessibleBase> rowAcc =
     nsAccUtils::QueryObject<nsXULTreeItemAccessibleBase>(rowAccessible);
 
   rowAcc->GetCellAccessible(column, aCell);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULTreeGridAccessible::GetIndexAt(PRInt32 aRowIndex, PRInt32 aColumnIndex,
-                                    PRInt32 *aCellIndex)
+nsXULTreeGridAccessible::GetCellIndexAt(PRInt32 aRowIndex, PRInt32 aColumnIndex,
+                                        PRInt32 *aCellIndex)
 {
   NS_ENSURE_ARG_POINTER(aCellIndex);
   *aCellIndex = -1;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  PRInt32 columnsCount = 0;
-  nsresult rv = GetColumns(&columnsCount);
+  PRInt32 columnCount = 0;
+  nsresult rv = GetColumnCount(&columnCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aCellIndex = aRowIndex * columnsCount + aColumnIndex;
+  *aCellIndex = aRowIndex * columnCount + aColumnIndex;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULTreeGridAccessible::GetColumnAtIndex(PRInt32 aCellIndex,
+nsXULTreeGridAccessible::GetColumnIndexAt(PRInt32 aCellIndex,
                                           PRInt32 *aColumnIndex)
 {
   NS_ENSURE_ARG_POINTER(aColumnIndex);
   *aColumnIndex = -1;
 
-  PRInt32 columnsCount = 0;
-  nsresult rv = GetColumns(&columnsCount);
+  PRInt32 columnCount = 0;
+  nsresult rv = GetColumnCount(&columnCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aColumnIndex = aCellIndex % columnsCount;
+  *aColumnIndex = aCellIndex % columnCount;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXULTreeGridAccessible::GetRowAtIndex(PRInt32 aCellIndex, PRInt32 *aRowIndex)
+nsXULTreeGridAccessible::GetRowIndexAt(PRInt32 aCellIndex, PRInt32 *aRowIndex)
 {
   NS_ENSURE_ARG_POINTER(aRowIndex);
   *aRowIndex = -1;
 
-  PRInt32 columnsCount;
-  nsresult rv = GetColumns(&columnsCount);
+  PRInt32 columnCount;
+  nsresult rv = GetColumnCount(&columnCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aRowIndex = aCellIndex / columnsCount;
+  *aRowIndex = aCellIndex / columnCount;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTreeGridAccessible::GetColumnExtentAt(PRInt32 aRowIndex,
                                            PRInt32 aColumnIndex,
                                            PRInt32 *aExtentCount)
 {
@@ -423,50 +448,61 @@ nsXULTreeGridAccessible::GetRowExtentAt(
 }
 
 NS_IMETHODIMP
 nsXULTreeGridAccessible::GetColumnDescription(PRInt32 aColumnIndex,
                                               nsAString& aDescription)
 {
   aDescription.Truncate();
 
-  return NS_ERROR_NOT_IMPLEMENTED;
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsCOMPtr<nsIAccessible> treeColumns;
+  nsAccessible::GetFirstChild(getter_AddRefs(treeColumns));
+  if (treeColumns) {
+    nsCOMPtr<nsIAccessible> treeColumnItem;
+    treeColumns->GetChildAt(aColumnIndex, getter_AddRefs(treeColumnItem));
+    if (treeColumnItem)
+      return treeColumnItem->GetName(aDescription);
+  }
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTreeGridAccessible::GetRowDescription(PRInt32 aRowIndex,
                                            nsAString& aDescription)
 {
   aDescription.Truncate();
-
-  return NS_ERROR_NOT_IMPLEMENTED;
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTreeGridAccessible::IsColumnSelected(PRInt32 aColumnIndex,
                                           PRBool *aIsSelected)
 {
   NS_ENSURE_ARG_POINTER(aIsSelected);
   *aIsSelected = PR_FALSE;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   // If all the row has been selected, then all the columns are selected.
   // Because we can't select a column alone.
   
-  PRInt32 rowsCount = 0;
-  nsresult rv = GetRows(&rowsCount);
+  PRInt32 rowCount = 0;
+  nsresult rv = GetRowCount(&rowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRInt32 selectedRowsCount = 0;
-  rv = GetSelectionCount(&selectedRowsCount);
+  PRInt32 selectedrowCount = 0;
+  rv = GetSelectionCount(&selectedrowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  *aIsSelected = rowsCount == selectedRowsCount;
+  *aIsSelected = rowCount == selectedrowCount;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTreeGridAccessible::IsRowSelected(PRInt32 aRowIndex, PRBool *aIsSelected)
 {
   NS_ENSURE_ARG_POINTER(aIsSelected);
   *aIsSelected = PR_FALSE;
@@ -642,17 +678,17 @@ NS_IMETHODIMP
 nsXULTreeGridRowAccessible::GetChildCount(PRInt32 *aChildCount)
 {
   NS_ENSURE_ARG_POINTER(aChildCount);
   *aChildCount = 0;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  *aChildCount = nsCoreUtils::GetSensibleColumnsCount(mTree);
+  *aChildCount = nsCoreUtils::GetSensiblecolumnCount(mTree);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTreeGridRowAccessible::GetChildAt(PRInt32 aChildIndex,
                                        nsIAccessible **aChild)
 {
   NS_ENSURE_ARG_POINTER(aChild);
@@ -736,18 +772,18 @@ nsXULTreeGridRowAccessible::GetCellAcces
 
   void* key = static_cast<void*>(aColumn);
 
   nsCOMPtr<nsIAccessNode> accessNode;
   GetCacheEntry(mAccessNodeCache, key, getter_AddRefs(accessNode));
 
   if (!accessNode) {
     nsRefPtr<nsAccessNode> cellAcc =
-      new nsXULTreeGridCellAccessible(mDOMNode, mWeakShell, this, mTree,
-                                      mTreeView, mRow, aColumn);
+      new nsXULTreeGridCellAccessibleWrap(mDOMNode, mWeakShell, this, mTree,
+                                          mTreeView, mRow, aColumn);
     if (!cellAcc)
       return;
 
     nsresult rv = cellAcc->Init();
     if (NS_FAILED(rv))
       return;
 
     accessNode = cellAcc;
@@ -796,18 +832,19 @@ nsXULTreeGridCellAccessible(nsIDOMNode *
   mTreeView(aTreeView), mRow(aRow), mColumn(aColumn)
 {
   mParent = aRowAcc;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeGridCellAccessible: nsISupports implementation
 
-NS_IMPL_ISUPPORTS_INHERITED1(nsXULTreeGridCellAccessible,
+NS_IMPL_ISUPPORTS_INHERITED2(nsXULTreeGridCellAccessible,
                              nsLeafAccessible,
+                             nsIAccessibleTableCell,
                              nsXULTreeGridCellAccessible)
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeGridCellAccessible: nsIAccessNode implementation
 
 NS_IMETHODIMP
 nsXULTreeGridCellAccessible::GetUniqueID(void **aUniqueID)
 {
@@ -1026,16 +1063,141 @@ nsXULTreeGridCellAccessible::DoAction(PR
   mColumn->GetType(&type);
   if (type == nsITreeColumn::TYPE_CHECKBOX && IsEditable())
     return DoCommand();
 
   return NS_ERROR_INVALID_ARG;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+// nsXULTreeGridCellAccessible: nsIAccessibleTableCell implementation
+
+NS_IMETHODIMP
+nsXULTreeGridCellAccessible::GetTable(nsIAccessibleTable **aTable)
+{
+  NS_ENSURE_ARG_POINTER(aTable);
+  *aTable = nsnull;
+
+  if (IsDefunct())
+    return NS_OK;
+
+  nsCOMPtr<nsIAccessible> accessible;
+  mParent->GetParent(getter_AddRefs(accessible));
+  CallQueryInterface(accessible, aTable);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXULTreeGridCellAccessible::GetColumnIndex(PRInt32 *aColumnIndex)
+{
+  NS_ENSURE_ARG_POINTER(aColumnIndex);
+  *aColumnIndex = -1;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  *aColumnIndex = GetColumnIndex();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXULTreeGridCellAccessible::GetRowIndex(PRInt32 *aRowIndex)
+{
+  NS_ENSURE_ARG_POINTER(aRowIndex);
+  *aRowIndex = -1;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  *aRowIndex = mRow;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXULTreeGridCellAccessible::GetColumnExtent(PRInt32 *aExtentCount)
+{
+  NS_ENSURE_ARG_POINTER(aExtentCount);
+  *aExtentCount = 1;
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXULTreeGridCellAccessible::GetRowExtent(PRInt32 *aExtentCount)
+{
+  NS_ENSURE_ARG_POINTER(aExtentCount);
+  *aExtentCount = 1;
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXULTreeGridCellAccessible::GetColumnHeaderCells(nsIArray **aHeaderCells)
+{
+  NS_ENSURE_ARG_POINTER(aHeaderCells);
+  *aHeaderCells = nsnull;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsresult rv = NS_OK;
+  nsCOMPtr<nsIMutableArray> headerCells =
+    do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCOMPtr<nsIDOMElement> columnElm;
+  mColumn->GetElement(getter_AddRefs(columnElm));
+
+  nsCOMPtr<nsIAccessible> headerCell;
+  GetAccService()->GetAccessibleInWeakShell(columnElm, mWeakShell,
+                                            getter_AddRefs(headerCell));
+
+  if (headerCell)
+    headerCells->AppendElement(headerCell, PR_FALSE);
+
+  NS_ADDREF(*aHeaderCells = headerCells);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXULTreeGridCellAccessible::GetRowHeaderCells(nsIArray **aHeaderCells)
+{
+  NS_ENSURE_ARG_POINTER(aHeaderCells);
+  *aHeaderCells = nsnull;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsresult rv = NS_OK;
+  nsCOMPtr<nsIMutableArray> headerCells =
+    do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  NS_ADDREF(*aHeaderCells = headerCells);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsXULTreeGridCellAccessible::IsSelected(PRBool *aIsSelected)
+{
+  NS_ENSURE_ARG_POINTER(aIsSelected);
+  *aIsSelected = PR_FALSE;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsCOMPtr<nsITreeSelection> selection;
+  nsresult rv = mTreeView->GetSelection(getter_AddRefs(selection));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return selection->IsSelected(mRow, aIsSelected);
+}
+
+////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeGridCellAccessible: nsAccessNode implementation
 
 PRBool
 nsXULTreeGridCellAccessible::IsDefunct()
 {
   return nsLeafAccessible::IsDefunct() || !mParent || !mTree || !mTreeView ||
     !mColumn;
 }
@@ -1070,17 +1232,17 @@ nsXULTreeGridCellAccessible::GetAttribut
   // "table-cell-index" attribute
   nsCOMPtr<nsIAccessible> accessible;
   mParent->GetParent(getter_AddRefs(accessible));
   nsCOMPtr<nsIAccessibleTable> tableAccessible = do_QueryInterface(accessible);
 
   PRInt32 colIdx = GetColumnIndex();
 
   PRInt32 cellIdx = -1;
-  tableAccessible->GetIndexAt(mRow, colIdx, &cellIdx);
+  tableAccessible->GetCellIndexAt(mRow, colIdx, &cellIdx);
 
   nsAutoString stringIdx;
   stringIdx.AppendInt(cellIdx);
   nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::tableCellIndex,
                          stringIdx);
 
   // "cycles" attribute
   PRBool isCycler = PR_FALSE;
--- a/accessible/src/xul/nsXULTreeGridAccessible.h
+++ b/accessible/src/xul/nsXULTreeGridAccessible.h
@@ -118,17 +118,18 @@ protected:
 #define NS_XULTREEGRIDCELLACCESSIBLE_IMPL_CID         \
 {  /* 84588ad4-549c-4196-a932-4c5ca5de5dff */         \
   0x84588ad4,                                         \
   0x549c,                                             \
   0x4196,                                             \
   { 0xa9, 0x32, 0x4c, 0x5c, 0xa5, 0xde, 0x5d, 0xff }  \
 }
 
-class nsXULTreeGridCellAccessible : public nsLeafAccessible
+class nsXULTreeGridCellAccessible : public nsLeafAccessible,
+                                    public nsIAccessibleTableCell
 {
 public:
   nsXULTreeGridCellAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
                               nsXULTreeGridRowAccessible *aRowAcc,
                               nsITreeBoxObject *aTree, nsITreeView *aTreeView,
                               PRInt32 aRow, nsITreeColumn* aColumn);
 
   // nsISupports
@@ -147,16 +148,19 @@ public:
   NS_IMETHOD GetName(nsAString& aName);
   NS_IMETHOD GetBounds(PRInt32 *aX, PRInt32 *aY,
                        PRInt32 *aWidth, PRInt32 *aHeight);
 
   NS_IMETHOD GetNumActions(PRUint8 *aCount);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 aIndex);
 
+  // nsIAccessibleTableCell
+  NS_DECL_NSIACCESSIBLETABLECELL
+
   // nsAccessNode
   virtual PRBool IsDefunct();
   virtual nsresult Init();
 
   // nsAccessible
   virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
--- a/accessible/tests/mochitest/Makefile.in
+++ b/accessible/tests/mochitest/Makefile.in
@@ -73,29 +73,28 @@ include $(topsrcdir)/config/rules.mk
 		test_actions_anchors.html \
 		test_actions_aria.html \
 		test_actions_inputs.html \
 		test_actions_tree.xul \
 		test_actions_treegrid.xul \
 		test_aria_activedescendant.html \
 		test_aria_role_article.html \
 		test_aria_role_equation.html \
-		test_aria_role_grid.html \
 		test_aria_roles.html \
 		test_aria_roles.xul \
 		test_aria_token_attrs.html \
 		test_attrs_elm_tree.xul \
 		test_bug420863.html \
 	$(warning   test_childAtPoint.html temporarily disabled) \
 	$(warning	test_childAtPoint.xul temporarily disabled) \
 		test_cssattrs.html \
 		test_descr.html \
 		test_elm_filectrl.html \
+		test_elm_listbox.xul \
 	$(warning   test_elm_media.html temporarily disabled) \
-		test_elm_table.html \
 		test_elm_tree.xul \
 		test_elm_txtcntnr.html \
 		test_events_caretmove.html \
 		test_events_coalescence.html \
 		test_events_doc.html \
 		test_events_draganddrop.html \
 		test_events_flush.html \
 		test_events_focus.xul \
@@ -115,43 +114,50 @@ include $(topsrcdir)/config/rules.mk
  		test_nsIAccessible_selects.html \
 		test_nsIAccessible_focus.html \
 		test_nsIAccessibleDocument.html \
 		test_nsIAccessibleEditableText.html \
 		test_nsIAccessibleHyperLink.html \
 		test_nsIAccessibleHyperLink.xul \
 		test_nsIAccessibleHyperText.html \
 		test_nsIAccessibleImage.html \
-		$(warning test_nsIAccessibleTable_listboxes.xul temporarily disabled) \
 		test_nsIAccessNode_utils.html \
 		test_nsOuterDocAccessible.html \
  		test_objectattrs.html \
 		test_relations.html \
 		test_relations.xul \
-		test_relations_table.html \
 		test_relations_tree.xul \
 		test_role_nsHyperTextAcc.html \
 		test_role_table_cells.html \
 		test_states.html \
 		test_states_doc.html \
 		test_states_docarticle.html \
 		test_states_editablebody.html \
 		test_states_frames.html \
 		test_states_popup.xul \
 		test_states_tree.xul \
 		test_table_1.html \
-		test_table_2.html \
 		test_table_4.html \
+		test_table_headers.html \
+		test_table_headers_ariagrid.html \
+		test_table_headers_listbox.xul \
+		test_table_headers_tree.xul \
 		test_table_indexes.html \
 		test_table_indexes_ariagrid.html \
+		test_table_indexes_listbox.xul \
 		test_table_indexes_tree.xul \
 		test_table_layoutguess.html \
 		test_table_sels.html \
 		test_table_sels_ariagrid.html \
+		test_table_sels_listbox.xul \
 		test_table_sels_tree.xul \
+		test_table_struct.html \
+		test_table_struct_ariagrid.html \
+		test_table_struct_listbox.xul \
+		test_table_struct_tree.xul \
 		test_textattrs.html \
 		test_textboxes.html \
 		test_textboxes.xul \
 		test_value.xul \
 		testTextboxes.js \
 		treeview.css \
 		treeview.js \
 		z_states_frame.html \
--- a/accessible/tests/mochitest/common.js
+++ b/accessible/tests/mochitest/common.js
@@ -27,16 +27,17 @@ const nsIAccessibleText = Components.int
 const nsIAccessibleEditableText = Components.interfaces.nsIAccessibleEditableText;
 
 const nsIAccessibleHyperLink = Components.interfaces.nsIAccessibleHyperLink;
 const nsIAccessibleHyperText = Components.interfaces.nsIAccessibleHyperText;
 
 const nsIAccessibleImage = Components.interfaces.nsIAccessibleImage;
 const nsIAccessibleSelectable = Components.interfaces.nsIAccessibleSelectable;
 const nsIAccessibleTable = Components.interfaces.nsIAccessibleTable;
+const nsIAccessibleTableCell = Components.interfaces.nsIAccessibleTableCell;
 const nsIAccessibleValue = Components.interfaces.nsIAccessibleValue;
 
 const nsIObserverService = Components.interfaces.nsIObserverService;
 
 const nsIDOMDocument = Components.interfaces.nsIDOMDocument;
 const nsIDOMEvent = Components.interfaces.nsIDOMEvent;
 const nsIDOMHTMLDocument = Components.interfaces.nsIDOMHTMLDocument;
 const nsIDOMNode = Components.interfaces.nsIDOMNode;
@@ -287,25 +288,34 @@ function ensureAccessibleTree(aAccOrElmO
     } catch (e) {
       child = null;
     }
   }
 }
 
 /**
  * Compare expected and actual accessibles trees.
+ *
+ * @param  aAccOrElmOrID  [in] accessible identifier
+ * @param  aAccTree       [in] JS object, each field corresponds to property of
+ *                         accessible object. Additionally special properties
+ *                         are presented:
+ *                          children - an array of JS objects representing
+ *                                      children of accessible
+ *                          states   - an object having states and extraStates
+ *                                      fields
  */
 function testAccessibleTree(aAccOrElmOrID, aAccTree)
 {
   var acc = getAccessible(aAccOrElmOrID);
   if (!acc)
     return;
 
   for (var prop in aAccTree) {
-    var msg = "Wrong value of property '" + prop + "'.";
+    var msg = "Wrong value of property '" + prop + "' for " + prettyName(acc) + ".";
     if (prop == "role") {
       is(roleToString(acc[prop]), roleToString(aAccTree[prop]), msg);
 
     } else if (prop == "states") {
       var statesObj = aAccTree[prop];
       testStates(acc, statesObj.states, statesObj.extraStates,
                  statesObj.absentStates, statesObj.absentExtraStates);
 
--- a/accessible/tests/mochitest/grid.js
+++ b/accessible/tests/mochitest/grid.js
@@ -1,37 +1,37 @@
 const nsIDOMKeyEvent = Components.interfaces.nsIDOMKeyEvent;
 
 /**
  * Create grid object based on HTML table.
  */
 function grid(aTableIdentifier)
 {
-  this.getRowsCount = function getRowsCount()
+  this.getrowCount = function getrowCount()
   {
     return this.table.rows.length - (this.table.tHead ? 1 : 0);
   }
   this.getColsCount = function getColsCount()
   {
     return this.table.rows[0].cells.length;
   }
 
   this.getRowAtIndex = function getRowAtIndex(aIndex)
   {
     return this.table.rows[this.table.tHead ? aIndex + 1 : aIndex];
   }
 
   this.getMaxIndex = function getMaxIndex()
   {
-    return this.getRowsCount() * this.getColsCount() - 1;
+    return this.getrowCount() * this.getColsCount() - 1;
   }
 
   this.getCellAtIndex = function getCellAtIndex(aIndex)
   {
-    var rowsCount = this.getRowsCount();
+    var rowCount = this.getrowCount();
     var colsCount = this.getColsCount();
 
     var rowIdx = Math.floor(aIndex / colsCount);
     var colIdx = aIndex % colsCount;
 
     var row = this.getRowAtIndex(rowIdx);
     return row.cells[colIdx];
   }
@@ -45,19 +45,19 @@ function grid(aTableIdentifier)
       rowIdx -= 1;
 
     var colsCount = this.getColsCount();
     return rowIdx * colsCount + colIdx;
   }
 
   this.getCurrentCell = function getCurrentCell()
   {
-    var rowsCount = this.table.rows.length;
+    var rowCount = this.table.rows.length;
     var colsCount = this.getColsCount();
-    for (var rowIdx = 0; rowIdx < rowsCount; rowIdx++) {
+    for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
       for (var colIdx = 0; colIdx < colsCount; colIdx++) {
         var cell = this.table.rows[rowIdx].cells[colIdx];
         if (cell.hasAttribute("tabindex"))
           return cell;
       }
     }
     return null;
   }
--- a/accessible/tests/mochitest/role.js
+++ b/accessible/tests/mochitest/role.js
@@ -1,14 +1,15 @@
 ////////////////////////////////////////////////////////////////////////////////
 // Role constants
 
 const ROLE_ALERT = nsIAccessibleRole.ROLE_ALERT;
 const ROLE_APPLICATION = nsIAccessibleRole.ROLE_APPLICATION;
 const ROLE_APP_ROOT = nsIAccessibleRole.ROLE_APP_ROOT;
+const ROLE_CAPTION = nsIAccessibleRole.ROLE_CAPTION;
 const ROLE_CELL = nsIAccessibleRole.ROLE_CELL;
 const ROLE_CHROME_WINDOW = nsIAccessibleRole.ROLE_CHROME_WINDOW;
 const ROLE_COMBOBOX = nsIAccessibleRole.ROLE_COMBOBOX;
 const ROLE_COMBOBOX_LIST = nsIAccessibleRole.ROLE_COMBOBOX_LIST;
 const ROLE_COMBOBOX_OPTION = nsIAccessibleRole.ROLE_COMBOBOX_OPTION;
 const ROLE_COLUMNHEADER = nsIAccessibleRole.ROLE_COLUMNHEADER;
 const ROLE_DOCUMENT = nsIAccessibleRole.ROLE_DOCUMENT;
 const ROLE_ENTRY = nsIAccessibleRole.ROLE_ENTRY;
@@ -29,16 +30,17 @@ const ROLE_NOTHING = nsIAccessibleRole.R
 const ROLE_OPTION = nsIAccessibleRole.ROLE_OPTION;
 const ROLE_OUTLINE = nsIAccessibleRole.ROLE_OUTLINE;
 const ROLE_OUTLINEITEM = nsIAccessibleRole.ROLE_OUTLINEITEM;
 const ROLE_PARAGRAPH = nsIAccessibleRole.ROLE_PARAGRAPH;
 const ROLE_PASSWORD_TEXT = nsIAccessibleRole.ROLE_PASSWORD_TEXT;
 const ROLE_PROGRESSBAR = nsIAccessibleRole.ROLE_PROGRESSBAR;
 const ROLE_PUSHBUTTON = nsIAccessibleRole.ROLE_PUSHBUTTON;
 const ROLE_ROW = nsIAccessibleRole.ROLE_ROW;
+const ROLE_ROWHEADER = nsIAccessibleRole.ROLE_ROWHEADER;
 const ROLE_SECTION = nsIAccessibleRole.ROLE_SECTION;
 const ROLE_SLIDER = nsIAccessibleRole.ROLE_SLIDER;
 const ROLE_TABLE = nsIAccessibleRole.ROLE_TABLE;
 const ROLE_TEXT_CONTAINER = nsIAccessibleRole.ROLE_TEXT_CONTAINER;
 const ROLE_TEXT_LEAF = nsIAccessibleRole.ROLE_TEXT_LEAF;
 const ROLE_TOGGLE_BUTTON = nsIAccessibleRole.ROLE_TOGGLE_BUTTON;
 const ROLE_TREE_TABLE = nsIAccessibleRole.ROLE_TREE_TABLE;
 
--- a/accessible/tests/mochitest/table.js
+++ b/accessible/tests/mochitest/table.js
@@ -1,18 +1,199 @@
 /**
  * This file provides set of helper functions to test nsIAccessibleTable
  * interface.
  *
  * Required:
  *   common.js
+ *   role.js
  *   states.js
  */
 
 /**
+ * Constants used to describe cells array.
+ */
+const kDataCell = 1; // Indicates the cell is origin data cell
+const kRowHeaderCell = 2; // Indicates the cell is row header cell
+const kColHeaderCell = 4; // Indicated teh cell is column header cell
+const kOrigin = kDataCell | kRowHeaderCell | kColHeaderCell;
+
+const kRowSpanned = 8; // Indicates the cell is not origin and row spanned 
+const kColSpanned = 16; // Indicates the cell is not origin and column spanned
+const kSpanned = kRowSpanned | kColSpanned;
+
+/**
+ * Constants to define column header type.
+ */
+const kNoColumnHeader = 0;
+const kListboxColumnHeader = 1;
+const kTreeColumnHeader = 2;
+
+/**
+ * Test table structure and related methods.
+ *
+ * @param  aIdentifier     [in] table accessible identifier
+ * @param  aCellsArray     [in] two dimensional array (row X columns) of
+ *                          cell types (see constants defined above).
+ * @param  aColHeaderType  [in] specifies wether column header cells are
+ *                          arranged into the list.
+ * @param  aCaption        [in] caption text if any
+ * @param  aSummary        [in] summary text if any
+ */
+function testTableStruct(aIdentifier, aCellsArray, aColHeaderType,
+                         aCaption, aSummary)
+{
+  var tableNode = getNode(aIdentifier);
+  var isGrid = tableNode.getAttribute("role") == "grid" ||
+    tableNode.localName == "tree";
+
+  var rowCount = aCellsArray.length;
+  var colsCount = aCellsArray[0].length;
+
+  // Test table accessible tree.
+  var tableObj = {
+    role: ROLE_TABLE,
+    children: []
+  };
+
+  // caption accessible handling
+  if (aCaption) {
+    var captionObj = {
+      role: ROLE_CAPTION,
+      children: [
+        {
+          role: ROLE_TEXT_LEAF,
+          name: aCaption
+        }
+      ]
+    };
+
+    tableObj.children.push(captionObj);
+  }
+
+  // special types of column headers handling
+  if (aColHeaderType) {
+    var headersObj = {
+      role: ROLE_LIST,
+      children: []
+    };
+
+    for (var idx = 0; idx < colsCount; idx++) {
+      var headerCellObj = {
+        role: ROLE_COLUMNHEADER
+      };
+      headersObj.children.push(headerCellObj);
+    }
+
+    if (aColHeaderType == kTreeColumnHeader) {
+      var columnPickerObj = {
+        role: ROLE_PUSHBUTTON
+      };
+
+      headersObj.children.push(columnPickerObj);
+    }
+
+    tableObj.children.push(headersObj);
+  }
+
+  // rows and cells accessibles
+  for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
+    var rowObj = {
+      role: ROLE_ROW,
+      children: []
+    };
+
+    for (var colIdx = 0; colIdx < colsCount; colIdx++) {
+      var celltype = aCellsArray[rowIdx][colIdx];
+
+      var role = ROLE_NOTHING;
+      switch (celltype) {
+        case kDataCell:
+          role = (isGrid ? ROLE_GRID_CELL : ROLE_CELL);
+          break;
+        case kRowHeaderCell:
+          role = ROLE_ROWHEADER;
+          break;
+        case kColHeaderCell:
+          role = ROLE_COLUMNHEADER;
+          break;
+      }
+
+      if (role != ROLE_NOTHING) {
+        var cellObj = {
+          role: role
+        };
+        rowObj.children.push(cellObj);
+      }
+    }
+
+    tableObj.children.push(rowObj);
+  }
+
+  testAccessibleTree(aIdentifier, tableObj);
+
+  // Test table table interface.
+  var table = getAccessible(aIdentifier, [nsIAccessibleTable]);
+
+  // summary
+  if (aSummary)
+    is(table.summary, aSummary,
+       "Wrong summary of the table " + prettyName(aIdentifier));
+
+  // rowCount and columnCount
+  is(table.rowCount, rowCount,
+     "Wrong rows count of " + prettyName(aIdentifier));
+  is(table.columnCount, colsCount,
+     "Wrong columns count of " + prettyName(aIdentifier));
+
+  // rows and columns extents
+  for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
+    for (var colIdx = 0; colIdx < colsCount; colIdx++) {
+      var celltype = aCellsArray[rowIdx][colIdx];
+      if (celltype & kOrigin) {
+
+        // table getRowExtentAt
+        var rowExtent = table.getRowExtentAt(rowIdx, colIdx);
+        for (var idx = rowIdx + 1;
+             idx < rowCount && (aCellsArray[idx][colIdx] & kRowSpanned);
+             idx++);
+
+        var expectedRowExtent = idx - rowIdx;
+        is(rowExtent, expectedRowExtent,
+           "getRowExtentAt: Wrong number of spanned rows at (" + rowIdx + ", " +
+           colIdx + ") for " + prettyName(aIdentifier));
+
+        // table getColumnExtentAt
+        var colExtent = table.getColumnExtentAt(rowIdx, colIdx);
+        for (var idx = colIdx + 1;
+             idx < colsCount && (aCellsArray[rowIdx][idx] & kColSpanned);
+             idx++);
+
+        var expectedColExtent = idx - colIdx;
+        is(colExtent, expectedColExtent,
+           "getColumnExtentAt: Wrong number of spanned columns at (" + rowIdx +
+           ", " + colIdx + ") for " + prettyName(aIdentifier));
+
+        // cell rowExtent and columnExtent
+        var cell = getAccessible(table.getCellAt(rowIdx, colIdx),
+                                 [nsIAccessibleTableCell]);
+
+        is(cell.rowExtent, expectedRowExtent,
+           "rowExtent: Wrong number of spanned rows at (" + rowIdx + ", " +
+           colIdx + ") for " + prettyName(aIdentifier));
+
+        is(cell.columnExtent, expectedColExtent,
+           "columnExtent: Wrong number of spanned column at (" + rowIdx + ", " +
+           colIdx + ") for " + prettyName(aIdentifier));
+      }
+    }
+  }
+}
+
+/**
  * Test table indexes.
  *
  * @param  aIdentifier  [in] table accessible identifier
  * @param  aIdxes       [in] two dimensional array of cell indexes
  */
 function testTableIndexes(aIdentifier, aIdxes)
 {
   var tableAcc = getAccessible(aIdentifier, [nsIAccessibleTable]);
@@ -25,237 +206,284 @@ function testTableIndexes(aIdentifier, a
   var id = prettyName(aIdentifier);
 
   var rowCount = aIdxes.length;
   for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
     var colCount = aIdxes[rowIdx].length;
     for (var colIdx = 0; colIdx < colCount; colIdx++) {
       var idx = aIdxes[rowIdx][colIdx];
 
-      // cellRefAt
+      // getCellAt
       try {
         cellAcc = null;
-        cellAcc = tableAcc.cellRefAt(rowIdx, colIdx);
+        cellAcc = tableAcc.getCellAt(rowIdx, colIdx);
       } catch (e) { }
-      
+
       ok(idx != -1 && cellAcc || idx == -1 && !cellAcc,
          id + ": Can't get cell accessible at row = " + rowIdx + ", column = " + colIdx);
 
       if (idx != - 1) {
+
         // getRowAtIndex
         var origRowIdx = rowIdx;
         while (origRowIdx > 0 &&
                aIdxes[rowIdx][colIdx] == aIdxes[origRowIdx - 1][colIdx])
           origRowIdx--;
 
         try {
-          obtainedRowIdx = tableAcc.getRowAtIndex(idx);
+          obtainedRowIdx = tableAcc.getRowIndexAt(idx);
         } catch (e) {
           ok(false, id + ": can't get row index for cell index " + idx + "," + e);
         }
 
         is(obtainedRowIdx, origRowIdx,
-           id + ": row  for index " + idx +" is not correct");
+           id + ": row for index " + idx +" is not correct");
 
         // getColumnAtIndex
         var origColIdx = colIdx;
         while (origColIdx > 0 &&
                aIdxes[rowIdx][colIdx] == aIdxes[rowIdx][origColIdx - 1])
           origColIdx--;
 
         try {
-          obtainedColIdx = tableAcc.getColumnAtIndex(idx);
+          obtainedColIdx = tableAcc.getColumnIndexAt(idx);
         } catch (e) {
           ok(false, id + ": can't get column index for cell index " + idx + "," + e);
         }
 
         is(obtainedColIdx, origColIdx,
            id + ": column  for index " + idx +" is not correct");
 
-        // 'table-cell-index' attribute
         if (cellAcc) {
+
+          var cellId = prettyName(cellAcc);
+          cellAcc = getAccessible(cellAcc, [nsIAccessibleTableCell]);
+
+          // cell: 'table-cell-index' attribute
           var attrs = cellAcc.attributes;
           var strIdx = "";
           try {
             strIdx = attrs.getStringProperty("table-cell-index");
           } catch (e) {
             ok(false,
-               id + ": no cell index from object attributes on the cell accessible at index " + idx + ".");
+               cellId + ": no cell index from object attributes on the cell accessible at index " + idx + ".");
           }
 
           if (strIdx) {
             is (parseInt(strIdx), idx,
-                id + ": cell index from object attributes of cell accessible isn't corrent.");
+                cellId + ": cell index from object attributes of cell accessible isn't corrent.");
+          }
+
+          // cell: table
+          try {
+            is(cellAcc.table, tableAcc,
+               cellId + ": wrong table accessible for the cell.");
+
+          } catch (e) {
+            ok(false,
+               cellId + ": can't get table accessible from the cell.");
           }
+
+          // cell: getRowIndex
+          try {
+            obtainedRowIdx = cellAcc.rowIndex;
+          } catch (e) {
+            ok(false,
+               cellId + ": can't get row index of the cell at index " + idx + "," + e);
+          }
+
+          is(obtainedRowIdx, origRowIdx,
+             cellId + ": row for the cell at index " + idx +" is not correct");
+
+          // cell: getColumnIndex
+          try {
+            obtainedColIdx = cellAcc.columnIndex;
+          } catch (e) {
+            ok(false,
+               cellId + ": can't get column index of the cell at index " + idx + "," + e);
+          }
+
+          is(obtainedColIdx, origColIdx,
+             id + ": column for the cell at index " + idx +" is not correct");
         }
       }
 
-      // getIndexAt
+      // getCellIndexAt
       try {
-        obtainedIdx = tableAcc.getIndexAt(rowIdx, colIdx);
+        obtainedIdx = tableAcc.getCellIndexAt(rowIdx, colIdx);
       } catch (e) {
         obtainedIdx = -1;
       }
 
       is(obtainedIdx, idx,
          id + ": row " + rowIdx + " /column " + colIdx + " and index " + obtainedIdx + " aren't inconsistent.");
     }
   }
 }
 
 /**
- * Constants used to describe cells states array. Values 0 and 1 are reserved
- * for boolean flag indicating the cell is origin and it is whether unselected
- * or selected.
- */
-const kRowSpanned = 2; // Indicates the cell is not origin and row spanned 
-const kColSpanned = 4; // Indicates the cell is not origin and column spanned
-const kSpanned = kRowSpanned | kColSpanned;
-
-/**
  * Test table getters selection methods.
  *
  * @param  aIdentifier  [in] table accessible identifier
  * @param  aCellsArray  [in] two dimensional array (row X columns) of cells
  *                       states (either boolean (selected/unselected) if cell is
- *                       origin, or one of constants defined above).
+ *                       origin, otherwise kRowSpanned or kColSpanned constant).
  * @param  aMsg         [in] text appended before every message
  */
 function testTableSelection(aIdentifier, aCellsArray, aMsg)
 {
   var msg = aMsg ? aMsg : "";
   var acc = getAccessible(aIdentifier, [nsIAccessibleTable]);
   if (!acc)
     return;
 
-  var rowsCount = aCellsArray.length;
+  var rowCount = aCellsArray.length;
   var colsCount = aCellsArray[0].length;
 
   // Columns selection tests.
   var selCols = new Array();
 
   // isColumnSelected test
   for (var colIdx = 0; colIdx < colsCount; colIdx++) {
     var isColSelected = true;
-    for (var rowIdx = 0; rowIdx < rowsCount; rowIdx++) {
+    for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
       if (aCellsArray[rowIdx][colIdx] == false) {
         isColSelected = false;
         break;
       }
     }
 
     is(acc.isColumnSelected(colIdx), isColSelected,
        msg + "Wrong selection state of " + colIdx + " column for " +
        prettyName(aIdentifier));
 
     if (isColSelected)
       selCols.push(colIdx);
   }
 
   // selectedColsCount test
-  is(acc.selectedColumnsCount, selCols.length,
+  is(acc.selectedcolumnCount, selCols.length,
      msg + "Wrong count of selected columns for " + prettyName(aIdentifier));
 
   // getSelectedColumns test
   var actualSelColsCountObj = { value: null };
-  var actualSelCols = acc.getSelectedColumns(actualSelColsCountObj);
+  var actualSelCols = acc.getSelectedColumnIndices(actualSelColsCountObj);
 
   var actualSelColsCount = actualSelColsCountObj.value;
   is (actualSelColsCount, selCols.length,
       msg + "Wrong count of selected columns for " + prettyName(aIdentifier) +
       "from getSelectedColumns.");
 
   for (var i = 0; i < actualSelColsCount; i++) {
     is (actualSelCols[i], selCols[i],
         msg + "Column at index " + selCols[i] + " should be selected.");
   }
 
   // Rows selection tests.
   var selRows = new Array();
 
   // isRowSelected test
-  var selRowsCount = 0;
-  for (var rowIdx = 0; rowIdx < rowsCount; rowIdx++) {
+  var selrowCount = 0;
+  for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
     var isRowSelected = true;
     for (var colIdx = 0; colIdx < colsCount; colIdx++) {
       if (aCellsArray[rowIdx][colIdx] == false) {
         isRowSelected = false;
         break;
       }
     }
 
     is(acc.isRowSelected(rowIdx), isRowSelected,
        msg + "Wrong selection state of " + rowIdx + " row for " +
        prettyName(aIdentifier));
 
     if (isRowSelected)
       selRows.push(rowIdx);
   }
 
-  // selectedRowsCount test
-  is(acc.selectedRowsCount, selRows.length,
+  // selectedrowCount test
+  is(acc.selectedrowCount, selRows.length,
      msg + "Wrong count of selected rows for " + prettyName(aIdentifier));
 
   // getSelectedRows test
-  var actualSelRowsCountObj = { value: null };
-  var actualSelRows = acc.getSelectedRows(actualSelRowsCountObj);
+  var actualSelrowCountObj = { value: null };
+  var actualSelRows = acc.getSelectedRowIndices(actualSelrowCountObj);
 
-  var actualSelRowsCount = actualSelRowsCountObj.value;
-  is (actualSelRowsCount, selRows.length,
+  var actualSelrowCount = actualSelrowCountObj.value;
+  is (actualSelrowCount, selRows.length,
       msg + "Wrong count of selected rows for " + prettyName(aIdentifier) +
       "from getSelectedRows.");
 
-  for (var i = 0; i < actualSelRowsCount; i++) {
+  for (var i = 0; i < actualSelrowCount; i++) {
     is (actualSelRows[i], selRows[i],
         msg + "Row at index " + selRows[i] + " should be selected.");
   }
 
   // Cells selection tests.
   var selCells = new Array();
 
   // isCellSelected test
-  for (var rowIdx = 0; rowIdx < rowsCount; rowIdx++) {
+  for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
     for (var colIdx = 0; colIdx < colsCount; colIdx++) {
-      if (!isOrigCell(aCellsArray[rowIdx][colIdx]))
+      if (aCellsArray[rowIdx][colIdx] & kSpanned)
         continue;
 
       is(acc.isCellSelected(rowIdx, colIdx), aCellsArray[rowIdx][colIdx],
          msg + "Wrong selection state of cell at " + rowIdx + " row and " +
          colIdx + " column for " + prettyName(aIdentifier));
 
       if (aCellsArray[rowIdx][colIdx])
-        selCells.push(acc.getIndexAt(rowIdx, colIdx));
+        selCells.push(acc.getCellIndexAt(rowIdx, colIdx));
     }
   }
 
-  // selectedCellsCount tests
-  is(acc.selectedCellsCount, selCells.length,
+  // selectedCellCount tests
+  is(acc.selectedCellCount, selCells.length,
      msg + "Wrong count of selected cells for " + prettyName(aIdentifier));
 
-  // getSelectedCells test
+  // getSelectedCellIndices test
   var actualSelCellsCountObj = { value: null };
-  var actualSelCells = acc.getSelectedCells(actualSelCellsCountObj);
+  var actualSelCells = acc.getSelectedCellIndices(actualSelCellsCountObj);
 
   var actualSelCellsCount = actualSelCellsCountObj.value;
-  is (actualSelCellsCount, selCells.length,
-      msg + "Wrong count of selected cells for " + prettyName(aIdentifier) +
-      "from getSelectedCells.");
+  is(actualSelCellsCount, selCells.length,
+     msg + "Wrong count of selected cells for " + prettyName(aIdentifier) +
+     "from getSelectedCells.");
 
   for (var i = 0; i < actualSelCellsCount; i++) {
-    is (actualSelCells[i], selCells[i],
-        msg + "Cell at index " + selCells[i] + " should be selected.");
+    is(actualSelCells[i], selCells[i],
+       msg + "getSelectedCellIndices: Cell at index " + selCells[i] +
+       " should be selected.");
+  }
+
+  // selectedCells and isSelected tests
+  var actualSelCellsArray = acc.selectedCells;
+  for (var i = 0; i < actualSelCellsCount; i++) {
+    var actualSelCellAccessible =
+      actualSelCellsArray.queryElementAt(i, nsIAccessibleTableCell);
+
+    var colIdx = acc.getColumnIndexAt(selCells[i]);
+    var rowIdx = acc.getRowIndexAt(selCells[i]);
+    var expectedSelCellAccessible = acc.getCellAt(rowIdx, colIdx);
+
+    ok(actualSelCellAccessible, expectedSelCellAccessible,
+       msg + "getSelectedCells: Cell at index " + selCells[i] +
+       " should be selected.");
+
+    ok(actualSelCellAccessible.isSelected(),
+       "isSelected: Cell at index " + selCells[i] + " should be selected.");
   }
 
   // selected states tests
-  for (var rowIdx = 0; rowIdx < rowsCount; rowIdx++) {
+  for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
     for (var colIdx = 0; colIdx < colsCount; colIdx++) {
-      if (!isOrigCell(aCellsArray[rowIdx][colIdx]))
+      if (aCellsArray[rowIdx][colIdx] & kSpanned)
         continue;
 
-      var cell = acc.cellRefAt(rowIdx, colIdx);
+      var cell = acc.getCellAt(rowIdx, colIdx);
       var isSel = aCellsArray[rowIdx][colIdx];
       if (isSel)
         testStates(cell, STATE_SELECTED);
       else
         testStates(cell, STATE_SELECTABLE, 0, STATE_SELECTED);
     }
   }
 }
@@ -264,18 +492,18 @@ function testTableSelection(aIdentifier,
  * Test unselectColumn method of accessible table.
  */
 function testUnselectTableColumn(aIdentifier, aColIdx, aCellsArray)
 {
   var acc = getAccessible(aIdentifier, [nsIAccessibleTable]);
   if (!acc)
     return;
 
-  var rowsCount = aCellsArray.length;
-  for (var rowIdx = 0; rowIdx < rowsCount; rowIdx++) {
+  var rowCount = aCellsArray.length;
+  for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
     var cellState = aCellsArray[rowIdx][aColIdx];
     // Unselect origin cell.
     var [origRowIdx, origColIdx] =
       getOrigRowAndColumn(aCellsArray, rowIdx, aColIdx);
     aCellsArray[origRowIdx][origColIdx] = false;
   }
 
   acc.unselectColumn(aColIdx);
@@ -287,51 +515,51 @@ function testUnselectTableColumn(aIdenti
  * Test selectColumn method of accessible table.
  */
 function testSelectTableColumn(aIdentifier, aColIdx, aCellsArray)
 {
   var acc = getAccessible(aIdentifier, [nsIAccessibleTable]);
   if (!acc)
     return;
 
-  var rowsCount = aCellsArray.length;
+  var rowCount = aCellsArray.length;
   var colsCount = aCellsArray[0].length;
 
-  for (var rowIdx = 0; rowIdx < rowsCount; rowIdx++) {
+  for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
     for (var colIdx = 0; colIdx < colsCount; colIdx++) {
       var cellState = aCellsArray[rowIdx][colIdx];
 
       if (colIdx == aColIdx) { // select target column
-        if (isOrigCell(cellState)) {
+        if (!(cellState & kSpanned)) {
           // Select the cell if it is origin.
           aCellsArray[rowIdx][colIdx] = true;
 
         } else {
           // If the cell is spanned then search origin cell and select it.
           var [origRowIdx, origColIdx] = getOrigRowAndColumn(aCellsArray,
                                                              rowIdx, colIdx);
           aCellsArray[origRowIdx][origColIdx] = true;
         }
 
-      } else if (isOrigCell(cellState)) { // unselect other columns
+      } else if (!(cellState & kSpanned)) { // unselect other columns
         if (colIdx > aColIdx) {
           // Unselect the cell if traversed column index is greater than column
           // index of target cell.
           aCellsArray[rowIdx][colIdx] = false;
 
-        } else if (!isColSpannedCell(aCellsArray[rowIdx][aColIdx])) {
+        } else if (!(aCellsArray[rowIdx][aColIdx] & kColSpanned)) {
           // Unselect the cell if the target cell is not row spanned.
           aCellsArray[rowIdx][colIdx] = false;
 
         } else {
           // Unselect the cell if it is not spanned to the target cell.
           for (var spannedColIdx = colIdx + 1; spannedColIdx < aColIdx;
                spannedColIdx++) {
             var spannedCellState = aCellsArray[rowIdx][spannedColIdx];
-            if (!isRowSpannedCell(spannedCellState)) {
+            if (!(spannedCellState & kRowSpanned)) {
               aCellsArray[rowIdx][colIdx] = false;
               break;
             }
           }
         }
       }
     }
   }
@@ -367,106 +595,144 @@ function testUnselectTableRow(aIdentifie
  * Test selectRow method of accessible table.
  */
 function testSelectTableRow(aIdentifier, aRowIdx, aCellsArray)
 {
   var acc = getAccessible(aIdentifier, [nsIAccessibleTable]);
   if (!acc)
     return;
 
-  var rowsCount = aCellsArray.length;
+  var rowCount = aCellsArray.length;
   var colsCount = aCellsArray[0].length;
 
-  for (var rowIdx = 0; rowIdx < rowsCount; rowIdx++) {
+  for (var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
     for (var colIdx = 0; colIdx < colsCount; colIdx++) {
       var cellState = aCellsArray[rowIdx][colIdx];
 
       if (rowIdx == aRowIdx) { // select the given row
-        if (isOrigCell(cellState)) {
+        if (!(cellState & kSpanned)) {
           // Select the cell if it is origin.
           aCellsArray[rowIdx][colIdx] = true;
 
         } else {
           // If the cell is spanned then search origin cell and select it.
           var [origRowIdx, origColIdx] = getOrigRowAndColumn(aCellsArray,
                                                              rowIdx, colIdx);
 
           aCellsArray[origRowIdx][origColIdx] = true;
         }
 
-      } else if (isOrigCell(cellState)) { // unselect other rows
+      } else if (!(cellState & kSpanned)) { // unselect other rows
         if (rowIdx > aRowIdx) {
           // Unselect the cell if traversed row index is greater than row
           // index of target cell.
           aCellsArray[rowIdx][colIdx] = false;
 
-        } else if (!isRowSpannedCell(aCellsArray[aRowIdx][colIdx])) {
+        } else if (!(aCellsArray[aRowIdx][colIdx] & kRowSpanned)) {
           // Unselect the cell if the target cell is not row spanned.
           aCellsArray[rowIdx][colIdx] = false;
 
         } else {
           // Unselect the cell if it is not spanned to the target cell.
           for (var spannedRowIdx = rowIdx + 1; spannedRowIdx < aRowIdx;
                spannedRowIdx++) {
             var spannedCellState = aCellsArray[spannedRowIdx][colIdx];
-            if (!isRowSpannedCell(spannedCellState)) {
+            if (!(spannedCellState & kRowSpanned)) {
               aCellsArray[rowIdx][colIdx] = false;
               break;
             }
           }
         }
       }
     }
   }
 
   acc.selectRow(aRowIdx);
   testTableSelection(aIdentifier, aCellsArray,
                      "Select " + aRowIdx + " row: ");
 }
 
+/**
+ * Test columnHeaderCells and rowHeaderCells of accessible table.
+ */
+function testHeaderCells(aHeaderInfoMap)
+{
+  for (var testIdx = 0; testIdx < aHeaderInfoMap.length; testIdx++) {
+    var dataCellIdentifier = aHeaderInfoMap[testIdx].cell;
+    var dataCell = getAccessible(dataCellIdentifier, [nsIAccessibleTableCell]);
+
+    // row header cells
+    var rowHeaderCells = aHeaderInfoMap[testIdx].rowHeaderCells;
+    var rowHeaderCellsCount = rowHeaderCells.length;
+    var actualRowHeaderCells = dataCell.rowHeaderCells;
+    var actualRowHeaderCellsCount = actualRowHeaderCells.length;
+
+    is(actualRowHeaderCellsCount, rowHeaderCellsCount,
+       "Wrong number of row header cells for the cell " +
+       prettyName(dataCellIdentifier));
+
+    if (actualRowHeaderCellsCount == rowHeaderCellsCount) {
+      for (var idx = 0; idx < rowHeaderCellsCount; idx++) {
+        var rowHeaderCell = getAccessible(rowHeaderCells[idx]);
+        var actualRowHeaderCell =
+          actualRowHeaderCells.queryElementAt(idx, nsIAccessible);
+        ok(actualRowHeaderCell, rowHeaderCell,
+           "Wrong row header cell at index " + idx + " for the cell " +
+           prettyName(rowHeaderCells[idx]));
+      }
+    }
+
+    // column header cells
+    var colHeaderCells = aHeaderInfoMap[testIdx].columnHeaderCells;
+    var colHeaderCellsCount = colHeaderCells.length;
+    var actualColHeaderCells = dataCell.columnHeaderCells;
+    var actualColHeaderCellsCount = actualColHeaderCells.length;
+
+    is(actualColHeaderCellsCount, colHeaderCellsCount,
+       "Wrong number of column header cells for the cell " +
+       prettyName(dataCellIdentifier));
+
+    if (actualColHeaderCellsCount == colHeaderCellsCount) {
+      for (var idx = 0; idx < colHeaderCellsCount; idx++) {
+        var colHeaderCell = getAccessible(colHeaderCells[idx]);
+        var actualColHeaderCell =
+          actualColHeaderCells.queryElementAt(idx, nsIAccessible);
+        ok(actualColHeaderCell, colHeaderCell,
+           "Wrong column header cell at index " + idx + " for the cell " +
+           prettyName(colHeaderCells[idx]));
+      }
+    }
+  }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // private implementation
 
 /**
  * Return row and column of orig cell for the given spanned cell.
  */
 function getOrigRowAndColumn(aCellsArray, aRowIdx, aColIdx)
 {
   var cellState = aCellsArray[aRowIdx][aColIdx];
 
   var origRowIdx = aRowIdx, origColIdx = aColIdx;
-  if (isRowSpannedCell(cellState)) {
+  if (cellState & kRowSpanned) {
     for (var prevRowIdx = aRowIdx - 1; prevRowIdx >= 0; prevRowIdx--) {
       var prevCellState = aCellsArray[prevRowIdx][aColIdx];
-      if (!isRowSpannedCell(prevCellState)) {
+      if (!(prevCellState & kRowSpanned)) {
         origRowIdx = prevRowIdx;
         break;
       }
     }
   }
 
-  if (isColSpannedCell(cellState)) {
+  if (cellState & kColSpanned) {
     for (var prevColIdx = aColIdx - 1; prevColIdx >= 0; prevColIdx--) {
       var prevCellState = aCellsArray[aRowIdx][prevColIdx];
-      if (!isColSpannedCell(prevCellState)) {
+      if (!(prevCellState & kColSpanned)) {
         origColIdx = prevColIdx;
         break;
       }
     }
   }
 
   return [origRowIdx, origColIdx];
 }
-
-function isOrigCell(aCellState)
-{
-  return !(aCellState & (kRowSpanned | kColSpanned));
-}
-
-function isRowSpannedCell(aCellState)
-{
-  return aCellState & kRowSpanned;
-}
-
-function isColSpannedCell(aCellState)
-{
-  return aCellState & kColSpanned;
-}
deleted file mode 100644
--- a/accessible/tests/mochitest/test_aria_role_grid.html
+++ /dev/null
@@ -1,146 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <title>ARIA grid based on HTML table tests</title>
-  <link rel="stylesheet" type="text/css"
-        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
-
-  <style>
-    td:focus {
-      background-color: lightblue;
-    }
-    th {
-      -moz-box-align: center;
-      -moz-box-pack: center;
-      border: 2px solid;
-      -moz-border-top-colors: ThreeDHighlight ThreeDLightShadow;
-      -moz-border-right-colors: ThreeDDarkShadow ThreeDShadow;
-      -moz-border-bottom-colors: ThreeDDarkShadow ThreeDShadow;
-      -moz-border-left-colors: ThreeDHighlight ThreeDLightShadow;
-      background-color: -moz-Dialog;
-      color: -moz-DialogText;
-      padding: 0px 4px;
-    }
-  </style>
-
-  <script type="application/javascript"
-          src="chrome://mochikit/content/MochiKit/packed.js"></script>
-  <script type="application/javascript"
-          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-
-  <script type="application/javascript"
-          src="chrome://mochikit/content/a11y/accessible/grid.js"></script>
-
-  <script type="application/javascript"
-          src="chrome://mochikit/content/a11y/accessible/common.js"></script>
-  <script type="application/javascript"
-          src="chrome://mochikit/content/a11y/accessible/role.js"></script>
-
-  <script type="application/javascript">
-    var gGrid = null;
-    function doTest()
-    {
-      gGrid = new grid("grid");
-
-      // Test accessible hierarchy of ARIA grid.
-      var accTree = {
-        role: ROLE_TABLE,
-        children: [
-          {
-            role: ROLE_TEXT_CONTAINER, // thead
-            children: [
-              {
-                role: ROLE_ROW,
-