Fix for bug 374390 - merge GetExtState into GetState by using two out params, r=evan.yan
authorsurkov.alexander@gmail.com
Mon, 02 Apr 2007 08:56:24 -0700
changeset 262 3ac8184e6eaf19f0adecdb90015a7494c216e92f
parent 261 51c0af3d48dcecbccb32ed1f1dac4a4be6d99c8b
child 263 c3e0a6bb84ddac5a90a640b3811f2535074dd7d4
push idunknown
push userunknown
push dateunknown
reviewersevan
bugs374390
milestone1.9a4pre
Fix for bug 374390 - merge GetExtState into GetState by using two out params, r=evan.yan
accessible/public/nsIAccessible.idl
accessible/src/atk/nsAccessibleWrap.cpp
accessible/src/atk/nsAppRootAccessible.cpp
accessible/src/atk/nsAppRootAccessible.h
accessible/src/atk/nsRootAccessibleWrap.cpp
accessible/src/base/nsAccessible.cpp
accessible/src/base/nsAccessible.h
accessible/src/base/nsBaseWidgetAccessible.cpp
accessible/src/base/nsBaseWidgetAccessible.h
accessible/src/base/nsCaretAccessible.cpp
accessible/src/base/nsCaretAccessible.h
accessible/src/base/nsDocAccessible.cpp
accessible/src/base/nsDocAccessible.h
accessible/src/base/nsOuterDocAccessible.cpp
accessible/src/base/nsOuterDocAccessible.h
accessible/src/base/nsRootAccessible.cpp
accessible/src/base/nsRootAccessible.h
accessible/src/html/nsHTMLFormControlAccessible.cpp
accessible/src/html/nsHTMLFormControlAccessible.h
accessible/src/html/nsHTMLImageAccessible.cpp
accessible/src/html/nsHTMLImageAccessible.h
accessible/src/html/nsHTMLLinkAccessible.cpp
accessible/src/html/nsHTMLLinkAccessible.h
accessible/src/html/nsHTMLSelectAccessible.cpp
accessible/src/html/nsHTMLSelectAccessible.h
accessible/src/html/nsHTMLTableAccessible.cpp
accessible/src/html/nsHTMLTableAccessible.h
accessible/src/html/nsHTMLTextAccessible.cpp
accessible/src/html/nsHTMLTextAccessible.h
accessible/src/html/nsHyperTextAccessible.cpp
accessible/src/html/nsHyperTextAccessible.h
accessible/src/mac/mozAccessible.mm
accessible/src/mac/mozTextAccessible.mm
accessible/src/msaa/nsAccessibleWrap.cpp
accessible/src/xforms/nsXFormsAccessible.cpp
accessible/src/xforms/nsXFormsAccessible.h
accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
accessible/src/xforms/nsXFormsFormControlsAccessible.h
accessible/src/xforms/nsXFormsWidgetsAccessible.cpp
accessible/src/xforms/nsXFormsWidgetsAccessible.h
accessible/src/xul/nsXULAlertAccessible.cpp
accessible/src/xul/nsXULAlertAccessible.h
accessible/src/xul/nsXULColorPickerAccessible.cpp
accessible/src/xul/nsXULColorPickerAccessible.h
accessible/src/xul/nsXULFormControlAccessible.cpp
accessible/src/xul/nsXULFormControlAccessible.h
accessible/src/xul/nsXULMenuAccessible.cpp
accessible/src/xul/nsXULMenuAccessible.h
accessible/src/xul/nsXULSelectAccessible.cpp
accessible/src/xul/nsXULSelectAccessible.h
accessible/src/xul/nsXULTabAccessible.cpp
accessible/src/xul/nsXULTabAccessible.h
accessible/src/xul/nsXULTextAccessible.cpp
accessible/src/xul/nsXULTextAccessible.h
accessible/src/xul/nsXULTreeAccessible.cpp
accessible/src/xul/nsXULTreeAccessible.h
--- a/accessible/public/nsIAccessible.idl
+++ b/accessible/public/nsIAccessible.idl
@@ -52,17 +52,17 @@ interface nsIDOMDOMStringList;
  * Can also be used by in-process accessibility clients to get information
  * about objects in the accessible tree. The accessible tree is a subset of 
  * nodes in the DOM tree -- such as documents, focusable elements and text.
  * Mozilla creates the implementations of nsIAccessible on demand.
  * See http://www.mozilla.org/projects/ui/accessibility for more information.
  *
  * @status UNDER_REVIEW
  */
-[scriptable, uuid(1f4ab23c-2878-4b26-9679-855f839d4542)]
+[scriptable, uuid(3494b81a-1d90-491a-be34-7893f8e27117)]
 interface nsIAccessible : nsISupports
 {
   /**
    * Parent node in accessible tree.
    */
   readonly attribute nsIAccessible parent;
 
   /**
@@ -149,26 +149,26 @@ interface nsIAccessible : nsISupports
   /**
    * Enumerated accessible role. The values depend on platform because of variations.
    * See the ROLE_* constants defined in nsIAccessibleRole.
    * Widgets can use role attribute to force the final role
    */
   readonly attribute unsigned long finalRole;
 
   /**
-   * Accessible states -- bit field which describes boolean properties of node. 
-   * See the STATE_* constants defined later in this file.
-   * Many states are only valid given a certain role attribute that supports them
+   * Accessible states -- bit fields which describe boolean properties of node.
+   * Many states are only valid given a certain role attribute that supports
+   * them.
+   *
+   * @param aState - the first bit field (see nsIAccessibleStates::STATE_*
+   *                 constants)
+   * @param aExtraState - the second bit field
+   *                      (see nsIAccessibleStates::EXT_STATE_* constants)
    */
-  readonly attribute unsigned long finalState;
-
-  /**
-   * Extended accessible states -- second bit field describing node
-   */
-  readonly attribute unsigned long extState;
+  void getFinalState(out unsigned long aState, out unsigned long aExtraState);
 
   /**
    * True if this element is live in an editor.
    * False if the content is being displayed but not edited. 
    */
   readonly attribute boolean isEditable;
 
   /**
--- a/accessible/src/atk/nsAccessibleWrap.cpp
+++ b/accessible/src/atk/nsAccessibleWrap.cpp
@@ -926,26 +926,21 @@ refStateSetCB(AtkObject *aAtkObj)
     AtkStateSet *state_set = nsnull;
     state_set = ATK_OBJECT_CLASS(parent_class)->ref_state_set(aAtkObj);
 
     NS_ENSURE_SUCCESS(CheckMaiAtkObject(aAtkObj), state_set);
     nsAccessibleWrap *accWrap =
         NS_REINTERPRET_CAST(MaiAtkObject*, aAtkObj)->accWrap;
 
     // Map states
-    PRUint32 accState;
-    nsresult rv = accWrap->GetFinalState(&accState);
-    NS_ENSURE_SUCCESS(rv, state_set);
-    TranslateStates(accState, gAtkStateMap, state_set);
-
-    // Map extended states
-    PRUint32 accExtState;
-    rv = accWrap->GetExtState(&accExtState);
+    PRUint32 accState = 0, accExtState = 0;
+    nsresult rv = accWrap->GetFinalState(&accState, &accExtState);
     NS_ENSURE_SUCCESS(rv, state_set);
 
+    TranslateStates(accState, gAtkStateMap, state_set);
     TranslateStates(accExtState, gAtkStateMapExt, state_set);
 
     // OFFSCREEN can live with INVISIBLE. However, SHOWING is no meaningful
     // with INVISIBLE.
     if (!atk_state_set_contains_state(state_set, ATK_STATE_VISIBLE)) {
       atk_state_set_remove_state(state_set, ATK_STATE_SHOWING);
     }
 
--- a/accessible/src/atk/nsAppRootAccessible.cpp
+++ b/accessible/src/atk/nsAppRootAccessible.cpp
@@ -620,16 +620,26 @@ NS_IMETHODIMP nsAppRootAccessible::GetRo
     return NS_OK;
 }
 
 NS_IMETHODIMP nsAppRootAccessible::GetFinalRole(PRUint32 *aFinalRole)
 {
     return GetRole(aFinalRole);
 }
 
+NS_IMETHODIMP
+nsAppRootAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
+{
+  *aState = 0;
+  if (aExtraState)
+    *aExtraState = 0;
+
+  return NS_OK;
+}
+
 NS_IMETHODIMP nsAppRootAccessible::GetParent(nsIAccessible **  aParent)
 {
     *aParent = nsnull;
     return NS_OK;
 }
 
 NS_IMETHODIMP nsAppRootAccessible::GetChildAt(PRInt32 aChildNum,
                                               nsIAccessible **aChild)
--- a/accessible/src/atk/nsAppRootAccessible.h
+++ b/accessible/src/atk/nsAppRootAccessible.h
@@ -74,16 +74,17 @@ public:
     /* virtual function from nsAccessNode */
     NS_IMETHOD Init();
 
     /* virtual functions from nsAccessible */
     NS_IMETHOD GetName(nsAString & aName);
     NS_IMETHOD GetDescription(nsAString & aDescription);
     NS_IMETHOD GetRole(PRUint32 *aRole);
     NS_IMETHOD GetFinalRole(PRUint32 *aFinalRole);
+    NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
     NS_IMETHOD GetParent(nsIAccessible * *aParent);
     NS_IMETHOD GetNextSibling(nsIAccessible * *aNextSibling);
     NS_IMETHOD GetPreviousSibling(nsIAccessible **aPreviousSibling);
     NS_IMETHOD GetChildAt(PRInt32 aChildNum, nsIAccessible **aChild);
 
     // return the atk object for app root accessible
     NS_IMETHOD GetNativeInterface(void **aOutAccessible);
 
--- a/accessible/src/atk/nsRootAccessibleWrap.cpp
+++ b/accessible/src/atk/nsRootAccessibleWrap.cpp
@@ -162,17 +162,17 @@ nsresult nsRootAccessibleWrap::HandleEve
         if (localName.EqualsIgnoreCase("radiogroup")) {
             // fire focus event for checked radio instead of radiogroup
             PRInt32 childCount = 0;
             accessible->GetChildCount(&childCount);
             nsCOMPtr<nsIAccessible> radioAcc;
             for (PRInt32 index = 0; index < childCount; index++) {
                 accessible->GetChildAt(index, getter_AddRefs(radioAcc));
                 if (radioAcc) {
-                    radioAcc->GetFinalState(&stateData.state);
+                    stateData.state = State(radioAcc);
                     if (stateData.state & (nsIAccessibleStates::STATE_CHECKED |
                         nsIAccessibleStates::STATE_SELECTED)) {
                         break;
                     }
                 }
             }
             accessible = radioAcc;
             if (radioAcc) {
@@ -202,32 +202,32 @@ nsresult nsRootAccessibleWrap::HandleEve
 #endif
         if (localName.LowerCaseEqualsLiteral("tabpanels")) {
             // make GOK refresh "UI-Grab" window
             privAcc->FireToolkitEvent(nsIAccessibleEvent::EVENT_REORDER, accessible, nsnull);
         }
     }
     else if (eventType.LowerCaseEqualsLiteral("checkboxstatechange") || // it's a XUL <checkbox>
              eventType.LowerCaseEqualsLiteral("radiostatechange")) { // it's a XUL <radio>
-        accessible->GetFinalState(&stateData.state);
+        stateData.state = State(accessible);
         // prefPane tab is implemented as list items in A11y, so we need to
         // check nsIAccessibleStates::STATE_SELECTED also
         stateData.enable = (stateData.state &
           (nsIAccessibleStates::STATE_CHECKED |
            nsIAccessibleStates::STATE_SELECTED)) != 0;
         stateData.state = nsIAccessibleStates::STATE_CHECKED;
         privAcc->FireToolkitEvent(nsIAccessibleEvent::EVENT_STATE_CHANGE, accessible, &stateData);
         // only fire focus event for checked radio
         if (eventType.LowerCaseEqualsLiteral("radiostatechange") &&
             stateData.enable) {
             FireAccessibleFocusEvent(accessible, aTargetNode, aEvent);
         }
     }
     else if (eventType.LowerCaseEqualsLiteral("openstatechange")) { // collapsed/expanded changed
-        accessible->GetFinalState(&stateData.state);
+        stateData.state = State(accessible);
         stateData.enable = (stateData.state & nsIAccessibleStates::STATE_EXPANDED) != 0;
         stateData.state = nsIAccessibleStates::STATE_EXPANDED;
         privAcc->FireToolkitEvent(nsIAccessibleEvent::EVENT_STATE_CHANGE, accessible, &stateData);
     }
     else if (eventType.LowerCaseEqualsLiteral("popuphiding")) {
         // If accessible focus was inside popup that closes,
         // then restore it to true current focus.
         // This is the case when we've been getting DOMMenuItemActive events
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -972,25 +972,31 @@ PRBool nsAccessible::IsVisible(PRBool *a
     GetParent(getter_AddRefs(parentAccessible));
     if (State(parentAccessible) & nsIAccessibleStates::STATE_OFFSCREEN) {
       *aIsOffscreen = PR_TRUE;
     }
   }
   return hasArea;
 }
 
-/* readonly attribute wstring state; */
-NS_IMETHODIMP nsAccessible::GetState(PRUint32 *aState) 
-{ 
+NS_IMETHODIMP
+nsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
+{
   *aState = 0;
 
+  if (aExtraState)
+    *aExtraState = 0;
+
+  if (!mDOMNode && aExtraState) {
+    *aExtraState = nsIAccessibleStates::EXT_STATE_DEFUNCT;
+    return NS_OK; // Node shut down
+  }
+
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
-  if (!content) {
-    return NS_ERROR_FAILURE;  // Node shut down
-  }
+  NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
 
   // Set STATE_UNAVAILABLE state based on disabled attribute
   // The disabled attribute is mostly used in XUL elements and HTML forms, but
   // if someone sets it on another attribute, 
   // it seems reasonable to consider it unavailable
   PRBool isDisabled;
   if (content->IsNodeOfType(nsINode::eHTML)) {
     // In HTML, just the presence of the disabled attribute means it is disabled,
@@ -1022,16 +1028,59 @@ NS_IMETHODIMP nsAccessible::GetState(PRU
   PRBool isOffscreen;
   if (!IsVisible(&isOffscreen)) {
     *aState |= nsIAccessibleStates::STATE_INVISIBLE;
   }
   if (isOffscreen) {
     *aState |= nsIAccessibleStates::STATE_OFFSCREEN;
   }
 
+  if (!aExtraState)
+    return NS_OK;
+
+  PRUint32 state = *aState;
+  nsresult rv = GetARIAState(&state);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsIFrame *frame = GetFrame();
+  if (frame) {
+    const nsStyleDisplay* display = frame->GetStyleDisplay();
+    if (display && display->mOpacity == 1.0f &&
+        !(state & nsIAccessibleStates::STATE_INVISIBLE)) {
+      *aExtraState |= nsIAccessibleStates::EXT_STATE_OPAQUE;
+    }
+
+    const nsStyleXUL *xulStyle = frame->GetStyleXUL();
+    if (xulStyle) {
+      // In XUL all boxes are either vertical or horizontal
+      *aExtraState |= (xulStyle->mBoxOrient == NS_STYLE_BOX_ORIENT_VERTICAL) ?
+        nsIAccessibleStates::EXT_STATE_VERTICAL :
+        nsIAccessibleStates::EXT_STATE_HORIZONTAL;
+    }
+  }
+
+  // XXX We can remove this hack once we support RDF-based role & state maps
+  if (mRoleMapEntry && (mRoleMapEntry->role == nsIAccessibleRole::ROLE_ENTRY ||
+      mRoleMapEntry->role == nsIAccessibleRole::ROLE_PASSWORD_TEXT)) {
+    PRBool isEqual =
+      NS_LITERAL_CSTRING("textarea").Equals(mRoleMapEntry->roleString);
+    *aExtraState =  isEqual? nsIAccessibleStates::EXT_STATE_MULTI_LINE :
+                             nsIAccessibleStates::EXT_STATE_SINGLE_LINE;
+  }
+
+  if (!(state & nsIAccessibleStates::STATE_UNAVAILABLE)) {  // If not disabled
+    *aExtraState |= nsIAccessibleStates::EXT_STATE_ENABLED |
+                    nsIAccessibleStates::EXT_STATE_SENSITIVE;
+  }
+
+  if (state & (nsIAccessibleStates::STATE_COLLAPSED |
+               nsIAccessibleStates::STATE_EXPANDED)) {
+    *aExtraState |= nsIAccessibleStates::EXT_STATE_EXPANDABLE;
+  }
+
   return NS_OK;
 }
 
   /* readonly attribute boolean focusedChild; */
 NS_IMETHODIMP nsAccessible::GetFocusedChild(nsIAccessible **aFocusedChild) 
 { 
   nsCOMPtr<nsIAccessible> focusedChild;
   if (gLastFocusedNode == mDOMNode) {
@@ -1070,17 +1119,17 @@ NS_IMETHODIMP nsAccessible::GetChildAtPo
   nsCOMPtr<nsIAccessible> childAtPoint;
   while (child) {
     child->GetBounds(&x, &y, &w, &h);
     if (tx >= x && tx < x + w && ty >= y && ty < y + h) {
       nsCOMPtr<nsPIAccessNode> accessNode(do_QueryInterface(child));
       if (accessNode) {
         nsIFrame *frame = accessNode->GetFrame();
         if (!frame) {
-          child->GetFinalState(&state);
+          state = State(child);
           // In some cases accessibles don't have a frame; examples are
           // tree items or combo box dropdown markers. For these cases
           // just ensure that the returned accessible is visible.
           if ((state & (nsIAccessibleStates::STATE_OFFSCREEN |
               nsIAccessibleStates::STATE_INVISIBLE)) == 0) {
             // Don't walk into offscreen or invisible items
             NS_IF_ADDREF(*aAccessible = child);
             return NS_OK;
@@ -1106,17 +1155,17 @@ NS_IMETHODIMP nsAccessible::GetChildAtPo
     child->GetNextSibling(getter_AddRefs(next));
     child = next;
   }
 
   if (childAtPoint) {
     NS_ADDREF(*aAccessible = childAtPoint);
     return NS_OK;
   }
-  GetState(&state);
+  GetState(&state, nsnull);
   GetBounds(&x, &y, &w, &h);
   if ((state & (nsIAccessibleStates::STATE_OFFSCREEN |
                 nsIAccessibleStates::STATE_INVISIBLE)) == 0 &&
       tx >= x && tx < x + w && ty >= y && ty < y + h) {
     *aAccessible = this;
     NS_ADDREF_THIS();
     return NS_OK;
   }
@@ -1275,47 +1324,45 @@ nsAccessible::GetMultiSelectFor(nsIDOMNo
     do_GetService("@mozilla.org/accessibilityService;1");
   NS_ENSURE_TRUE(accService, nsnull);
   nsCOMPtr<nsIAccessible> accessible;
   accService->GetAccessibleFor(aNode, getter_AddRefs(accessible));
   if (!accessible) {
     return nsnull;
   }
 
-  PRUint32 state;
-  accessible->GetFinalState(&state);
+  PRUint32 state = State(accessible);
   if (0 == (state & nsIAccessibleStates::STATE_SELECTABLE)) {
     return nsnull;
   }
 
   PRUint32 containerRole;
   while (0 == (state & nsIAccessibleStates::STATE_MULTISELECTABLE)) {
     nsIAccessible *current = accessible;
     current->GetParent(getter_AddRefs(accessible));
     if (!accessible || (NS_SUCCEEDED(accessible->GetFinalRole(&containerRole)) &&
                         containerRole == nsIAccessibleRole::ROLE_PANE)) {
       return nsnull;
     }
-    accessible->GetFinalState(&state);
+    state = State(accessible);
   }
   nsIAccessible *returnAccessible = nsnull;
   accessible.swap(returnAccessible);
   return returnAccessible;
 }
 
 /* void removeSelection (); */
 NS_IMETHODIMP nsAccessible::SetSelected(PRBool aSelect)
 {
   // Add or remove selection
   if (!mDOMNode) {
     return NS_ERROR_FAILURE;
   }
 
-  PRUint32 state;
-  GetFinalState(&state);
+  PRUint32 state = State(this);
   if (state & nsIAccessibleStates::STATE_SELECTABLE) {
     nsCOMPtr<nsIAccessible> multiSelect = GetMultiSelectFor(mDOMNode);
     if (!multiSelect) {
       return aSelect ? TakeFocus() : NS_ERROR_FAILURE;
     }
     nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
     NS_ASSERTION(content, "Called for dead accessible");
 
@@ -1333,18 +1380,17 @@ NS_IMETHODIMP nsAccessible::SetSelected(
 /* void takeSelection (); */
 NS_IMETHODIMP nsAccessible::TakeSelection()
 {
   // Select only this item
   if (!mDOMNode) {
     return NS_ERROR_FAILURE;
   }
 
-  PRUint32 state;
-  GetFinalState(&state);
+  PRUint32 state = State(this);
   if (state & nsIAccessibleStates::STATE_SELECTABLE) {
     nsCOMPtr<nsIAccessible> multiSelect = GetMultiSelectFor(mDOMNode);
     if (multiSelect) {
       nsCOMPtr<nsIAccessibleSelectable> selectable = do_QueryInterface(multiSelect);
       selectable->ClearSelection();
     }
     return SetSelected(PR_TRUE);
   }
@@ -2183,61 +2229,66 @@ PRBool nsAccessible::MappedAttrState(nsI
     if (NS_ConvertUTF16toUTF8(attribValue).Equals(aStateMapEntry->attributeValue)) {
       return *aStateInOut |= aStateMapEntry->state;
     }
   }
 
   return PR_TRUE;
 }
 
-NS_IMETHODIMP nsAccessible::GetFinalState(PRUint32 *aState)
+NS_IMETHODIMP
+nsAccessible::GetFinalState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  *aState = 0;
-  if (!mDOMNode) {
-    return NS_ERROR_FAILURE;  // Node already shut down
-  }
-  nsresult rv = GetState(aState);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
+  NS_ENSURE_ARG_POINTER(aState);
+
+  nsresult rv = GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // Apply ARIA states to be sure accessible states will be overriden.
+  return GetARIAState(aState);
+}
+
+nsresult
+nsAccessible::GetARIAState(PRUint32 *aState)
+{
+  NS_ENSURE_TRUE(mDOMNode, NS_ERROR_FAILURE); // Node already shut down
 
   // Test for universal states first
   nsIContent *content = GetRoleContent(mDOMNode);
-  if (!content) {
-    return NS_ERROR_FAILURE;  // Node already shut down
-  }
-  for (PRUint32 index = 0; index < NS_ARRAY_LENGTH(gUnivStateMap); index ++) {
-    MappedAttrState(content, aState, &gUnivStateMap[index]);
+  NS_ENSURE_TRUE(content, NS_ERROR_FAILURE); // Node already shut down
+
+  PRUint32 length = NS_ARRAY_LENGTH(nsAccessible::gUnivStateMap);
+  for (PRUint32 index = 0; index < length; index++) {
+    MappedAttrState(content, aState, &nsAccessible::gUnivStateMap[index]);
   }
-  if (!mRoleMapEntry) {
-    return rv;
-  }
-
-  PRUint32 finalState = *aState;
+
+  if (!mRoleMapEntry)
+    return NS_OK;
+
   // Once DHTML role is used, we're only readonly if DHTML readonly used
-  finalState &= ~nsIAccessibleStates::STATE_READONLY;
-
-  if (finalState & nsIAccessibleStates::STATE_UNAVAILABLE) {
+  (*aState) &= ~nsIAccessibleStates::STATE_READONLY;
+
+  if ((*aState) & nsIAccessibleStates::STATE_UNAVAILABLE) {
     // Disabled elements are not selectable or focusable, even if disabled
     // via DHTML accessibility disabled property
-    finalState &= ~(nsIAccessibleStates::STATE_SELECTABLE | nsIAccessibleStates::STATE_FOCUSABLE);
+    (*aState) &= ~(nsIAccessibleStates::STATE_SELECTABLE |
+                   nsIAccessibleStates::STATE_FOCUSABLE);
   }
 
-  finalState |= mRoleMapEntry->state;
-  if (MappedAttrState(content, &finalState, &mRoleMapEntry->attributeMap1) &&
-      MappedAttrState(content, &finalState, &mRoleMapEntry->attributeMap2) &&
-      MappedAttrState(content, &finalState, &mRoleMapEntry->attributeMap3) &&
-      MappedAttrState(content, &finalState, &mRoleMapEntry->attributeMap4) &&
-      MappedAttrState(content, &finalState, &mRoleMapEntry->attributeMap5) &&
-      MappedAttrState(content, &finalState, &mRoleMapEntry->attributeMap6)) {
-    MappedAttrState(content, &finalState, &mRoleMapEntry->attributeMap7);
+  (*aState) |= mRoleMapEntry->state;
+  if (MappedAttrState(content, aState, &mRoleMapEntry->attributeMap1) &&
+      MappedAttrState(content, aState, &mRoleMapEntry->attributeMap2) &&
+      MappedAttrState(content, aState, &mRoleMapEntry->attributeMap3) &&
+      MappedAttrState(content, aState, &mRoleMapEntry->attributeMap4) &&
+      MappedAttrState(content, aState, &mRoleMapEntry->attributeMap5) &&
+      MappedAttrState(content, aState, &mRoleMapEntry->attributeMap6)) {
+    MappedAttrState(content, aState, &mRoleMapEntry->attributeMap7);
   }
 
-  *aState = finalState;
-  return rv;
+  return NS_OK;
 }
 
 // Not implemented by this class
 
 /* DOMString getValue (); */
 NS_IMETHODIMP nsAccessible::GetValue(nsAString& aValue)
 {
   if (!mDOMNode) {
@@ -2335,18 +2386,17 @@ NS_IMETHODIMP nsAccessible::SetCurrentVa
   }
   if (mRoleMapEntry) {
     if (mRoleMapEntry->valueRule == eNoValue) {
       return NS_OK;
     }
     const PRUint32 kValueCannotChange = nsIAccessibleStates::STATE_READONLY |
                                         nsIAccessibleStates::STATE_UNAVAILABLE;
 
-    PRUint32 state;
-    if (NS_FAILED(GetFinalState(&state)) || (state & kValueCannotChange)) {
+    if (State(this) & kValueCannotChange) {
       return NS_ERROR_FAILURE;
     }
     double minValue;
     if (NS_SUCCEEDED(GetMinimumValue(&minValue)) && aValue < minValue) {
       return NS_ERROR_INVALID_ARG;
     }
     double maxValue;
     if (NS_SUCCEEDED(GetMaximumValue(&maxValue)) && aValue > maxValue) {
@@ -2665,64 +2715,16 @@ NS_IMETHODIMP nsAccessible::GetAccessibl
 
 /* void extendSelection (); */
 NS_IMETHODIMP nsAccessible::ExtendSelection()
 {
   // XXX Should be implemented, but not high priority
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
-/* unsigned long getExtState (); */
-NS_IMETHODIMP nsAccessible::GetExtState(PRUint32 *aExtState)
-{
-  *aExtState = 0;
-
-  if (!mDOMNode) {
-    *aExtState = nsIAccessibleStates::EXT_STATE_DEFUNCT;
-    return NS_OK; // Node shut down
-  }
-  nsIFrame *frame = GetFrame();
-  if (frame) {
-    const nsStyleDisplay* display = frame->GetStyleDisplay();
-    if (display && display->mOpacity == 1.0f &&
-        !(State(this) & nsIAccessibleStates::STATE_INVISIBLE)) {
-      *aExtState |= nsIAccessibleStates::EXT_STATE_OPAQUE;
-    }
-    const nsStyleXUL *xulStyle = frame->GetStyleXUL();
-    if (xulStyle) {
-      // In XUL all boxes are either vertical or horizontal
-      *aExtState |= (xulStyle->mBoxOrient == NS_STYLE_BOX_ORIENT_VERTICAL) ?
-        nsIAccessibleStates::EXT_STATE_VERTICAL :
-        nsIAccessibleStates::EXT_STATE_HORIZONTAL;
-    }
-  }
-
-  // XXX We can remove this hack once we support RDF-based role & state maps
-  if (mRoleMapEntry && (mRoleMapEntry->role == nsIAccessibleRole::ROLE_ENTRY ||
-      mRoleMapEntry->role == nsIAccessibleRole::ROLE_PASSWORD_TEXT)) {
-    *aExtState = NS_LITERAL_CSTRING("textarea").Equals(mRoleMapEntry->roleString) ? 
-       nsIAccessibleStates::EXT_STATE_MULTI_LINE :
-       nsIAccessibleStates::EXT_STATE_SINGLE_LINE;
-  }
-
-  PRUint32 state ;
-  GetFinalState(&state);
-  if (0 == (state & nsIAccessibleStates::STATE_UNAVAILABLE)) {  // If not disabled
-    *aExtState |= nsIAccessibleStates::EXT_STATE_ENABLED |
-                  nsIAccessibleStates::EXT_STATE_SENSITIVE;
-  }
-
-  if (state & (nsIAccessibleStates::STATE_COLLAPSED |
-      nsIAccessibleStates::STATE_EXPANDED)) {
-    *aExtState |= nsIAccessibleStates::EXT_STATE_EXPANDABLE;
-  }
-
-  return NS_OK;
-}
-
 NS_IMETHODIMP nsAccessible::GetIsEditable(PRBool *aIsEditable)
 {
   *aIsEditable = PR_FALSE;
   return NS_OK;
 }
 
 /* [noscript] void getNativeInterface(out voidPtr aOutAccessible); */
 NS_IMETHODIMP nsAccessible::GetNativeInterface(void **aOutAccessible)
@@ -2817,17 +2819,17 @@ nsAccessible::GetNextWithState(nsIAccess
       current->GetNextSibling(getter_AddRefs(look));
       if (!look) {
         current->GetParent(getter_AddRefs(look));
         current.swap(look);
         continue;
       }
     }
     current.swap(look);
-    current->GetFinalState(&state);
+    state = State(current);
   }
 
   nsIAccessible *returnAccessible = nsnull;
   current.swap(returnAccessible);
 
   return returnAccessible;
 }
 
@@ -2891,20 +2893,17 @@ NS_IMETHODIMP nsAccessible::AddChildToSe
   // implement a selection methods for their specific interfaces, because being
   // able to deal with selection on a per-child basis would not be enough.
 
   NS_ENSURE_TRUE(aIndex >= 0, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIAccessible> child;
   GetChildAt(aIndex, getter_AddRefs(child));
 
-  PRUint32 state;
-  nsresult rv = child->GetFinalState(&state);
-  NS_ENSURE_SUCCESS(rv, rv);
-
+  PRUint32 state = State(child);
   if (!(state & nsIAccessibleStates::STATE_SELECTABLE)) {
     return NS_OK;
   }
 
   return child->SetSelected(PR_TRUE);
 }
 
 NS_IMETHODIMP nsAccessible::RemoveChildFromSelection(PRInt32 aIndex)
@@ -2913,20 +2912,17 @@ NS_IMETHODIMP nsAccessible::RemoveChildF
   // implement a selection methods for their specific interfaces, because being
   // able to deal with selection on a per-child basis would not be enough.
 
   NS_ENSURE_TRUE(aIndex >= 0, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIAccessible> child;
   GetChildAt(aIndex, getter_AddRefs(child));
 
-  PRUint32 state;
-  nsresult rv = child->GetFinalState(&state);
-  NS_ENSURE_SUCCESS(rv, rv);
-
+  PRUint32 state = State(child);
   if (!(state & nsIAccessibleStates::STATE_SELECTED)) {
     return NS_OK;
   }
 
   return child->SetSelected(PR_FALSE);
 }
 
 NS_IMETHODIMP nsAccessible::IsChildSelected(PRInt32 aIndex, PRBool *aIsSelected)
@@ -2936,20 +2932,17 @@ NS_IMETHODIMP nsAccessible::IsChildSelec
   // able to deal with selection on a per-child basis would not be enough.
 
   *aIsSelected = PR_FALSE;
   NS_ENSURE_TRUE(aIndex >= 0, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIAccessible> child;
   GetChildAt(aIndex, getter_AddRefs(child));
 
-  PRUint32 state;
-  nsresult rv = child->GetFinalState(&state);
-  NS_ENSURE_SUCCESS(rv, rv);
-
+  PRUint32 state = State(child);
   if (state & nsIAccessibleStates::STATE_SELECTED) {
     *aIsSelected = PR_TRUE;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP nsAccessible::ClearSelection()
 {
@@ -3010,18 +3003,17 @@ NS_IMETHODIMP nsAccessible::GetObject(PR
   *aAccessible = this;
   NS_ADDREF_THIS();
   return NS_OK;
 }
 
 // nsIAccessibleHyperLink::IsValid()
 NS_IMETHODIMP nsAccessible::IsValid(PRBool *aIsValid)
 {
-  PRUint32 state;
-  GetFinalState(&state);
+  PRUint32 state = State(this);
   *aIsValid = (state & nsIAccessibleStates::STATE_INVALID) != 0;
   // XXX In order to implement this we would need to follow every link
   // Perhaps we can get information about invalid links from the cache
   // In the mean time authors can use role="wairole:link" aaa:invalid="true"
   // to force it for links they internally know to be invalid
   return NS_OK;
 }
 
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -153,29 +153,42 @@ public:
   NS_DECL_NSIACCESSIBLEHYPERLINK
   NS_DECL_NSIACCESSIBLESELECTABLE
   NS_DECL_NSIACCESSIBLEVALUE
 
   // nsIAccessNode
   NS_IMETHOD Init();
   NS_IMETHOD Shutdown();
 
-  NS_IMETHOD GetState(PRUint32 *aState);  // Must support GetFinalState()
+  /**
+   * Return the state of accessible that doesn't take into account ARIA states.
+   * Use nsIAccessible::finalState() to get all states for accessible. If
+   * second argument is omitted then second bit field of accessible state won't
+   * be calculated.
+   */
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
+
+  /**
+   * Maps ARIA state attributes to state of accessible. Note the given state
+   * argument should hold states for accessible before you pass it into this
+   * method.
+   */
+  nsresult GetARIAState(PRUint32 *aState);
 
 #ifdef MOZ_ACCESSIBILITY_ATK
   static PRBool FindTextFrame(PRInt32 &index, nsPresContext *aPresContext, nsIFrame *aCurFrame, 
                                    nsIFrame **aFirstTextFrame, const nsIFrame *aTextFrame);
 #endif
 
 #ifdef DEBUG_A11Y
   static PRBool IsTextInterfaceSupportCorrect(nsIAccessible *aAccessible);
 #endif
 
   static PRBool IsCorrectFrameType(nsIFrame* aFrame, nsIAtom* aAtom);
-  static PRUint32 State(nsIAccessible *aAcc) { PRUint32 state; aAcc->GetFinalState(&state); return state; }
+  static PRUint32 State(nsIAccessible *aAcc) { PRUint32 state; aAcc->GetFinalState(&state, nsnull); return state; }
   static PRUint32 Role(nsIAccessible *aAcc) { PRUint32 role; aAcc->GetFinalRole(&role); return role; }
   static PRBool IsText(nsIAccessible *aAcc) { PRUint32 role = Role(aAcc); return role == nsIAccessibleRole::ROLE_TEXT_LEAF || role == nsIAccessibleRole::ROLE_STATICTEXT; }
   static PRBool IsEmbeddedObject(nsIAccessible *aAcc) { PRUint32 role = Role(aAcc); return role != nsIAccessibleRole::ROLE_TEXT_LEAF && role != nsIAccessibleRole::ROLE_WHITESPACE && role != nsIAccessibleRole::ROLE_STATICTEXT; }
   static PRInt32 TextLength(nsIAccessible *aAccessible);
   static PRBool IsLeaf(nsIAccessible *aAcc) { PRInt32 numChildren; aAcc->GetChildCount(&numChildren); return numChildren > 0; }
   
   already_AddRefed<nsIAccessible> GetParent() {
     nsIAccessible *parent = nsnull;
--- a/accessible/src/base/nsBaseWidgetAccessible.cpp
+++ b/accessible/src/base/nsBaseWidgetAccessible.cpp
@@ -110,37 +110,39 @@ NS_IMETHODIMP nsLinkableAccessible::Take
   if (mActionContent && mActionContent->IsFocusable()) {
     mActionContent->SetFocus(nsCOMPtr<nsPresContext>(GetPresContext()));
   }
   
   return NS_OK;
 }
 
 /* long GetState (); */
-NS_IMETHODIMP nsLinkableAccessible::GetState(PRUint32 *aState)
+NS_IMETHODIMP
+nsLinkableAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsHyperTextAccessible::GetState(aState);
+  nsresult rv = nsHyperTextAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   if (mIsLink) {
     *aState |= nsIAccessibleStates::STATE_LINKED;
     nsCOMPtr<nsILink> link = do_QueryInterface(mActionContent);
     if (link) {
       nsLinkState linkState;
       link->GetLinkState(linkState);
       if (linkState == eLinkState_Visited) {
         *aState |= nsIAccessibleStates::STATE_TRAVERSED;
       }
     }
     // Make sure we also include all the states of the parent link, such as focusable, focused, etc.
     PRUint32 role;
     GetRole(&role);
     if (role != nsIAccessibleRole::ROLE_LINK) {
       nsCOMPtr<nsIAccessible> parentAccessible(GetParent());
       if (parentAccessible) {
-        PRUint32 orState = 0;
-        parentAccessible->GetFinalState(&orState);
+        PRUint32 orState = State(parentAccessible);
         *aState |= orState;
       }
     }
   }
   if (mActionContent && !mActionContent->IsFocusable()) {
     // Links must have href or tabindex
     *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;
   }
--- a/accessible/src/base/nsBaseWidgetAccessible.h
+++ b/accessible/src/base/nsBaseWidgetAccessible.h
@@ -75,17 +75,17 @@ class nsLinkableAccessible : public nsHy
 public:
   enum { eAction_Jump = 0 };
 
   nsLinkableAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_DECL_ISUPPORTS_INHERITED
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 index);
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetValue(nsAString& _retval);
   NS_IMETHOD TakeFocus();
   NS_IMETHOD GetKeyboardShortcut(nsAString& _retval);
   NS_IMETHOD GetURI(PRInt32 i, nsIURI **aURI);
   NS_IMETHOD Init();
   NS_IMETHOD Shutdown();
 
 protected:
--- a/accessible/src/base/nsCaretAccessible.cpp
+++ b/accessible/src/base/nsCaretAccessible.cpp
@@ -223,19 +223,23 @@ NS_IMETHODIMP nsCaretAccessible::GetBoun
 }
 
 NS_IMETHODIMP nsCaretAccessible::GetRole(PRUint32 *_retval)
 {
   *_retval = nsIAccessibleRole::ROLE_CARET;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsCaretAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsCaretAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  *_retval = mVisible? 0: nsIAccessibleStates::STATE_INVISIBLE;
+  if (aExtraState)
+    *aExtraState = 0;
+
+  *aState = mVisible? 0: nsIAccessibleStates::STATE_INVISIBLE;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsCaretAccessible::GetParent(nsIAccessible **aParent)
 {   
   NS_ADDREF(*aParent = mRootAccessible);
   return NS_OK;
 }
--- a/accessible/src/base/nsCaretAccessible.h
+++ b/accessible/src/base/nsCaretAccessible.h
@@ -61,17 +61,17 @@ class nsCaretAccessible : public nsLeafA
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
   nsCaretAccessible(nsIDOMNode* aDocumentNode, nsIWeakReference* aShell, nsRootAccessible *aRootAccessible);
 
   /* ----- nsIAccessible ----- */
   NS_IMETHOD GetParent(nsIAccessible **_retval);
   NS_IMETHOD GetRole(PRUint32 *_retval);
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height);
   NS_IMETHOD GetNextSibling(nsIAccessible **_retval);
   NS_IMETHOD GetPreviousSibling(nsIAccessible **_retval);
 
   /* ----- nsIAccessibleCaret ------ */
   NS_IMETHOD AttachNewSelectionListener(nsIDOMNode *aFocusedNode);
   NS_IMETHOD RemoveSelectionListener();
 
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -191,22 +191,22 @@ NS_IMETHODIMP nsDocAccessible::GetRole(P
   return NS_OK;
 }
 
 NS_IMETHODIMP nsDocAccessible::GetValue(nsAString& aValue)
 {
   return GetURL(aValue);
 }
 
-NS_IMETHODIMP nsDocAccessible::GetState(PRUint32 *aState)
+NS_IMETHODIMP
+nsDocAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  if (!mDOMNode) {
-    return NS_ERROR_FAILURE;
-  }
-  nsAccessible::GetState(aState);
+  // nsAccessible::GetState() always fail for document accessible.
+  nsAccessible::GetState(aState, aExtraState);
+
   *aState |= nsIAccessibleStates::STATE_FOCUSABLE;
 
   if (!mIsContentLoaded) {
     *aState |= nsIAccessibleStates::STATE_BUSY;
   }
  
   nsIFrame* frame = GetFrame();
   while (frame != nsnull && !frame->HasView()) {
--- a/accessible/src/base/nsDocAccessible.h
+++ b/accessible/src/base/nsDocAccessible.h
@@ -73,17 +73,17 @@ class nsDocAccessible : public nsHyperTe
 
   public:
     nsDocAccessible(nsIDOMNode *aNode, nsIWeakReference* aShell);
     virtual ~nsDocAccessible();
 
     NS_IMETHOD GetRole(PRUint32 *aRole);
     NS_IMETHOD GetName(nsAString& aName);
     NS_IMETHOD GetValue(nsAString& aValue);
-    NS_IMETHOD GetState(PRUint32 *aState);
+    NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
     NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
     NS_IMETHOD GetParent(nsIAccessible **aParent);
     NS_IMETHOD TakeFocus(void);
 
     // ----- nsIScrollPositionListener ---------------------------
     NS_IMETHOD ScrollPositionWillChange(nsIScrollableView *aView, nscoord aX, nscoord aY);
     NS_IMETHOD ScrollPositionDidChange(nsIScrollableView *aView, nscoord aX, nscoord aY);
 
--- a/accessible/src/base/nsOuterDocAccessible.cpp
+++ b/accessible/src/base/nsOuterDocAccessible.cpp
@@ -71,19 +71,20 @@ NS_IMETHODIMP nsOuterDocAccessible::GetN
 
 /* unsigned long getRole (); */
 NS_IMETHODIMP nsOuterDocAccessible::GetRole(PRUint32 *aRole)
 {
   *aRole = nsIAccessibleRole::ROLE_CLIENT;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsOuterDocAccessible::GetState(PRUint32 *aState)
+NS_IMETHODIMP
+nsOuterDocAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsAccessible::GetState(aState);
+  nsAccessible::GetState(aState, aExtraState);
   *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;
   return NS_OK;
 }
 
 void nsOuterDocAccessible::CacheChildren()
 {  
   // An outer doc accessible usually has 1 nsDocAccessible child,
   // but could have none if we can't get to the inner documnet
--- a/accessible/src/base/nsOuterDocAccessible.h
+++ b/accessible/src/base/nsOuterDocAccessible.h
@@ -49,13 +49,13 @@ class nsOuterDocAccessible : public nsAc
   NS_DECL_ISUPPORTS_INHERITED
 
   public:
     nsOuterDocAccessible(nsIDOMNode* aNode, 
                          nsIWeakReference* aShell);
 
     NS_IMETHOD GetName(nsAString& aName);
     NS_IMETHOD GetRole(PRUint32 *aRole);
-    NS_IMETHOD GetState(PRUint32 *aState);
+    NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
     void CacheChildren();
 };
 
 #endif  
--- a/accessible/src/base/nsRootAccessible.cpp
+++ b/accessible/src/base/nsRootAccessible.cpp
@@ -191,25 +191,21 @@ PRUint32 nsRootAccessible::GetChromeFlag
     return 0;
   }
   PRUint32 chromeFlags;
   xulWin->GetChromeFlags(&chromeFlags);
   return chromeFlags;
 }
 #endif
 
-NS_IMETHODIMP nsRootAccessible::GetState(PRUint32 *aState) 
+NS_IMETHODIMP
+nsRootAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsresult rv = NS_ERROR_FAILURE;
-  if (mDOMNode) {
-    rv = nsDocAccessibleWrap::GetState(aState);
-  }
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
+  nsresult rv = nsDocAccessibleWrap::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   NS_ASSERTION(mDocument, "mDocument should not be null unless mDOMNode is");
   if (gLastFocusedNode) {
     nsCOMPtr<nsIDOMDocument> rootAccessibleDoc(do_QueryInterface(mDocument));
     nsCOMPtr<nsIDOMDocument> focusedDoc;
     gLastFocusedNode->GetOwnerDocument(getter_AddRefs(focusedDoc));
     if (rootAccessibleDoc == focusedDoc) {
       *aState |= nsIAccessibleStates::STATE_FOCUSED;
@@ -224,38 +220,34 @@ NS_IMETHODIMP nsRootAccessible::GetState
   if (chromeFlags & nsIWebBrowserChrome::CHROME_TITLEBAR) {
     // If it has a titlebar it's movable
     // XXX unless it's minimized or maximized, but not sure
     //     how to detect that
     *aState |= nsIAccessibleStates::STATE_MOVEABLE;
   }
 #endif
 
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsRootAccessible::GetExtState(PRUint32 *aExtState)
-{
-  nsDocAccessibleWrap::GetExtState(aExtState);
+  if (!aExtraState)
+    return NS_OK;
 
   nsCOMPtr<nsIDOMWindow> domWin;
   GetWindow(getter_AddRefs(domWin));
   nsCOMPtr<nsPIDOMWindow> privateDOMWindow(do_QueryInterface(domWin));
   if (privateDOMWindow) {
     nsIFocusController *focusController =
       privateDOMWindow->GetRootFocusController();
     PRBool isActive = PR_FALSE;
     focusController->GetActive(&isActive);
     if (isActive) {
-      *aExtState |= nsIAccessibleStates::EXT_STATE_ACTIVE;
+      *aExtraState |= nsIAccessibleStates::EXT_STATE_ACTIVE;
     }
   }
 #ifdef MOZ_XUL
   if (GetChromeFlags() & nsIWebBrowserChrome::CHROME_MODAL) {
-    *aExtState |= nsIAccessibleStates::EXT_STATE_MODAL;
+    *aExtraState |= nsIAccessibleStates::EXT_STATE_MODAL;
   }
 #endif
 
   return NS_OK;
 }
 
 void
 nsRootAccessible::GetChromeEventHandler(nsIDOMEventTarget **aChromeTarget)
@@ -420,18 +412,17 @@ void nsRootAccessible::TryFireEarlyLoadE
   if (rootContentTreeItem != treeItem) {
     nsCOMPtr<nsIAccessibleDocument> rootContentDocAccessible =
       GetDocAccessibleFor(rootContentTreeItem);
     nsCOMPtr<nsIAccessible> rootContentAccessible =
       do_QueryInterface(rootContentDocAccessible);
     if (!rootContentAccessible) {
       return;
     }
-    PRUint32 state;
-    rootContentAccessible->GetFinalState(&state);
+    PRUint32 state = State(rootContentAccessible);
     if (state & nsIAccessibleStates::STATE_BUSY) {
       // Don't fire page load events on subdocuments for initial page load of entire page
       return;
     }
   }
 
   // No frames or iframes, so we can fire the doc load finished event early
   FireDelayedToolkitEvent(nsIAccessibleEvent::EVENT_INTERNAL_LOAD, aDocNode,
@@ -767,18 +758,17 @@ nsresult nsRootAccessible::HandleEventWi
   }
   else if (eventType.EqualsLiteral("AlertActive")) { 
     privAcc->FireToolkitEvent(nsIAccessibleEvent::EVENT_ALERT, 
                               accessible, nsnull);
   }
   else if (eventType.LowerCaseEqualsLiteral("radiostatechange") ) {
     privAcc->FireToolkitEvent(nsIAccessibleEvent::EVENT_STATE_CHANGE, 
                               accessible, nsnull);
-    PRUint32 finalState;
-    accessible->GetFinalState(&finalState);
+    PRUint32 finalState = State(accessible);
     if (finalState & (nsIAccessibleStates::STATE_CHECKED |
         nsIAccessibleStates::STATE_SELECTED)) {
       FireAccessibleFocusEvent(accessible, aTargetNode, aEvent);
     }
   }
   else if (eventType.LowerCaseEqualsLiteral("popuphiding")) {
     // If accessible focus was inside popup that closes,
     // then restore it to true current focus.
--- a/accessible/src/base/nsRootAccessible.h
+++ b/accessible/src/base/nsRootAccessible.h
@@ -65,18 +65,17 @@ class nsRootAccessible : public nsDocAcc
 
   public:
     nsRootAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell);
     virtual ~nsRootAccessible();
 
     NS_IMETHOD GetName(nsAString& aName);
     NS_IMETHOD GetParent(nsIAccessible * *aParent);
     NS_IMETHOD GetRole(PRUint32 *aRole);
-    NS_IMETHOD GetState(PRUint32 *aState);
-    NS_IMETHOD GetExtState(PRUint32 *aExtState);
+    NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
     NS_IMETHOD GetAccessibleRelated(PRUint32 aRelationType,
                                     nsIAccessible **aRelated);
 
     // ----- nsPIAccessibleDocument -----------------------
     NS_IMETHOD FireDocLoadEvents(PRUint32 aEventType);
 
     // ----- nsIDOMEventListener --------------------------
     NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
--- a/accessible/src/html/nsHTMLFormControlAccessible.cpp
+++ b/accessible/src/html/nsHTMLFormControlAccessible.cpp
@@ -70,17 +70,17 @@ NS_IMETHODIMP nsHTMLCheckboxAccessible::
   return NS_OK;
 }
 
 NS_IMETHODIMP nsHTMLCheckboxAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
 {
   if (aIndex == eAction_Click) {    // 0 is the magic value for default action
     // check or uncheck
     PRUint32 state;
-    GetState(&state);
+    GetState(&state, nsnull);
 
     if (state & nsIAccessibleStates::STATE_CHECKED)
       aName.AssignLiteral("uncheck"); 
     else
       aName.AssignLiteral("check"); 
 
     return NS_OK;
   }
@@ -90,49 +90,55 @@ NS_IMETHODIMP nsHTMLCheckboxAccessible::
 NS_IMETHODIMP nsHTMLCheckboxAccessible::DoAction(PRUint8 index)
 {
   if (index == 0) {   // 0 is the magic value for default action
     return DoCommand();
   }
   return NS_ERROR_INVALID_ARG;
 }
 
-NS_IMETHODIMP nsHTMLCheckboxAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsHTMLCheckboxAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsFormControlAccessible::GetState(_retval);
+  nsresult rv = nsFormControlAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   PRBool checked = PR_FALSE;   // Radio buttons and check boxes can be checked
 
   nsCOMPtr<nsIDOMHTMLInputElement> htmlCheckboxElement(do_QueryInterface(mDOMNode));
-  if (htmlCheckboxElement) 
+  if (htmlCheckboxElement)
     htmlCheckboxElement->GetChecked(&checked);
 
-  if (checked) 
-    *_retval |= nsIAccessibleStates::STATE_CHECKED;
-  
+  if (checked)
+    *aState |= nsIAccessibleStates::STATE_CHECKED;
+
   return NS_OK;
 }
 
 //------ Radio button -------
 
 nsHTMLRadioButtonAccessible::nsHTMLRadioButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
 nsRadioButtonAccessible(aNode, aShell)
 { 
 }
 
-NS_IMETHODIMP nsHTMLRadioButtonAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsHTMLRadioButtonAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsAccessibleWrap::GetState(_retval);
+  nsresult rv = nsAccessibleWrap::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   PRBool checked = PR_FALSE;   // Radio buttons and check boxes can be checked
 
   nsCOMPtr<nsIDOMHTMLInputElement> htmlRadioElement(do_QueryInterface(mDOMNode));
-  if (htmlRadioElement) 
+  if (htmlRadioElement)
     htmlRadioElement->GetChecked(&checked);
 
-  if (checked) 
-    *_retval |= nsIAccessibleStates::STATE_CHECKED;
+  if (checked)
+    *aState |= nsIAccessibleStates::STATE_CHECKED;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLRadioButtonAccessible::GetAttributes(nsIPersistentProperties **aAttributes)
 {
   NS_ENSURE_ARG_POINTER(aAttributes);
@@ -201,27 +207,29 @@ NS_IMETHODIMP nsHTMLButtonAccessible::Ge
 NS_IMETHODIMP nsHTMLButtonAccessible::DoAction(PRUint8 index)
 {
   if (index == eAction_Click) {
     return DoCommand();
   }
   return NS_ERROR_INVALID_ARG;
 }
 
-NS_IMETHODIMP nsHTMLButtonAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsHTMLButtonAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
-  if (!element) {
-    return NS_ERROR_FAILURE;  // Button accessible shut down
-  }
-  nsHyperTextAccessible::GetState(_retval);
+  NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
+
+  nsresult rv = nsHyperTextAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   nsAutoString buttonType;
   element->GetAttribute(NS_LITERAL_STRING("type"), buttonType);
   if (buttonType.LowerCaseEqualsLiteral("submit"))
-    *_retval |= nsIAccessibleStates::STATE_DEFAULT;
+    *aState |= nsIAccessibleStates::STATE_DEFAULT;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsHTMLButtonAccessible::GetRole(PRUint32 *_retval)
 {
   *_retval = nsIAccessibleRole::ROLE_PUSHBUTTON;
   return NS_OK;
@@ -301,29 +309,31 @@ NS_IMETHODIMP nsHTML4ButtonAccessible::D
 }
 
 NS_IMETHODIMP nsHTML4ButtonAccessible::GetRole(PRUint32 *_retval)
 {
   *_retval = nsIAccessibleRole::ROLE_PUSHBUTTON;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsHTML4ButtonAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsHTML4ButtonAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
-  if (!element) {
-    return NS_ERROR_FAILURE;  // Button accessible shut down
-  }
-  nsHyperTextAccessible::GetState(_retval);
-  *_retval |= nsIAccessibleStates::STATE_FOCUSABLE;
+  NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);  // Button accessible shut down
+
+  nsresult rv = nsHyperTextAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  *aState |= nsIAccessibleStates::STATE_FOCUSABLE;
 
   nsAutoString buttonType;
   element->GetAttribute(NS_LITERAL_STRING("type"), buttonType);
   if (buttonType.LowerCaseEqualsLiteral("submit"))
-    *_retval |= nsIAccessibleStates::STATE_DEFAULT;
+    *aState |= nsIAccessibleStates::STATE_DEFAULT;
 
   return NS_OK;
 }
 
 // --- textfield -----
 
 nsHTMLTextFieldAccessible::nsHTMLTextFieldAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
 nsHyperTextAccessible(aNode, aShell)
@@ -357,39 +367,38 @@ NS_IMETHODIMP nsHTMLTextFieldAccessible:
     *aRole = nsIAccessibleRole::ROLE_PASSWORD_TEXT;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP nsHTMLTextFieldAccessible::GetValue(nsAString& _retval)
 {
   PRUint32 state;
-  GetState(&state);
+  GetState(&state, nsnull);
   if (state & nsIAccessibleStates::STATE_PROTECTED)    // Don't return password text!
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIDOMHTMLTextAreaElement> textArea(do_QueryInterface(mDOMNode));
   if (textArea) {
     return textArea->GetValue(_retval);
   }
   
   nsCOMPtr<nsIDOMHTMLInputElement> inputElement(do_QueryInterface(mDOMNode));
   if (inputElement) {
     return inputElement->GetValue(_retval);
   }
 
   return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP nsHTMLTextFieldAccessible::GetState(PRUint32 *aState)
+NS_IMETHODIMP
+nsHTMLTextFieldAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsresult rv = nsHyperTextAccessible::GetState(aState);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
+  nsresult rv = nsHyperTextAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   // can be focusable, focused, protected. readonly, unavailable, selected
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
   NS_ASSERTION(content, "Should not have gotten here if upcalled GetExtState() succeeded");
 
   if (content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::type,
                            nsAccessibilityAtoms::password, eIgnoreCase)) {
     *aState |= nsIAccessibleStates::STATE_PROTECTED;
@@ -401,61 +410,52 @@ NS_IMETHODIMP nsHTMLTextFieldAccessible:
       *aState |= nsIAccessibleStates::STATE_HASPOPUP;
     }
   }
 
   if (content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::readonly)) {
     *aState |= nsIAccessibleStates::STATE_READONLY;
   }
 
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsHTMLTextFieldAccessible::GetExtState(PRUint32 *aExtState)
-{
-  nsresult rv = nsHyperTextAccessible::GetExtState(aExtState);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
+  if (!aExtraState)
+    return NS_OK;
 
   nsCOMPtr<nsIDOMHTMLInputElement> htmlInput(do_QueryInterface(mDOMNode, &rv));
   // Is it an <input> or a <textarea> ?
-  *aExtState |= htmlInput ? nsIAccessibleStates::EXT_STATE_SINGLE_LINE :
-                            nsIAccessibleStates::EXT_STATE_MULTI_LINE;
+  *aExtraState |= htmlInput ? nsIAccessibleStates::EXT_STATE_SINGLE_LINE :
+                              nsIAccessibleStates::EXT_STATE_MULTI_LINE;
 
-  PRUint32 state;
-  GetState(&state);
   const PRUint32 kNonEditableStates = nsIAccessibleStates::STATE_READONLY |
                                       nsIAccessibleStates::STATE_UNAVAILABLE;
-  if (0 == (state & kNonEditableStates)) {
-    *aExtState |= nsIAccessibleStates::EXT_STATE_EDITABLE;
+  if (0 == (*aState & kNonEditableStates)) {
+    *aExtraState |= nsIAccessibleStates::EXT_STATE_EDITABLE;
     nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
     if (content && (content = content->GetBindingParent()) != nsnull &&
         content->NodeInfo()->Equals(nsAccessibilityAtoms::textbox, kNameSpaceID_XUL)) {
       // If parent is XUL textbox, then it supports autocompletion if type="autocomplete"
       if (content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::type,
                                NS_LITERAL_STRING("autocomplete"), eIgnoreCase)) {
-        *aExtState |= nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION;
+        *aExtraState |= nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION;
       }
     } else if (gIsFormFillEnabled && htmlInput &&
-               !(state & nsIAccessibleStates::STATE_PROTECTED)) {
+               !(*aState & nsIAccessibleStates::STATE_PROTECTED)) {
       // Check to see if autocompletion is allowed on this input
       // We don't expose it for password fields even though the entire password can
       // be remembered for a page if the user asks it to be.
       // However, the kind of autocomplete we're talking here is based on what
       // the user types, where a popup of possible choices comes up.
       nsAutoString autocomplete;
       htmlInput->GetAttribute(NS_LITERAL_STRING("autocomplete"), autocomplete);
       if (!autocomplete.LowerCaseEqualsLiteral("off")) {
         nsCOMPtr<nsIDOMHTMLFormElement> form;
         htmlInput->GetForm(getter_AddRefs(form));
         if (form)
           form->GetAttribute(NS_LITERAL_STRING("autocomplete"), autocomplete);
         if (!form || !autocomplete.LowerCaseEqualsLiteral("off")) {
-          *aExtState |= nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION;
+          *aExtraState |= nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION;
         }
       }
     }
   }
 
   return NS_OK;
 }
 
@@ -521,20 +521,23 @@ nsAccessibleWrap(aNode, aShell)
 }
 
 NS_IMETHODIMP nsHTMLGroupboxAccessible::GetRole(PRUint32 *_retval)
 {
   *_retval = nsIAccessibleRole::ROLE_GROUPING;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsHTMLGroupboxAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsHTMLGroupboxAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // Groupbox doesn't support any states!
-  *_retval = 0;
+  *aState = 0;
+  if (aExtraState)
+    *aExtraState = 0;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsHTMLGroupboxAccessible::GetName(nsAString& aName)
 {
   if (mRoleMapEntry) {
     nsAccessible::GetName(aName);
--- a/accessible/src/html/nsHTMLFormControlAccessible.h
+++ b/accessible/src/html/nsHTMLFormControlAccessible.h
@@ -48,53 +48,53 @@ class nsHTMLCheckboxAccessible : public 
 public:
   enum { eAction_Click = 0 };
 
   nsHTMLCheckboxAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *_retval); 
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 index);
-  NS_IMETHOD GetState(PRUint32 *aState); 
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
 };
 
 class nsHTMLRadioButtonAccessible : public nsRadioButtonAccessible
 {
 
 public:
   nsHTMLRadioButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
 
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
 };
 
 class nsHTMLButtonAccessible : public nsHyperTextAccessible
 {
 
 public:
   enum { eAction_Click = 0 };
 
   nsHTMLButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *_retval); 
-  NS_IMETHOD GetState(PRUint32 *_retval); 
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetName(nsAString& _retval); 
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 index);
 };
 
 class nsHTML4ButtonAccessible : public nsHyperTextAccessible
 {
 
 public:
   enum { eAction_Click = 0 };
 
   nsHTML4ButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *_retval); 
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetName(nsAString& aName) { aName.Truncate(); return GetHTMLName(aName, PR_TRUE); }
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 index);
 };
 
 class nsHTMLTextFieldAccessible : public nsHyperTextAccessible
 {
@@ -105,33 +105,32 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   nsHTMLTextFieldAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
 
   NS_IMETHOD Init(); 
   NS_IMETHOD Shutdown(); 
   NS_IMETHOD GetRole(PRUint32 *_retval); 
   NS_IMETHOD GetValue(nsAString& _retval); 
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 index);
-  NS_IMETHOD GetExtState(PRUint32 *aExtState); 
 
 protected:
   // Editor helpers, subclasses of nsHyperTextAccessible may have editor
   virtual void SetEditor(nsIEditor *aEditor);
   virtual already_AddRefed<nsIEditor> GetEditor() { nsIEditor *editor = mEditor; NS_IF_ADDREF(editor); return editor; }
   void CheckForEditor();
   nsCOMPtr<nsIEditor> mEditor;
 };
 
 class nsHTMLGroupboxAccessible : public nsAccessibleWrap
 {
 public:
   nsHTMLGroupboxAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *_retval); 
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetName(nsAString& _retval);
   void CacheChildren();
 };
 
 #endif  
--- a/accessible/src/html/nsHTMLImageAccessible.cpp
+++ b/accessible/src/html/nsHTMLImageAccessible.cpp
@@ -72,39 +72,40 @@ nsLinkableAccessible(aDOMNode, aShell)
         mapElementName.Cut(0,1);
       mMapElement = htmlDoc->GetImageMap(mapElementName);
     }
   }
 }
 
 NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLImageAccessible, nsLinkableAccessible, nsIAccessibleImage)
 
-NS_IMETHODIMP nsHTMLImageAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsHTMLImageAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // The state is a bitfield, get our inherited state, then logically OR it with
   // STATE_ANIMATED if this is an animated image.
 
-  nsLinkableAccessible::GetState(_retval);
+  nsresult rv = nsLinkableAccessible::GetState(aState, aExtraState);
 
   nsCOMPtr<nsIImageLoadingContent> content(do_QueryInterface(mDOMNode));
   nsCOMPtr<imgIRequest> imageRequest;
 
-  if (content) 
+  if (content)
     content->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
                         getter_AddRefs(imageRequest));
-  
+
   nsCOMPtr<imgIContainer> imgContainer;
-  if (imageRequest) 
+  if (imageRequest)
     imageRequest->GetImage(getter_AddRefs(imgContainer));
 
   if (imgContainer) {
     PRUint32 numFrames;
     imgContainer->GetNumFrames(&numFrames);
     if (numFrames > 1)
-      *_retval |= nsIAccessibleStates::STATE_ANIMATED;
+      *aState |= nsIAccessibleStates::STATE_ANIMATED;
   }
 
   return NS_OK;
 }
 
 
 /* wstring getName (); */
 NS_IMETHODIMP nsHTMLImageAccessible::GetName(nsAString& aName)
--- a/accessible/src/html/nsHTMLImageAccessible.h
+++ b/accessible/src/html/nsHTMLImageAccessible.h
@@ -56,17 +56,17 @@ class nsHTMLImageAccessible : public nsL
 
 public:
   //action0 may exist depends on whether an onclick is associated with it
   enum { eAction_ShowLongDescription = 1 };
 
   nsHTMLImageAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
 
   NS_IMETHOD GetName(nsAString& _retval); 
-  NS_IMETHOD GetState(PRUint32 *_retval); 
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetRole(PRUint32 *_retval);
   NS_IMETHOD DoAction(PRUint8 index);
 
   NS_IMETHOD GetImageBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height);
 
 protected:
   virtual void CacheChildren();
   already_AddRefed<nsIAccessible> CreateAreaAccessible(PRInt32 areaNum);
--- a/accessible/src/html/nsHTMLLinkAccessible.cpp
+++ b/accessible/src/html/nsHTMLLinkAccessible.cpp
@@ -60,19 +60,22 @@ NS_IMETHODIMP nsHTMLLinkAccessible::GetN
 /* unsigned long getRole (); */
 NS_IMETHODIMP nsHTMLLinkAccessible::GetRole(PRUint32 *_retval)
 {
   *_retval = nsIAccessibleRole::ROLE_LINK;
 
   return NS_OK;
 }
 
-NS_IMETHODIMP nsHTMLLinkAccessible::GetState(PRUint32 *aState)
+NS_IMETHODIMP
+nsHTMLLinkAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsLinkableAccessible::GetState(aState);
+  nsresult rv = nsLinkableAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   *aState  &= ~nsIAccessibleStates::STATE_READONLY;
 
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
   if (content && content->HasAttr(kNameSpaceID_None,
                                   nsAccessibilityAtoms::name)) {
     // This is how we indicate it is a named anchor
     // In other words, this anchor can be selected as a location :)
     // There is no other better state to use to indicate this.
--- a/accessible/src/html/nsHTMLLinkAccessible.h
+++ b/accessible/src/html/nsHTMLLinkAccessible.h
@@ -46,17 +46,17 @@ class nsHTMLLinkAccessible : public nsLi
   NS_DECL_ISUPPORTS_INHERITED
 
 public:
   nsHTMLLinkAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell, nsIFrame *aFrame);
   
   // nsIAccessible
   NS_IMETHOD GetName(nsAString& _retval); 
   NS_IMETHOD GetRole(PRUint32 *_retval); 
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD Shutdown() { mFrame = nsnull; return nsLinkableAccessible::Shutdown(); }
   
   // nsPIAccessNode
   NS_IMETHOD_(nsIFrame *) GetFrame(void);
 
   // nsPIAccessible
   NS_IMETHOD FireToolkitEvent(PRUint32 aEvent, nsIAccessible *aTarget,
                               void *aData);
--- a/accessible/src/html/nsHTMLSelectAccessible.cpp
+++ b/accessible/src/html/nsHTMLSelectAccessible.cpp
@@ -320,26 +320,29 @@ nsHTMLSelectListAccessible::nsHTMLSelect
 {
 }
 
 /**
   * As a nsHTMLSelectListAccessible we can have the following states:
   *     nsIAccessibleStates::STATE_MULTISELECTABLE
   *     nsIAccessibleStates::STATE_EXTSELECTABLE
   */
-NS_IMETHODIMP nsHTMLSelectListAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsHTMLSelectListAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsHTMLSelectableAccessible::GetState(_retval);
+  nsresult rv = nsHTMLSelectableAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   nsCOMPtr<nsIDOMHTMLSelectElement> select (do_QueryInterface(mDOMNode));
-  if ( select ) {
+  if (select) {
     PRBool multiple;
     select->GetMultiple(&multiple);
     if ( multiple )
-      *_retval |= nsIAccessibleStates::STATE_MULTISELECTABLE |
-                  nsIAccessibleStates::STATE_EXTSELECTABLE;
+      *aState |= nsIAccessibleStates::STATE_MULTISELECTABLE |
+                 nsIAccessibleStates::STATE_EXTSELECTABLE;
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsHTMLSelectListAccessible::GetRole(PRUint32 *aRole)
 {
   if (mParent && Role(mParent) == nsIAccessibleRole::ROLE_COMBOBOX) {
@@ -555,18 +558,17 @@ nsIFrame* nsHTMLSelectOptionAccessible::
   }
 
   nsCOMPtr<nsIDOMNode> selectNode(do_QueryInterface(selectContent));
   if (selectNode) {
     nsCOMPtr<nsIAccessibilityService> accService(do_GetService("@mozilla.org/accessibilityService;1"));
     nsCOMPtr<nsIAccessible> selAcc;
     accService->GetAccessibleFor(selectNode, getter_AddRefs(selAcc));
     if (selAcc) {
-      PRUint32 state;
-      selAcc->GetFinalState(&state);
+      PRUint32 state = State(selAcc);
       if (state & nsIAccessibleStates::STATE_COLLAPSED) {
         nsCOMPtr<nsIPresShell> presShell(GetPresShell());
         if (!presShell) {
           return nsnull;
         }
         return presShell->GetPrimaryFrameFor(selectContent);
       }
     }
@@ -578,19 +580,20 @@ nsIFrame* nsHTMLSelectOptionAccessible::
 /**
   * As a nsHTMLSelectOptionAccessible we can have the following states:
   *     STATE_SELECTABLE
   *     STATE_SELECTED
   *     STATE_FOCUSED
   *     STATE_FOCUSABLE
   *     STATE_INVISIBLE -- not implemented yet
   */
-NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsHTMLSelectOptionAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  *_retval = 0;
+  *aState = 0;
   nsCOMPtr<nsIDOMNode> focusedOptionNode, parentNode;
   // Go up to parent <select> element
   nsCOMPtr<nsIDOMNode> thisNode(do_QueryInterface(mDOMNode));
   do {
     thisNode->GetParentNode(getter_AddRefs(parentNode));
     nsCOMPtr<nsIDOMHTMLSelectElement> selectControl(do_QueryInterface(parentNode));
     if (selectControl) {
       break;
@@ -599,29 +602,29 @@ NS_IMETHODIMP nsHTMLSelectOptionAccessib
   } while (parentNode);
   if (!parentNode) {
     return NS_ERROR_FAILURE;
   }
   
   // find out if we are the focused node
   GetFocusedOptionNode(parentNode, getter_AddRefs(focusedOptionNode));
   if (focusedOptionNode == mDOMNode)
-    *_retval |= nsIAccessibleStates::STATE_FOCUSED;
+    *aState |= nsIAccessibleStates::STATE_FOCUSED;
 
   // Are we selected?
   nsCOMPtr<nsIDOMHTMLOptionElement> option (do_QueryInterface(mDOMNode));
   if ( option ) {
     PRBool isSelected = PR_FALSE;
     option->GetSelected(&isSelected);
     if ( isSelected ) 
-      *_retval |= nsIAccessibleStates::STATE_SELECTED;
+      *aState |= nsIAccessibleStates::STATE_SELECTED;
   }
 
-  *_retval |= nsIAccessibleStates::STATE_SELECTABLE |
-              nsIAccessibleStates::STATE_FOCUSABLE;
+  *aState |= nsIAccessibleStates::STATE_SELECTABLE |
+             nsIAccessibleStates::STATE_FOCUSABLE;
 
   return NS_OK;
 }
 
 /** select us! close combo box if necessary*/
 NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
 {
   if (aIndex == eAction_Select) {
@@ -772,18 +775,17 @@ void nsHTMLSelectOptionAccessible::Selec
   nsCOMPtr<nsIAccessible> optionAccessible;
   accService->GetAccessibleFor(optionNode, getter_AddRefs(optionAccessible));
   if (!optionAccessible) {
     return;
   }
 
   privateMultiSelect->FireToolkitEvent(nsIAccessibleEvent::EVENT_SELECTION_WITHIN,
                       multiSelect, nsnull);
-  PRUint32 state;
-  optionAccessible->GetFinalState(&state);
+  PRUint32 state = State(optionAccessible);
   PRUint32 eventType = (state & nsIAccessibleStates::STATE_SELECTED) ?
                        nsIAccessibleEvent::EVENT_SELECTION_ADD :
                        nsIAccessibleEvent::EVENT_SELECTION_REMOVE; 
   privateMultiSelect->FireToolkitEvent(eventType, optionAccessible, nsnull);
 }
 
 /** ----- nsHTMLSelectOptGroupAccessible ----- */
 
@@ -793,21 +795,24 @@ nsHTMLSelectOptionAccessible(aDOMNode, a
 {
 }
 
 
 /**
   * As a nsHTMLSelectOptGroupAccessible we can have the following states:
   *     nsIAccessibleStates::STATE_SELECTABLE
   */
-NS_IMETHODIMP nsHTMLSelectOptGroupAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsHTMLSelectOptGroupAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsHTMLSelectOptionAccessible::GetState(_retval);
-  *_retval &= ~(nsIAccessibleStates::STATE_FOCUSABLE |
-                nsIAccessibleStates::STATE_SELECTABLE);
+  nsresult rv = nsHTMLSelectOptionAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  *aState &= ~(nsIAccessibleStates::STATE_FOCUSABLE |
+               nsIAccessibleStates::STATE_SELECTABLE);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsHTMLSelectOptGroupAccessible::DoAction(PRUint8 index)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
@@ -912,33 +917,35 @@ void nsHTMLComboboxAccessible::CacheChil
   * As a nsHTMLComboboxAccessible we can have the following states:
   *     STATE_FOCUSED
   *     STATE_READONLY
   *     STATE_FOCUSABLE
   *     STATE_HASPOPUP
   *     STATE_EXPANDED
   *     STATE_COLLAPSED
   */
-NS_IMETHODIMP nsHTMLComboboxAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsHTMLComboboxAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // Get focus status from base class
-  nsAccessible::GetState(_retval);
+  nsresult rv = nsAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   nsIFrame *frame = GetBoundsFrame();
   nsIComboboxControlFrame *comboFrame = nsnull;
   frame->QueryInterface(NS_GET_IID(nsIComboboxControlFrame), (void**)&comboFrame);
 
   if (comboFrame && comboFrame->IsDroppedDown())
-    *_retval |= nsIAccessibleStates::STATE_EXPANDED;
+    *aState |= nsIAccessibleStates::STATE_EXPANDED;
   else
-    *_retval |= nsIAccessibleStates::STATE_COLLAPSED;
+    *aState |= nsIAccessibleStates::STATE_COLLAPSED;
 
-  *_retval |= nsIAccessibleStates::STATE_HASPOPUP |
-              nsIAccessibleStates::STATE_READONLY |
-              nsIAccessibleStates::STATE_FOCUSABLE;
+  *aState |= nsIAccessibleStates::STATE_HASPOPUP |
+             nsIAccessibleStates::STATE_READONLY |
+             nsIAccessibleStates::STATE_FOCUSABLE;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsHTMLComboboxAccessible::GetDescription(nsAString& aDescription)
 {
   aDescription.Truncate();
   // First check to see if combo box itself has a description, perhaps through
@@ -1222,31 +1229,33 @@ NS_IMETHODIMP nsHTMLComboboxButtonAccess
 }
 
 /**
   * As a nsHTMLComboboxButtonAccessible we can have the following states:
   *     STATE_PRESSED
   *     STATE_FOCUSED
   *     STATE_FOCUSABLE
   */
-NS_IMETHODIMP nsHTMLComboboxButtonAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsHTMLComboboxButtonAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // Get focus status from base class
-  nsAccessible::GetState(_retval);
+  nsresult rv = nsAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   nsIFrame *boundsFrame = GetBoundsFrame();
   nsIComboboxControlFrame* comboFrame;
   boundsFrame->QueryInterface(NS_GET_IID(nsIComboboxControlFrame), (void**)&comboFrame);
   if (!comboFrame)
     return NS_ERROR_FAILURE;
 
   if (comboFrame->IsDroppedDown())
-    *_retval |= nsIAccessibleStates::STATE_PRESSED;
+    *aState |= nsIAccessibleStates::STATE_PRESSED;
 
-  *_retval |= nsIAccessibleStates::STATE_FOCUSABLE;
+  *aState |= nsIAccessibleStates::STATE_FOCUSABLE;
 
   return NS_OK;
 }
 #endif
 
 /** ----- nsHTMLComboboxListAccessible ----- */
 
 nsHTMLComboboxListAccessible::nsHTMLComboboxListAccessible(nsIAccessible *aParent,
@@ -1264,20 +1273,22 @@ nsIFrame *nsHTMLComboboxListAccessible::
 
 /**
   * As a nsHTMLComboboxListAccessible we can have the following states:
   *     STATE_FOCUSED
   *     STATE_FOCUSABLE
   *     STATE_INVISIBLE
   *     STATE_FLOATING
   */
-NS_IMETHODIMP nsHTMLComboboxListAccessible::GetState(PRUint32 *aState)
+NS_IMETHODIMP
+nsHTMLComboboxListAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // Get focus status from base class
-  nsAccessible::GetState(aState);
+  nsresult rv = nsAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   nsIFrame *boundsFrame = GetBoundsFrame();
   nsIComboboxControlFrame* comboFrame = nsnull;
   boundsFrame->QueryInterface(NS_GET_IID(nsIComboboxControlFrame), (void**)&comboFrame);
   if (!comboFrame)
     return NS_ERROR_FAILURE;
 
   if (comboFrame->IsDroppedDown())
--- a/accessible/src/html/nsHTMLSelectAccessible.h
+++ b/accessible/src/html/nsHTMLSelectAccessible.h
@@ -125,17 +125,17 @@ class nsHTMLSelectListAccessible : publi
 {
 public:
   
   nsHTMLSelectListAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
   virtual ~nsHTMLSelectListAccessible() {}
 
   /* ----- nsIAccessible ----- */
   NS_IMETHOD GetRole(PRUint32 *aRole);
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   void CacheChildren();
 
 protected:
   already_AddRefed<nsIAccessible>
     AccessibleForOption(nsIAccessibilityService *aAccService,
                         nsIContent *aContent,
                         nsIAccessible *aLastGoodAccessible,
                         PRInt32 *aChildCount);
@@ -156,17 +156,17 @@ public:
   
   nsHTMLSelectOptionAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
   virtual ~nsHTMLSelectOptionAccessible() {}
 
   /* ----- nsIAccessible ----- */
   NS_IMETHOD DoAction(PRUint8 index);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetRole(PRUint32 *aRole);
   NS_IMETHOD GetName(nsAString& aName);
   NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
 
   nsIFrame*  GetBoundsFrame();
   static nsresult GetFocusedOptionNode(nsIDOMNode *aListNode, nsIDOMNode **aFocusedOptionNode);
   static void SelectionChangedIfOption(nsIContent *aPossibleOption);
 };
@@ -177,17 +177,17 @@ public:
 class nsHTMLSelectOptGroupAccessible : public nsHTMLSelectOptionAccessible
 {
 public:
 
   nsHTMLSelectOptGroupAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
   virtual ~nsHTMLSelectOptGroupAccessible() {}
 
   /* ----- nsIAccessible ----- */
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD DoAction(PRUint8 index);  
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
 };
 
 /** ------------------------------------------------------ */
 /**  Finally, the Combobox widgets                         */
 /** ------------------------------------------------------ */
@@ -200,17 +200,17 @@ class nsHTMLComboboxAccessible : public 
 public:
   enum { eAction_Click = 0 };
 
   nsHTMLComboboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
   virtual ~nsHTMLComboboxAccessible() {}
 
   /* ----- nsIAccessible ----- */
   NS_IMETHOD GetRole(PRUint32 *_retval);
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetValue(nsAString& _retval);
   NS_IMETHOD GetDescription(nsAString& aDescription);
   NS_IMETHOD DoAction(PRUint8 index);
   NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
 
   void CacheChildren();
 
@@ -253,17 +253,17 @@ public:
 
   /* ----- nsIAccessible ----- */
   NS_IMETHOD DoAction(PRUint8 index);
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD GetParent(nsIAccessible **_retval);
   NS_IMETHOD GetName(nsAString& _retval);
   NS_IMETHOD GetRole(PRUint32 *_retval);
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetUniqueID(void **aUniqueID);
 
   virtual void GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame);
 };
 #endif
 
 /*
  * A class that represents the window that lives to the right
@@ -276,17 +276,17 @@ public:
 
   nsHTMLComboboxListAccessible(nsIAccessible *aParent, 
                                nsIDOMNode* aDOMNode, 
                                nsIFrame *aListFrame,
                                nsIWeakReference* aShell);
   virtual ~nsHTMLComboboxListAccessible() {}
 
   /* ----- nsIAccessible ----- */
-  NS_IMETHOD GetState(PRUint32 *aState);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetParent(nsIAccessible **aParent);
   NS_IMETHOD GetUniqueID(void **aUniqueID);
 
   // nsPIAccessNode
   NS_IMETHOD_(nsIFrame *) GetFrame(void);
 
   virtual void GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame);
 
--- a/accessible/src/html/nsHTMLTableAccessible.cpp
+++ b/accessible/src/html/nsHTMLTableAccessible.cpp
@@ -65,20 +65,25 @@ nsHyperTextAccessible(aDomNode, aShell)
 
 /* unsigned long getRole (); */
 NS_IMETHODIMP nsHTMLTableCellAccessible::GetRole(PRUint32 *aResult)
 {
   *aResult = nsIAccessibleRole::ROLE_CELL;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsHTMLTableCellAccessible::GetState(PRUint32 *aResult)
+NS_IMETHODIMP
+nsHTMLTableCellAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsAccessible::GetState(aResult);
-  *aResult &= ~nsIAccessibleStates::STATE_FOCUSABLE;   // Inherit all states except focusable state since table cells cannot be focused
+  nsresult rv = nsAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // Inherit all states except focusable state since table cells cannot be
+  // focused.
+  *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;
   return NS_OK;
 }
 
 NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLTableAccessible, nsAccessible, nsIAccessibleTable)
 
 nsHTMLTableAccessible::nsHTMLTableAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell):
 nsAccessibleWrap(aDomNode, aShell)
 { 
@@ -142,21 +147,25 @@ void nsHTMLTableAccessible::CacheChildre
 
 /* unsigned long getRole (); */
 NS_IMETHODIMP nsHTMLTableAccessible::GetRole(PRUint32 *aResult)
 {
   *aResult = nsIAccessibleRole::ROLE_TABLE;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsHTMLTableAccessible::GetState(PRUint32 *aResult)
+NS_IMETHODIMP
+nsHTMLTableAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsAccessible::GetState(aResult);
-  *aResult |= nsIAccessibleStates::STATE_READONLY;
-  *aResult &= ~nsIAccessibleStates::STATE_FOCUSABLE;   // Inherit all states except focusable state since tables cannot be focused
+  nsresult rv= nsAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  *aState |= nsIAccessibleStates::STATE_READONLY;
+  // Inherit all states except focusable state since tables cannot be focused.
+  *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsHTMLTableAccessible::GetName(nsAString& aName)
 {
   aName.Truncate();  // Default name is blank
 
   if (mRoleMapEntry) {
--- a/accessible/src/html/nsHTMLTableAccessible.h
+++ b/accessible/src/html/nsHTMLTableAccessible.h
@@ -44,17 +44,17 @@
 
 class nsHTMLTableCellAccessible : public nsHyperTextAccessible
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
   nsHTMLTableCellAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *aResult); 
-  NS_IMETHOD GetState(PRUint32 *aResult); 
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
 };
 
 class nsITableLayout;
 
 // XXX For now debugging descriptions are always on via SHOW_LAYOUT_HEURISTIC
 // This will allow release trunk builds to be used by testers to refine the algorithm
 // Change to |#define SHOW_LAYOUT_HEURISTIC DEBUG| before final release
 #define SHOW_LAYOUT_HEURISTIC
@@ -63,17 +63,17 @@ class nsHTMLTableAccessible : public nsA
                               public nsIAccessibleTable
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIACCESSIBLETABLE
 
   nsHTMLTableAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *aResult); 
-  NS_IMETHOD GetState(PRUint32 *aResult); 
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetName(nsAString& aResult);
   NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
 #ifdef SHOW_LAYOUT_HEURISTIC
   NS_IMETHOD GetDescription(nsAString& aDescription);
 #endif
 
 protected:
   virtual void CacheChildren();
--- a/accessible/src/html/nsHTMLTextAccessible.cpp
+++ b/accessible/src/html/nsHTMLTextAccessible.cpp
@@ -106,25 +106,27 @@ NS_IMETHODIMP nsHTMLTextAccessible::GetR
   if (frame->IsGeneratedContentFrame()) {
     *aRole = nsIAccessibleRole::ROLE_STATICTEXT;
     return NS_OK;
   }
 
   return nsTextAccessible::GetRole(aRole);
 }
 
-NS_IMETHODIMP nsHTMLTextAccessible::GetState(PRUint32 *aState)
+NS_IMETHODIMP
+nsHTMLTextAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsTextAccessible::GetState(aState);
+  nsresult rv = nsTextAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIAccessible> docAccessible = 
     do_QueryInterface(nsCOMPtr<nsIAccessibleDocument>(GetDocAccessible()));
   if (docAccessible) {
-     PRUint32 extState;
-     docAccessible->GetExtState(&extState);
+     PRUint32 state, extState;
+     docAccessible->GetFinalState(&state, &extState);
      if (0 == (extState & nsIAccessibleStates::EXT_STATE_EDITABLE)) {
        *aState |= nsIAccessibleStates::STATE_READONLY; // Links not focusable in editor
      }
   }
 
   return NS_OK;
 }
 
@@ -157,35 +159,39 @@ nsLeafAccessible(aDomNode, aShell)
 }
 
 NS_IMETHODIMP nsHTMLHRAccessible::GetRole(PRUint32 *aRole)
 {
   *aRole = nsIAccessibleRole::ROLE_SEPARATOR;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsHTMLHRAccessible::GetState(PRUint32 *aState)
+NS_IMETHODIMP
+nsHTMLHRAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsLeafAccessible::GetState(aState);
+  nsresult rv = nsLeafAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;
   return NS_OK;
 }
 
 nsHTMLBRAccessible::nsHTMLBRAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell):
 nsLeafAccessible(aDomNode, aShell)
 { 
 }
 
 NS_IMETHODIMP nsHTMLBRAccessible::GetRole(PRUint32 *aRole)
 {
   *aRole = nsIAccessibleRole::ROLE_WHITESPACE;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsHTMLBRAccessible::GetState(PRUint32 *aState)
+NS_IMETHODIMP
+nsHTMLBRAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   *aState = nsIAccessibleStates::STATE_READONLY;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsHTMLBRAccessible::GetName(nsAString& aName)
 {
   aName = NS_STATIC_CAST(PRUnichar, '\n');    // Newline char
@@ -216,19 +222,22 @@ NS_IMETHODIMP nsHTMLLabelAccessible::Get
 }
 
 NS_IMETHODIMP nsHTMLLabelAccessible::GetRole(PRUint32 *aRole)
 {
   *aRole = nsIAccessibleRole::ROLE_LABEL;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsHTMLLabelAccessible::GetState(PRUint32 *aState)
+NS_IMETHODIMP
+nsHTMLLabelAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsTextAccessible::GetState(aState);
+  nsresult rv = nsTextAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   *aState &= (nsIAccessibleStates::STATE_LINKED |
               nsIAccessibleStates::STATE_TRAVERSED);  // Only use link states
   return NS_OK;
 }
 
 NS_IMETHODIMP nsHTMLLabelAccessible::GetFirstChild(nsIAccessible **aFirstChild) 
 {  
   // A <label> is not necessarily a leaf!
@@ -329,8 +338,45 @@ NS_IMETHODIMP nsHTMLListBulletAccessible
   return nsHTMLTextAccessible::Shutdown();
 }
 
 NS_IMETHODIMP nsHTMLListBulletAccessible::GetName(nsAString &aName)
 {
   aName = mBulletText;
   return NS_OK;
 }
+
+NS_IMETHODIMP
+nsHTMLListBulletAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
+{
+  nsresult rv = nsHTMLTextAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;
+  *aState |= nsIAccessibleStates::STATE_READONLY;
+  return NS_OK;
+}
+
+// nsHTMLListAccessible
+
+NS_IMETHODIMP
+nsHTMLListAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
+{
+  nsresult rv = nsHyperTextAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;
+  *aState |= nsIAccessibleStates::STATE_READONLY;
+  return NS_OK;
+}
+
+// nsHTMLLIAccessible
+
+NS_IMETHODIMP
+nsHTMLLIAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
+{
+  nsresult rv = nsAccessibleWrap::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  *aState |= nsIAccessibleStates::STATE_READONLY;
+  return NS_OK;
+}
+
--- a/accessible/src/html/nsHTMLTextAccessible.h
+++ b/accessible/src/html/nsHTMLTextAccessible.h
@@ -47,17 +47,17 @@ class nsIWeakReference;
 
 class nsHTMLTextAccessible : public nsTextAccessibleWrap
 {
 public:
   nsHTMLTextAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell, nsIFrame *aFrame);
   
   // nsIAccessible
   NS_IMETHOD GetName(nsAString& _retval);
-  NS_IMETHOD GetState(PRUint32 *aState);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetRole(PRUint32 *aRole);
   NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
   NS_IMETHOD Shutdown() { mFrame = nsnull; return nsTextAccessibleWrap::Shutdown(); }
   
   // nsPIAccessNode
   NS_IMETHOD_(nsIFrame *) GetFrame(void);
 
   // nsPIAccessible
@@ -71,50 +71,50 @@ private:
   nsIFrame *mFrame; // Only valid if node is not shut down (mWeakShell != null)
 };
 
 class nsHTMLHRAccessible : public nsLeafAccessible
 {
 public:
   nsHTMLHRAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *aRole); 
-  NS_IMETHOD GetState(PRUint32 *aState); 
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
 };
 
 class nsHTMLBRAccessible : public nsLeafAccessible
 {
 public:
   nsHTMLBRAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *aRole); 
-  NS_IMETHOD GetState(PRUint32 *aState); 
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetName(nsAString& aName);
 };
 
 class nsHTMLLabelAccessible : public nsTextAccessible 
 {
 public:
   nsHTMLLabelAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
   NS_IMETHOD GetName(nsAString& _retval);
   NS_IMETHOD GetRole(PRUint32 *_retval); 
-  NS_IMETHOD GetState(PRUint32 *_retval); 
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetFirstChild(nsIAccessible **aFirstChild);
   NS_IMETHOD GetLastChild(nsIAccessible **aLastChild);
   NS_IMETHOD GetChildCount(PRInt32 *aAccChildCount);
 };
 
 class nsHTMLListBulletAccessible : public nsHTMLTextAccessible
 {
 public:
   nsHTMLListBulletAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell,
                              nsIFrame *aFrame, const nsAString& aBulletText);
   NS_IMETHOD GetUniqueID(void **aUniqueID);
   NS_IMETHOD Shutdown();
   NS_IMETHOD GetName(nsAString& aName);
   NS_IMETHOD GetRole(PRUint32 *aRole) { *aRole = nsIAccessibleRole::ROLE_STATICTEXT; return NS_OK; }
-  NS_IMETHOD GetState(PRUint32 *aState) { nsHTMLTextAccessible::GetState(aState); *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE; *aState |= nsIAccessibleStates::STATE_READONLY; return NS_OK; }
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   // Don't cache via unique ID -- bullet accessible shares the same dom node as this LI accessible.
   // Also, don't cache via mParent/SetParent(), prevent circular reference since li holds onto us.
   NS_IMETHOD SetParent(nsIAccessible *aParentAccessible) { mParent = nsnull; mWeakParent = aParentAccessible; return NS_OK; }
   NS_IMETHOD GetParent(nsIAccessible **aParentAccessible) { NS_IF_ADDREF(*aParentAccessible = mWeakParent); return NS_OK; }
 protected:
   // XXX Ideally we'd get the bullet text directly from the bullet frame via
   // nsBulletFrame::GetListItemText(), but we'd need an interface
   // for getting text from contentless anonymous frames.
@@ -127,27 +127,27 @@ protected:
 };
 
 class nsHTMLListAccessible : public nsHyperTextAccessible
 {
 public:
   nsHTMLListAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell):
     nsHyperTextAccessible(aDOMNode, aShell) { }
   NS_IMETHOD GetRole(PRUint32 *aRole) { *aRole = nsIAccessibleRole::ROLE_LIST; return NS_OK; }
-  NS_IMETHOD GetState(PRUint32 *aState) { nsHyperTextAccessible::GetState(aState); *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE; *aState |= nsIAccessibleStates::STATE_READONLY; return NS_OK; }
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
 };
 
 class nsHTMLLIAccessible : public nsHyperTextAccessible
 {
 public:
   nsHTMLLIAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell, 
                      nsIFrame *aBulletFrame, const nsAString& aBulletText);
   NS_IMETHOD Shutdown();
   NS_IMETHOD GetRole(PRUint32 *aRole) { *aRole = nsIAccessibleRole::ROLE_LISTITEM; return NS_OK; }
-  NS_IMETHOD GetState(PRUint32 *aState) { nsAccessibleWrap::GetState(aState); *aState |= nsIAccessibleStates::STATE_READONLY; return NS_OK; }
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetName(nsAString& aName) { aName.SetIsVoid(PR_TRUE); return mRoleMapEntry ? nsAccessible::GetName(aName) : NS_OK; }
   NS_IMETHOD GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height);
   void CacheChildren();  // Include bullet accessible
 protected:
   nsRefPtr<nsHTMLListBulletAccessible> mBulletAccessible;
 };
 
 #endif  
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -95,18 +95,18 @@ nsresult nsHyperTextAccessible::QueryInt
         NS_ADDREF_THIS();
         return NS_OK;
       }
       return NS_ERROR_NO_INTERFACE;
     }
 
     if (aIID.Equals(NS_GET_IID(nsIAccessibleEditableText))) {
       // If this contains editable text
-      PRUint32 extState;
-      GetExtState(&extState);
+      PRUint32 state, extState;
+      GetState(&state, &extState);
       if (extState & nsIAccessibleStates::EXT_STATE_EDITABLE) {
         *aInstancePtr = NS_STATIC_CAST(nsIAccessibleEditableText*, this);
         NS_ADDREF_THIS();
         return NS_OK;
       }
       return NS_ERROR_NO_INTERFACE;
     }
   }
@@ -165,39 +165,41 @@ NS_IMETHODIMP nsHyperTextAccessible::Get
     }
     else {
       *aRole = nsIAccessibleRole::ROLE_TEXT_CONTAINER; // In ATK this works
     }
   }
   return NS_OK;
 }
 
-NS_IMETHODIMP nsHyperTextAccessible::GetExtState(PRUint32 *aExtState)
+NS_IMETHODIMP
+nsHyperTextAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  *aExtState = 0;
-  if (!mDOMNode) {
-    return NS_ERROR_FAILURE; // Node is shut down
-  }
+  nsresult rv = nsAccessibleWrap::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
 
-  nsresult rv = nsAccessibleWrap::GetExtState(aExtState);
+  if (!aExtraState)
+    return NS_OK;
+
   nsCOMPtr<nsIEditor> editor = GetEditor();
   if (editor) {
     PRUint32 flags;
     editor->GetFlags(&flags);
     if (0 == (flags & nsIPlaintextEditor::eEditorReadonlyMask)) {
-      *aExtState |= nsIAccessibleStates::EXT_STATE_EDITABLE;
+      *aExtraState |= nsIAccessibleStates::EXT_STATE_EDITABLE;
     }
   }
 
   PRInt32 childCount;
   GetChildCount(&childCount);
   if (childCount > 0) {
-    *aExtState |= nsIAccessibleStates::EXT_STATE_SELECTABLE_TEXT;
+    *aExtraState |= nsIAccessibleStates::EXT_STATE_SELECTABLE_TEXT;
   }
-  return rv;
+
+  return NS_OK;
 }
 
 void nsHyperTextAccessible::CacheChildren()
 {
   if (!mWeakShell) {
     // This node has been shut down
     mAccChildCount = eChildCountUninitialized;
     return;
--- a/accessible/src/html/nsHyperTextAccessible.h
+++ b/accessible/src/html/nsHyperTextAccessible.h
@@ -70,17 +70,17 @@ public:
   nsHyperTextAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIACCESSIBLETEXT
   NS_DECL_NSIACCESSIBLEHYPERTEXT
   NS_DECL_NSIACCESSIBLEEDITABLETEXT
   NS_DECL_NSIEDITACTIONLISTENER
 
   NS_IMETHOD GetRole(PRUint32 *aRole);
-  NS_IMETHOD GetExtState(PRUint32 *aState);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
   void CacheChildren();
 
 protected:
   PRBool IsHyperText();
 
   /*
    * This does the work for nsIAccessibleText::GetText[At|Before|After]Offset
--- a/accessible/src/mac/mozAccessible.mm
+++ b/accessible/src/mac/mozAccessible.mm
@@ -467,37 +467,37 @@ GetNativeFromGeckoAccessible(nsIAccessib
 - (NSString*)description
 {
   return [NSString stringWithFormat:@"(%p) %@", self, [self role]];
 }
 
 - (BOOL)isFocused
 {
   PRUint32 state = 0;
-  mGeckoAccessible->GetFinalState (&state);
+  mGeckoAccessible->GetFinalState (&state, nsnull);
   return (state & nsIAccessibleStates::STATE_FOCUSED) != 0;
 }
 
 - (BOOL)canBeFocused
 {
   PRUint32 state = 0;
-  mGeckoAccessible->GetFinalState (&state);
+  mGeckoAccessible->GetFinalState (&state, nsnull);
   return (state & nsIAccessibleStates::STATE_FOCUSABLE) != 0;
 }
 
 - (BOOL)focus
 {
   nsresult rv = mGeckoAccessible->TakeFocus();
   return NS_SUCCEEDED(rv);
 }
 
 - (BOOL)isEnabled
 {
   PRUint32 state = 0;
-  mGeckoAccessible->GetFinalState (&state);
+  mGeckoAccessible->GetFinalState (&state, nsnull);
   return (state & nsIAccessibleStates::STATE_UNAVAILABLE) == 0;
 }
 
 // The root accessible calls this when the focused node was
 // changed to us.
 - (void)didReceiveFocus
 {
 #ifdef DEBUG_hakan
--- a/accessible/src/mac/mozTextAccessible.mm
+++ b/accessible/src/mac/mozTextAccessible.mm
@@ -108,17 +108,17 @@ extern const NSString *kTopLevelUIElemen
 
 - (BOOL)isReadOnly
 {
   if ([[self role] isEqualToString:NSAccessibilityStaticTextRole])
     return YES;
     
   if (mGeckoEditableTextAccessible) {
     PRUint32 state = 0;
-    mGeckoAccessible->GetFinalState(&state);
+    mGeckoAccessible->GetFinalState(&state, nsnull);
     return (state & nsIAccessibleStates::STATE_READONLY) == 0;
   }
 
   return NO;
 }
 
 - (void)setText:(NSString*)newString
 {
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -529,18 +529,18 @@ STDMETHODIMP nsAccessibleWrap::get_accSt
   pvarState->vt = VT_I4;
   pvarState->lVal = 0;
 
   nsCOMPtr<nsIAccessible> xpAccessible;
   GetXPAccessibleFor(varChild, getter_AddRefs(xpAccessible));
   if (!xpAccessible)
     return E_FAIL;
 
-  PRUint32 state;
-  if (NS_FAILED(xpAccessible->GetFinalState(&state)))
+  PRUint32 state = 0, extraState;
+  if (NS_FAILED(xpAccessible->GetFinalState(&state, &extraState)))
     return E_FAIL;
 
   pvarState->lVal = state;
 
   return S_OK;
 }
 
 
@@ -1172,62 +1172,57 @@ nsAccessibleWrap::get_localizedRoleName(
 
 STDMETHODIMP
 nsAccessibleWrap::get_states(AccessibleStates *aStates)
 {
   *aStates = 0;
 
   // XXX: bug 344674 should come with better approach that we have here.
 
-  PRUint32 states = 0;
-  nsresult rv = GetState(&states);
+  PRUint32 states = 0, extraStates = 0;
+  nsresult rv = GetFinalState(&states, &extraStates);
   if (NS_FAILED(rv))
     return E_FAIL;
 
   if (states & nsIAccessibleStates::STATE_INVALID)
     *aStates |= IA2_STATE_INVALID_ENTRY;
   else if (states & nsIAccessibleStates::STATE_REQUIRED)
     *aStates |= IA2_STATE_REQUIRED;
 
-  states = 0;
-  rv = GetExtState(&states);
-  if (NS_FAILED(rv))
-    return E_FAIL;
-
   // The following IA2 states are not supported by Gecko
   // IA2_STATE_ARMED
   // IA2_STATE_MANAGES_DESCENDAN
   // IA2_STATE_ICONIFIED
   // IA2_STATE_INVALID
 
-  if (states & nsIAccessibleStates::EXT_STATE_ACTIVE)
+  if (extraStates & nsIAccessibleStates::EXT_STATE_ACTIVE)
     *aStates |= IA2_STATE_ACTIVE;
-  else if (states & nsIAccessibleStates::EXT_STATE_DEFUNCT)
+  else if (extraStates & nsIAccessibleStates::EXT_STATE_DEFUNCT)
     *aStates |= IA2_STATE_DEFUNCT;
-  else if (states & nsIAccessibleStates::EXT_STATE_EDITABLE)
+  else if (extraStates & nsIAccessibleStates::EXT_STATE_EDITABLE)
     *aStates |= IA2_STATE_EDITABLE;
-  else if (states & nsIAccessibleStates::EXT_STATE_HORIZONTAL)
+  else if (extraStates & nsIAccessibleStates::EXT_STATE_HORIZONTAL)
     *aStates |= IA2_STATE_HORIZONTAL;
-  else if (states & nsIAccessibleStates::EXT_STATE_MODAL)
+  else if (extraStates & nsIAccessibleStates::EXT_STATE_MODAL)
     *aStates |= IA2_STATE_MODAL;
-  else if (states & nsIAccessibleStates::EXT_STATE_MULTI_LINE)
+  else if (extraStates & nsIAccessibleStates::EXT_STATE_MULTI_LINE)
     *aStates |= IA2_STATE_MULTI_LINE;
-  else if (states & nsIAccessibleStates::EXT_STATE_OPAQUE)
+  else if (extraStates & nsIAccessibleStates::EXT_STATE_OPAQUE)
     *aStates |= IA2_STATE_OPAQUE;
-  else if (states & nsIAccessibleStates::EXT_STATE_SELECTABLE_TEXT)
+  else if (extraStates & nsIAccessibleStates::EXT_STATE_SELECTABLE_TEXT)
     *aStates |= IA2_STATE_SELECTABLE_TEXT;
-  else if (states & nsIAccessibleStates::EXT_STATE_SINGLE_LINE)
+  else if (extraStates & nsIAccessibleStates::EXT_STATE_SINGLE_LINE)
     *aStates |= IA2_STATE_SINGLE_LINE;
-  else if (states & nsIAccessibleStates::EXT_STATE_STALE)
+  else if (extraStates & nsIAccessibleStates::EXT_STATE_STALE)
     *aStates |= IA2_STATE_STALE;
-  else if (states & nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION)
+  else if (extraStates & nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION)
     *aStates |= IA2_STATE_SUPPORTS_AUTOCOMPLETION;
-  else if (states & nsIAccessibleStates::EXT_STATE_TRANSIENT)
+  else if (extraStates & nsIAccessibleStates::EXT_STATE_TRANSIENT)
     *aStates |= IA2_STATE_TRANSIENT;
-  else if (states & nsIAccessibleStates::EXT_STATE_VERTICAL)
+  else if (extraStates & nsIAccessibleStates::EXT_STATE_VERTICAL)
     *aStates |= IA2_STATE_VERTICAL;
 
   return S_OK;
 }
 
 STDMETHODIMP
 nsAccessibleWrap::get_localizedStateNames(long maxLocalizedStateNames,
                                           BSTR **localizedStateNames,
--- a/accessible/src/xforms/nsXFormsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsAccessible.cpp
@@ -165,17 +165,17 @@ nsXFormsAccessible::CacheSelectChildren(
 NS_IMETHODIMP
 nsXFormsAccessible::GetValue(nsAString& aValue)
 {
   NS_ENSURE_TRUE(sXFormsService, NS_ERROR_FAILURE);
   return sXFormsService->GetValue(mDOMNode, aValue);
 }
 
 NS_IMETHODIMP
-nsXFormsAccessible::GetState(PRUint32 *aState)
+nsXFormsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   NS_ENSURE_ARG_POINTER(aState);
   *aState = 0;
 
   NS_ENSURE_TRUE(sXFormsService, NS_ERROR_FAILURE);
 
   PRBool isRelevant = PR_FALSE;
   nsresult rv = sXFormsService->IsRelevant(mDOMNode, &isRelevant);
@@ -188,17 +188,17 @@ nsXFormsAccessible::GetState(PRUint32 *a
   PRBool isRequired = PR_FALSE;
   rv = sXFormsService->IsRequired(mDOMNode, &isRequired);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRBool isValid = PR_FALSE;
   rv = sXFormsService->IsValid(mDOMNode, &isValid);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  rv = nsHyperTextAccessible::GetState(aState);
+  rv = nsHyperTextAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!isRelevant)
     *aState |= nsIAccessibleStates::STATE_UNAVAILABLE;
 
   if (isReadonly)
     *aState |= nsIAccessibleStates::STATE_READONLY;
 
@@ -297,48 +297,46 @@ nsXFormsContainerAccessible::GetAllowsAn
 
 nsXFormsEditableAccessible::
   nsXFormsEditableAccessible(nsIDOMNode *aNode, nsIWeakReference *aShell):
   nsXFormsAccessible(aNode, aShell)
 {
 }
 
 NS_IMETHODIMP
-nsXFormsEditableAccessible::GetExtState(PRUint32 *aExtState)
+nsXFormsEditableAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  NS_ENSURE_ARG_POINTER(aExtState);
+  NS_ENSURE_ARG_POINTER(aState);
 
-  *aExtState = 0;
-
-  nsresult rv = nsXFormsAccessible::GetExtState(aExtState);
+  nsresult rv = nsXFormsAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (!mEditor)
+  if (!aExtraState || !mEditor)
     return NS_OK;
 
   PRBool isReadonly = PR_FALSE;
   rv = sXFormsService->IsReadonly(mDOMNode, &isReadonly);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!isReadonly) {
     PRBool isRelevant = PR_FALSE;
     rv = sXFormsService->IsRelevant(mDOMNode, &isRelevant);
     NS_ENSURE_SUCCESS(rv, rv);
     if (isRelevant) {
-      *aExtState |= nsIAccessibleStates::EXT_STATE_EDITABLE |
-                    nsIAccessibleStates::EXT_STATE_SELECTABLE_TEXT;
+      *aExtraState |= nsIAccessibleStates::EXT_STATE_EDITABLE |
+                      nsIAccessibleStates::EXT_STATE_SELECTABLE_TEXT;
     }
   }
 
   PRUint32 flags;
   mEditor->GetFlags(&flags);
   if (flags & nsIPlaintextEditor::eEditorSingleLineMask)
-    *aExtState |= nsIAccessibleStates::EXT_STATE_SINGLE_LINE;
+    *aExtraState |= nsIAccessibleStates::EXT_STATE_SINGLE_LINE;
   else
-    *aExtState |= nsIAccessibleStates::EXT_STATE_MULTI_LINE;
+    *aExtraState |= nsIAccessibleStates::EXT_STATE_MULTI_LINE;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXFormsEditableAccessible::Init()
 {
   nsCOMPtr<nsIEditor> editor;
--- a/accessible/src/xforms/nsXFormsAccessible.h
+++ b/accessible/src/xforms/nsXFormsAccessible.h
@@ -72,17 +72,17 @@ class nsXFormsAccessible : public nsHype
 public:
   nsXFormsAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
 
   // Returns value of instance node that xforms element is bound to.
   NS_IMETHOD GetValue(nsAString& aValue);
 
   // Returns state of xforms element taking into account state of instance node
   // that it is bound to.
-  NS_IMETHOD GetState(PRUint32 *aState);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
 
   // Returns value of child xforms 'label' element.
   NS_IMETHOD GetName(nsAString& aName);
 
   // Returns value of child xforms 'hint' element.
   NS_IMETHOD GetDescription(nsAString& aDescription);
 
   // Appends ARIA 'datatype' property based on datatype of instance node that
@@ -140,17 +140,17 @@ public:
  * The class is base for accessible objects for XForms elements that have
  * editable area.
  */
 class nsXFormsEditableAccessible : public nsXFormsAccessible
 {
 public:
   nsXFormsEditableAccessible(nsIDOMNode *aNode, nsIWeakReference *aShell);
 
-  NS_IMETHOD GetExtState(PRUint32 *aState);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
 
   NS_IMETHOD Init();
   NS_IMETHOD Shutdown();
 
 protected:
   virtual void SetEditor(nsIEditor *aEditor);
   virtual already_AddRefed<nsIEditor> GetEditor();
 
--- a/accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
@@ -201,19 +201,19 @@ nsXFormsInputBooleanAccessible::GetRole(
 {
   NS_ENSURE_ARG_POINTER(aRole);
 
   *aRole = nsIAccessibleRole::ROLE_CHECKBUTTON;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXFormsInputBooleanAccessible::GetState(PRUint32 *aState)
+nsXFormsInputBooleanAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsresult rv = nsXFormsAccessible::GetState(aState);
+  nsresult rv = nsXFormsAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoString value;
   rv = sXFormsService->GetValue(mDOMNode, value);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (value.EqualsLiteral("true"))
     *aState |= nsIAccessibleStates::STATE_CHECKED;
@@ -287,19 +287,19 @@ nsXFormsSecretAccessible::GetRole(PRUint
 {
   NS_ENSURE_ARG_POINTER(aRole);
 
   *aRole = nsIAccessibleRole::ROLE_PASSWORD_TEXT;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXFormsSecretAccessible::GetState(PRUint32 *aState)
+nsXFormsSecretAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsresult rv = nsXFormsInputAccessible::GetState(aState);
+  nsresult rv = nsXFormsInputAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
 
   *aState |= nsIAccessibleStates::STATE_PROTECTED;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXFormsSecretAccessible::GetValue(nsAString& aValue)
@@ -321,19 +321,19 @@ nsXFormsRangeAccessible::GetRole(PRUint3
 {
   NS_ENSURE_ARG_POINTER(aRole);
 
   *aRole = nsIAccessibleRole::ROLE_SLIDER;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXFormsRangeAccessible::GetState(PRUint32 *aState)
+nsXFormsRangeAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsresult rv = nsXFormsAccessible::GetState(aState);
+  nsresult rv = nsXFormsAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRUint32 isInRange = nsIXFormsUtilityService::STATE_NOT_A_RANGE;
   rv = sXFormsService->IsInRange(mDOMNode, &isInRange);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (isInRange == nsIXFormsUtilityService::STATE_OUT_OF_RANGE)
     *aState |= nsIAccessibleStates::STATE_INVALID;
@@ -402,19 +402,19 @@ nsXFormsRangeAccessible::GetCurrentValue
 
 nsXFormsSelectAccessible::
   nsXFormsSelectAccessible(nsIDOMNode *aNode, nsIWeakReference *aShell):
   nsXFormsContainerAccessible(aNode, aShell)
 {
 }
 
 NS_IMETHODIMP
-nsXFormsSelectAccessible::GetState(PRUint32 *aState)
+nsXFormsSelectAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsresult rv = nsXFormsContainerAccessible::GetState(aState);
+  nsresult rv = nsXFormsContainerAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRUint32 isInRange = nsIXFormsUtilityService::STATE_NOT_A_RANGE;
   rv = sXFormsService->IsInRange(mDOMNode, &isInRange);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (isInRange == nsIXFormsUtilityService::STATE_OUT_OF_RANGE)
     *aState |= nsIAccessibleStates::STATE_INVALID;
@@ -492,19 +492,20 @@ nsXFormsItemCheckgroupAccessible::GetRol
 {
   NS_ENSURE_ARG_POINTER(aRole);
 
   *aRole = nsIAccessibleRole::ROLE_CHECKBUTTON;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXFormsItemCheckgroupAccessible::GetState(PRUint32 *aState)
+nsXFormsItemCheckgroupAccessible::GetState(PRUint32 *aState,
+                                           PRUint32 *aExtraState)
 {
-  nsresult rv = nsXFormsSelectableItemAccessible::GetState(aState);
+  nsresult rv = nsXFormsSelectableItemAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (IsItemSelected())
     *aState |= nsIAccessibleStates::STATE_CHECKED;
 
   return NS_OK;
 }
 
@@ -536,19 +537,20 @@ nsXFormsItemRadiogroupAccessible::GetRol
 {
   NS_ENSURE_ARG_POINTER(aRole);
 
   *aRole = nsIAccessibleRole::ROLE_RADIOBUTTON;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXFormsItemRadiogroupAccessible::GetState(PRUint32 *aState)
+nsXFormsItemRadiogroupAccessible::GetState(PRUint32 *aState,
+                                           PRUint32 *aExtraState)
 {
-  nsresult rv = nsXFormsSelectableItemAccessible::GetState(aState);
+  nsresult rv = nsXFormsSelectableItemAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (IsItemSelected())
     *aState |= nsIAccessibleStates::STATE_CHECKED;
 
   return NS_OK;
 }
 
@@ -576,19 +578,20 @@ nsXFormsSelectComboboxAccessible::GetRol
 {
   NS_ENSURE_ARG_POINTER(aRole);
 
   *aRole = nsIAccessibleRole::ROLE_COMBOBOX;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXFormsSelectComboboxAccessible::GetState(PRUint32 *aState)
+nsXFormsSelectComboboxAccessible::GetState(PRUint32 *aState,
+                                           PRUint32 *aExtraState)
 {
-  nsresult rv = nsXFormsSelectableAccessible::GetState(aState);
+  nsresult rv = nsXFormsSelectableAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRBool isOpen = PR_FALSE;
   rv = sXFormsService->IsDropmarkerOpen(mDOMNode, &isOpen);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (isOpen)
     *aState = nsIAccessibleStates::STATE_EXPANDED;
@@ -623,19 +626,20 @@ nsXFormsItemComboboxAccessible::GetRole(
 {
   NS_ENSURE_ARG_POINTER(aRole);
 
   *aRole = nsIAccessibleRole::ROLE_LISTITEM;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXFormsItemComboboxAccessible::GetState(PRUint32 *aState)
+nsXFormsItemComboboxAccessible::GetState(PRUint32 *aState,
+                                         PRUint32 *aExtraState)
 {
-  nsresult rv = nsXFormsSelectableItemAccessible::GetState(aState);
+  nsresult rv = nsXFormsSelectableItemAccessible::GetState(aState, aExtraState);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (*aState & nsIAccessibleStates::STATE_UNAVAILABLE)
     return NS_OK;
 
   *aState |= nsIAccessibleStates::STATE_SELECTABLE;
   if (IsItemSelected())
     *aState |= nsIAccessibleStates::STATE_SELECTED;
--- a/accessible/src/xforms/nsXFormsFormControlsAccessible.h
+++ b/accessible/src/xforms/nsXFormsFormControlsAccessible.h
@@ -104,17 +104,17 @@ public:
  */
 
 class nsXFormsInputBooleanAccessible : public nsXFormsAccessible
 {
 public:
   nsXFormsInputBooleanAccessible(nsIDOMNode *aNode, nsIWeakReference *aShell);
 
   NS_IMETHOD GetRole(PRUint32 *aRole);
-  NS_IMETHOD GetState(PRUint32 *aState);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetNumActions(PRUint8 *aCount);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 aIndex);
 };
 
 /**
  * Accessible object for xforms:input[type="xsd:date"].
  */
@@ -132,32 +132,32 @@ public:
  */
 
 class nsXFormsSecretAccessible : public nsXFormsInputAccessible
 {
 public:
   nsXFormsSecretAccessible(nsIDOMNode *aNode, nsIWeakReference *aShell);
 
   NS_IMETHOD GetRole(PRUint32 *aRole);
-  NS_IMETHOD GetState(PRUint32 *aState);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetValue(nsAString& aValue);
 };
 
 
 /**
  * Accessible object for xforms:range.
  */
 
 class nsXFormsRangeAccessible : public nsXFormsAccessible
 {
 public:
   nsXFormsRangeAccessible(nsIDOMNode *aNode, nsIWeakReference *aShell);
 
   NS_IMETHOD GetRole(PRUint32 *aRole);
-  NS_IMETHOD GetState(PRUint32 *aState);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
 
   // nsIAccessibleValue
   NS_IMETHOD GetMaximumValue(double *aMaximumValue);
   NS_IMETHOD GetMinimumValue(double *aMinimumValue);
   NS_IMETHOD GetMinimumIncrement(double *aMinimumIncrement);
   NS_IMETHOD GetCurrentValue(double *aCurrentValue);
 };
 
@@ -167,17 +167,17 @@ public:
  * using host document's native widget.
  */
 
 class nsXFormsSelectAccessible : public nsXFormsContainerAccessible
 {
 public:
   nsXFormsSelectAccessible(nsIDOMNode *aNode, nsIWeakReference *aShell);
 
-  NS_IMETHOD GetState(PRUint32 *aState);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
 };
 
 
 /**
  * Accessible object for xforms:choices.
  */
 
 class nsXFormsChoicesAccessible : public nsXFormsAccessible
@@ -215,50 +215,50 @@ public:
  */
 
 class nsXFormsItemCheckgroupAccessible : public nsXFormsSelectableItemAccessible
 {
 public:
   nsXFormsItemCheckgroupAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
 
   NS_IMETHOD GetRole(PRUint32 *aRole);
-  NS_IMETHOD GetState(PRUint32 *aState);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
 };
 
 
 /**
  * Accessible object for a xforms:item when it is represented by a radiobutton.
  * This occurs when the item is contained in a xforms:select1 with full
  * appearance. Such a xforms:select1 is represented as a radiogroup.
  */
 
 class nsXFormsItemRadiogroupAccessible : public nsXFormsSelectableItemAccessible
 {
 public:
   nsXFormsItemRadiogroupAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
 
   NS_IMETHOD GetRole(PRUint32 *aRole);
-  NS_IMETHOD GetState(PRUint32 *aState);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
 };
 
 
 /**
  * Accessible object for xforms:select1 of minimal appearance that is
  * represented by combobox.
  */
 
 class nsXFormsSelectComboboxAccessible : public nsXFormsSelectableAccessible
 {
 public:
   nsXFormsSelectComboboxAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
 
   NS_IMETHOD GetRole(PRUint32 *aRole);
-  NS_IMETHOD GetState(PRUint32 *aState);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
 
   // Allows accessible nodes in anonymous content of xforms element by
   // always returning PR_TRUE value.
   NS_IMETHOD GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren);
 };
 
 
 /**
@@ -268,14 +268,14 @@ public:
  */
 
 class nsXFormsItemComboboxAccessible : public nsXFormsSelectableItemAccessible
 {
 public:
   nsXFormsItemComboboxAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
 
   NS_IMETHOD GetRole(PRUint32 *aRole);
-  NS_IMETHOD GetState(PRUint32 *aState);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
 };
 
 #endif
 
--- a/accessible/src/xforms/nsXFormsWidgetsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsWidgetsAccessible.cpp
@@ -51,21 +51,24 @@ nsXFormsDropmarkerWidgetAccessible::GetR
 {
   NS_ENSURE_ARG_POINTER(aRole);
 
   *aRole = nsIAccessibleRole::ROLE_PUSHBUTTON;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXFormsDropmarkerWidgetAccessible::GetState(PRUint32 *aState)
+nsXFormsDropmarkerWidgetAccessible::GetState(PRUint32 *aState,
+                                             PRUint32 *aExtraState)
 {
   NS_ENSURE_ARG_POINTER(aState);
 
   *aState = 0;
+  if (aExtraState)
+    *aExtraState = 0;
 
   PRBool isOpen = PR_FALSE;
   nsresult rv = sXFormsService->IsDropmarkerOpen(mDOMNode, &isOpen);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (isOpen)
     *aState = nsIAccessibleStates::STATE_PRESSED;
 
@@ -141,24 +144,26 @@ nsXFormsComboboxPopupWidgetAccessible::G
 {
   NS_ENSURE_ARG_POINTER(aRole);
 
   *aRole = nsIAccessibleRole::ROLE_LIST;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsXFormsComboboxPopupWidgetAccessible::GetState(PRUint32 *aState)
+nsXFormsComboboxPopupWidgetAccessible::GetState(PRUint32 *aState,
+                                                PRUint32 *aExtraState)
 {
   NS_ENSURE_ARG_POINTER(aState);
 
-  nsXFormsAccessible::GetState(aState);
+  nsresult rv = nsXFormsAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   PRBool isOpen = PR_FALSE;
-  nsresult rv = sXFormsService->IsDropmarkerOpen(mDOMNode, &isOpen);
+  rv = sXFormsService->IsDropmarkerOpen(mDOMNode, &isOpen);
   NS_ENSURE_SUCCESS(rv, rv);
 
   *aState |= nsIAccessibleStates::STATE_FOCUSABLE;
 
   if (isOpen)
     *aState = nsIAccessibleStates::STATE_FLOATING;
   else
     *aState = nsIAccessibleStates::STATE_INVISIBLE;
--- a/accessible/src/xforms/nsXFormsWidgetsAccessible.h
+++ b/accessible/src/xforms/nsXFormsWidgetsAccessible.h
@@ -50,17 +50,17 @@
 class nsXFormsDropmarkerWidgetAccessible : public nsLeafAccessible,
                                            public nsXFormsAccessibleBase
 {
 public:
   nsXFormsDropmarkerWidgetAccessible(nsIDOMNode *aNode,
                                      nsIWeakReference *aShell);
 
   NS_IMETHOD GetRole(PRUint32 *aRole);
-  NS_IMETHOD GetState(PRUint32 *aState);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
 
   NS_IMETHOD GetNumActions(PRUint8 *aCount);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 aIndex);
 };
 
 
 /**
@@ -81,17 +81,17 @@ public:
  */
 class nsXFormsComboboxPopupWidgetAccessible : public nsXFormsAccessible
 {
 public:
   nsXFormsComboboxPopupWidgetAccessible(nsIDOMNode *aNode,
                                         nsIWeakReference *aShell);
 
   NS_IMETHOD GetRole(PRUint32 *aRole);
-  NS_IMETHOD GetState(PRUint32 *aState);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetValue(nsAString& aValue);
   NS_IMETHOD GetName(nsAString& aName);
   NS_IMETHOD GetDescription(nsAString& aDescription);
 
   void CacheChildren();
 };
 
 #endif
--- a/accessible/src/xul/nsXULAlertAccessible.cpp
+++ b/accessible/src/xul/nsXULAlertAccessible.cpp
@@ -48,19 +48,22 @@ nsXULAlertAccessible::nsXULAlertAccessib
 }
 
 NS_IMETHODIMP nsXULAlertAccessible::GetRole(PRUint32 *aRole)
 {
   *aRole = nsIAccessibleRole::ROLE_ALERT;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsXULAlertAccessible::GetState(PRUint32 *aState)
+NS_IMETHODIMP
+nsXULAlertAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsAccessible::GetState(aState);
+  nsresult rv = nsAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;
   *aState |= nsIAccessibleStates::STATE_ALERT_MEDIUM; // XUL has no markup for low, medium or high
   return NS_OK;
 }
 
 #if 0
 // We don't need this, but the AT will need to read all of the alert's children
 // when it receives EVENT_ALERT on a ROLE_ALERT
--- a/accessible/src/xul/nsXULAlertAccessible.h
+++ b/accessible/src/xul/nsXULAlertAccessible.h
@@ -44,12 +44,12 @@
  */
 
 class nsXULAlertAccessible : public nsAccessibleWrap
 {
 public:
   nsXULAlertAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_DECL_ISUPPORTS_INHERITED
   NS_IMETHOD GetRole(PRUint32 *aRole);
-  NS_IMETHOD GetState(PRUint32 *aState);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
 };
 
 #endif  
--- a/accessible/src/xul/nsXULColorPickerAccessible.cpp
+++ b/accessible/src/xul/nsXULColorPickerAccessible.cpp
@@ -60,34 +60,37 @@ NS_IMETHODIMP nsXULColorPickerTileAccess
 {
   *_retval = nsIAccessibleRole::ROLE_PUSHBUTTON;
   return NS_OK;
 }
 
 /**
   * Possible states: focused, focusable, selected
   */
-NS_IMETHODIMP nsXULColorPickerTileAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsXULColorPickerTileAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // get focus and disable status from base class
-  nsFormControlAccessible::GetState(_retval);
-  *_retval |= nsIAccessibleStates::STATE_FOCUSABLE;
+  nsresult rv = nsFormControlAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  *aState |= nsIAccessibleStates::STATE_FOCUSABLE;
 
   // Focused?
   nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
   NS_ASSERTION(element, "No XUL Element for colorpicker");
   PRBool isFocused = PR_FALSE;
   element->HasAttribute(NS_LITERAL_STRING("hover"), &isFocused);
   if (isFocused)
-    *_retval |= nsIAccessibleStates::STATE_FOCUSED;
+    *aState |= nsIAccessibleStates::STATE_FOCUSED;
 
   PRBool isSelected = PR_FALSE;
   element->HasAttribute(NS_LITERAL_STRING("selected"), &isSelected);
   if (isFocused)
-    *_retval |= nsIAccessibleStates::STATE_SELECTED;
+    *aState |= nsIAccessibleStates::STATE_SELECTED;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsXULColorPickerTileAccessible::GetName(nsAString& _retval)
 {
   return GetXULName(_retval);
 }
@@ -109,22 +112,25 @@ NS_IMETHODIMP nsXULColorPickerTileAccess
 nsXULColorPickerAccessible::nsXULColorPickerAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
 nsXULColorPickerTileAccessible(aNode, aShell)
 { 
 }
 
 /**
   * Possible states: focused, focusable, unavailable(disabled)
   */
-NS_IMETHODIMP nsXULColorPickerAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsXULColorPickerAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // get focus and disable status from base class
-  nsFormControlAccessible::GetState(_retval);
-  *_retval |= nsIAccessibleStates::STATE_FOCUSABLE |
-              nsIAccessibleStates::STATE_HASPOPUP;
+  nsresult rv = nsFormControlAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  *aState |= nsIAccessibleStates::STATE_FOCUSABLE |
+             nsIAccessibleStates::STATE_HASPOPUP;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsXULColorPickerAccessible::GetRole(PRUint32 *_retval)
 {
   *_retval = nsIAccessibleRole::ROLE_BUTTONDROPDOWNGRID;
   return NS_OK;
--- a/accessible/src/xul/nsXULColorPickerAccessible.h
+++ b/accessible/src/xul/nsXULColorPickerAccessible.h
@@ -42,22 +42,22 @@
 // NOTE: alphabetically ordered
 #include "nsFormControlAccessible.h"
 
 class nsXULColorPickerTileAccessible : public nsFormControlAccessible
 {
 public:
   nsXULColorPickerTileAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *_retval);
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetName(nsAString& _retval);
   NS_IMETHOD GetValue(nsAString& _retval);
 };
 
 class nsXULColorPickerAccessible : public nsXULColorPickerTileAccessible
 {
 public:
   nsXULColorPickerAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetRole(PRUint32 *_retval);
 };
 
 #endif  
--- a/accessible/src/xul/nsXULFormControlAccessible.cpp
+++ b/accessible/src/xul/nsXULFormControlAccessible.cpp
@@ -108,23 +108,25 @@ NS_IMETHODIMP nsXULButtonAccessible::Get
 {
   *_retval = nsIAccessibleRole::ROLE_PUSHBUTTON;
   return NS_OK;
 }
 
 /**
   * Possible states: focused, focusable, unavailable(disabled)
   */
-NS_IMETHODIMP nsXULButtonAccessible::GetState(PRUint32 *aState)
+NS_IMETHODIMP
+nsXULButtonAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // get focus and disable status from base class
-  nsAccessible::GetState(aState);
+  nsresult rv = nsAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   PRBool disabled = PR_FALSE;
-  nsCOMPtr<nsIDOMXULControlElement> xulFormElement(do_QueryInterface(mDOMNode));  
+  nsCOMPtr<nsIDOMXULControlElement> xulFormElement(do_QueryInterface(mDOMNode));
   if (xulFormElement) {
     xulFormElement->GetDisabled(&disabled);
     if (disabled)
       *aState |= nsIAccessibleStates::STATE_UNAVAILABLE;
     else 
       *aState |= nsIAccessibleStates::STATE_FOCUSABLE;
   }
 
@@ -275,22 +277,25 @@ NS_IMETHODIMP nsXULDropmarkerAccessible:
   * We are a pushbutton
   */
 NS_IMETHODIMP nsXULDropmarkerAccessible::GetRole(PRUint32 *aResult)
 {
   *aResult = nsIAccessibleRole::ROLE_PUSHBUTTON;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsXULDropmarkerAccessible::GetState(PRUint32 *aResult)
+NS_IMETHODIMP
+nsXULDropmarkerAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  *aResult = 0;
-  
+  *aState = 0;
+  if (aExtraState)
+    *aExtraState = 0;
+
   if (DropmarkerOpen(PR_FALSE))
-    *aResult = nsIAccessibleStates::STATE_PRESSED;
+    *aState = nsIAccessibleStates::STATE_PRESSED;
 
   return NS_OK;
 }
 
 /**
   * XUL checkbox
   */
 
@@ -323,17 +328,17 @@ NS_IMETHODIMP nsXULCheckboxAccessible::G
 /**
   * Return the name of our only action
   */
 NS_IMETHODIMP nsXULCheckboxAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
 {
   if (aIndex == eAction_Click) {
     // check or uncheck
     PRUint32 state;
-    GetState(&state);
+    GetState(&state, nsnull);
 
     if (state & nsIAccessibleStates::STATE_CHECKED)
       aName.AssignLiteral("uncheck");
     else
       aName.AssignLiteral("check");
 
     return NS_OK;
   }
@@ -349,35 +354,37 @@ NS_IMETHODIMP nsXULCheckboxAccessible::D
    return DoCommand();
   }
   return NS_ERROR_INVALID_ARG;
 }
 
 /**
   * Possible states: focused, focusable, unavailable(disabled), checked
   */
-NS_IMETHODIMP nsXULCheckboxAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsXULCheckboxAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // Get focus and disable status from base class
-  nsFormControlAccessible::GetState(_retval);
+  nsresult rv = nsFormControlAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   // Determine Checked state
   nsCOMPtr<nsIDOMXULCheckboxElement> xulCheckboxElement(do_QueryInterface(mDOMNode));
   if (xulCheckboxElement) {
     PRBool checked = PR_FALSE;
     xulCheckboxElement->GetChecked(&checked);
     if (checked) {
-      *_retval |= nsIAccessibleStates::STATE_CHECKED;
+      *aState |= nsIAccessibleStates::STATE_CHECKED;
       PRInt32 checkState = 0;
       xulCheckboxElement->GetCheckState(&checkState);
-      if (checkState == nsIDOMXULCheckboxElement::CHECKSTATE_MIXED)   
-        *_retval |= nsIAccessibleStates::STATE_MIXED;
+      if (checkState == nsIDOMXULCheckboxElement::CHECKSTATE_MIXED)
+        *aState |= nsIAccessibleStates::STATE_MIXED;
     }
   }
-  
+
   return NS_OK;
 }
 
 /**
   * XUL groupbox
   */
 
 nsXULGroupboxAccessible::nsXULGroupboxAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
@@ -386,21 +393,24 @@ nsAccessibleWrap(aNode, aShell)
 }
 
 NS_IMETHODIMP nsXULGroupboxAccessible::GetRole(PRUint32 *_retval)
 {
   *_retval = nsIAccessibleRole::ROLE_GROUPING;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsXULGroupboxAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsXULGroupboxAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // Groupbox doesn't support focusable state!
-  nsAccessible::GetState(_retval);
-  *_retval &= ~nsIAccessibleStates::STATE_FOCUSABLE;
+  nsresult rv = nsAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsXULGroupboxAccessible::GetName(nsAString& aName)
 {
   aName.Truncate();  // Default name is blank 
 
@@ -441,21 +451,24 @@ nsFormControlAccessible(aNode, aShell)
 }
 
 NS_IMETHODIMP nsXULProgressMeterAccessible::GetRole(PRUint32 *_retval)
 {
   *_retval = nsIAccessibleRole::ROLE_PROGRESSBAR;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsXULProgressMeterAccessible::GetState(PRUint32 *aState)
+NS_IMETHODIMP
+nsXULProgressMeterAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsresult rv = nsAccessible::GetState(aState);
+  nsresult rv = nsAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE; // Progress meters are not focusable
-  return rv;
+  return NS_OK;
 }
 
 NS_IMETHODIMP nsXULProgressMeterAccessible::GetValue(nsAString& aValue)
 {
   aValue.Truncate();
   nsAccessible::GetValue(aValue);
   if (!aValue.IsEmpty()) {
     return NS_OK;
@@ -507,26 +520,29 @@ NS_IMETHODIMP nsXULProgressMeterAccessib
 
 /** Constructor */
 nsXULRadioButtonAccessible::nsXULRadioButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
 nsRadioButtonAccessible(aNode, aShell)
 { 
 }
 
 /** We are Focusable and can be Checked and focused */
-NS_IMETHODIMP nsXULRadioButtonAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsXULRadioButtonAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsFormControlAccessible::GetState(_retval);
+  nsresult rv = nsFormControlAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   PRBool selected = PR_FALSE;   // Radio buttons can be selected
 
   nsCOMPtr<nsIDOMXULSelectControlItemElement> radioButton(do_QueryInterface(mDOMNode));
   if (radioButton) {
     radioButton->GetSelected(&selected);
     if (selected) {
-      *_retval |= nsIAccessibleStates::STATE_CHECKED;
+      *aState |= nsIAccessibleStates::STATE_CHECKED;
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULRadioButtonAccessible::GetAttributes(nsIPersistentProperties **aAttributes)
@@ -559,24 +575,28 @@ nsXULSelectableAccessible(aNode, aShell)
 }
 
 NS_IMETHODIMP nsXULRadioGroupAccessible::GetRole(PRUint32 *_retval)
 {
   *_retval = nsIAccessibleRole::ROLE_GROUPING;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsXULRadioGroupAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsXULRadioGroupAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // The radio group is not focusable.
   // Sometimes the focus controller will report that it is focused.
   // That means that the actual selected radio button should be considered focused
-  nsAccessible::GetState(_retval);
-  *_retval &= ~(nsIAccessibleStates::STATE_FOCUSABLE |
-                nsIAccessibleStates::STATE_FOCUSED);
+  nsresult rv = nsAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  *aState &= ~(nsIAccessibleStates::STATE_FOCUSABLE |
+               nsIAccessibleStates::STATE_FOCUSED);
+
   return NS_OK;
 }
 /**
   * XUL StatusBar: can contain arbitrary HTML content
   */
 
 /**
   * Default Constructor
@@ -590,40 +610,38 @@ nsAccessibleWrap(aNode, aShell)
   * We are a statusbar
   */
 NS_IMETHODIMP nsXULStatusBarAccessible::GetRole(PRUint32 *_retval)
 {
   *_retval = nsIAccessibleRole::ROLE_STATUSBAR;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsXULStatusBarAccessible::GetState(PRUint32 *_retval)
-{
-  return nsAccessible::GetState(_retval);
-}
-
 /**
   * XUL ToolBar
   */
 
 nsXULToolbarAccessible::nsXULToolbarAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
 nsAccessibleWrap(aNode, aShell)
 { 
 }
 
 NS_IMETHODIMP nsXULToolbarAccessible::GetRole(PRUint32 *_retval)
 {
   *_retval = nsIAccessibleRole::ROLE_TOOLBAR;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsXULToolbarAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsXULToolbarAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsAccessible::GetState(_retval);
-  *_retval &= ~nsIAccessibleStates::STATE_FOCUSABLE;  // toolbar is not focusable
+  nsresult rv = nsAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;  // toolbar is not focusable
   return NS_OK;
 }
 
 /**
   * XUL Toolbar Separator
   */
 
 nsXULToolbarSeparatorAccessible::nsXULToolbarSeparatorAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell):
@@ -632,19 +650,24 @@ nsLeafAccessible(aNode, aShell)
 }
 
 NS_IMETHODIMP nsXULToolbarSeparatorAccessible::GetRole(PRUint32 *_retval)
 {
   *_retval = nsIAccessibleRole::ROLE_SEPARATOR;
   return NS_OK;
 }
 
-NS_IMETHODIMP nsXULToolbarSeparatorAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsXULToolbarSeparatorAccessible::GetState(PRUint32 *aState,
+                                          PRUint32 *aExtraState)
 {
-  *_retval = 0;  // no special state flags for toolbar separator
+  *aState = 0;  // no special state flags for toolbar separator
+  if (aExtraState)
+    *aExtraState = 0;
+
   return NS_OK;
 }
 
 /**
   * XUL Textfield
   */
 
 nsXULTextFieldAccessible::nsXULTextFieldAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell) :
@@ -667,87 +690,65 @@ NS_IMETHODIMP nsXULTextFieldAccessible::
     mEditor = nsnull;
   }
   return nsHyperTextAccessible::Shutdown();
 }
 
 NS_IMETHODIMP nsXULTextFieldAccessible::GetValue(nsAString& aValue)
 {
   PRUint32 state;
-  GetState(&state);
+  GetState(&state, nsnull);
   if (state & nsIAccessibleStates::STATE_PROTECTED)    // Don't return password text!
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIDOMXULTextBoxElement> textBox(do_QueryInterface(mDOMNode));
   if (textBox) {
     return textBox->GetValue(aValue);
   }
   nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mDOMNode));
   if (menuList) {
     return menuList->GetLabel(aValue);
   }
   return NS_ERROR_FAILURE;
 }
 
-NS_IMETHODIMP nsXULTextFieldAccessible::GetExtState(PRUint32 *aExtState)
-{
-  nsresult rv = nsHyperTextAccessible::GetExtState(aExtState);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
-  NS_ASSERTION(content, "Should not have gotten past nsAccessible::GetExtState() without node");
-
-  PRBool isMultiLine = content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::multiline);
-  *aExtState |= (isMultiLine ? nsIAccessibleStates::EXT_STATE_MULTI_LINE :
-                               nsIAccessibleStates::EXT_STATE_SINGLE_LINE);
-
-  PRUint32 state;
-  GetState(&state);
-  const PRUint32 kNonEditableStates = nsIAccessibleStates::STATE_READONLY |
-                                      nsIAccessibleStates::STATE_UNAVAILABLE;
-  if (0 == (state & kNonEditableStates)) {
-    *aExtState |= nsIAccessibleStates::EXT_STATE_EDITABLE;
-  }
-
-  return NS_OK;
-}
-
 already_AddRefed<nsIDOMNode> nsXULTextFieldAccessible::GetInputField()
 {
   nsIDOMNode *inputField = nsnull;
   nsCOMPtr<nsIDOMXULTextBoxElement> textBox = do_QueryInterface(mDOMNode);
   if (textBox) {
     textBox->GetInputField(&inputField);
     return inputField;
   }
   nsCOMPtr<nsIDOMXULMenuListElement> menuList = do_QueryInterface(mDOMNode);
   if (menuList) {   // <xul:menulist droppable="false">
     menuList->GetInputField(&inputField);
   }
   NS_ASSERTION(inputField, "No input field for nsXULTextFieldAccessible");
   return inputField;
 }
 
-NS_IMETHODIMP nsXULTextFieldAccessible::GetState(PRUint32 *aState)
+NS_IMETHODIMP
+nsXULTextFieldAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  if (!mDOMNode) {
-    return NS_ERROR_FAILURE;
-  }
-  nsHyperTextAccessible::GetState(aState);
+  NS_ENSURE_TRUE(mDOMNode, NS_ERROR_FAILURE);
+
+  nsresult rv = nsHyperTextAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIDOMNode> inputField = GetInputField();
-  if (!inputField) {
-    return NS_ERROR_FAILURE;
-  }
+  NS_ENSURE_TRUE(inputField, NS_ERROR_FAILURE);
+
   // Create a temporary accessible from the HTML text field
   // to get the accessible state from. Doesn't add to cache
   // because Init() is not called.
   nsHTMLTextFieldAccessible tempAccessible(inputField, mWeakShell);
-  nsresult rv = tempAccessible.GetState(aState);
+  rv = tempAccessible.GetState(aState, nsnull);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   if (gLastFocusedNode == mDOMNode) {
     *aState |= nsIAccessibleStates::STATE_FOCUSED;
   }
 
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
   NS_ASSERTION(content, "Not possible since we have an mDOMNode");
 
   nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mDOMNode));
@@ -765,17 +766,31 @@ NS_IMETHODIMP nsXULTextFieldAccessible::
       *aState |= nsIAccessibleStates::STATE_PROTECTED;
     }
     if (content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::readonly,
                              nsAccessibilityAtoms::_true, eIgnoreCase)) {
       *aState |= nsIAccessibleStates::STATE_READONLY;
     }
   }
 
-  return rv;
+  if (!aExtraState)
+    return NS_OK;
+
+  PRBool isMultiLine = content->HasAttr(kNameSpaceID_None,
+                                        nsAccessibilityAtoms::multiline);
+
+  *aExtraState |= (isMultiLine ? nsIAccessibleStates::EXT_STATE_MULTI_LINE :
+                                 nsIAccessibleStates::EXT_STATE_SINGLE_LINE);
+
+  const PRUint32 kNonEditableStates = nsIAccessibleStates::STATE_READONLY |
+                                      nsIAccessibleStates::STATE_UNAVAILABLE;
+  if (0 == (*aState & kNonEditableStates))
+    *aExtraState |= nsIAccessibleStates::EXT_STATE_EDITABLE;
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP nsXULTextFieldAccessible::GetRole(PRUint32 *aRole)
 {
   *aRole = nsIAccessibleRole::ROLE_ENTRY;
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
   if (content &&
       content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::type,
--- a/accessible/src/xul/nsXULFormControlAccessible.h
+++ b/accessible/src/xul/nsXULFormControlAccessible.h
@@ -48,126 +48,124 @@
 
 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);
   NS_IMETHOD GetRole(PRUint32 *_retval); 
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 index);
   void CacheChildren();
 };
 
 class nsXULCheckboxAccessible : public nsFormControlAccessible
 {
 public:
   enum { eAction_Click = 0 };
   nsXULCheckboxAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *_retval); 
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 index);
-  NS_IMETHOD GetState(PRUint32 *_retval); 
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
 };
 
 class nsXULDropmarkerAccessible : public nsFormControlAccessible
 {
 public:
   enum { eAction_Click = 0 };
   nsXULDropmarkerAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *_retval); 
-  NS_IMETHOD GetState(PRUint32 *_retval); 
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 index);
 
 private:
   PRBool DropmarkerOpen(PRBool aToggleOpen);
 };
 
 class nsXULGroupboxAccessible : public nsAccessibleWrap
 {
 public:
   nsXULGroupboxAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *_retval); 
-  NS_IMETHOD GetState(PRUint32 *_retval); 
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetName(nsAString& _retval);
 };
 
 class nsXULProgressMeterAccessible : public nsFormControlAccessible
 {
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIACCESSIBLEVALUE
 
 public:
   nsXULProgressMeterAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *aRole); 
-  NS_IMETHOD GetState(PRUint32 *aState); 
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetValue(nsAString &aValue);
 };
 
 class nsXULRadioButtonAccessible : public nsRadioButtonAccessible
 {
 
 public:
   nsXULRadioButtonAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
-  NS_IMETHOD GetState(PRUint32 *aState);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
 };
 
 class nsXULRadioGroupAccessible : public nsXULSelectableAccessible
 {
 public:
   nsXULRadioGroupAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *_retval); 
-  NS_IMETHOD GetState(PRUint32 *_retval); 
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
 };
 
 class nsXULStatusBarAccessible : public nsAccessibleWrap
 {
 public:
   nsXULStatusBarAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
-  NS_IMETHOD GetRole(PRUint32 *_retval); 
-  NS_IMETHOD GetState(PRUint32 *_retval); 
+  NS_IMETHOD GetRole(PRUint32 *aRole);
 };
 
 class nsXULToolbarAccessible : public nsAccessibleWrap
 {
 public:
   nsXULToolbarAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *_retval); 
-  NS_IMETHOD GetState(PRUint32 *_retval); 
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
 };
 
 class nsXULToolbarSeparatorAccessible : public nsLeafAccessible
 {
 public:
   nsXULToolbarSeparatorAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *_retval); 
-  NS_IMETHOD GetState(PRUint32 *_retval); 
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
 };
 
 class nsXULTextFieldAccessible : public nsHyperTextAccessible
 {
 public:
   enum { eAction_Click = 0 };
 
   NS_DECL_ISUPPORTS_INHERITED
 
   nsXULTextFieldAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
 
-  NS_IMETHOD Init(); 
-  NS_IMETHOD Shutdown(); 
+  NS_IMETHOD Init();
+  NS_IMETHOD Shutdown();
   NS_IMETHOD GetValue(nsAString& aValue);
-  NS_IMETHOD GetState(PRUint32 *aState);
-  NS_IMETHOD GetExtState(PRUint32 *aExtState);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetRole(PRUint32 *aRole);
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 index);
   NS_IMETHOD GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren);
 
 protected:
   already_AddRefed<nsIDOMNode> GetInputField();
--- a/accessible/src/xul/nsXULMenuAccessible.cpp
+++ b/accessible/src/xul/nsXULMenuAccessible.cpp
@@ -265,64 +265,68 @@ nsAccessibleWrap(aDOMNode, aShell)
 
 NS_IMETHODIMP nsXULMenuitemAccessible::Init()
 {
   nsresult rv = nsAccessibleWrap::Init();
   nsXULMenupopupAccessible::GenerateMenu(mDOMNode);
   return rv;
 }
 
-NS_IMETHODIMP nsXULMenuitemAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsXULMenuitemAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsAccessible::GetState(_retval);
+  nsresult rv = nsAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   // Focused?
   nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
   if (!element)
     return NS_ERROR_FAILURE;
   PRBool isFocused = PR_FALSE;
   element->HasAttribute(NS_LITERAL_STRING("_moz-menuactive"), &isFocused); 
   if (isFocused)
-    *_retval |= nsIAccessibleStates::STATE_FOCUSED;
+    *aState |= nsIAccessibleStates::STATE_FOCUSED;
 
   // Has Popup?
   nsAutoString tagName;
   element->GetLocalName(tagName);
   if (tagName.EqualsLiteral("menu")) {
-    *_retval |= nsIAccessibleStates::STATE_HASPOPUP;
+    *aState |= nsIAccessibleStates::STATE_HASPOPUP;
     PRBool isOpen;
     element->HasAttribute(NS_LITERAL_STRING("open"), &isOpen);
-    *_retval |= isOpen ? nsIAccessibleStates::STATE_EXPANDED :
-                         nsIAccessibleStates::STATE_COLLAPSED;
+    *aState |= isOpen ? nsIAccessibleStates::STATE_EXPANDED :
+                        nsIAccessibleStates::STATE_COLLAPSED;
   }
 
   nsAutoString menuItemType;
   element->GetAttribute(NS_LITERAL_STRING("type"), menuItemType); 
 
   if (!menuItemType.IsEmpty()) {
     // Checkable?
     if (menuItemType.EqualsIgnoreCase("radio") ||
         menuItemType.EqualsIgnoreCase("checkbox"))
-      *_retval |= nsIAccessibleStates::STATE_CHECKABLE;
+      *aState |= nsIAccessibleStates::STATE_CHECKABLE;
 
     // Checked?
     nsAutoString checkValue;
     element->GetAttribute(NS_LITERAL_STRING("checked"), checkValue);
     if (checkValue.EqualsLiteral("true")) {
-      *_retval |= nsIAccessibleStates::STATE_CHECKED;
+      *aState |= nsIAccessibleStates::STATE_CHECKED;
     }
   }
 
   // Offscreen?
   // If parent or grandparent menuitem is offscreen, then we're offscreen too
   // We get it by replacing the current offscreen bit with the parent's
   nsCOMPtr<nsIAccessible> parentAccessible(GetParent());
   if (parentAccessible) {
-    *_retval &= ~nsIAccessibleStates::STATE_OFFSCREEN;  // clear the old OFFSCREEN bit
-    *_retval |= (State(parentAccessible) & nsIAccessibleStates::STATE_OFFSCREEN);  // or it with the parent's offscreen bit
+    // clear the old OFFSCREEN bit
+    *aState &= ~nsIAccessibleStates::STATE_OFFSCREEN;
+    // or it with the parent's offscreen bit
+    *aState |= (State(parentAccessible) & nsIAccessibleStates::STATE_OFFSCREEN);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsXULMenuitemAccessible::GetName(nsAString& _retval)
 {
   nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
@@ -489,21 +493,24 @@ NS_IMETHODIMP nsXULMenuitemAccessible::G
 
 // ------------------------ Menu Separator ----------------------------
 
 nsXULMenuSeparatorAccessible::nsXULMenuSeparatorAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell): 
 nsXULMenuitemAccessible(aDOMNode, aShell)
 { 
 }
 
-NS_IMETHODIMP nsXULMenuSeparatorAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsXULMenuSeparatorAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // Isn't focusable, but can be offscreen
-  nsXULMenuitemAccessible::GetState(_retval);
-  *_retval &= nsIAccessibleStates::STATE_OFFSCREEN;
+  nsresult rv = nsXULMenuitemAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  *aState &= nsIAccessibleStates::STATE_OFFSCREEN;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsXULMenuSeparatorAccessible::GetName(nsAString& _retval)
 {
   _retval.Truncate();
   return NS_OK;
@@ -535,37 +542,41 @@ nsXULMenupopupAccessible::nsXULMenupopup
   nsXULSelectableAccessible(aDOMNode, aShell)
 { 
   // May be the anonymous <menupopup> inside <menulist> (a combobox)
   nsCOMPtr<nsIDOMNode> parentNode;
   aDOMNode->GetParentNode(getter_AddRefs(parentNode));
   mSelectControl = do_QueryInterface(parentNode);
 }
 
-NS_IMETHODIMP nsXULMenupopupAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsXULMenupopupAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // We are onscreen if our parent is active
-  *_retval = 0;
+  *aState = 0;
+  if (aExtraState)
+    *aExtraState = 0;
+
   PRBool isActive = PR_FALSE;
 
   nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
   element->HasAttribute(NS_LITERAL_STRING("menuactive"), &isActive);
   if (!isActive) {
     nsCOMPtr<nsIAccessible> parent(GetParent());
     nsCOMPtr<nsIDOMNode> parentNode;
     nsCOMPtr<nsIAccessNode> accessNode(do_QueryInterface(parent));
     if (accessNode) 
       accessNode->GetDOMNode(getter_AddRefs(parentNode));
     element = do_QueryInterface(parentNode);
     if (element)
       element->HasAttribute(NS_LITERAL_STRING("open"), &isActive);
   }
 
   if (!isActive)
-    *_retval |= nsIAccessibleStates::STATE_OFFSCREEN;
+    *aState |= nsIAccessibleStates::STATE_OFFSCREEN;
 
   return NS_OK;
 }
 
 already_AddRefed<nsIDOMNode>
 nsXULMenupopupAccessible::FindInNodeList(nsIDOMNodeList *aNodeList, 
                                          nsIAtom *aAtom, PRUint32 aNameSpaceID)
 {
@@ -637,20 +648,24 @@ NS_IMETHODIMP nsXULMenupopupAccessible::
 
 // ------------------------ Menu Bar -----------------------------
 
 nsXULMenubarAccessible::nsXULMenubarAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell): 
   nsAccessibleWrap(aDOMNode, aShell)
 { 
 }
 
-NS_IMETHODIMP nsXULMenubarAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsXULMenubarAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsresult rv = nsAccessible::GetState(_retval);
-  *_retval &= ~nsIAccessibleStates::STATE_FOCUSABLE; // Menu bar iteself is not actually focusable
+  nsresult rv = nsAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // Menu bar iteself is not actually focusable
+  *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;
   return rv;
 }
 
 
 NS_IMETHODIMP nsXULMenubarAccessible::GetName(nsAString& _retval)
 {
   _retval.AssignLiteral("Application");
 
--- a/accessible/src/xul/nsXULMenuAccessible.h
+++ b/accessible/src/xul/nsXULMenuAccessible.h
@@ -76,51 +76,51 @@ public:
   enum { eAction_Click = 0 };
 
   nsXULMenuitemAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
   NS_IMETHOD Init();
   NS_IMETHOD GetName(nsAString& _retval); 
   NS_IMETHOD GetDescription(nsAString& aDescription);
   NS_IMETHOD GetKeyboardShortcut(nsAString& _retval);
   NS_IMETHOD GetDefaultKeyBinding(nsAString& aKeyBinding);
-  NS_IMETHOD GetState(PRUint32 *_retval); 
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetRole(PRUint32 *_retval); 
   NS_IMETHOD DoAction(PRUint8 index);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
   NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
   NS_IMETHOD GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren);
 };
 
 class nsXULMenuSeparatorAccessible : public nsXULMenuitemAccessible
 {
 public:
   nsXULMenuSeparatorAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
   NS_IMETHOD GetName(nsAString& _retval); 
-  NS_IMETHOD GetState(PRUint32 *_retval); 
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetRole(PRUint32 *_retval); 
   NS_IMETHOD DoAction(PRUint8 index);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
 };
 
 class nsXULMenupopupAccessible : public nsXULSelectableAccessible
 {
 public:
   nsXULMenupopupAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
   NS_IMETHOD GetName(nsAString& _retval); 
-  NS_IMETHOD GetState(PRUint32 *_retval); 
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetRole(PRUint32 *_retval); 
   static already_AddRefed<nsIDOMNode> FindInNodeList(nsIDOMNodeList *aNodeList,
                                                      nsIAtom *aAtom, PRUint32 aNameSpaceID);
   static void GenerateMenu(nsIDOMNode *aNode);
 };
 
 class nsXULMenubarAccessible : public nsAccessibleWrap
 {
 public:
   nsXULMenubarAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
   NS_IMETHOD GetName(nsAString& _retval); 
-  NS_IMETHOD GetState(PRUint32 *_retval); 
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetRole(PRUint32 *_retval); 
 };
 
 #endif  
--- a/accessible/src/xul/nsXULSelectAccessible.cpp
+++ b/accessible/src/xul/nsXULSelectAccessible.cpp
@@ -74,20 +74,22 @@ nsXULSelectableAccessible(aDOMNode, aShe
 }
 
 /**
   * As a nsXULListboxAccessible we can have the following states:
   *     nsIAccessibleStates::STATE_FOCUSED
   *     nsIAccessibleStates::STATE_READONLY
   *     nsIAccessibleStates::STATE_FOCUSABLE
   */
-NS_IMETHODIMP nsXULListboxAccessible::GetState(PRUint32 *aState)
+NS_IMETHODIMP
+nsXULListboxAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // Get focus status from base class
-  nsAccessible::GetState(aState);
+  nsresult rv = nsAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
 
 // see if we are multiple select if so set ourselves as such
   nsCOMPtr<nsIDOMElement> element (do_QueryInterface(mDOMNode));
   if (element) {
     nsAutoString selType;
     element->GetAttribute(NS_LITERAL_STRING("seltype"), selType);
     if (!selType.IsEmpty() && selType.EqualsLiteral("multiple"))
       *aState |= nsIAccessibleStates::STATE_MULTISELECTABLE |
@@ -169,20 +171,21 @@ NS_IMETHODIMP nsXULListitemAccessible::G
   else
     *aRole = nsIAccessibleRole::ROLE_LISTITEM;
   return NS_OK;
 }
 
 /**
   *
   */
-NS_IMETHODIMP nsXULListitemAccessible::GetState(PRUint32 *aState)
+NS_IMETHODIMP
+nsXULListitemAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   if (mIsCheckbox) {
-    nsXULMenuitemAccessible::GetState(aState);
+    nsXULMenuitemAccessible::GetState(aState, aExtraState);
     return NS_OK;
   }
 
   *aState = nsIAccessibleStates::STATE_FOCUSABLE |
             nsIAccessibleStates::STATE_SELECTABLE;
   nsCOMPtr<nsIDOMXULSelectControlItemElement> listItem (do_QueryInterface(mDOMNode));
   if (listItem) {
     PRBool isSelected;
@@ -198,17 +201,17 @@ NS_IMETHODIMP nsXULListitemAccessible::G
   return NS_OK;
 }
 
 NS_IMETHODIMP nsXULListitemAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
 {
   if (aIndex == eAction_Click && mIsCheckbox) {
     // check or uncheck
     PRUint32 state;
-    GetState(&state);
+    GetState(&state, nsnull);
 
     if (state & nsIAccessibleStates::STATE_CHECKED)
       aName.AssignLiteral("uncheck");
     else
       aName.AssignLiteral("check");
 
     return NS_OK;
   }
@@ -252,40 +255,42 @@ NS_IMETHODIMP nsXULComboboxAccessible::G
   * As a nsComboboxAccessible we can have the following states:
   *     STATE_FOCUSED
   *     STATE_READONLY
   *     STATE_FOCUSABLE
   *     STATE_HASPOPUP
   *     STATE_EXPANDED
   *     STATE_COLLAPSED
   */
-NS_IMETHODIMP nsXULComboboxAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsXULComboboxAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // Get focus status from base class
-  nsAccessible::GetState(_retval);
+  nsresult rv = nsAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mDOMNode));
   if (menuList) {
     PRBool isOpen;
     menuList->GetOpen(&isOpen);
     if (isOpen) {
-      *_retval |= nsIAccessibleStates::STATE_EXPANDED;
+      *aState |= nsIAccessibleStates::STATE_EXPANDED;
     }
     else {
-      *_retval |= nsIAccessibleStates::STATE_COLLAPSED;
+      *aState |= nsIAccessibleStates::STATE_COLLAPSED;
     }
     PRBool isEditable;
     menuList->GetEditable(&isEditable);
     if (!isEditable) {
-      *_retval |= nsIAccessibleStates::STATE_READONLY;
+      *aState |= nsIAccessibleStates::STATE_READONLY;
     }
   }
 
-  *_retval |= nsIAccessibleStates::STATE_HASPOPUP |
-              nsIAccessibleStates::STATE_FOCUSABLE;
+  *aState |= nsIAccessibleStates::STATE_HASPOPUP |
+             nsIAccessibleStates::STATE_FOCUSABLE;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsXULComboboxAccessible::GetValue(nsAString& _retval)
 {
   _retval.Truncate();
 
--- a/accessible/src/xul/nsXULSelectAccessible.h
+++ b/accessible/src/xul/nsXULSelectAccessible.h
@@ -69,17 +69,17 @@ class nsXULListboxAccessible : public ns
 {
 public:
 
   nsXULListboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
   virtual ~nsXULListboxAccessible() {}
 
   /* ----- nsIAccessible ----- */
   NS_IMETHOD GetRole(PRUint32 *_retval);
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetValue(nsAString& _retval);
 };
 
 /**
   * Listitems -- used in listboxes 
   */
 class nsXULListitemAccessible : public nsXULMenuitemAccessible
 {
@@ -89,17 +89,17 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
   
   nsXULListitemAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
   virtual ~nsXULListitemAccessible() {}
 
   /* ----- nsIAccessible ----- */
   NS_IMETHOD GetName(nsAString& _retval);
   NS_IMETHOD GetRole(PRUint32 *_retval);
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetActionName(PRUint8 index, nsAString& aName);
   // Don't use XUL menuitems's description attribute
   NS_IMETHOD GetDescription(nsAString& aDesc) { return nsAccessibleWrap::GetDescription(aDesc); }
 
 private:
   PRBool mIsCheckbox;
 };
 
@@ -118,17 +118,17 @@ public:
   nsXULComboboxAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
   virtual ~nsXULComboboxAccessible() {}
 
   /* ----- nsPIAccessible ---- */
   NS_IMETHOD Init();
 
   /* ----- nsIAccessible ----- */
   NS_IMETHOD GetRole(PRUint32 *_retval);
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetValue(nsAString& _retval);
   NS_IMETHOD GetDescription(nsAString& aDescription);
   NS_IMETHOD GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren);
   NS_IMETHOD DoAction(PRUint8 index);
   NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
   NS_IMETHOD GetActionName(PRUint8 index, nsAString& aName);
 };
 
--- a/accessible/src/xul/nsXULTabAccessible.cpp
+++ b/accessible/src/xul/nsXULTabAccessible.cpp
@@ -91,43 +91,45 @@ NS_IMETHODIMP nsXULTabAccessible::GetRol
 {
   *_retval = nsIAccessibleRole::ROLE_PAGETAB;
   return NS_OK;
 }
 
 /**
   * Possible states: focused, focusable, unavailable(disabled), offscreen
   */
-NS_IMETHODIMP nsXULTabAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsXULTabAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // get focus and disable status from base class
-  nsLeafAccessible::GetState(_retval);
+  nsresult rv = nsLeafAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   // In the past, tabs have been focusable in classic theme
   // They may be again in the future
   // Check style for -moz-user-focus: normal to see if it's focusable
-  *_retval &= ~nsIAccessibleStates::STATE_FOCUSABLE;
+  *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
   nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
   if (presShell && content) {
     nsIFrame *frame = presShell->GetPrimaryFrameFor(content);
     if (frame) {
       const nsStyleUserInterface* ui = frame->GetStyleUserInterface();
       if (ui->mUserFocus == NS_STYLE_USER_FOCUS_NORMAL)
-        *_retval |= nsIAccessibleStates::STATE_FOCUSABLE;
+        *aState |= nsIAccessibleStates::STATE_FOCUSABLE;
     }
   }
   // Check whether the tab is selected
-  *_retval |= nsIAccessibleStates::STATE_SELECTABLE;
-  *_retval &= ~nsIAccessibleStates::STATE_SELECTED;
+  *aState |= nsIAccessibleStates::STATE_SELECTABLE;
+  *aState &= ~nsIAccessibleStates::STATE_SELECTED;
   nsCOMPtr<nsIDOMXULSelectControlItemElement> tab(do_QueryInterface(mDOMNode));
   if (tab) {
     PRBool selected = PR_FALSE;
     if (NS_SUCCEEDED(tab->GetSelected(&selected)) && selected)
-      *_retval |= nsIAccessibleStates::STATE_SELECTED;
+      *aState |= nsIAccessibleStates::STATE_SELECTED;
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTabAccessible::GetAttributes(nsIPersistentProperties **aAttributes)
 {
   NS_ENSURE_ARG_POINTER(aAttributes);
@@ -157,20 +159,23 @@ nsAccessibleWrap(aNode, aShell)
 /** We are a window*/
 NS_IMETHODIMP nsXULTabBoxAccessible::GetRole(PRUint32 *_retval)
 {
   *_retval = nsIAccessibleRole::ROLE_PANE;
   return NS_OK;
 }
 
 /** Possible states: normal */
-NS_IMETHODIMP nsXULTabBoxAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsXULTabBoxAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsAccessible::GetState(_retval);
-  *_retval &= ~nsIAccessibleStates::STATE_FOCUSABLE;
+  nsresult rv = nsAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;
   return NS_OK;
 }
 
 #ifdef NEVER
 /** 2 children, tabs, tabpanels */
 NS_IMETHODIMP nsXULTabBoxAccessible::GetChildCount(PRInt32 *_retval)
 {
   *_retval = 2;
@@ -199,26 +204,16 @@ nsAccessibleWrap(aNode, aShell)
 
 /** We are a Property Page */
 NS_IMETHODIMP nsXULTabPanelsAccessible::GetRole(PRUint32 *aRole)
 {
   *aRole = nsIAccessibleRole::ROLE_PROPERTYPAGE;
   return NS_OK;
 }
 
-/**
-  * Possible values: unavailable
-  */
-NS_IMETHODIMP nsXULTabPanelsAccessible::GetState(PRUint32 *_retval)
-{
-  // get focus and disable status from base class -- skip container because we have state
-  nsAccessible::GetState(_retval);
-  return NS_OK;
-}
-
 /** 
   * The name for the panel is the name from the tab associated with
   *  the panel. XXX not sure if the "panels" object should have the
   *  same name.
   */
 NS_IMETHODIMP nsXULTabPanelsAccessible::GetName(nsAString& _retval)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
@@ -244,19 +239,20 @@ NS_IMETHODIMP nsXULTabsAccessible::GetRo
 /** no actions */
 NS_IMETHODIMP nsXULTabsAccessible::GetNumActions(PRUint8 *_retval)
 {
   *_retval = 0;
   return NS_OK;
 }
 
 /** no state -- normal */
-NS_IMETHODIMP nsXULTabsAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsXULTabsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  return nsAccessible::GetState(_retval);
+  return nsAccessible::GetState(aState, aExtraState);
 }
 
 /** no value */
 NS_IMETHODIMP nsXULTabsAccessible::GetValue(nsAString& _retval)
 {
   return NS_OK;
 }
 
--- a/accessible/src/xul/nsXULTabAccessible.h
+++ b/accessible/src/xul/nsXULTabAccessible.h
@@ -46,62 +46,61 @@
 /** An individual tab */
 class nsXULTabAccessible : public nsLeafAccessible
 {
 public:
   enum { eAction_Switch = 0 };
 
   nsXULTabAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *_retval); 
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD DoAction(PRUint8 index);
   NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
 };
 
 /** 
   * Contains a tabs object and a tabPanels object. A complete
   *    entity with relationships between tabs and content to
   *    be displayed in the tabpanels object
   */
 class nsXULTabBoxAccessible : public nsAccessibleWrap
 {
 public:
   nsXULTabBoxAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *_retval); 
-  NS_IMETHOD GetState(PRUint32 *_retval); 
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   //NS_IMETHOD GetChildCount(PRInt32 *_retval); // aaronl remove this?
 };
 
 /** 
   * Represents the content area associated with the tabs object (when
   *   used together)
   */
 class nsXULTabPanelsAccessible : public nsAccessibleWrap
 {
 public:
   nsXULTabPanelsAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *_retval); 
   NS_IMETHOD GetName(nsAString& _retval); 
-  NS_IMETHOD GetState(PRUint32 *_retval);
 
 protected:
   nsresult GetAccPluginChild(nsIAccessible **_retval);
 
   // data members
   nsCOMPtr<nsIDOMNode> mGParentDOMNode;
   nsCOMPtr<nsIDOMNode> mParentDOMNode;
 };
 
 /** merely a container of tab obejcts */
 class nsXULTabsAccessible : public nsXULSelectableAccessible
 {
 public:
   nsXULTabsAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
   NS_IMETHOD GetRole(PRUint32 *_retval);
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetValue(nsAString& _retval);
   NS_IMETHOD GetName(nsAString& _retval);
 };
 
-#endif  
+#endif
--- a/accessible/src/xul/nsXULTextAccessible.cpp
+++ b/accessible/src/xul/nsXULTextAccessible.cpp
@@ -64,19 +64,21 @@ NS_IMETHODIMP nsXULTextAccessible::GetNa
                         aName)) {
     // if the value doesn't exist, flatten the inner content as the name (for descriptions)
     return AppendFlatStringFromSubtree(content, &aName);
   }
   // otherwise, use the value attribute as the name (for labels)
   return NS_OK;
 }
 
-NS_IMETHODIMP nsXULTextAccessible::GetState(PRUint32 *aState)
+NS_IMETHODIMP
+nsXULTextAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsHyperTextAccessible::GetState(aState);
+  nsresult rv = nsHyperTextAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   // Labels and description have read only state
   // They are not focusable or selectable
   *aState |= nsIAccessibleStates::STATE_READONLY;
   return NS_OK;
 }
 
 /**
@@ -87,21 +89,24 @@ nsLeafAccessible(aDomNode, aShell)
 { 
 }
 
 NS_IMETHODIMP nsXULTooltipAccessible::GetName(nsAString& aName)
 {
   return GetXULName(aName, PR_TRUE);
 }
 
-NS_IMETHODIMP nsXULTooltipAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsXULTooltipAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  nsLeafAccessible::GetState(_retval);
-  *_retval &= ~nsIAccessibleStates::STATE_FOCUSABLE;
-  *_retval |= nsIAccessibleStates::STATE_READONLY;
+  nsresult rv = nsLeafAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  *aState &= ~nsIAccessibleStates::STATE_FOCUSABLE;
+  *aState |= nsIAccessibleStates::STATE_READONLY;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsXULTooltipAccessible::GetRole(PRUint32 *_retval)
 {
   *_retval = nsIAccessibleRole::ROLE_TOOLTIP;
   return NS_OK;
 }
--- a/accessible/src/xul/nsXULTextAccessible.h
+++ b/accessible/src/xul/nsXULTextAccessible.h
@@ -47,27 +47,27 @@
 class nsIWeakReference;
 
 class nsXULTextAccessible : public nsHyperTextAccessible
 {
 
 public:
   nsXULTextAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
   NS_IMETHOD GetName(nsAString& _retval); 
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetRole(PRUint32 *aRole) { *aRole = nsIAccessibleRole::ROLE_LABEL; return NS_OK; }
 };
 
 class nsXULTooltipAccessible : public nsLeafAccessible
 {
 
 public:
   nsXULTooltipAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
   NS_IMETHOD GetName(nsAString& _retval); 
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetRole(PRUint32 *_retval); 
 };
 
 class nsXULLinkAccessible : public nsLinkableAccessible
 {
 
 public:
   nsXULLinkAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
--- a/accessible/src/xul/nsXULTreeAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeAccessible.cpp
@@ -166,33 +166,35 @@ void nsXULTreeAccessible::GetTreeBoxObje
     }
     currentNode->GetParentNode(getter_AddRefs(parentNode));
     currentNode = parentNode;
   }
 
   *aBoxObject = nsnull;
 }
 
-NS_IMETHODIMP nsXULTreeAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsXULTreeAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  // Get focus status from base class                                           
-  nsAccessible::GetState(_retval);                                           
+  // Get focus status from base class
+  nsresult rv = nsAccessible::GetState(aState, aExtraState);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   // see if we are multiple select if so set ourselves as such
   nsCOMPtr<nsIDOMElement> element (do_QueryInterface(mDOMNode));
   if (element) {
     // the default selection type is multiple
     nsAutoString selType;
     element->GetAttribute(NS_LITERAL_STRING("seltype"), selType);
     if (selType.IsEmpty() || !selType.EqualsLiteral("single"))
-      *_retval |= nsIAccessibleStates::STATE_MULTISELECTABLE;
+      *aState |= nsIAccessibleStates::STATE_MULTISELECTABLE;
   }
 
-  *_retval |= nsIAccessibleStates::STATE_READONLY |
-              nsIAccessibleStates::STATE_FOCUSABLE;
+  *aState |= nsIAccessibleStates::STATE_READONLY |
+             nsIAccessibleStates::STATE_FOCUSABLE;
 
   return NS_OK;
 }
 
 // The value is the first selected child
 NS_IMETHODIMP nsXULTreeAccessible::GetValue(nsAString& _retval)
 {
   _retval.Truncate(0);
@@ -571,60 +573,67 @@ NS_IMETHODIMP nsXULTreeitemAccessible::G
   if (NS_SUCCEEDED(nsXULTreeAccessible::GetColumnCount(mTree, &colCount)) && colCount > 1)
     *aRole = nsIAccessibleRole::ROLE_CELL;
   else
     *aRole = nsIAccessibleRole::ROLE_OUTLINEITEM;
   return NS_OK;
 }
 
 // Possible states: focused, focusable, selected, expanded/collapsed
-NS_IMETHODIMP nsXULTreeitemAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsXULTreeitemAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
+  NS_ENSURE_ARG_POINTER(aState);
+
+  *aState = 0;
+  if (aExtraState)
+    *aExtraState = 0;
+
   NS_ENSURE_TRUE(mTree && mTreeView, NS_ERROR_FAILURE);
 
-  *_retval = nsIAccessibleStates::STATE_FOCUSABLE |
-             nsIAccessibleStates::STATE_SELECTABLE;
+  *aState = nsIAccessibleStates::STATE_FOCUSABLE |
+            nsIAccessibleStates::STATE_SELECTABLE;
 
   // get expanded/collapsed state
   PRBool isContainer, isContainerOpen, isContainerEmpty;
   mTreeView->IsContainer(mRow, &isContainer);
   if (isContainer) {
     mTreeView->IsContainerEmpty(mRow, &isContainerEmpty);
     if (!isContainerEmpty) {
       mTreeView->IsContainerOpen(mRow, &isContainerOpen);
-      *_retval |= isContainerOpen? nsIAccessibleStates::STATE_EXPANDED:
-                                   nsIAccessibleStates::STATE_COLLAPSED;
+      *aState |= isContainerOpen? nsIAccessibleStates::STATE_EXPANDED:
+                                  nsIAccessibleStates::STATE_COLLAPSED;
     }
   }
 
   // get selected state
   nsCOMPtr<nsITreeSelection> selection;
   mTreeView->GetSelection(getter_AddRefs(selection));
   if (selection) {
     PRBool isSelected;
     selection->IsSelected(mRow, &isSelected);
     if (isSelected)
-      *_retval |= nsIAccessibleStates::STATE_SELECTED;
+      *aState |= nsIAccessibleStates::STATE_SELECTED;
   }
 
   nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelect =
     do_QueryInterface(mDOMNode);
   if (multiSelect) {
     PRInt32 currentIndex;
     multiSelect->GetCurrentIndex(&currentIndex);
     if (currentIndex == mRow) {
-      *_retval |= nsIAccessibleStates::STATE_FOCUSED;
+      *aState |= nsIAccessibleStates::STATE_FOCUSED;
     }
   }
 
   PRInt32 firstVisibleRow, lastVisibleRow;
   mTree->GetFirstVisibleRow(&firstVisibleRow);
   mTree->GetLastVisibleRow(&lastVisibleRow);
   if (mRow < firstVisibleRow || mRow > lastVisibleRow)
-    *_retval |= nsIAccessibleStates::STATE_INVISIBLE;
+    *aState |= nsIAccessibleStates::STATE_INVISIBLE;
 
   return NS_OK;
 }
 
 // "activate" (xor "cycle") action is available for all treeitems
 // "expand/collapse" action is avaible for treeitem which is container
 NS_IMETHODIMP nsXULTreeitemAccessible::GetNumActions(PRUint8 *_retval)
 {
@@ -955,19 +964,23 @@ NS_IMETHODIMP nsXULTreeitemAccessible::G
 
 nsXULTreeColumnsAccessible::nsXULTreeColumnsAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell):
 nsAccessibleWrap(aDOMNode, aShell)
 {
 }
 
 NS_IMPL_ISUPPORTS_INHERITED0(nsXULTreeColumnsAccessible, nsAccessible)
 
-NS_IMETHODIMP nsXULTreeColumnsAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsXULTreeColumnsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  *_retval = nsIAccessibleStates::STATE_READONLY;
+  if (aExtraState)
+    *aExtraState = 0;
+
+  *aState = nsIAccessibleStates::STATE_READONLY;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsXULTreeColumnsAccessible::GetRole(PRUint32 *_retval)
 {
   *_retval = nsIAccessibleRole::ROLE_LIST;
   return NS_OK;
 }
@@ -1032,19 +1045,23 @@ NS_IMETHODIMP nsXULTreeColumnsAccessible
 
 nsXULTreeColumnitemAccessible::nsXULTreeColumnitemAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell):
 nsLeafAccessible(aDOMNode, aShell)
 {
 }
 
 NS_IMPL_ISUPPORTS_INHERITED0(nsXULTreeColumnitemAccessible, nsLeafAccessible)
 
-NS_IMETHODIMP nsXULTreeColumnitemAccessible::GetState(PRUint32 *_retval)
+NS_IMETHODIMP
+nsXULTreeColumnitemAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
-  *_retval = nsIAccessibleStates::STATE_READONLY;
+  if (aExtraState)
+    *aExtraState = 0;
+
+  *aState = nsIAccessibleStates::STATE_READONLY;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsXULTreeColumnitemAccessible::GetName(nsAString& _retval)
 {
   return GetXULName(_retval);
 }
 
--- a/accessible/src/xul/nsXULTreeAccessible.h
+++ b/accessible/src/xul/nsXULTreeAccessible.h
@@ -60,17 +60,17 @@ public:
   NS_DECL_NSIACCESSIBLETREECACHE
 
   nsXULTreeAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
   virtual ~nsXULTreeAccessible() {};
 
   /* ----- nsIAccessible ----- */
   NS_IMETHOD Shutdown();
   NS_IMETHOD GetRole(PRUint32 *_retval);
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetValue(nsAString& _retval);
 
   NS_IMETHOD GetFirstChild(nsIAccessible **_retval);
   NS_IMETHOD GetLastChild(nsIAccessible **_retval);
   NS_IMETHOD GetChildCount(PRInt32 *_retval);
   NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
 
   static void GetTreeBoxObject(nsIDOMNode* aDOMNode, nsITreeBoxObject** aBoxObject);
@@ -102,17 +102,17 @@ public:
   nsXULTreeitemAccessible(nsIAccessible *aParent, nsIDOMNode *aDOMNode, nsIWeakReference *aShell, PRInt32 aRow, nsITreeColumn* aColumn = nsnull);
   virtual ~nsXULTreeitemAccessible() {}
 
   NS_IMETHOD Shutdown();
 
   /* ----- nsIAccessible ----- */
   NS_IMETHOD GetName(nsAString& _retval);
   NS_IMETHOD GetRole(PRUint32 *_retval);
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
   NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
 
   NS_IMETHOD GetParent(nsIAccessible **_retval);
   NS_IMETHOD GetNextSibling(nsIAccessible **_retval);
   NS_IMETHOD GetPreviousSibling(nsIAccessible **_retval);
 
@@ -139,17 +139,17 @@ public:
 
   NS_DECL_ISUPPORTS_INHERITED
 
   nsXULTreeColumnsAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
   virtual ~nsXULTreeColumnsAccessible() {}
 
   /* ----- nsIAccessible ----- */
   NS_IMETHOD GetRole(PRUint32 *_retval);
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
 
   NS_IMETHOD GetNextSibling(nsIAccessible **_retval); 
   NS_IMETHOD GetPreviousSibling(nsIAccessible **_retval); 
 
   NS_IMETHOD DoAction(PRUint8 index);
 };
@@ -162,16 +162,16 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   nsXULTreeColumnitemAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
   virtual ~nsXULTreeColumnitemAccessible() {}
 
   /* ----- nsIAccessible ----- */
   NS_IMETHOD GetName(nsAString& _retval);
   NS_IMETHOD GetRole(PRUint32 *_retval);
-  NS_IMETHOD GetState(PRUint32 *_retval);
+  NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetNumActions(PRUint8 *_retval);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
 
   NS_IMETHOD DoAction(PRUint8 index);
 };
 
 #endif