Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Wed, 05 Oct 2011 19:31:59 -0700
changeset 78606 f606d92ca592497db15f59e0b25dfd2cd5368ed8
parent 78011 0a8cd435a41a12d550c395a253b85a8d2cd38bd4 (current diff)
parent 78600 4a69b3fdd602624c4d7d6aca74b7d4836d1e90de (diff)
child 78607 7ee944b1fb20bcd536455ddcfb6705560c7daf08
push idunknown
push userunknown
push dateunknown
milestone10.0a1
Merge from mozilla-central.
accessible/tests/mochitest/events/test_focus.html
accessible/tests/mochitest/events/test_focus.xul
accessible/tests/mochitest/events/test_focusdoc.html
accessible/tests/mochitest/nsIAccessible_selects.js
accessible/tests/mochitest/states/test_comboboxes.xul
accessible/tests/mochitest/test_aria_activedescendant.html
accessible/tests/mochitest/test_nsIAccessible_selects.html
browser/base/content/browser.js
browser/components/feeds/test/test_bug368464.html
browser/components/feeds/test/test_bug408328.html
browser/devtools/highlighter/insideOutBox.js
browser/devtools/highlighter/inspector.js
build/autoconf/libIDL.m4
content/base/test/test_text_replaceWholeText.html
content/html/content/src/nsGenericHTMLElement.cpp
content/svg/content/src/nsISVGValue.h
content/svg/content/src/nsISVGValueObserver.h
content/svg/content/src/nsISVGValueUtils.h
content/svg/content/src/nsSVGStringProxyValue.cpp
content/svg/content/src/nsSVGValue.cpp
content/svg/content/src/nsSVGValue.h
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/base/nsGlobalWindow.cpp
dom/base/nsJSEnvironment.cpp
dom/base/nsJSEnvironment.h
dom/interfaces/core/nsIDOMNameList.idl
embedding/android/GeckoPhoneStateListener.java
extensions/pref/system-pref/Makefile.in
js/src/Makefile.in
js/src/assembler/assembler/X86Assembler.h
js/src/config/autoconf.mk.in
js/src/configure.in
js/src/jsanalyze.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsarena.h
js/src/jsarray.cpp
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jscntxtinlines.h
js/src/jscompartment.cpp
js/src/jscompartment.h
js/src/jsdate.cpp
js/src/jsdbgapi.cpp
js/src/jsemit.cpp
js/src/jsemit.h
js/src/jsexn.cpp
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
js/src/jsfun.cpp
js/src/jsfun.h
js/src/jsgc.cpp
js/src/jsgc.h
js/src/jsgcstats.cpp
js/src/jsgcstats.h
js/src/jsinfer.cpp
js/src/jsinterp.cpp
js/src/jsinterp.h
js/src/jsinterpinlines.h
js/src/jsiter.cpp
js/src/jsnum.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/jsopcode.cpp
js/src/jsopcode.h
js/src/jsparse.cpp
js/src/jsparse.h
js/src/jsproxy.cpp
js/src/jsprvtd.h
js/src/jspubtd.h
js/src/jsregexp.cpp
js/src/jsregexpinlines.h
js/src/jsscope.cpp
js/src/jsscript.cpp
js/src/jsscript.h
js/src/jsstr.cpp
js/src/jstracer.cpp
js/src/jstypedarray.cpp
js/src/jsutil.h
js/src/jsval.h
js/src/jswrapper.cpp
js/src/jswrapper.h
js/src/jsxml.cpp
js/src/methodjit/Compiler.cpp
js/src/methodjit/MethodJIT.h
js/src/shell/js.cpp
js/src/tests/js1_5/Function/15.3.4.4.js
js/src/vm/GlobalObject.cpp
js/src/vm/Stack-inl.h
js/src/vm/Stack.cpp
js/src/vm/Stack.h
js/src/xpconnect/shell/xpcshell.cpp
js/src/xpconnect/src/nsXPConnect.cpp
js/src/xpconnect/src/xpcjsruntime.cpp
js/src/xpconnect/src/xpcprivate.h
js/src/xpconnect/src/xpcruntimesvc.cpp
layout/build/nsLayoutModule.cpp
layout/generic/nsFrame.cpp
layout/tools/layout-debug/makefiles.sh
layout/tools/reftest/remotereftest.py
media/libvorbis/bug666672_gccWarnings.diff
modules/libpr0n/src/Endian.h
modules/libpref/src/init/all.js
testing/mochitest/runtestsremote.py
testing/mochitest/specialpowers/content/specialpowers.js
tools/trace-malloc/bloatblame.c
widget/src/gtk2/nsAccessibilityHelper.cpp
widget/src/gtk2/nsAccessibilityHelper.h
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_linux.s
xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_sparc_solaris_GCC.s
xpcom/typelib/xpidl/README
xpcom/typelib/xpidl/xpidl.c
xpcom/typelib/xpidl/xpidl.h
xpcom/typelib/xpidl/xpidl_doc.c
xpcom/typelib/xpidl/xpidl_header.c
xpcom/typelib/xpidl/xpidl_idl.c
xpcom/typelib/xpidl/xpidl_java.c
xpcom/typelib/xpidl/xpidl_typelib.c
xpcom/typelib/xpidl/xpidl_util.c
--- a/.hgtags
+++ b/.hgtags
@@ -63,8 +63,9 @@ a71bd564ebf5bf4f93d13e84114f759c263130b0
 a71bd564ebf5bf4f93d13e84114f759c263130b0 MOBILE_MERGE_DONE_20110406
 a95d426422816513477e5863add1b00ac7041dcb AURORA_BASE_20110412
 138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R14
 9eae975b3d6fb7748fe5a3c0113d449b1c7cc0b2 AURORA_BASE_20110524
 138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R14
 462c726144bc1fb45b61e774f64ac5d61b4e047c UPDATE_PACKAGING_R14
 5eb553dd2ceae5f88d80f27afc5ef3935c5d43b0 AURORA_BASE_20110705
 41b84b87c816403e1b74963d8094cff0406c989e AURORA_BASE_20110816
+c0983049bcaa9551e5f276d5a77ce154c151e0b0 AURORA_BASE_20110927
--- a/accessible/public/nsIAccessibilityService.h
+++ b/accessible/public/nsIAccessibilityService.h
@@ -78,17 +78,17 @@ public:
    * Return root document accessible that is or contains a document accessible
    * for the given presshell.
    *
    * @param aPresShell  [in] the presshell
    * @param aCanCreate  [in] points whether the root document accessible
    *                        should be returned from the cache or can be created
    */
   virtual nsAccessible* GetRootDocumentAccessible(nsIPresShell* aPresShell,
-                                                  PRBool aCanCreate) = 0;
+                                                  bool aCanCreate) = 0;
 
   /**
    * Creates accessible for the given DOM node or frame.
    */
   virtual already_AddRefed<nsAccessible>
     CreateHTMLBRAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
   virtual already_AddRefed<nsAccessible>
     CreateHTML4ButtonAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
--- a/accessible/src/atk/nsAccessibleWrap.cpp
+++ b/accessible/src/atk/nsAccessibleWrap.cpp
@@ -315,17 +315,17 @@ void nsAccessibleWrap::ShutdownAtkObject
 
 void
 nsAccessibleWrap::Shutdown()
 {
     ShutdownAtkObject();
     nsAccessible::Shutdown();
 }
 
-MaiHyperlink* nsAccessibleWrap::GetMaiHyperlink(PRBool aCreate /* = PR_TRUE */)
+MaiHyperlink* nsAccessibleWrap::GetMaiHyperlink(bool aCreate /* = true */)
 {
     // make sure mAtkObject is created
     GetAtkObject();
 
     NS_ASSERTION(quark_mai_hyperlink, "quark_mai_hyperlink not initialized");
     NS_ASSERTION(IS_MAI_OBJECT(mAtkObject), "Invalid AtkObject");
     MaiHyperlink* maiHyperlink = nsnull;
     if (quark_mai_hyperlink && IS_MAI_OBJECT(mAtkObject)) {
@@ -545,17 +545,17 @@ GetUniqueMaiAtkTypeName(PRUint16 interfa
                 interfacesBits);
     name[MAI_ATK_TYPE_NAME_LEN] = '\0';
 
     MAI_LOG_DEBUG(("MaiWidget::LastedTypeName=%s\n", name));
 
     return name;
 }
 
-PRBool nsAccessibleWrap::IsValidObject()
+bool nsAccessibleWrap::IsValidObject()
 {
     // to ensure we are not shut down
     return !IsDefunct();
 }
 
 /* static functions for ATK callbacks */
 void
 classInitCB(AtkObjectClass *aClass)
@@ -763,17 +763,17 @@ ConvertToAtkAttributeSet(nsIPersistentPr
     if (!aAttributes)
         return nsnull;
 
     AtkAttributeSet *objAttributeSet = nsnull;
     nsCOMPtr<nsISimpleEnumerator> propEnum;
     nsresult rv = aAttributes->Enumerate(getter_AddRefs(propEnum));
     NS_ENSURE_SUCCESS(rv, nsnull);
 
-    PRBool hasMore;
+    bool hasMore;
     while (NS_SUCCEEDED(propEnum->HasMoreElements(&hasMore)) && hasMore) {
         nsCOMPtr<nsISupports> sup;
         rv = propEnum->GetNext(getter_AddRefs(sup));
         NS_ENSURE_SUCCESS(rv, objAttributeSet);
 
         nsCOMPtr<nsIPropertyElement> propElem(do_QueryInterface(sup));
         NS_ENSURE_TRUE(propElem, objAttributeSet);
 
@@ -904,17 +904,17 @@ static void
 TranslateStates(PRUint64 aState, AtkStateSet* aStateSet)
 {
 
   // Convert every state to an entry in AtkStateMap
   PRUint32 stateIndex = 0;
   PRUint64 bitMask = 1;
   while (gAtkStateMap[stateIndex].stateMapEntryType != kNoSuchState) {
     if (gAtkStateMap[stateIndex].atkState) { // There's potentially an ATK state for this
-      PRBool isStateOn = (aState & bitMask) != 0;
+      bool isStateOn = (aState & bitMask) != 0;
       if (gAtkStateMap[stateIndex].stateMapEntryType == kMapOpposite) {
         isStateOn = !isStateOn;
       }
       if (isStateOn) {
         atk_state_set_add_state(aStateSet, gAtkStateMap[stateIndex].atkState);
       }
     }
     bitMask <<= 1;
@@ -1236,17 +1236,17 @@ nsAccessibleWrap::FirePlatformEvent(AccE
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_WINDOW_ACTIVATED\n"));
         nsRootAccessible *rootAcc =
           static_cast<nsRootAccessible *>(accessible);
         rootAcc->mActivated = PR_TRUE;
         guint id = g_signal_lookup ("activate", MAI_TYPE_ATK_OBJECT);
         g_signal_emit(atkObj, id, 0);
 
         // Always fire a current focus event after activation.
-        rootAcc->FireCurrentFocusEvent();
+        FocusMgr()->ForceFocusEvent();
       } break;
 
     case nsIAccessibleEvent::EVENT_WINDOW_DEACTIVATE:
       {
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_WINDOW_DEACTIVATED\n"));
         nsRootAccessible *rootAcc =
           static_cast<nsRootAccessible *>(accessible);
         rootAcc->mActivated = PR_FALSE;
@@ -1314,17 +1314,17 @@ nsresult
 nsAccessibleWrap::FireAtkStateChangeEvent(AccEvent* aEvent,
                                           AtkObject *aObject)
 {
     MAI_LOG_DEBUG(("\n\nReceived: EVENT_STATE_CHANGE\n"));
 
     AccStateChangeEvent* event = downcast_accEvent(aEvent);
     NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);
 
-    PRBool isEnabled = event->IsStateEnabled();
+    bool isEnabled = event->IsStateEnabled();
     PRInt32 stateIndex = AtkStateMap::GetStateIndexFor(event->GetState());
     if (stateIndex >= 0) {
         NS_ASSERTION(gAtkStateMap[stateIndex].stateMapEntryType != kNoSuchState,
                      "No such state");
 
         if (gAtkStateMap[stateIndex].atkState != kNone) {
             NS_ASSERTION(gAtkStateMap[stateIndex].stateMapEntryType != kNoStateChange,
                          "State changes should not fired for this state");
@@ -1348,18 +1348,18 @@ nsAccessibleWrap::FireAtkTextChangedEven
 {
     MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_REMOVED/INSERTED\n"));
 
     AccTextChangeEvent* event = downcast_accEvent(aEvent);
     NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);
 
     PRInt32 start = event->GetStartOffset();
     PRUint32 length = event->GetLength();
-    PRBool isInserted = event->IsTextInserted();
-    PRBool isFromUserInput = aEvent->IsFromUserInput();
+    bool isInserted = event->IsTextInserted();
+    bool isFromUserInput = aEvent->IsFromUserInput();
     char* signal_name = nsnull;
 
   if (gAvailableAtkSignals == eUnknown)
     gAvailableAtkSignals = g_signal_lookup("text-insert", ATK_TYPE_TEXT) ?
       eHaveNewAtkTextSignals : eNoNewAtkSignals;
 
   if (gAvailableAtkSignals == eNoNewAtkSignals) {
     // XXX remove this code and the gHaveNewTextSignals check when we can
@@ -1379,28 +1379,28 @@ nsAccessibleWrap::FireAtkTextChangedEven
   }
 
   g_free(signal_name);
   return NS_OK;
 }
 
 nsresult
 nsAccessibleWrap::FireAtkShowHideEvent(AccEvent* aEvent,
-                                       AtkObject *aObject, PRBool aIsAdded)
+                                       AtkObject *aObject, bool aIsAdded)
 {
     if (aIsAdded)
         MAI_LOG_DEBUG(("\n\nReceived: Show event\n"));
     else
         MAI_LOG_DEBUG(("\n\nReceived: Hide event\n"));
 
     PRInt32 indexInParent = getIndexInParentCB(aObject);
     AtkObject *parentObject = getParentCB(aObject);
     NS_ENSURE_STATE(parentObject);
 
-    PRBool isFromUserInput = aEvent->IsFromUserInput();
+    bool isFromUserInput = aEvent->IsFromUserInput();
     char *signal_name = g_strconcat(aIsAdded ? "children_changed::add" :  "children_changed::remove",
                                     isFromUserInput ? "" : kNonUserInputEvent, NULL);
     g_signal_emit_by_name(parentObject, signal_name, indexInParent, aObject, NULL);
     g_free(signal_name);
 
     return NS_OK;
 }
 
--- a/accessible/src/atk/nsAccessibleWrap.h
+++ b/accessible/src/atk/nsAccessibleWrap.h
@@ -99,35 +99,35 @@ public:
 
     // return the atk object for this nsAccessibleWrap
     NS_IMETHOD GetNativeInterface(void **aOutAccessible);
     virtual nsresult HandleAccEvent(AccEvent* aEvent);
 
     AtkObject * GetAtkObject(void);
     static AtkObject * GetAtkObject(nsIAccessible * acc);
 
-    PRBool IsValidObject();
+    bool IsValidObject();
     
     // get/set the MaiHyperlink object for this nsAccessibleWrap
-    MaiHyperlink* GetMaiHyperlink(PRBool aCreate = PR_TRUE);
+    MaiHyperlink* GetMaiHyperlink(bool aCreate = true);
     void SetMaiHyperlink(MaiHyperlink* aMaiHyperlink);
 
     static const char * ReturnString(nsAString &aString) {
       static nsCString returnedString;
       returnedString = NS_ConvertUTF16toUTF8(aString);
       return returnedString.get();
     }
 
 protected:
     virtual nsresult FirePlatformEvent(AccEvent* aEvent);
 
     nsresult FireAtkStateChangeEvent(AccEvent* aEvent, AtkObject *aObject);
     nsresult FireAtkTextChangedEvent(AccEvent* aEvent, AtkObject *aObject);
     nsresult FireAtkShowHideEvent(AccEvent* aEvent, AtkObject *aObject,
-                                  PRBool aIsAdded);
+                                  bool aIsAdded);
 
     AtkObject *mAtkObject;
 
 private:
 
   /*
    * do we have text-remove and text-insert signals if not we need to use
    * text-changed see nsAccessibleWrap::FireAtkTextChangedEvent() and
--- a/accessible/src/atk/nsApplicationAccessibleWrap.cpp
+++ b/accessible/src/atk/nsApplicationAccessibleWrap.cpp
@@ -606,25 +606,25 @@ toplevel_event_watcher(GSignalInvocation
       }
 
     }
   }
 
   return TRUE;
 }
 
-PRBool
+bool
 nsApplicationAccessibleWrap::Init()
 {
     // XXX following code is copied from widget/src/gtk2/nsWindow.cpp
     // we should put it to somewhere that can be used from both modules
     // see bug 390761
 
     // check if accessibility enabled/disabled by environment variable
-    PRBool isGnomeATEnabled = PR_FALSE;
+    bool isGnomeATEnabled = false;
     const char *envValue = PR_GetEnv(sAccEnv);
     if (envValue) {
         isGnomeATEnabled = !!atoi(envValue);
     } else {
         //check gconf-2 setting
         nsresult rv;
         nsCOMPtr<nsIPrefBranch> sysPrefService =
             do_GetService(sSysPrefService, &rv);
@@ -747,17 +747,17 @@ gboolean fireRootAccessibleAddedCB(gpoin
                           eventData->index, eventData->root_accessible, NULL);
     g_object_unref(eventData->app_accessible);
     g_object_unref(eventData->root_accessible);
     free(data);
 
     return FALSE;
 }
 
-PRBool
+bool
 nsApplicationAccessibleWrap::AppendChild(nsAccessible *aChild)
 {
     if (!nsApplicationAccessible::AppendChild(aChild))
       return PR_FALSE;
 
     AtkObject *atkAccessible = nsAccessibleWrap::GetAtkObject(aChild);
     atk_object_set_parent(atkAccessible, mAtkObject);
 
@@ -774,17 +774,17 @@ nsApplicationAccessibleWrap::AppendChild
       g_object_ref(mAtkObject);
       g_object_ref(atkAccessible);
       g_timeout_add(0, fireRootAccessibleAddedCB, eventData);
     }
 
     return PR_TRUE;
 }
 
-PRBool
+bool
 nsApplicationAccessibleWrap::RemoveChild(nsAccessible* aChild)
 {
     PRInt32 index = aChild->IndexInParent();
 
     AtkObject *atkAccessible = nsAccessibleWrap::GetAtkObject(aChild);
     atk_object_set_parent(atkAccessible, NULL);
     g_signal_emit_by_name(mAtkObject, "children_changed::remove", index,
                           atkAccessible, NULL);
--- a/accessible/src/atk/nsApplicationAccessibleWrap.h
+++ b/accessible/src/atk/nsApplicationAccessibleWrap.h
@@ -49,19 +49,19 @@ public:
     static void Unload();
     static void PreCreate();
 
 public:
     nsApplicationAccessibleWrap();
     virtual ~nsApplicationAccessibleWrap();
 
     // nsAccessNode
-    virtual PRBool Init();
+    virtual bool Init();
 
     // nsAccessible
-    virtual PRBool AppendChild(nsAccessible* aChild);
-    virtual PRBool RemoveChild(nsAccessible* aChild);
+    virtual bool AppendChild(nsAccessible* aChild);
+    virtual bool RemoveChild(nsAccessible* aChild);
 
     // return the atk object for app root accessible
     NS_IMETHOD GetNativeInterface(void **aOutAccessible);
 };
 
 #endif   /* __NS_APP_ROOT_ACCESSIBLE_H__ */
--- a/accessible/src/atk/nsDocAccessibleWrap.h
+++ b/accessible/src/atk/nsDocAccessibleWrap.h
@@ -49,12 +49,12 @@
 
 class nsDocAccessibleWrap: public nsDocAccessible
 {
 public:
   nsDocAccessibleWrap(nsIDocument *aDocument, nsIContent *aRootContent,
                       nsIWeakReference *aShell);
   virtual ~nsDocAccessibleWrap();
 
-  PRBool mActivated;
+  bool mActivated;
 };
 
 #endif
--- a/accessible/src/atk/nsMaiInterfaceTable.cpp
+++ b/accessible/src/atk/nsMaiInterfaceTable.cpp
@@ -459,46 +459,46 @@ isColumnSelectedCB(AtkTable *aTable, gin
     if (!accWrap)
         return FALSE;
 
     nsCOMPtr<nsIAccessibleTable> accTable;
     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
                             getter_AddRefs(accTable));
     NS_ENSURE_TRUE(accTable, FALSE);
 
-    PRBool outValue;
+    bool outValue;
     nsresult rv = accTable->IsColumnSelected(aColumn, &outValue);
     return NS_FAILED(rv) ? FALSE : static_cast<gboolean>(outValue);
 }
 
 gboolean
 isRowSelectedCB(AtkTable *aTable, gint aRow)
 {
     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
     if (!accWrap)
         return FALSE;
 
     nsCOMPtr<nsIAccessibleTable> accTable;
     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
                             getter_AddRefs(accTable));
     NS_ENSURE_TRUE(accTable, FALSE);
 
-    PRBool outValue;
+    bool outValue;
     nsresult rv = accTable->IsRowSelected(aRow, &outValue);
     return NS_FAILED(rv) ? FALSE : static_cast<gboolean>(outValue);
 }
 
 gboolean
 isCellSelectedCB(AtkTable *aTable, gint aRow, gint aColumn)
 {
     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aTable));
     if (!accWrap)
         return FALSE;
 
     nsCOMPtr<nsIAccessibleTable> accTable;
     accWrap->QueryInterface(NS_GET_IID(nsIAccessibleTable),
                             getter_AddRefs(accTable));
     NS_ENSURE_TRUE(accTable, FALSE);
 
-    PRBool outValue;
+    bool outValue;
     nsresult rv = accTable->IsCellSelected(aRow, aColumn, &outValue);
     return NS_FAILED(rv) ? FALSE : static_cast<gboolean>(outValue);
 }
--- a/accessible/src/base/AccEvent.cpp
+++ b/accessible/src/base/AccEvent.cpp
@@ -188,25 +188,25 @@ AccEvent::CaptureIsFromUserInput(EIsFrom
 // AccStateChangeEvent
 ////////////////////////////////////////////////////////////////////////////////
 
 // Note: we pass in eAllowDupes to the base class because we don't currently
 // support correct state change coalescence (XXX Bug 569356). Also we need to
 // decide how to coalesce events created via accessible (instead of node).
 AccStateChangeEvent::
   AccStateChangeEvent(nsAccessible* aAccessible, PRUint64 aState,
-                      PRBool aIsEnabled, EIsFromUserInput aIsFromUserInput):
+                      bool aIsEnabled, EIsFromUserInput aIsFromUserInput):
   AccEvent(nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible,
            aIsFromUserInput, eAllowDupes),
   mState(aState), mIsEnabled(aIsEnabled)
 {
 }
 
 AccStateChangeEvent::
-  AccStateChangeEvent(nsINode* aNode, PRUint64 aState, PRBool aIsEnabled):
+  AccStateChangeEvent(nsINode* aNode, PRUint64 aState, bool aIsEnabled):
   AccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aNode,
            eAutoDetect, eAllowDupes),
   mState(aState), mIsEnabled(aIsEnabled)
 {
 }
 
 AccStateChangeEvent::
   AccStateChangeEvent(nsINode* aNode, PRUint64 aState) :
@@ -239,17 +239,17 @@ AccStateChangeEvent::CreateXPCOMObject()
 // we continue to base the event off the accessible object rather than just the
 // node. This means we won't try to create an accessible based on the node when
 // we are ready to fire the event and so we will no longer assert at that point
 // if the node was removed from the document. Either way, the AT won't work with
 // a defunct accessible so the behaviour should be equivalent.
 // XXX revisit this when coalescence is faster (eCoalesceFromSameSubtree)
 AccTextChangeEvent::
   AccTextChangeEvent(nsAccessible* aAccessible, PRInt32 aStart,
-                     const nsAString& aModifiedText, PRBool aIsInserted,
+                     const nsAString& aModifiedText, bool aIsInserted,
                      EIsFromUserInput aIsFromUserInput)
   : AccEvent(aIsInserted ?
              static_cast<PRUint32>(nsIAccessibleEvent::EVENT_TEXT_INSERTED) :
              static_cast<PRUint32>(nsIAccessibleEvent::EVENT_TEXT_REMOVED),
              aAccessible, aIsFromUserInput, eAllowDupes)
   , mStart(aStart)
   , mIsInserted(aIsInserted)
   , mModifiedText(aModifiedText)
--- a/accessible/src/base/AccEvent.h
+++ b/accessible/src/base/AccEvent.h
@@ -73,19 +73,19 @@ public:
      //    This event will always be emitted.
      eAllowDupes,
 
      // eCoalesceFromSameSubtree : For events of the same type from the same
      //    subtree or the same node, only the umbrella event on the ancestor
      //    will be emitted.
      eCoalesceFromSameSubtree,
 
-    // eCoalesceFromSameDocument : For events of the same type from the same
-    //    document, only the newest event will be emitted.
-    eCoalesceFromSameDocument,
+    // eCoalesceOfSameType : For events of the same type, only the newest event
+    // will be processed.
+    eCoalesceOfSameType,
 
      // eRemoveDupes : For repeat events, only the newest event in queue
      //    will be emitted.
      eRemoveDupes,
 
      // eDoNotEmit : This event is confirmed as a duplicate, do not emit it.
      eDoNotEmit
   };
@@ -98,17 +98,17 @@ public:
   AccEvent(PRUint32 aEventType, nsINode* aNode,
            EIsFromUserInput aIsFromUserInput = eAutoDetect,
            EEventRule aEventRule = eRemoveDupes);
   virtual ~AccEvent() {}
 
   // AccEvent
   PRUint32 GetEventType() const { return mEventType; }
   EEventRule GetEventRule() const { return mEventRule; }
-  PRBool IsFromUserInput() const { return mIsFromUserInput; }
+  bool IsFromUserInput() const { return mIsFromUserInput; }
 
   nsAccessible *GetAccessible();
   nsDocAccessible* GetDocAccessible();
   nsINode* GetNode();
 
   /**
    * Create and return an XPCOM object for accessible event object.
    */
@@ -147,88 +147,88 @@ protected:
   nsAccessible *GetAccessibleForNode() const;
 
   /**
    * Determine whether the event is from user input by event state manager if
    * it's not pointed explicetly.
    */
   void CaptureIsFromUserInput(EIsFromUserInput aIsFromUserInput);
 
-  PRBool mIsFromUserInput;
+  bool mIsFromUserInput;
   PRUint32 mEventType;
   EEventRule mEventRule;
   nsRefPtr<nsAccessible> mAccessible;
   nsCOMPtr<nsINode> mNode;
 
   friend class NotificationController;
 };
 
 
 /**
  * Accessible state change event.
  */
 class AccStateChangeEvent: public AccEvent
 {
 public:
   AccStateChangeEvent(nsAccessible* aAccessible, PRUint64 aState,
-                      PRBool aIsEnabled,
+                      bool aIsEnabled,
                       EIsFromUserInput aIsFromUserInput = eAutoDetect);
 
-  AccStateChangeEvent(nsINode* aNode, PRUint64 aState, PRBool aIsEnabled);
+  AccStateChangeEvent(nsINode* aNode, PRUint64 aState, bool aIsEnabled);
 
   AccStateChangeEvent(nsINode* aNode, PRUint64 aState);
 
   // AccEvent
   virtual already_AddRefed<nsAccEvent> CreateXPCOMObject();
 
   static const EventGroup kEventGroup = eStateChangeEvent;
   virtual unsigned int GetEventGroups() const
   {
     return AccEvent::GetEventGroups() | (1U << eStateChangeEvent);
   }
 
   // AccStateChangeEvent
   PRUint64 GetState() const { return mState; }
-  PRBool IsStateEnabled() const { return mIsEnabled; }
+  bool IsStateEnabled() const { return mIsEnabled; }
 
 private:
   PRUint64 mState;
-  PRBool mIsEnabled;
+  bool mIsEnabled;
 };
 
 
 /**
  * Accessible text change event.
  */
 class AccTextChangeEvent: public AccEvent
 {
 public:
   AccTextChangeEvent(nsAccessible* aAccessible, PRInt32 aStart,
-                     const nsAString& aModifiedText, PRBool aIsInserted,
+                     const nsAString& aModifiedText, bool aIsInserted,
                      EIsFromUserInput aIsFromUserInput = eAutoDetect);
 
   // AccEvent
   virtual already_AddRefed<nsAccEvent> CreateXPCOMObject();
 
   static const EventGroup kEventGroup = eTextChangeEvent;
   virtual unsigned int GetEventGroups() const
   {
     return AccEvent::GetEventGroups() | (1U << eTextChangeEvent);
   }
 
   // AccTextChangeEvent
   PRInt32 GetStartOffset() const { return mStart; }
   PRUint32 GetLength() const { return mModifiedText.Length(); }
-  PRBool IsTextInserted() const { return mIsInserted; }
+  bool IsTextInserted() const { return mIsInserted; }
   void GetModifiedText(nsAString& aModifiedText)
     { aModifiedText = mModifiedText; }
 
 private:
   PRInt32 mStart;
-  PRBool mIsInserted;
+  bool mIsInserted;
   nsString mModifiedText;
 
   friend class NotificationController;
 };
 
 
 /**
  * Base class for show and hide accessible events.
@@ -320,16 +320,26 @@ public:
   PRInt32 GetCaretOffset() const { return mCaretOffset; }
 
 private:
   PRInt32 mCaretOffset;
 };
 
 
 /**
+ * Accessible widget selection change event.
+ */
+class AccSelectionChangeEvent : public AccEvent
+{
+public:
+
+};
+
+
+/**
  * Accessible table change event.
  */
 class AccTableChangeEvent : public AccEvent
 {
 public:
   AccTableChangeEvent(nsAccessible* aAccessible, PRUint32 aEventType,
                       PRInt32 aRowOrColIndex, PRInt32 aNumRowsOrCols);
 
--- a/accessible/src/base/AccIterator.cpp
+++ b/accessible/src/base/AccIterator.cpp
@@ -71,17 +71,17 @@ AccIterator::Next()
     if (!child) {
       IteratorState *tmp = mState;
       mState = mState->mParentState;
       delete tmp;
 
       continue;
     }
 
-    PRBool isComplying = mFilterFunc(child);
+    bool isComplying = mFilterFunc(child);
     if (isComplying)
       return child;
 
     if (mIsDeep) {
       IteratorState *childState = new IteratorState(child, mState);
       mState = childState;
     }
   }
@@ -147,48 +147,56 @@ RelatedAccIterator::Next()
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLLabelIterator
 ////////////////////////////////////////////////////////////////////////////////
 
 HTMLLabelIterator::
-  HTMLLabelIterator(nsDocAccessible* aDocument, nsIContent* aElement,
+  HTMLLabelIterator(nsDocAccessible* aDocument, const nsAccessible* aAccessible,
                     LabelFilter aFilter) :
-  mRelIter(aDocument, aElement, nsGkAtoms::_for),
-  mElement(aElement), mLabelFilter(aFilter)
+  mRelIter(aDocument, aAccessible->GetContent(), nsGkAtoms::_for),
+  mAcc(aAccessible), mLabelFilter(aFilter)
 {
 }
 
 nsAccessible*
 HTMLLabelIterator::Next()
 {
   // Get either <label for="[id]"> element which explicitly points to given
   // element, or <label> ancestor which implicitly point to it.
   nsAccessible* label = nsnull;
   while ((label = mRelIter.Next())) {
     if (label->GetContent()->Tag() == nsGkAtoms::label)
       return label;
   }
 
-  if (mLabelFilter == eSkipAncestorLabel)
+  // Ignore ancestor label on not widget accessible.
+  if (mLabelFilter == eSkipAncestorLabel || !mAcc->IsWidget())
     return nsnull;
 
-  // Go up tree get name of ancestor label if there is one (an ancestor <label>
-  // implicitly points to us). Don't go up farther than form or body element.
-  nsIContent* walkUpContent = mElement;
-  while ((walkUpContent = walkUpContent->GetParent()) &&
-         walkUpContent->Tag() != nsGkAtoms::form &&
-         walkUpContent->Tag() != nsGkAtoms::body) {
-    if (walkUpContent->Tag() == nsGkAtoms::label) {
-      // Prevent infinite loop.
-      mLabelFilter = eSkipAncestorLabel;
-      return GetAccService()->GetAccessible(walkUpContent);
+  // Go up tree to get a name of ancestor label if there is one (an ancestor
+  // <label> implicitly points to us). Don't go up farther than form or
+  // document.
+  nsAccessible* walkUp = mAcc->Parent();
+  while (walkUp && !walkUp->IsDoc()) {
+    nsIContent* walkUpElm = walkUp->GetContent();
+    if (walkUpElm->IsHTML()) {
+      if (walkUpElm->Tag() == nsGkAtoms::label &&
+          !walkUpElm->HasAttr(kNameSpaceID_None, nsGkAtoms::_for)) {
+        mLabelFilter = eSkipAncestorLabel; // prevent infinite loop
+        return walkUp;
+      }
+
+      if (walkUpElm->Tag() == nsGkAtoms::form)
+        break;
     }
+
+    walkUp = walkUp->Parent();
   }
 
   return nsnull;
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLOutputIterator
--- a/accessible/src/base/AccIterator.h
+++ b/accessible/src/base/AccIterator.h
@@ -104,17 +104,17 @@ private:
     IteratorState(nsAccessible *aParent, IteratorState *mParentState = nsnull);
 
     nsAccessible *mParent;
     PRInt32 mIndex;
     IteratorState *mParentState;
   };
 
   filters::FilterFuncPtr mFilterFunc;
-  PRBool mIsDeep;
+  bool mIsDeep;
   IteratorState *mState;
 };
 
 
 /**
  * Allows to traverse through related accessibles that are pointing to the given
  * dependent accessible by relation attribute.
  */
@@ -150,43 +150,45 @@ private:
   nsIAtom* mRelAttr;
   nsDocAccessible::AttrRelProviderArray* mProviders;
   nsIContent* mBindingParent;
   PRUint32 mIndex;
 };
 
 
 /**
- * Used to iterate through HTML labels associated with the given element.
+ * Used to iterate through HTML labels associated with the given accessible.
  */
 class HTMLLabelIterator : public AccIterable
 {
 public:
   enum LabelFilter {
     eAllLabels,
     eSkipAncestorLabel
   };
 
-  HTMLLabelIterator(nsDocAccessible* aDocument, nsIContent* aElement,
+  HTMLLabelIterator(nsDocAccessible* aDocument, const nsAccessible* aAccessible,
                     LabelFilter aFilter = eAllLabels);
 
   virtual ~HTMLLabelIterator() { }
 
   /**
    * Return next label accessible associated with the given element.
    */
   virtual nsAccessible* Next();
 
 private:
   HTMLLabelIterator();
   HTMLLabelIterator(const HTMLLabelIterator&);
   HTMLLabelIterator& operator = (const HTMLLabelIterator&);
 
   RelatedAccIterator mRelIter;
-  nsIContent* mElement;
+  // XXX: replace it on weak reference (bug 678429), it's safe to use raw
+  // pointer now because iterators life cycle is short.
+  const nsAccessible* mAcc;
   LabelFilter mLabelFilter;
 };
 
 
 /**
  * Used to iterate through HTML outputs associated with the given element.
  */
 class HTMLOutputIterator : public AccIterable
new file mode 100644
--- /dev/null
+++ b/accessible/src/base/FocusManager.cpp
@@ -0,0 +1,361 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Alexander Surkov <surkov.alexander@gmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "FocusManager.h"
+
+#include "nsAccessibilityService.h"
+#include "nsAccUtils.h"
+#include "nsRootAccessible.h"
+
+#include "nsFocusManager.h"
+
+namespace dom = mozilla::dom;
+using namespace mozilla::a11y;
+
+FocusManager::FocusManager()
+{
+}
+
+FocusManager::~FocusManager()
+{
+}
+
+nsAccessible*
+FocusManager::FocusedAccessible() const
+{
+  if (mActiveItem)
+    return mActiveItem;
+
+  nsINode* focusedNode = FocusedDOMNode();
+  if (focusedNode)
+    return GetAccService()->GetAccessibleOrContainer(focusedNode, nsnull);
+
+  return nsnull;
+}
+
+bool
+FocusManager::IsFocused(const nsAccessible* aAccessible) const
+{
+  if (mActiveItem)
+    return mActiveItem == aAccessible;
+
+  nsINode* focusedNode = FocusedDOMNode();
+  if (focusedNode) {
+    // XXX: Before getting an accessible for node having a DOM focus make sure
+    // they belong to the same document because it can trigger unwanted document
+    // accessible creation for temporary about:blank document. Without this
+    // peculiarity we would end up with plain implementation based on
+    // FocusedAccessible() method call. Make sure this issue is fixed in
+    // bug 638465.
+    if (focusedNode->GetOwnerDoc() == aAccessible->GetNode()->GetOwnerDoc()) {
+      return aAccessible ==
+        GetAccService()->GetAccessibleOrContainer(focusedNode, nsnull);
+    }
+  }
+  return false;
+}
+
+bool
+FocusManager::IsFocusWithin(const nsAccessible* aContainer) const
+{
+  nsAccessible* child = FocusedAccessible();
+  while (child) {
+    if (child == aContainer)
+      return true;
+
+    child = child->Parent();
+  }
+  return false;
+}
+
+FocusManager::FocusDisposition
+FocusManager::IsInOrContainsFocus(const nsAccessible* aAccessible) const
+{
+  nsAccessible* focus = FocusedAccessible();
+  if (!focus)
+    return eNone;
+
+  // If focused.
+  if (focus == aAccessible)
+    return eFocused;
+
+  // If contains the focus.
+  nsAccessible* child = focus->Parent();
+  while (child) {
+    if (child == aAccessible)
+      return eContainsFocus;
+
+    child = child->Parent();
+  }
+
+  // If contained by focus.
+  child = aAccessible->Parent();
+  while (child) {
+    if (child == focus)
+      return eContainedByFocus;
+
+    child = child->Parent();
+  }
+
+  return eNone;
+}
+
+void
+FocusManager::NotifyOfDOMFocus(nsISupports* aTarget)
+{
+  A11YDEBUG_FOCUS_NOTIFICATION_SUPPORTSTARGET("DOM focus", "DOM focus target",
+                                              aTarget)
+
+  mActiveItem = nsnull;
+
+  nsCOMPtr<nsINode> targetNode(do_QueryInterface(aTarget));
+  if (targetNode) {
+    nsDocAccessible* document =
+      GetAccService()->GetDocAccessible(targetNode->GetOwnerDoc());
+    if (document) {
+      // Set selection listener for focused element.
+      if (targetNode->IsElement()) {
+        nsRootAccessible* root = document->RootAccessible();
+        nsCaretAccessible* caretAcc = root->GetCaretAccessible();
+        caretAcc->SetControlSelectionListener(targetNode->AsElement());
+      }
+
+      document->HandleNotification<FocusManager, nsINode>
+        (this, &FocusManager::ProcessDOMFocus, targetNode);
+    }
+  }
+}
+
+void
+FocusManager::NotifyOfDOMBlur(nsISupports* aTarget)
+{
+  A11YDEBUG_FOCUS_NOTIFICATION_SUPPORTSTARGET("DOM blur", "DOM blur target",
+                                              aTarget)
+
+  mActiveItem = nsnull;
+
+  // If DOM document stays focused then fire accessible focus event to process
+  // the case when no element within this DOM document will be focused.
+  nsCOMPtr<nsINode> targetNode(do_QueryInterface(aTarget));
+  if (targetNode && targetNode->GetOwnerDoc() == FocusedDOMDocument()) {
+    nsIDocument* DOMDoc = targetNode->GetOwnerDoc();
+    nsDocAccessible* document =
+      GetAccService()->GetDocAccessible(DOMDoc);
+    if (document) {
+      document->HandleNotification<FocusManager, nsINode>
+        (this, &FocusManager::ProcessDOMFocus, DOMDoc);
+    }
+  }
+}
+
+void
+FocusManager::ActiveItemChanged(nsAccessible* aItem, bool aCheckIfActive)
+{
+  A11YDEBUG_FOCUS_NOTIFICATION_ACCTARGET("active item changed",
+                                         "Active item", aItem)
+
+  // Nothing changed, happens for XUL trees and HTML selects.
+  if (aItem && aItem == mActiveItem)
+    return;
+
+  mActiveItem = nsnull;
+
+  if (aItem && aCheckIfActive) {
+    nsAccessible* widget = aItem->ContainerWidget();
+    A11YDEBUG_FOCUS_LOG_WIDGET("Active item widget", widget)
+    if (!widget || !widget->IsActiveWidget() || !widget->AreItemsOperable())
+      return;
+  }
+  mActiveItem = aItem;
+
+  // If active item is changed then fire accessible focus event on it, otherwise
+  // if there's no an active item then fire focus event to accessible having
+  // DOM focus.
+  nsAccessible* target = FocusedAccessible();
+  if (target)
+    DispatchFocusEvent(target->GetDocAccessible(), target);
+}
+
+void
+FocusManager::ForceFocusEvent()
+{
+  nsINode* focusedNode = FocusedDOMNode();
+  if (focusedNode) {
+    nsDocAccessible* document =
+      GetAccService()->GetDocAccessible(focusedNode->GetOwnerDoc());
+    if (document) {
+      document->HandleNotification<FocusManager, nsINode>
+        (this, &FocusManager::ProcessDOMFocus, focusedNode);
+    }
+  }
+}
+
+void
+FocusManager::DispatchFocusEvent(nsDocAccessible* aDocument,
+                                 nsAccessible* aTarget)
+{
+  NS_PRECONDITION(aDocument, "No document for focused accessible!");
+  if (aDocument) {
+    nsRefPtr<AccEvent> event =
+      new AccEvent(nsIAccessibleEvent::EVENT_FOCUS, aTarget,
+                   eAutoDetect, AccEvent::eCoalesceOfSameType);
+    aDocument->FireDelayedAccessibleEvent(event);
+
+    A11YDEBUG_FOCUS_LOG_ACCTARGET("Focus notification", aTarget)
+  }
+}
+
+void
+FocusManager::ProcessDOMFocus(nsINode* aTarget)
+{
+  A11YDEBUG_FOCUS_NOTIFICATION_DOMTARGET("Process DOM focus",
+                                         "Notification target", aTarget)
+
+  nsDocAccessible* document =
+    GetAccService()->GetDocAccessible(aTarget->GetOwnerDoc());
+
+  nsAccessible* target = document->GetAccessibleOrContainer(aTarget);
+  if (target) {
+    // Check if still focused. Otherwise we can end up with storing the active
+    // item for control that isn't focused anymore.
+    nsAccessible* DOMFocus =
+      GetAccService()->GetAccessibleOrContainer(FocusedDOMNode(), nsnull);
+    if (target != DOMFocus)
+      return;
+
+    nsAccessible* activeItem = target->CurrentItem();
+    if (activeItem) {
+      mActiveItem = activeItem;
+      target = activeItem;
+    }
+
+    DispatchFocusEvent(document, target);
+  }
+}
+
+void
+FocusManager::ProcessFocusEvent(AccEvent* aEvent)
+{
+  NS_PRECONDITION(aEvent->GetEventType() == nsIAccessibleEvent::EVENT_FOCUS,
+                  "Focus event is expected!");
+
+  EIsFromUserInput fromUserInputFlag = aEvent->IsFromUserInput() ?
+    eFromUserInput : eNoUserInput;
+
+  // Emit focus event if event target is the active item. Otherwise then check
+  // if it's still focused and then update active item and emit focus event.
+  nsAccessible* target = aEvent->GetAccessible();
+  if (target != mActiveItem) {
+    // Check if still focused. Otherwise we can end up with storing the active
+    // item for control that isn't focused anymore.
+    nsAccessible* DOMFocus =
+      GetAccService()->GetAccessibleOrContainer(FocusedDOMNode(), nsnull);
+    if (target != DOMFocus)
+      return;
+
+    nsAccessible* activeItem = target->CurrentItem();
+    if (activeItem) {
+      mActiveItem = activeItem;
+      target = activeItem;
+    }
+  }
+
+  // Fire menu start/end events for ARIA menus.
+  if (target->ARIARole() == nsIAccessibleRole::ROLE_MENUITEM) {
+    // The focus was moved into menu.
+    nsAccessible* ARIAMenubar =
+      nsAccUtils::GetAncestorWithRole(target, nsIAccessibleRole::ROLE_MENUBAR);
+
+    if (ARIAMenubar != mActiveARIAMenubar) {
+      // Leaving ARIA menu. Fire menu_end event on current menubar.
+      if (mActiveARIAMenubar) {
+        nsRefPtr<AccEvent> menuEndEvent =
+          new AccEvent(nsIAccessibleEvent::EVENT_MENU_END, mActiveARIAMenubar,
+                       fromUserInputFlag);
+        nsEventShell::FireEvent(menuEndEvent);
+      }
+
+      mActiveARIAMenubar = ARIAMenubar;
+
+      // Entering ARIA menu. Fire menu_start event.
+      if (mActiveARIAMenubar) {
+        nsRefPtr<AccEvent> menuStartEvent =
+          new AccEvent(nsIAccessibleEvent::EVENT_MENU_START,
+                       mActiveARIAMenubar, fromUserInputFlag);
+        nsEventShell::FireEvent(menuStartEvent);
+      }
+    }
+  } else if (mActiveARIAMenubar) {
+    // Focus left a menu. Fire menu_end event.
+    nsRefPtr<AccEvent> menuEndEvent =
+      new AccEvent(nsIAccessibleEvent::EVENT_MENU_END, mActiveARIAMenubar,
+                   fromUserInputFlag);
+    nsEventShell::FireEvent(menuEndEvent);
+
+    mActiveARIAMenubar = nsnull;
+  }
+
+  A11YDEBUG_FOCUS_NOTIFICATION_ACCTARGET("FIRE FOCUS EVENT", "Focus target",
+                                         target)
+
+  nsRefPtr<AccEvent> focusEvent =
+    new AccEvent(nsIAccessibleEvent::EVENT_FOCUS, target, fromUserInputFlag);
+  nsEventShell::FireEvent(focusEvent);
+}
+
+nsIContent*
+FocusManager::FocusedDOMElm() const
+{
+  nsFocusManager* DOMFocusManager = nsFocusManager::GetFocusManager();
+  return DOMFocusManager->GetFocusedContent();
+}
+
+nsIDocument*
+FocusManager::FocusedDOMDocument() const
+{
+  nsFocusManager* DOMFocusManager = nsFocusManager::GetFocusManager();
+
+  nsCOMPtr<nsIDOMWindow> focusedWnd;
+  DOMFocusManager->GetFocusedWindow(getter_AddRefs(focusedWnd));
+  if (focusedWnd) {
+    nsCOMPtr<nsIDOMDocument> DOMDoc;
+    focusedWnd->GetDocument(getter_AddRefs(DOMDoc));
+    nsCOMPtr<nsIDocument> DOMDocNode(do_QueryInterface(DOMDoc));
+    return DOMDocNode;
+  }
+  return nsnull;
+}
new file mode 100644
--- /dev/null
+++ b/accessible/src/base/FocusManager.h
@@ -0,0 +1,297 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Alexander Surkov <surkov.alexander@gmail.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_a11y_FocusManager_h_
+#define mozilla_a11y_FocusManager_h_
+
+#include "nsAutoPtr.h"
+#include "mozilla/dom/Element.h"
+
+class AccEvent;
+class nsAccessible;
+class nsDocAccessible;
+
+namespace mozilla {
+namespace a11y {
+
+/**
+ * Manage the accessible focus. Used to fire and process accessible events.
+ */
+class FocusManager
+{
+public:
+  virtual ~FocusManager();
+
+  /**
+   * Return a focused accessible.
+   */
+  nsAccessible* FocusedAccessible() const;
+
+  /**
+   * Return true if given accessible is focused.
+   */
+  bool IsFocused(const nsAccessible* aAccessible) const;
+
+  /**
+   * Return true if the given accessible is an active item, i.e. an item that
+   * is current within the active widget.
+   */
+  inline bool IsActiveItem(const nsAccessible* aAccessible)
+    { return aAccessible == mActiveItem; }
+
+  /**
+   * Return true if given DOM node has DOM focus.
+   */
+  inline bool HasDOMFocus(const nsINode* aNode) const
+    { return aNode == FocusedDOMNode(); }
+
+  /**
+   * Return true if focused accessible is within the given container.
+   */
+  bool IsFocusWithin(const nsAccessible* aContainer) const;
+
+  /**
+   * Return whether the given accessible is focused or contains the focus or
+   * contained by focused accessible.
+   */
+  enum FocusDisposition {
+    eNone,
+    eFocused,
+    eContainsFocus,
+    eContainedByFocus
+  };
+  FocusDisposition IsInOrContainsFocus(const nsAccessible* aAccessible) const;
+
+  //////////////////////////////////////////////////////////////////////////////
+  // Focus notifications and processing (don't use until you know what you do).
+
+  /**
+   * Called when DOM focus event is fired.
+   */
+  void NotifyOfDOMFocus(nsISupports* aTarget);
+
+  /**
+   * Called when DOM blur event is fired.
+   */
+  void NotifyOfDOMBlur(nsISupports* aTarget);
+
+  /**
+   * Called when active item is changed. Note: must be called when accessible
+   * tree is up to date.
+   */
+  void ActiveItemChanged(nsAccessible* aItem, bool aCheckIfActive = true);
+
+  /**
+   * Dispatch delayed focus event for the current focus accessible.
+   */
+  void ForceFocusEvent();
+
+  /**
+   * Dispatch delayed focus event for the given target.
+   */
+  void DispatchFocusEvent(nsDocAccessible* aDocument, nsAccessible* aTarget);
+
+  /**
+   * Process DOM focus notification.
+   */
+  void ProcessDOMFocus(nsINode* aTarget);
+
+  /**
+   * Process the delayed accessible event.
+   * do.
+   */
+  void ProcessFocusEvent(AccEvent* aEvent);
+
+protected:
+  FocusManager();
+
+private:
+  FocusManager(const FocusManager&);
+  FocusManager& operator =(const FocusManager&);
+
+  /**
+   * Return DOM node having DOM focus.
+   */
+  inline nsINode* FocusedDOMNode() const
+  {
+    nsINode* focusedNode = FocusedDOMElm();
+    if (focusedNode)
+      return focusedNode;
+    return FocusedDOMDocument();
+  }
+
+  /**
+   * Return DOM element having DOM focus.
+   */
+  nsIContent* FocusedDOMElm() const;
+
+  /**
+   * Return DOM document having DOM focus.
+   */
+  nsIDocument* FocusedDOMDocument() const;
+
+private:
+  nsRefPtr<nsAccessible> mActiveItem;
+  nsRefPtr<nsAccessible> mActiveARIAMenubar;
+};
+
+} // namespace a11y
+} // namespace mozilla
+
+
+//#define A11YDEBUG_FOCUS
+
+#ifdef A11YDEBUG_FOCUS
+
+// Util macros (don't use them directly)
+#define A11YDEBUG_FOCUS_STARTBLOCK                                             \
+  printf("  {\n    ");
+
+#define A11YDEBUG_FOCUS_ENDBLOCK                                               \
+  printf("\n  }\n");
+
+#define A11YDEBUG_FOCUS_BLOCKOFFSET                                            \
+  printf("    ");
+
+#define A11YDEBUG_FOCUS_LOG_TIME                                               \
+  {                                                                            \
+    PRIntervalTime time = PR_IntervalNow();                                    \
+    PRUint32 mins = (PR_IntervalToSeconds(time) / 60) % 60;                    \
+    PRUint32 secs = PR_IntervalToSeconds(time) % 60;                           \
+    PRUint32 msecs = PR_IntervalToMilliseconds(time) % 1000;                   \
+    printf("Time: %2d:%2d.%3d\n", mins, secs, msecs);                          \
+  }
+
+#define A11YDEBUG_FOCUS_LOG_DOMNODE(aNode)                                     \
+  if (aNode) {                                                                 \
+    if (aNode->IsElement()) {                                                  \
+      dom::Element* targetElm = aNode->AsElement();                            \
+      nsCAutoString tag;                                                       \
+      targetElm->Tag()->ToUTF8String(tag);                                     \
+      nsCAutoString id;                                                        \
+      nsIAtom* atomid = targetElm->GetID();                                    \
+      if (atomid)                                                              \
+        atomid->ToUTF8String(id);                                              \
+      printf("element %s@id='%s': %p", tag.get(), id.get(), (void*)aNode);     \
+    } else if (aNode->IsNodeOfType(nsINode::eDOCUMENT)) {                      \
+      nsCOMPtr<nsIDocument> document = do_QueryInterface(aNode);               \
+      nsIURI* uri = document->GetDocumentURI();                                \
+      nsCAutoString spec;                                                      \
+      uri->GetSpec(spec);                                                      \
+      printf("document: %p; uri: %s", (void*)aNode, spec.get());               \
+    }                                                                          \
+  }
+
+#define A11YDEBUG_FOCUS_LOG_ACCESSIBLE(aAccessible)                            \
+  printf("accessible: %p; ", (void*)aAccessible);                              \
+  if (aAccessible) {                                                           \
+    nsAutoString role;                                                         \
+    GetAccService()->GetStringRole(aAccessible->Role(), role);                 \
+    nsAutoString name;                                                         \
+    aAccessible->GetName(name);                                                \
+    printf(" role: %s, name: %s; ", NS_ConvertUTF16toUTF8(role).get(),         \
+           NS_ConvertUTF16toUTF8(name).get());                                 \
+    A11YDEBUG_FOCUS_LOG_DOMNODE(aAccessible->GetNode())                        \
+  }
+
+// Public macros
+#define A11YDEBUG_FOCUS_LOG_DOMTARGET(aMsg, aTarget)                           \
+  A11YDEBUG_FOCUS_STARTBLOCK                                                   \
+  printf(aMsg "\n");                                                           \
+  if (aTarget) {                                                               \
+    A11YDEBUG_FOCUS_BLOCKOFFSET                                                \
+    A11YDEBUG_FOCUS_LOG_DOMNODE(aTarget)                                       \
+  }                                                                            \
+  A11YDEBUG_FOCUS_ENDBLOCK
+
+#define A11YDEBUG_FOCUS_LOG_ACCTARGET(aMsg, aTarget)                           \
+  A11YDEBUG_FOCUS_STARTBLOCK                                                   \
+  printf(aMsg "\n");                                                           \
+  A11YDEBUG_FOCUS_BLOCKOFFSET                                                  \
+  A11YDEBUG_FOCUS_LOG_ACCESSIBLE(aTarget)                                      \
+  A11YDEBUG_FOCUS_ENDBLOCK
+
+#define A11YDEBUG_FOCUS_LOG_WIDGET(aMsg, aWidget)                              \
+  A11YDEBUG_FOCUS_STARTBLOCK                                                   \
+  printf(aMsg "\n");                                                           \
+  A11YDEBUG_FOCUS_BLOCKOFFSET                                                  \
+  A11YDEBUG_FOCUS_LOG_ACCESSIBLE(aWidget)                                      \
+  printf("; widget is active: %s, has operable items: %s",                     \
+         (aWidget && aWidget->IsActiveWidget() ? "true" : "false"),            \
+         (aWidget && aWidget->AreItemsOperable() ? "true" : "false"));         \
+  A11YDEBUG_FOCUS_ENDBLOCK
+
+#define A11YDEBUG_FOCUS_NOTIFICATION_SUPPORTSTARGET(aMsg, aTargetMsg, aTarget) \
+  printf("\nA11Y FOCUS: " aMsg ". ");                                          \
+  A11YDEBUG_FOCUS_LOG_TIME                                                     \
+  if (aTarget) {                                                               \
+    A11YDEBUG_FOCUS_STARTBLOCK                                                 \
+    printf(aTargetMsg "\n");                                                   \
+    A11YDEBUG_FOCUS_BLOCKOFFSET                                                \
+    nsCOMPtr<nsINode> targetNode(do_QueryInterface(aTarget));                  \
+    if (targetNode) {                                                          \
+      A11YDEBUG_FOCUS_LOG_DOMNODE(targetNode)                                  \
+    } else {                                                                   \
+      printf("window: %p", (void*)aTarget);                                    \
+    }                                                                          \
+    A11YDEBUG_FOCUS_ENDBLOCK                                                   \
+  }
+
+#define A11YDEBUG_FOCUS_NOTIFICATION_DOMTARGET(aMsg, aTargetMsg, aTarget)      \
+  printf("\nA11Y FOCUS: " aMsg ". ");                                          \
+  A11YDEBUG_FOCUS_LOG_TIME                                                     \
+  A11YDEBUG_FOCUS_LOG_DOMTARGET(aTargetMsg, aTarget)
+
+#define A11YDEBUG_FOCUS_NOTIFICATION_ACCTARGET(aMsg, aTargetMsg, aTarget)      \
+  printf("\nA11Y FOCUS: " aMsg ". ");                                          \
+  A11YDEBUG_FOCUS_LOG_TIME                                                     \
+  A11YDEBUG_FOCUS_LOG_ACCTARGET(aTargetMsg, aTarget)
+
+#define A11YDEBUG_FOCUS_ACTIVEITEMCHANGE_CAUSE(aMsg, aTarget)                  \
+  A11YDEBUG_FOCUS_LOG_ACCTARGET("Caused by: " aMsg, aTarget)
+
+#else
+#define A11YDEBUG_FOCUS_LOG_DOMTARGET(aMsg, aTarget)
+#define A11YDEBUG_FOCUS_LOG_ACCTARGET(aMsg, aTarget)
+#define A11YDEBUG_FOCUS_LOG_WIDGET(aMsg, aWidget)
+#define A11YDEBUG_FOCUS_NOTIFICATION_SUPPORTSTARGET(aMsg, aTargetMsg, aTarget)
+#define A11YDEBUG_FOCUS_NOTIFICATION_DOMTARGET(aMsg, aTargetMsg, aTarget)
+#define A11YDEBUG_FOCUS_NOTIFICATION_ACCTARGET(aMsg, aTargetMsg, aTarget)
+#define A11YDEBUG_FOCUS_ACTIVEITEMCHANGE_CAUSE(aMsg, aTarget)
+#endif
+
+#endif
--- a/accessible/src/base/Makefile.in
+++ b/accessible/src/base/Makefile.in
@@ -48,16 +48,17 @@ LIBXUL_LIBRARY = 1
 
 
 CPPSRCS = \
   AccCollector.cpp \
   AccEvent.cpp \
   AccGroupInfo.cpp \
   AccIterator.cpp \
   filters.cpp \
+  FocusManager.cpp \
   NotificationController.cpp \
   nsAccDocManager.cpp \
   nsAccessNode.cpp \
   nsARIAGridAccessible.cpp \
   nsARIAMap.cpp \
   nsDocAccessible.cpp \
   nsOuterDocAccessible.cpp \
   nsCoreUtils.cpp \
@@ -84,16 +85,17 @@ EXPORTS = \
   nsAccessible.h \
   nsAccessNode.h \
   nsARIAMap.h \
   $(NULL)
 
 EXPORTS_NAMESPACES = mozilla/a11y
 
 EXPORTS_mozilla/a11y = \
+  FocusManager.h \
   States.h \
   $(NULL)
 
 # we don't want the shared lib, but we want to force the creation of a static lib.
 FORCE_STATIC_LIB = 1
 
 include $(topsrcdir)/config/rules.mk
 
--- a/accessible/src/base/NotificationController.cpp
+++ b/accessible/src/base/NotificationController.cpp
@@ -39,19 +39,22 @@
 #include "NotificationController.h"
 
 #include "nsAccessibilityService.h"
 #include "nsAccUtils.h"
 #include "nsCoreUtils.h"
 #include "nsDocAccessible.h"
 #include "nsEventShell.h"
 #include "nsTextAccessible.h"
+#include "FocusManager.h"
 #include "TextUpdater.h"
+
 #include "mozilla/dom/Element.h"
 
+using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // NotificationCollector
 ////////////////////////////////////////////////////////////////////////////////
 
 NotificationController::NotificationController(nsDocAccessible* aDocument,
                                                nsIPresShell* aPresShell) :
   mObservingState(eNotObservingRefresh), mDocument(aDocument),
@@ -177,17 +180,18 @@ NotificationController::ScheduleProcessi
 }
 
 bool
 NotificationController::IsUpdatePending()
 {
   return mPresShell->IsLayoutFlushObserver() ||
     mObservingState == eRefreshProcessingForUpdate ||
     mContentInsertions.Length() != 0 || mNotifications.Length() != 0 ||
-    mTextHash.Count() != 0;
+    mTextHash.Count() != 0 ||
+    !mDocument->HasLoadState(nsDocAccessible::eTreeConstructed);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // NotificationCollector: private
 
 void
 NotificationController::WillRefresh(mozilla::TimeStamp aTime)
 {
@@ -307,18 +311,25 @@ NotificationController::WillRefresh(mozi
   // Process only currently queued events.
   nsTArray<nsRefPtr<AccEvent> > events;
   events.SwapElements(mEvents);
 
   PRUint32 eventCount = events.Length();
   for (PRUint32 idx = 0; idx < eventCount; idx++) {
     AccEvent* accEvent = events[idx];
     if (accEvent->mEventRule != AccEvent::eDoNotEmit) {
+      // Dispatch the focus event if target is still focused.
+      if (accEvent->mEventType == nsIAccessibleEvent::EVENT_FOCUS) {
+        FocusMgr()->ProcessFocusEvent(accEvent);
+        continue;
+      }
+
       mDocument->ProcessPendingEvent(accEvent);
 
+      // Fire text change event caused by tree mutation.
       AccMutationEvent* showOrHideEvent = downcast_accEvent(accEvent);
       if (showOrHideEvent) {
         if (showOrHideEvent->mTextChangeEvent)
           mDocument->ProcessPendingEvent(showOrHideEvent->mTextChangeEvent);
       }
     }
     if (!mDocument)
       return;
@@ -340,24 +351,24 @@ NotificationController::WillRefresh(mozi
 
 void
 NotificationController::CoalesceEvents()
 {
   PRUint32 numQueuedEvents = mEvents.Length();
   PRInt32 tail = numQueuedEvents - 1;
   AccEvent* tailEvent = mEvents[tail];
 
-  // No node means this is application accessible (which can be a subject
-  // of reorder events), we do not coalesce events for it currently.
-  if (!tailEvent->mNode)
-    return;
-
   switch(tailEvent->mEventRule) {
     case AccEvent::eCoalesceFromSameSubtree:
     {
+      // No node means this is application accessible (which is a subject of
+      // reorder events), we do not coalesce events for it currently.
+      if (!tailEvent->mNode)
+        return;
+
       for (PRInt32 index = tail - 1; index >= 0; index--) {
         AccEvent* thisEvent = mEvents[index];
 
         if (thisEvent->mEventType != tailEvent->mEventType)
           continue; // Different type
 
         // Skip event for application accessible since no coalescence for it
         // is supported. Ignore events from different documents since we don't
@@ -441,31 +452,28 @@ NotificationController::CoalesceEvents()
                           thisEvent->mNode, AccEvent::eDoNotEmit);
           continue;
         }
 
       } // for (index)
 
     } break; // case eCoalesceFromSameSubtree
 
-    case AccEvent::eCoalesceFromSameDocument:
+    case AccEvent::eCoalesceOfSameType:
     {
-      // Used for focus event, coalesce more older event since focus event
-      // for accessible can be duplicated by event for its document, we are
-      // interested in focus event for accessible.
+      // Coalesce old events by newer event.
       for (PRInt32 index = tail - 1; index >= 0; index--) {
-        AccEvent* thisEvent = mEvents[index];
-        if (thisEvent->mEventType == tailEvent->mEventType &&
-            thisEvent->mEventRule == tailEvent->mEventRule &&
-            thisEvent->GetDocAccessible() == tailEvent->GetDocAccessible()) {
-          thisEvent->mEventRule = AccEvent::eDoNotEmit;
+        AccEvent* accEvent = mEvents[index];
+        if (accEvent->mEventType == tailEvent->mEventType &&
+            accEvent->mEventRule == tailEvent->mEventRule) {
+          accEvent->mEventRule = AccEvent::eDoNotEmit;
           return;
         }
       }
-    } break; // case eCoalesceFromSameDocument
+    } break; // case eCoalesceOfSameType
 
     case AccEvent::eRemoveDupes:
     {
       // Check for repeat events, coalesce newly appended event by more older
       // event.
       for (PRInt32 index = tail - 1; index >= 0; index--) {
         AccEvent* accEvent = mEvents[index];
         if (accEvent->mEventType == tailEvent->mEventType &&
@@ -560,17 +568,17 @@ NotificationController::CreateTextChange
   if (!textAccessible)
     return;
 
   // Don't fire event for the first html:br in an editor.
   if (aEvent->mAccessible->Role() == nsIAccessibleRole::ROLE_WHITESPACE) {
     nsCOMPtr<nsIEditor> editor;
     textAccessible->GetAssociatedEditor(getter_AddRefs(editor));
     if (editor) {
-      PRBool isEmpty = PR_FALSE;
+      bool isEmpty = false;
       editor->GetDocumentIsEmpty(&isEmpty);
       if (isEmpty)
         return;
     }
   }
 
   PRInt32 offset = textAccessible->GetChildOffset(aEvent->mAccessible);
 
--- a/accessible/src/base/NotificationController.h
+++ b/accessible/src/base/NotificationController.h
@@ -339,17 +339,17 @@ private:
     typedef T* KeyType;
     typedef const T* KeyTypePointer;
 
     nsCOMPtrHashKey(const T* aKey) : mKey(const_cast<T*>(aKey)) {}
     nsCOMPtrHashKey(const nsPtrHashKey<T> &aToCopy) : mKey(aToCopy.mKey) {}
     ~nsCOMPtrHashKey() { }
 
     KeyType GetKey() const { return mKey; }
-    PRBool KeyEquals(KeyTypePointer aKey) const { return aKey == mKey; }
+    bool KeyEquals(KeyTypePointer aKey) const { return aKey == mKey; }
 
     static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
     static PLDHashNumber HashKey(KeyTypePointer aKey)
       { return NS_PTR_TO_INT32(aKey) >> 2; }
 
     enum { ALLOW_MEMMOVE = PR_TRUE };
 
    protected:
--- a/accessible/src/base/Statistics.h
+++ b/accessible/src/base/Statistics.h
@@ -44,14 +44,26 @@
 
 namespace mozilla {
 namespace a11y {
 namespace statistics {
 
   inline void A11yInitialized()
     { Telemetry::Accumulate(Telemetry::A11Y_INSTANTIATED, true); }
 
+  /**
+   * Report that ISimpleDOM* has been used.
+   */
+  inline void ISimpleDOMUsed()
+    { Telemetry::Accumulate(Telemetry::ISIMPLE_DOM_USAGE, 1); }
+
+  /**
+   * Report that IAccessibleTable has been used.
+   */
+  inline void IAccessibleTableUsed()
+    { Telemetry::Accumulate(Telemetry::IACCESSIBLE_TABLE_USAGE, 1); }
+
 } // namespace statistics
 } // namespace a11y
 } // namespace mozilla
 
 #endif
 
--- a/accessible/src/base/nsARIAGridAccessible.cpp
+++ b/accessible/src/base/nsARIAGridAccessible.cpp
@@ -311,17 +311,17 @@ nsARIAGridAccessible::GetRowDescription(
 
   NS_ENSURE_ARG(IsValidRow(aRow));
 
   // XXX: not implemented
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsARIAGridAccessible::IsColumnSelected(PRInt32 aColumn, PRBool *aIsSelected)
+nsARIAGridAccessible::IsColumnSelected(PRInt32 aColumn, bool *aIsSelected)
 {
   NS_ENSURE_ARG_POINTER(aIsSelected);
   *aIsSelected = PR_FALSE;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   NS_ENSURE_ARG(IsValidColumn(aColumn));
@@ -342,17 +342,17 @@ nsARIAGridAccessible::IsColumnSelected(P
     }
   } while ((row = rowIter.Next()));
 
   *aIsSelected = PR_TRUE;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsARIAGridAccessible::IsRowSelected(PRInt32 aRow, PRBool *aIsSelected)
+nsARIAGridAccessible::IsRowSelected(PRInt32 aRow, bool *aIsSelected)
 {
   NS_ENSURE_ARG_POINTER(aIsSelected);
   *aIsSelected = PR_FALSE;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   nsAccessible *row = GetRowAt(aRow);
@@ -368,17 +368,17 @@ nsARIAGridAccessible::IsRowSelected(PRIn
   }
 
   *aIsSelected = PR_TRUE;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsARIAGridAccessible::IsCellSelected(PRInt32 aRow, PRInt32 aColumn,
-                                     PRBool *aIsSelected)
+                                     bool *aIsSelected)
 {
   NS_ENSURE_ARG_POINTER(aIsSelected);
   *aIsSelected = PR_FALSE;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   nsAccessible *row = GetRowAt(aRow);
@@ -453,17 +453,17 @@ nsARIAGridAccessible::GetSelectedRowCoun
       continue;
     }
 
     AccIterator cellIter(row, filters::GetCell);
     nsAccessible *cell = cellIter.Next();
     if (!cell)
       continue;
 
-    PRBool isRowSelected = PR_TRUE;
+    bool isRowSelected = true;
     do {
       if (!nsAccUtils::IsARIASelected(cell)) {
         isRowSelected = PR_FALSE;
         break;
       }
     } while ((cell = cellIter.Next()));
 
     if (isRowSelected)
@@ -600,17 +600,17 @@ nsARIAGridAccessible::GetSelectedRowIndi
       continue;
     }
 
     AccIterator cellIter(row, filters::GetCell);
     nsAccessible *cell = cellIter.Next();
     if (!cell)
       continue;
 
-    PRBool isRowSelected = PR_TRUE;
+    bool isRowSelected = true;
     do {
       if (!nsAccUtils::IsARIASelected(cell)) {
         isRowSelected = PR_FALSE;
         break;
       }
     } while ((cell = cellIter.Next()));
 
     if (isRowSelected)
@@ -705,50 +705,50 @@ nsARIAGridAccessible::UnselectColumn(PRI
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsARIAGridAccessible::IsProbablyForLayout(PRBool *aIsProbablyForLayout)
+nsARIAGridAccessible::IsProbablyForLayout(bool *aIsProbablyForLayout)
 {
   NS_ENSURE_ARG_POINTER(aIsProbablyForLayout);
   *aIsProbablyForLayout = PR_FALSE;
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Protected
 
-PRBool
+bool
 nsARIAGridAccessible::IsValidRow(PRInt32 aRow)
 {
   if (aRow < 0)
     return PR_FALSE;
   
   PRInt32 rowCount = 0;
   GetRowCount(&rowCount);
   return aRow < rowCount;
 }
 
-PRBool
+bool
 nsARIAGridAccessible::IsValidColumn(PRInt32 aColumn)
 {
   if (aColumn < 0)
     return PR_FALSE;
 
   PRInt32 colCount = 0;
   GetColumnCount(&colCount);
   return aColumn < colCount;
 }
 
-PRBool
+bool
 nsARIAGridAccessible::IsValidRowNColumn(PRInt32 aRow, PRInt32 aColumn)
 {
   if (aRow < 0 || aColumn < 0)
     return PR_FALSE;
   
   PRInt32 rowCount = 0;
   GetRowCount(&rowCount);
   if (aRow >= rowCount)
@@ -783,17 +783,17 @@ nsARIAGridAccessible::GetCellInRowAt(nsA
   while (colIdx != 0 && (cell = cellIter.Next()))
     colIdx--;
 
   return cell;
 }
 
 nsresult
 nsARIAGridAccessible::SetARIASelected(nsAccessible *aAccessible,
-                                      PRBool aIsSelected, PRBool aNotify)
+                                      bool aIsSelected, bool aNotify)
 {
   nsIContent *content = aAccessible->GetContent();
   NS_ENSURE_STATE(content);
 
   nsresult rv = NS_OK;
   if (aIsSelected)
     rv = content->SetAttr(kNameSpaceID_None, nsGkAtoms::aria_selected,
                           NS_LITERAL_STRING("true"), aNotify);
@@ -874,17 +874,17 @@ nsARIAGridAccessible::GetSelectedColumns
 
   PRInt32 colCount = 0;
   GetColumnCount(&colCount);
   if (!colCount)
     return NS_OK;
 
   PRInt32 selColCount = colCount;
 
-  nsTArray<PRBool> isColSelArray(selColCount);
+  nsTArray<bool> isColSelArray(selColCount);
   isColSelArray.AppendElements(selColCount);
   for (PRInt32 i = 0; i < selColCount; i++)
     isColSelArray[i] = PR_TRUE;
 
   do {
     if (nsAccUtils::IsARIASelected(row))
       continue;
 
@@ -1087,17 +1087,17 @@ nsARIAGridCellAccessible::GetRowHeaderCe
     return NS_OK;
 
   return nsAccUtils::GetHeaderCellsFor(table, this,
                                        nsAccUtils::eRowHeaderCells,
                                        aHeaderCells);
 }
 
 NS_IMETHODIMP
-nsARIAGridCellAccessible::IsSelected(PRBool *aIsSelected)
+nsARIAGridCellAccessible::IsSelected(bool *aIsSelected)
 {
   NS_ENSURE_ARG_POINTER(aIsSelected);
   *aIsSelected = PR_FALSE;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   nsAccessible* row = Parent();
--- a/accessible/src/base/nsARIAGridAccessible.h
+++ b/accessible/src/base/nsARIAGridAccessible.h
@@ -57,27 +57,27 @@ public:
 
   // nsIAccessibleTable
   NS_DECL_NSIACCESSIBLETABLE
 
 protected:
   /**
    * Return true if the given row index is valid.
    */
-  PRBool IsValidRow(PRInt32 aRow);
+  bool IsValidRow(PRInt32 aRow);
 
   /**
    * Retrn true if the given column index is valid.
    */
-  PRBool IsValidColumn(PRInt32 aColumn);
+  bool IsValidColumn(PRInt32 aColumn);
 
   /**
    * Retrun true if given row and column indexes are valid.
    */
-  PRBool IsValidRowNColumn(PRInt32 aRow, PRInt32 aColumn);
+  bool IsValidRowNColumn(PRInt32 aRow, PRInt32 aColumn);
 
   /**
    * Return row accessible at the given row index.
    */
   nsAccessible *GetRowAt(PRInt32 aRow);
 
   /**
    * Return cell accessible at the given column index in the row.
@@ -87,18 +87,18 @@ protected:
   /**
    * Set aria-selected attribute value on DOM node of the given accessible.
    *
    * @param  aAccessible  [in] accessible
    * @param  aIsSelected  [in] new value of aria-selected attribute
    * @param  aNotify      [in, optional] specifies if DOM should be notified
    *                       about attribute change (used internally).
    */
-  nsresult SetARIASelected(nsAccessible *aAccessible, PRBool aIsSelected,
-                           PRBool aNotify = PR_TRUE);
+  nsresult SetARIASelected(nsAccessible *aAccessible, bool aIsSelected,
+                           bool aNotify = true);
 
   /**
    * Helper method for GetSelectedColumnCount and GetSelectedColumns.
    */
   nsresult GetSelectedColumnsArray(PRUint32 *acolumnCount,
                                    PRInt32 **aColumns = nsnull);
 };
 
--- a/accessible/src/base/nsARIAMap.cpp
+++ b/accessible/src/base/nsARIAMap.cpp
@@ -750,17 +750,17 @@ nsStateMapEntry::nsStateMapEntry() :
   mDefaultState(0),
   mDefinedIfAbsent(PR_FALSE)
 {}
 
 nsStateMapEntry::nsStateMapEntry(nsIAtom** aAttrName, eStateValueType aType,
                                  PRUint64 aPermanentState,
                                  PRUint64 aTrueState,
                                  PRUint64 aFalseState,
-                                 PRBool aDefinedIfAbsent) :
+                                 bool aDefinedIfAbsent) :
   mAttributeName(aAttrName),
   mIsToken(PR_TRUE),
   mPermanentState(aPermanentState),
   mValue1("false"),
   mState1(aFalseState),
   mValue2(nsnull),
   mState2(0),
   mValue3(nsnull),
@@ -796,30 +796,30 @@ nsStateMapEntry::nsStateMapEntry(nsIAtom
   mValue2(aValue2), mState2(aState2),
   mValue3(aValue3), mState3(aState3),
   mDefaultState(0), mDefinedIfAbsent(PR_TRUE)
 {
   if (aDefaultStateRule == eUseFirstState)
     mDefaultState = aState1;
 }
 
-PRBool
+bool
 nsStateMapEntry::MapToStates(nsIContent* aContent, PRUint64* aState,
                              eStateMapEntryID aStateMapEntryID)
 {
   // Return true if we should continue.
   if (aStateMapEntryID == eARIANone)
     return PR_FALSE;
 
   const nsStateMapEntry& entry = nsARIAMap::gWAIStateMap[aStateMapEntryID];
 
   if (entry.mIsToken) {
     // If attribute is considered as defined when it's absent then let's act
     // attribute value is "false" supposedly.
-    PRBool hasAttr = aContent->HasAttr(kNameSpaceID_None, *entry.mAttributeName);
+    bool hasAttr = aContent->HasAttr(kNameSpaceID_None, *entry.mAttributeName);
     if (entry.mDefinedIfAbsent && !hasAttr) {
       if (entry.mPermanentState)
         *aState |= entry.mPermanentState;
       if (entry.mState1)
         *aState |= entry.mState1;
       return PR_TRUE;
     }
 
@@ -846,17 +846,17 @@ nsStateMapEntry::MapToStates(nsIContent*
   }
 
   nsAutoString attrValue;
   if (!aContent->GetAttr(kNameSpaceID_None, *entry.mAttributeName, attrValue))
     return PR_TRUE;
 
   // Apply states for matched value. If no values was matched then apply default
   // states.
-  PRBool applyDefaultStates = PR_TRUE;
+  bool applyDefaultStates = true;
   if (entry.mValue1) {
     if (attrValue.EqualsASCII(entry.mValue1)) {
       applyDefaultStates = PR_FALSE;
 
       if (entry.mState1)
         *aState |= entry.mState1;
     } else if (entry.mValue2) {
       if (attrValue.EqualsASCII(entry.mValue2)) {
--- a/accessible/src/base/nsARIAMap.h
+++ b/accessible/src/base/nsARIAMap.h
@@ -102,22 +102,22 @@ enum ELiveAttrRule
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // Role constants
 
 /**
  * ARIA role overrides role from native markup.
  */
-const PRBool kUseMapRole = PR_TRUE;
+const bool kUseMapRole = true;
 
 /**
  * ARIA role doesn't override the role from native markup.
  */
-const PRBool kUseNativeRole = PR_FALSE;
+const bool kUseNativeRole = false;
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // ARIA attribute characteristic masks
 
 /**
  * This mask indicates the attribute should not be exposed as an object
  * attribute via the catch-all logic in nsAccessible::GetAttributes.
@@ -198,17 +198,17 @@ public:
 
   /**
    * Used for ARIA attributes having boolean or mixed values.
    */
   nsStateMapEntry(nsIAtom** aAttrName, eStateValueType aType,
                   PRUint64 aPermanentState,
                   PRUint64 aTrueState,
                   PRUint64 aFalseState = 0,
-                  PRBool aDefinedIfAbsent = PR_FALSE);
+                  bool aDefinedIfAbsent = false);
 
   /**
    * Used for ARIA attributes having enumerated values.
    */
   nsStateMapEntry(nsIAtom** aAttrName,
                   const char* aValue1, PRUint64 aState1,
                   const char* aValue2, PRUint64 aState2,
                   const char* aValue3 = 0, PRUint64 aState3 = 0);
@@ -225,25 +225,25 @@ public:
   /**
    * Maps ARIA state map pointed by state map entry ID to accessible states.
    *
    * @param  aContent         [in] node of the accessible
    * @param  aState           [in/out] accessible states
    * @param  aStateMapEntryID [in] state map entry ID
    * @return                   true if state map entry ID is valid
    */
-  static PRBool MapToStates(nsIContent* aContent, PRUint64* aState,
+  static bool MapToStates(nsIContent* aContent, PRUint64* aState,
                             eStateMapEntryID aStateMapEntryID);
 
 private:
   // ARIA attribute name
   nsIAtom** mAttributeName;
 
   // Indicates if attribute is token (can be undefined)
-  PRBool mIsToken;
+  bool mIsToken;
 
   // State applied always if attribute is defined
   PRUint64 mPermanentState;
 
   // States applied if attribute value is matched to the stored value
   const char* mValue1;
   PRUint64 mState1;
 
@@ -252,17 +252,17 @@ private:
 
   const char* mValue3;
   PRUint64 mState3;
 
   // States applied if no stored values above are matched
   PRUint64 mDefaultState;
 
   // Permanent and false states are applied if attribute is absent
-  PRBool mDefinedIfAbsent;
+  bool mDefinedIfAbsent;
 };
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // Role map entry
 
 /**
  * For each ARIA role, this maps the nsIAccessible information.
@@ -271,17 +271,17 @@ struct nsRoleMapEntry
 {
   // ARIA role: string representation such as "button"
   const char *roleString;
   
   // Role mapping rule: maps to this nsIAccessibleRole
   PRUint32 role;
   
   // Role rule: whether to use mapped role or native semantics
-  PRBool roleRule;
+  bool roleRule;
   
   // Value mapping rule: how to compute nsIAccessible value
   EValueRule valueRule;
 
   // Action mapping rule, how to expose nsIAccessible action
   EActionRule actionRule;
 
   // 'live' and 'container-live' object attributes mapping rule: how to expose
--- a/accessible/src/base/nsAccDocManager.cpp
+++ b/accessible/src/base/nsAccDocManager.cpp
@@ -93,17 +93,17 @@ nsAccDocManager::FindAccessibleInCache(n
 
   return arg.mAccessible;
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccDocManager protected
 
-PRBool
+bool
 nsAccDocManager::Init()
 {
   mDocAccessibleCache.Init(4);
 
   nsCOMPtr<nsIWebProgress> progress =
     do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID);
 
   if (!progress)
@@ -320,17 +320,17 @@ nsAccDocManager::HandleDOMDocumentLoad(n
       return;
   }
 
   docAcc->NotifyOfLoad(aLoadEventType);
 }
 
 void
 nsAccDocManager::AddListeners(nsIDocument *aDocument,
-                              PRBool aAddDOMContentLoadedListener)
+                              bool aAddDOMContentLoadedListener)
 {
   nsPIDOMWindow *window = aDocument->GetWindow();
   nsIDOMEventTarget *target = window->GetChromeEventHandler();
   nsEventListenerManager* elm = target->GetListenerManager(PR_TRUE);
   elm->AddEventListenerByType(this, NS_LITERAL_STRING("pagehide"),
                               NS_EVENT_FLAG_CAPTURE);
 
   NS_LOG_ACCDOCCREATE_TEXT("  added 'pagehide' listener")
@@ -357,17 +357,17 @@ nsAccDocManager::CreateDocOrRootAccessib
     return nsnull;
 
   // Do not create document accessible until role content is loaded, otherwise
   // we get accessible document with wrong role.
   nsIContent *rootElm = nsCoreUtils::GetRoleContent(aDocument);
   if (!rootElm)
     return nsnull;
 
-  PRBool isRootDoc = nsCoreUtils::IsRootDocument(aDocument);
+  bool isRootDoc = nsCoreUtils::IsRootDocument(aDocument);
 
   nsDocAccessible* parentDocAcc = nsnull;
   if (!isRootDoc) {
     // XXXaaronl: ideally we would traverse the presshell chain. Since there's
     // no easy way to do that, we cheat and use the document hierarchy.
     // GetAccessible() is bad because it doesn't support our concept of multiple
     // presshells per doc. It should be changed to use
     // GetAccessibleInWeakShell().
@@ -413,16 +413,17 @@ nsAccDocManager::CreateDocOrRootAccessib
                    AccEvent::eCoalesceFromSameSubtree);
     docAcc->FireDelayedAccessibleEvent(reorderEvent);
 
   } else {
     parentDocAcc->BindChildDocument(docAcc);
   }
 
   NS_LOG_ACCDOCCREATE("document creation finished", aDocument)
+  NS_LOG_ACCDOCCREATE_STACK
 
   AddListeners(aDocument, isRootDoc);
   return docAcc;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccDocManager static
 
--- a/accessible/src/base/nsAccDocManager.h
+++ b/accessible/src/base/nsAccDocManager.h
@@ -92,17 +92,17 @@ public:
   }
 
 protected:
   nsAccDocManager() { };
 
   /**
    * Initialize the manager.
    */
-  PRBool Init();
+  bool Init();
 
   /**
    * Shutdown the manager.
    */
   void Shutdown();
 
 private:
   nsAccDocManager(const nsAccDocManager&);
@@ -118,17 +118,17 @@ private:
    *                           if 0 then no event is fired
    */
   void HandleDOMDocumentLoad(nsIDocument *aDocument,
                              PRUint32 aLoadEventType);
 
   /**
    * Add 'pagehide' and 'DOMContentLoaded' event listeners.
    */
-  void AddListeners(nsIDocument *aDocument, PRBool aAddPageShowListener);
+  void AddListeners(nsIDocument *aDocument, bool aAddPageShowListener);
 
   /**
    * Create document or root accessible.
    */
   nsDocAccessible *CreateDocOrRootAccessible(nsIDocument *aDocument);
 
   typedef nsRefPtrHashtable<nsPtrHashKey<const nsIDocument>, nsDocAccessible>
     nsDocAccessibleHashtable;
@@ -160,16 +160,18 @@ private:
   nsDocAccessibleHashtable mDocAccessibleCache;
 };
 
 /**
  * nsAccDocManager debugging macros.
  */
 #ifdef DEBUG_ACCDOCMGR
 
+#include "nsTraceRefcntImpl.h"
+
 // Enable these to log accessible document loading, creation or destruction.
 #define DEBUG_ACCDOCMGR_DOCLOAD
 #define DEBUG_ACCDOCMGR_DOCCREATE
 #define DEBUG_ACCDOCMGR_DOCDESTROY
 
 // Common macros, do not use directly.
 #define NS_LOG_ACCDOC_ADDRESS(aDocument, aDocAcc)                              \
   printf("DOM id: %p, acc id: %p", aDocument, aDocAcc);
@@ -177,17 +179,17 @@ private:
 #define NS_LOG_ACCDOC_URI(aDocument)                                           \
   nsIURI *uri = aDocument->GetDocumentURI();                                   \
   nsCAutoString spec;                                                          \
   uri->GetSpec(spec);                                                          \
   printf("uri: %s", spec);
 
 #define NS_LOG_ACCDOC_TYPE(aDocument)                                          \
   if (aDocument->IsActive()) {                                                 \
-    PRBool isContent = nsCoreUtils::IsContentDocument(aDocument);              \
+    bool isContent = nsCoreUtils::IsContentDocument(aDocument);              \
     printf("%s document", (isContent ? "content" : "chrome"));                 \
   } else {                                                                     \
     printf("document type: [failed]");                                         \
   }
 
 #define NS_LOG_ACCDOC_DOCSHELLTREE(aDocument)                                  \
   if (aDocument->IsActive()) {                                                 \
     nsCOMPtr<nsISupports> container = aDocument->GetContainer();               \
@@ -400,16 +402,20 @@ private:
   }
 
 #define NS_LOG_ACCDOC_MSG(aMsg)                                                \
   printf("\n" aMsg "\n");                                                      \
 
 #define NS_LOG_ACCDOC_TEXT(aMsg)                                               \
   printf("  " aMsg "\n");
 
+#define NS_LOG_ACCDOC_STACK                                                    \
+  printf("  stack: \n");                                                       \
+  nsTraceRefcntImpl::WalkTheStack(stdout);
+
 // Accessible document loading macros.
 #ifdef DEBUG_ACCDOCMGR_DOCLOAD
 
 #define NS_LOG_ACCDOCLOAD_REQUEST(aRequest)                                    \
   if (aRequest) {                                                              \
     nsCAutoString name;                                                        \
     aRequest->GetName(name);                                                   \
     printf("    request spec: %s\n", name.get());                              \
@@ -453,17 +459,17 @@ private:
         nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(DOMWindow));         \
         nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(webNav));             \
         printf("    ");                                                        \
         NS_LOG_ACCDOC_SHELLLOADTYPE(docShell)                                  \
         printf("\n");                                                          \
         NS_LOG_ACCDOCLOAD_REQUEST(aRequest)                                    \
         printf("\n");                                                          \
         printf("    state flags: %x", aStateFlags);                            \
-        PRBool isDocLoading;                                                   \
+        bool isDocLoading;                                                   \
         aWebProgress->GetIsLoadingDocument(&isDocLoading);                     \
         printf(", document is %sloading\n", (isDocLoading ? "" : "not "));     \
         printf("  }\n");                                                       \
       }                                                                        \
     }                                                                          \
   }
 
 #define NS_LOG_ACCDOCLOAD2(aMsg, aDocument)                                    \
@@ -510,17 +516,20 @@ private:
       GetAccService()->GetDocAccessibleFromCache(aDocument);                   \
     NS_LOG_ACCDOCCREATE_FOR(aMsg, aDocument, docAcc)                           \
   }
 
 #define NS_LOG_ACCDOCCREATE_ACCADDRESS(aName, aAcc)                            \
   NS_LOG_ACCDOC_ACCADDRESS(aName, aAcc)
 
 #define NS_LOG_ACCDOCCREATE_TEXT(aMsg)                                         \
-    NS_LOG_ACCDOC_TEXT(aMsg)
+  NS_LOG_ACCDOC_TEXT(aMsg)
+
+#define NS_LOG_ACCDOCCREATE_STACK                                              \
+  NS_LOG_ACCDOC_STACK
 
 #endif // DEBUG_ACCDOCMGR_DOCCREATE
 
 // Accessible document destruction macros.
 #ifdef DEBUG_ACCDOCMGR_DOCDESTROY
 #define NS_LOG_ACCDOCDESTROY_FOR(aMsg, aDocument, aDocAcc)                     \
   NS_LOG_ACCDOC_MSG("A11Y DOCDESTROY: " aMsg);                                 \
   NS_LOG_ACCDOC_DOCINFO(aDocument, aDocAcc)
@@ -554,16 +563,17 @@ private:
 #define NS_LOG_ACCDOCLOAD_TEXT(aMsg)
 #endif
 
 #ifndef DEBUG_ACCDOCMGR_DOCCREATE
 #define NS_LOG_ACCDOCCREATE_FOR(aMsg, aDocument, aDocAcc)
 #define NS_LOG_ACCDOCCREATE(aMsg, aDocument)
 #define NS_LOG_ACCDOCCREATE_ACCADDRESS(aName, aAcc)
 #define NS_LOG_ACCDOCCREATE_TEXT(aMsg)
+#define NS_LOG_ACCDOCCREATE_STACK
 #endif
 
 #ifndef DEBUG_ACCDOCMGR_DOCDESTROY
 #define NS_LOG_ACCDOCDESTROY_FOR(aMsg, aDocument, aDocAcc)
 #define NS_LOG_ACCDOCDESTROY(aMsg, aDocument)
 #define NS_LOG_ACCDOCDESTROY_MSG(aMsg)
 #define NS_LOG_ACCDOCDESTROY_ACCADDRESS(aName, aAcc)
 #define NS_LOG_ACCDOCDESTROY_TEXT(aMsg)
--- a/accessible/src/base/nsAccTreeWalker.cpp
+++ b/accessible/src/base/nsAccTreeWalker.cpp
@@ -61,17 +61,17 @@ struct WalkState
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccTreeWalker
 ////////////////////////////////////////////////////////////////////////////////
 
 nsAccTreeWalker::
   nsAccTreeWalker(nsIWeakReference* aShell, nsIContent* aContent,
-                  PRBool aWalkAnonContent, bool aWalkCache) :
+                  bool aWalkAnonContent, bool aWalkCache) :
   mWeakShell(aShell), mWalkCache(aWalkCache), mState(nsnull)
 {
   NS_ASSERTION(aContent, "No node for the accessible tree walker!");
 
   if (aContent)
     mState = new WalkState(aContent);
 
   mChildFilter = aWalkAnonContent ? nsIContent::eAllChildren :
@@ -142,17 +142,17 @@ nsAccTreeWalker::NextChildInternal(bool 
 void
 nsAccTreeWalker::PopState()
 {
   WalkState* prevToLastState = mState->prevState;
   delete mState;
   mState = prevToLastState;
 }
 
-PRBool
+bool
 nsAccTreeWalker::PushState(nsIContent* aContent)
 {
   WalkState* nextToLastState = new WalkState(aContent);
   if (!nextToLastState)
     return PR_FALSE;
 
   nextToLastState->prevState = mState;
   mState = nextToLastState;
--- a/accessible/src/base/nsAccTreeWalker.h
+++ b/accessible/src/base/nsAccTreeWalker.h
@@ -49,17 +49,17 @@ struct WalkState;
 
 /**
  * This class is used to walk the DOM tree to create accessible tree.
  */
 class nsAccTreeWalker
 {
 public:
   nsAccTreeWalker(nsIWeakReference *aShell, nsIContent *aNode, 
-                  PRBool aWalkAnonymousContent, bool aWalkCache = false);
+                  bool aWalkAnonymousContent, bool aWalkCache = false);
   virtual ~nsAccTreeWalker();
 
   /**
    * Return the next child accessible.
    *
    * @note Returned accessible is bound to the document, if the accessible is
    *       rejected during tree creation then the caller should be unbind it
    *       from the document.
@@ -81,17 +81,17 @@ private:
   nsAccessible* NextChildInternal(bool aNoWalkUp);
 
   /**
    * Create new state for the given node and push it on top of stack.
    *
    * @note State stack is used to navigate up/down the DOM subtree during
    *        accessible children search.
    */
-  PRBool PushState(nsIContent *aNode);
+  bool PushState(nsIContent *aNode);
 
   /**
    * Pop state from stack.
    */
   void PopState();
 
   nsCOMPtr<nsIWeakReference> mWeakShell;
   PRInt32 mChildFilter;
--- a/accessible/src/base/nsAccUtils.cpp
+++ b/accessible/src/base/nsAccUtils.cpp
@@ -315,17 +315,17 @@ nsAccUtils::SetLiveContainerAttributes(n
       break;
 
     ancestor = ancestor->GetParent();
     if (!ancestor)
       ancestor = aTopContent; // Use <body>/<frameset>
   }
 }
 
-PRBool
+bool
 nsAccUtils::HasDefinedARIAToken(nsIContent *aContent, nsIAtom *aAtom)
 {
   NS_ASSERTION(aContent, "aContent is null in call to HasDefinedARIAToken!");
 
   if (!aContent->HasAttr(kNameSpaceID_None, aAtom) ||
       aContent->AttrValueIs(kNameSpaceID_None, aAtom,
                             nsGkAtoms::_empty, eCaseMatters) ||
       aContent->AttrValueIs(kNameSpaceID_None, aAtom,
@@ -395,17 +395,17 @@ nsAccUtils::GetMultiSelectableContainer(
                                                      accessible->State());
     if (container && container->State() & states::MULTISELECTABLE)
       return container;
   }
 
   return nsnull;
 }
 
-PRBool
+bool
 nsAccUtils::IsARIASelected(nsAccessible *aAccessible)
 {
   return aAccessible->GetContent()->
     AttrValueIs(kNameSpaceID_None, nsGkAtoms::aria_selected,
                 nsGkAtoms::_true, eCaseMatters);
 }
 
 nsHyperTextAccessible*
@@ -582,37 +582,37 @@ nsAccUtils::GetAttributeCharacteristics(
 {
     for (PRUint32 i = 0; i < nsARIAMap::gWAIUnivAttrMapLength; i++)
       if (*nsARIAMap::gWAIUnivAttrMap[i].attributeName == aAtom)
         return nsARIAMap::gWAIUnivAttrMap[i].characteristics;
 
     return 0;
 }
 
-PRBool
+bool
 nsAccUtils::GetLiveAttrValue(PRUint32 aRule, nsAString& aValue)
 {
   switch (aRule) {
     case eOffLiveAttr:
       aValue = NS_LITERAL_STRING("off");
       return PR_TRUE;
     case ePoliteLiveAttr:
       aValue = NS_LITERAL_STRING("polite");
       return PR_TRUE;
   }
 
   return PR_FALSE;
 }
 
 #ifdef DEBUG_A11Y
 
-PRBool
+bool
 nsAccUtils::IsTextInterfaceSupportCorrect(nsAccessible *aAccessible)
 {
-  PRBool foundText = PR_FALSE;
+  bool foundText = false;
   
   nsCOMPtr<nsIAccessibleDocument> accDoc = do_QueryObject(aAccessible);
   if (accDoc) {
     // Don't test for accessible docs, it makes us create accessibles too
     // early and fire mutation events before we need to
     return PR_TRUE;
   }
 
@@ -650,17 +650,17 @@ nsAccUtils::TextLength(nsAccessible *aAc
   // text. They don't have their own frame.
   // XXX In the future, list bullets may have frame and anon content, so 
   // we should be able to remove this at that point
   nsAutoString text;
   aAccessible->AppendTextTo(text); // Get all the text
   return text.Length();
 }
 
-PRBool
+bool
 nsAccUtils::MustPrune(nsIAccessible *aAccessible)
 { 
   PRUint32 role = nsAccUtils::Role(aAccessible);
 
   // We don't prune buttons any more however AT don't expect children inside of
   // button in general, we allow menu buttons to have children to make them
   // accessible.
   return role == nsIAccessibleRole::ROLE_MENUITEM || 
@@ -688,17 +688,17 @@ nsAccUtils::GetHeaderCellsFor(nsIAccessi
   PRInt32 rowIdx = -1;
   rv = aCell->GetRowIndex(&rowIdx);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32 colIdx = -1;
   rv = aCell->GetColumnIndex(&colIdx);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRBool moveToLeft = aRowOrColHeaderCells == eRowHeaderCells;
+  bool moveToLeft = aRowOrColHeaderCells == eRowHeaderCells;
 
   // Move to the left or top to find row header cells or column header cells.
   PRInt32 index = (moveToLeft ? colIdx : rowIdx) - 1;
   for (; index >= 0; index--) {
     PRInt32 curRowIdx = moveToLeft ? rowIdx : index;
     PRInt32 curColIdx = moveToLeft ? index : colIdx;
 
     nsCOMPtr<nsIAccessible> cell;
@@ -716,17 +716,17 @@ nsAccUtils::GetHeaderCellsFor(nsIAccessi
       rv = tableCellAcc->GetColumnIndex(&origIdx);
     else
       rv = tableCellAcc->GetRowIndex(&origIdx);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (origIdx == index) {
       // Append original header cells only.
       PRUint32 role = Role(cell);
-      PRBool isHeader = moveToLeft ?
+      bool isHeader = moveToLeft ?
         role == nsIAccessibleRole::ROLE_ROWHEADER :
         role == nsIAccessibleRole::ROLE_COLUMNHEADER;
 
       if (isHeader)
         cells->AppendElement(cell, PR_FALSE);
     }
   }
 
--- a/accessible/src/base/nsAccUtils.h
+++ b/accessible/src/base/nsAccUtils.h
@@ -143,17 +143,17 @@ public:
 
   /**
    * Any ARIA property of type boolean or NMTOKEN is undefined if the ARIA
    * property is not present, or is "" or "undefined". Do not call 
    * this method for properties of type string, decimal, IDREF or IDREFS.
    * 
    * Return PR_TRUE if the ARIA property is defined, otherwise PR_FALSE
    */
-  static PRBool HasDefinedARIAToken(nsIContent *aContent, nsIAtom *aAtom);
+  static bool HasDefinedARIAToken(nsIContent *aContent, nsIAtom *aAtom);
 
   /**
    * Return atomic value of ARIA attribute of boolean or NMTOKEN type.
    */
   static nsIAtom* GetARIAToken(mozilla::dom::Element* aElement, nsIAtom* aAttr);
 
   /**
    * Return document accessible for the given presshell.
@@ -211,17 +211,17 @@ public:
    * Return multi selectable container for the given item.
    */
   static nsAccessible *GetMultiSelectableContainer(nsINode *aNode);
 
   /**
    * Return true if the DOM node of given accessible has aria-selected="true"
    * attribute.
    */
-  static PRBool IsARIASelected(nsAccessible *aAccessible);
+  static bool IsARIASelected(nsAccessible *aAccessible);
 
   /**
    * Return text accessible containing focus point of the given selection.
    * Used for normal and misspelling selection changes processing.
    *
    * @param aSelection  [in] the given selection
    * @return            text accessible
    */
@@ -308,45 +308,45 @@ public:
    * Get the 'live' or 'container-live' object attribute value from the given
    * ELiveAttrRule constant.
    *
    * @param  aRule   [in] rule constant (see ELiveAttrRule in nsAccMap.h)
    * @param  aValue  [out] object attribute value
    *
    * @return         true if object attribute should be exposed
    */
-  static PRBool GetLiveAttrValue(PRUint32 aRule, nsAString& aValue);
+  static bool GetLiveAttrValue(PRUint32 aRule, nsAString& aValue);
 
 #ifdef DEBUG_A11Y
   /**
    * Detect whether the given accessible object implements nsIAccessibleText,
    * when it is text or has text child node.
    */
-  static PRBool IsTextInterfaceSupportCorrect(nsAccessible *aAccessible);
+  static bool IsTextInterfaceSupportCorrect(nsAccessible *aAccessible);
 #endif
 
   /**
    * Return true if the given accessible has text role.
    */
-  static PRBool IsText(nsIAccessible *aAcc)
+  static bool IsText(nsIAccessible *aAcc)
   {
     PRUint32 role = Role(aAcc);
     return role == nsIAccessibleRole::ROLE_TEXT_LEAF ||
            role == nsIAccessibleRole::ROLE_STATICTEXT;
   }
 
   /**
    * Return text length of the given accessible, return 0 on failure.
    */
   static PRUint32 TextLength(nsAccessible *aAccessible);
 
   /**
    * Return true if the given accessible is embedded object.
    */
-  static PRBool IsEmbeddedObject(nsIAccessible *aAcc)
+  static bool IsEmbeddedObject(nsIAccessible *aAcc)
   {
     PRUint32 role = Role(aAcc);
     return role != nsIAccessibleRole::ROLE_TEXT_LEAF &&
            role != nsIAccessibleRole::ROLE_WHITESPACE &&
            role != nsIAccessibleRole::ROLE_STATICTEXT;
   }
 
   /**
@@ -368,17 +368,17 @@ public:
     if (aState2)
       *aState2 = static_cast<PRUint32>(aState64 >> 31);
   }
 
   /**
    * Return true if the given accessible can't have children. Used when exposing
    * to platform accessibility APIs, should the children be pruned off?
    */
-  static PRBool MustPrune(nsIAccessible *aAccessible);
+  static bool MustPrune(nsIAccessible *aAccessible);
 
   /**
    * Search hint enum constants. Used by GetHeaderCellsFor() method.
    */
   enum {
     // search for row header cells, left direction
     eRowHeaderCells,
     // search for column header cells, top direction
--- a/accessible/src/base/nsAccessNode.cpp
+++ b/accessible/src/base/nsAccessNode.cpp
@@ -70,19 +70,18 @@
 #include "nsIObserverService.h"
 #include "mozilla/Services.h"
 
 /* For documentation of the accessibility architecture, 
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
 nsIStringBundle *nsAccessNode::gStringBundle = 0;
-nsINode *nsAccessNode::gLastFocusedNode = nsnull;
 
-PRBool nsAccessNode::gIsFormFillEnabled = PR_FALSE;
+bool nsAccessNode::gIsFormFillEnabled = false;
 
 nsApplicationAccessible *nsAccessNode::gApplicationAccessible = nsnull;
 
 /*
  * Class nsAccessNode
  */
  
 ////////////////////////////////////////////////////////////////////////////////
@@ -131,17 +130,17 @@ void nsAccessNode::LastRelease()
 // nsAccessNode public
 
 bool
 nsAccessNode::IsDefunct() const
 {
   return !mContent;
 }
 
-PRBool
+bool
 nsAccessNode::Init()
 {
   return PR_TRUE;
 }
 
 
 void
 nsAccessNode::Shutdown()
@@ -201,17 +200,17 @@ void nsAccessNode::InitXPAccessibility()
   if (prefBranch) {
     prefBranch->GetBoolPref("browser.formfill.enable", &gIsFormFillEnabled);
   }
 
   NotifyA11yInitOrShutdown(PR_TRUE);
 }
 
 // nsAccessNode protected static
-void nsAccessNode::NotifyA11yInitOrShutdown(PRBool aIsInit)
+void nsAccessNode::NotifyA11yInitOrShutdown(bool aIsInit)
 {
   nsCOMPtr<nsIObserverService> obsService =
     mozilla::services::GetObserverService();
   NS_ASSERTION(obsService, "No observer service to notify of a11y init/shutdown");
   if (!obsService)
     return;
 
   static const PRUnichar kInitIndicator[] = { '1', 0 };
@@ -222,17 +221,16 @@ void nsAccessNode::NotifyA11yInitOrShutd
 
 void nsAccessNode::ShutdownXPAccessibility()
 {
   // Called by nsAccessibilityService::Shutdown()
   // which happens when xpcom is shutting down
   // at exit of program
 
   NS_IF_RELEASE(gStringBundle);
-  NS_IF_RELEASE(gLastFocusedNode);
 
   // Release gApplicationAccessible after everything else is shutdown
   // so we don't accidently create it again while tearing down root accessibles
   nsApplicationAccessibleWrap::Unload();
   if (gApplicationAccessible) {
     gApplicationAccessible->Shutdown();
     NS_RELEASE(gApplicationAccessible);
   }
--- a/accessible/src/base/nsAccessNode.h
+++ b/accessible/src/base/nsAccessNode.h
@@ -103,32 +103,27 @@ public:
   nsDocAccessible *GetDocAccessible() const;
 
   /**
    * Return the root document accessible for this accessnode.
    */
   nsRootAccessible* RootAccessible() const;
 
   /**
-   * Reference to a node of focused accessible.
-   */
-  static nsINode *gLastFocusedNode;
-
-  /**
    * Return focused node within accessible window.
    *
    * XXX: it shouldn't break us if we return focused node not depending on
    * window so that we can turn this method into util method.
    */
   already_AddRefed<nsINode> GetCurrentFocus();
 
   /**
    * Initialize the access node object, add it to the cache.
    */
-  virtual PRBool Init();
+  virtual bool Init();
 
   /**
    * Shutdown the access node object.
    */
   virtual void Shutdown();
 
   /**
    * Returns true when the accessible is defunct.
@@ -157,17 +152,17 @@ public:
   virtual nsINode* GetNode() const { return mContent; }
   nsIContent* GetContent() const { return mContent; }
   virtual nsIDocument* GetDocumentNode() const
     { return mContent ? mContent->GetOwnerDoc() : nsnull; }
 
   /**
    * Return node type information of DOM node associated with the accessible.
    */
-  PRBool IsContent() const
+  bool IsContent() const
   {
     return GetNode() && GetNode()->IsNodeOfType(nsINode::eCONTENT);
   }
   bool IsElement() const
   {
     nsINode* node = GetNode();
     return node && node->IsElement();
   }
@@ -206,22 +201,22 @@ protected:
     void LastRelease();
 
   nsCOMPtr<nsIContent> mContent;
   nsCOMPtr<nsIWeakReference> mWeakShell;
 
     /**
      * Notify global nsIObserver's that a11y is getting init'd or shutdown
      */
-    static void NotifyA11yInitOrShutdown(PRBool aIsInit);
+    static void NotifyA11yInitOrShutdown(bool aIsInit);
 
     // Static data, we do our own refcounting for our static data
     static nsIStringBundle *gStringBundle;
 
-    static PRBool gIsFormFillEnabled;
+    static bool gIsFormFillEnabled;
 
 private:
   static nsApplicationAccessible *gApplicationAccessible;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsAccessNode,
                               NS_ACCESSNODE_IMPL_CID)
 
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -38,16 +38,18 @@
 
 // NOTE: alphabetically ordered
 #include "nsAccessibilityService.h"
 #include "nsCoreUtils.h"
 #include "nsAccUtils.h"
 #include "nsApplicationAccessibleWrap.h"
 #include "nsARIAGridAccessibleWrap.h"
 #include "nsARIAMap.h"
+#include "FocusManager.h"
+
 #include "nsIContentViewer.h"
 #include "nsCURILoader.h"
 #include "nsDocAccessible.h"
 #include "nsHTMLImageMapAccessible.h"
 #include "nsHTMLLinkAccessible.h"
 #include "nsHTMLSelectAccessible.h"
 #include "nsHTMLTableAccessibleWrap.h"
 #include "nsHTMLTextAccessible.h"
@@ -63,16 +65,17 @@
 #include "nsIDOMHTMLObjectElement.h"
 #include "nsIDOMHTMLOptGroupElement.h"
 #include "nsIDOMHTMLOptionElement.h"
 #include "nsIDOMXULElement.h"
 #include "nsIHTMLDocument.h"
 #include "nsImageFrame.h"
 #include "nsILink.h"
 #include "nsIObserverService.h"
+#include "nsLayoutUtils.h"
 #include "nsNPAPIPluginInstance.h"
 #include "nsISupportsUtils.h"
 #include "nsObjectFrame.h"
 #include "nsOuterDocAccessible.h"
 #include "nsRootAccessibleWrap.h"
 #include "nsTextFragment.h"
 #include "mozilla/Services.h"
 #include "nsEventStates.h"
@@ -110,19 +113,20 @@
 
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessibilityService
 ////////////////////////////////////////////////////////////////////////////////
 
 nsAccessibilityService *nsAccessibilityService::gAccessibilityService = nsnull;
-PRBool nsAccessibilityService::gIsShutdown = PR_TRUE;
+bool nsAccessibilityService::gIsShutdown = true;
 
-nsAccessibilityService::nsAccessibilityService() : nsAccDocManager()
+nsAccessibilityService::nsAccessibilityService() :
+  nsAccDocManager(), FocusManager()
 {
   NS_TIME_FUNCTION;
 }
 
 nsAccessibilityService::~nsAccessibilityService()
 {
   NS_ASSERTION(gIsShutdown, "Accessibility wasn't shutdown!");
   gAccessibilityService = nsnull;
@@ -170,17 +174,17 @@ nsAccessibilityService::FireAccessibleEv
   nsEventShell::FireEvent(aEvent, aTarget);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessibilityService
 
 nsAccessible*
 nsAccessibilityService::GetRootDocumentAccessible(nsIPresShell* aPresShell,
-                                                  PRBool aCanCreate)
+                                                  bool aCanCreate)
 {
   nsIDocument* documentNode = aPresShell->GetDocument();
   if (documentNode) {
     nsCOMPtr<nsISupports> container = documentNode->GetContainer();
     nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(container));
     if (treeItem) {
       nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
       treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
@@ -868,17 +872,17 @@ nsAccessibilityService::GetAccessibleOrC
   if (!aNode)
     return nsnull;
 
   // XXX: weak shell is ignored until multiple shell documents are supported.
   nsDocAccessible* document = GetDocAccessible(aNode->GetOwnerDoc());
   return document ? document->GetAccessibleOrContainer(aNode) : nsnull;
 }
 
-static PRBool HasRelatedContent(nsIContent *aContent)
+static bool HasRelatedContent(nsIContent *aContent)
 {
   nsAutoString id;
   if (!aContent || !nsCoreUtils::GetID(aContent, id) || id.IsEmpty()) {
     return PR_FALSE;
   }
 
   // If the given ID is referred by relation attribute then create an accessible
   // for it. Take care of HTML elements only for now.
@@ -953,20 +957,33 @@ nsAccessibilityService::GetOrCreateAcces
     return nsnull;
   }
 
   if (weakFrame.GetFrame()->GetContent() != content) {
     // Not the main content for this frame. This happens because <area>
     // elements return the image frame as their primary frame. The main content
     // for the image frame is the image content. If the frame is not an image
     // frame or the node is not an area element then null is returned.
-    // This setup will change when bug 135040 is fixed.
-    return GetAreaAccessible(weakFrame.GetFrame(), aNode, aWeakShell);
+    // This setup will change when bug 135040 is fixed. Make sure we don't
+    // create area accessible here. Hopefully assertion below will handle that.
+
+#ifdef DEBUG
+  nsImageFrame* imageFrame = do_QueryFrame(weakFrame.GetFrame());
+  NS_ASSERTION(imageFrame && content->IsHTML() && content->Tag() == nsGkAtoms::area,
+               "Unknown case of not main content for the frame!");
+#endif
+    return nsnull;
   }
 
+#ifdef DEBUG
+  nsImageFrame* imageFrame = do_QueryFrame(weakFrame.GetFrame());
+  NS_ASSERTION(!imageFrame || !content->IsHTML() || content->Tag() != nsGkAtoms::area,
+               "Image map manages the area accessible creation!");
+#endif
+
   nsDocAccessible* docAcc =
     GetAccService()->GetDocAccessible(aNode->GetOwnerDoc());
   if (!docAcc) {
     NS_NOTREACHED("Node has no host document accessible!");
     return nsnull;
   }
 
   // Attempt to create an accessible based on what we know.
@@ -987,29 +1004,28 @@ nsAccessibilityService::GetOrCreateAcces
     if (docAcc->BindToDocument(newAcc, nsnull)) {
       newAcc->AsTextLeaf()->SetText(text);
       return newAcc;
     }
 
     return nsnull;
   }
 
-  PRBool isHTML = content->IsHTML();
+  bool isHTML = content->IsHTML();
   if (isHTML && content->Tag() == nsGkAtoms::map) {
     // Create hyper text accessible for HTML map if it is used to group links
     // (see http://www.w3.org/TR/WCAG10-HTML-TECHS/#group-bypass). If the HTML
-    // map doesn't have 'name' attribute (or has empty name attribute) then we
-    // suppose it is used for links grouping. Otherwise we think it is used in
-    // conjuction with HTML image element and in this case we don't create any
-    // accessible for it and don't walk into it. The accessibles for HTML area
-    // (nsHTMLAreaAccessible) the map contains are attached as children of the
-    // appropriate accessible for HTML image (nsHTMLImageAccessible).
-    nsAutoString name;
-    content->GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
-    if (!name.IsEmpty()) {
+    // map rect is empty then it is used for links grouping. Otherwise it should
+    // be used in conjunction with HTML image element and in this case we don't
+    // create any accessible for it and don't walk into it. The accessibles for
+    // HTML area (nsHTMLAreaAccessible) the map contains are attached as
+    // children of the appropriate accessible for HTML image
+    // (nsHTMLImageAccessible).
+    if (nsLayoutUtils::GetAllInFlowRectsUnion(weakFrame,
+                                              weakFrame->GetParent()).IsEmpty()) {
       if (aIsSubtreeHidden)
         *aIsSubtreeHidden = true;
 
       return nsnull;
     }
 
     newAcc = new nsHyperTextAccessibleWrap(content, aWeakShell);
     if (docAcc->BindToDocument(newAcc, nsAccUtils::GetRoleMapEntry(aNode)))
@@ -1023,21 +1039,21 @@ nsAccessibilityService::GetOrCreateAcces
     // be ever lost and should be sensible).
     if (content->IsFocusable())
       roleMapEntry = nsnull;
     else
       return nsnull;
   }
 
   if (weakFrame.IsAlive() && !newAcc && isHTML) {  // HTML accessibles
-    PRBool tryTagNameOrFrame = PR_TRUE;
+    bool tryTagNameOrFrame = true;
 
     nsIAtom *frameType = weakFrame.GetFrame()->GetType();
 
-    PRBool partOfHTMLTable =
+    bool partOfHTMLTable =
       frameType == nsGkAtoms::tableCaptionFrame ||
       frameType == nsGkAtoms::tableCellFrame ||
       frameType == nsGkAtoms::tableRowGroupFrame ||
       frameType == nsGkAtoms::tableRowFrame;
 
     if (partOfHTMLTable) {
       // Table-related frames don't get table-related roles
       // unless they are inside a table, but they may still get generic
@@ -1201,17 +1217,17 @@ nsAccessibilityService::GetOrCreateAcces
   }
 
   return docAcc->BindToDocument(newAcc, roleMapEntry) ? newAcc : nsnull;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessibilityService private
 
-PRBool
+bool
 nsAccessibilityService::Init()
 {
   // Initialize accessible document manager.
   if (!nsAccDocManager::Init())
     return PR_FALSE;
 
   // Add observers.
   nsCOMPtr<nsIObserverService> observerService =
@@ -1247,17 +1263,17 @@ nsAccessibilityService::Shutdown()
 
   NS_ASSERTION(!gIsShutdown, "Accessibility was shutdown already");
 
   gIsShutdown = PR_TRUE;
 
   nsAccessNodeWrap::ShutdownAccessibility();
 }
 
-PRBool
+bool
 nsAccessibilityService::HasUniversalAriaProperty(nsIContent *aContent)
 {
   // ARIA attributes that take token values (NMTOKEN, bool) are special cased
   // because of special value "undefined" (see HasDefinedARIAToken).
   return nsAccUtils::HasDefinedARIAToken(aContent, nsGkAtoms::aria_atomic) ||
          nsAccUtils::HasDefinedARIAToken(aContent, nsGkAtoms::aria_busy) ||
          aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_controls) ||
          aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_describedby) ||
@@ -1270,60 +1286,16 @@ nsAccessibilityService::HasUniversalAria
          nsAccUtils::HasDefinedARIAToken(aContent, nsGkAtoms::aria_invalid) ||
          aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_label) ||
          aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_labelledby) ||
          nsAccUtils::HasDefinedARIAToken(aContent, nsGkAtoms::aria_live) ||
          nsAccUtils::HasDefinedARIAToken(aContent, nsGkAtoms::aria_owns) ||
          nsAccUtils::HasDefinedARIAToken(aContent, nsGkAtoms::aria_relevant);
 }
 
-nsAccessible*
-nsAccessibilityService::GetAreaAccessible(nsIFrame* aImageFrame,
-                                          nsINode* aAreaNode,
-                                          nsIWeakReference* aWeakShell,
-                                          nsAccessible** aImageAccessible)
-{
-  // Check if frame is an image frame, and content is <area>.
-  nsImageFrame *imageFrame = do_QueryFrame(aImageFrame);
-  if (!imageFrame)
-    return nsnull;
-
-  nsCOMPtr<nsIDOMHTMLAreaElement> areaElmt = do_QueryInterface(aAreaNode);
-  if (!areaElmt)
-    return nsnull;
-
-  // Try to get image map accessible from the global cache or create it
-  // if failed.
-  nsRefPtr<nsAccessible> image =
-    GetAccessibleInWeakShell(aImageFrame->GetContent(), aWeakShell);
-  if (!image) {
-    image = CreateHTMLImageAccessible(aImageFrame->GetContent(),
-                                      aImageFrame->PresContext()->PresShell());
-
-    nsDocAccessible* document =
-      GetAccService()->GetDocAccessible(aAreaNode->GetOwnerDoc());
-    if (!document) {
-      NS_NOTREACHED("No document for accessible being created!");
-      return nsnull;
-    }
-
-    if (!document->BindToDocument(image, nsnull))
-      return nsnull;
-  }
-
-  if (aImageAccessible)
-    *aImageAccessible = image;
-
-  // Make sure <area> accessible children of the image map are cached so
-  // that they should be available in global cache.
-  image->EnsureChildren();
-
-  return GetAccessibleInWeakShell(aAreaNode, aWeakShell);
-}
-
 already_AddRefed<nsAccessible>
 nsAccessibilityService::CreateAccessibleByType(nsIContent* aContent,
                                                nsIWeakReference* aWeakShell)
 {
   nsCOMPtr<nsIAccessibleProvider> accessibleProvider(do_QueryInterface(aContent));
   if (!accessibleProvider)
     return nsnull;
 
@@ -1847,8 +1819,18 @@ nsAccessibilityService::CreateAccessible
   }
 
   // Table or tree table accessible.
   nsAccessible* accessible = new nsXULTreeGridAccessibleWrap(aContent, aWeakShell);
   NS_IF_ADDREF(accessible);
   return accessible;
 }
 #endif
+
+////////////////////////////////////////////////////////////////////////////////
+// Services
+////////////////////////////////////////////////////////////////////////////////
+
+mozilla::a11y::FocusManager*
+mozilla::a11y::FocusMgr()
+{
+  return nsAccessibilityService::gAccessibilityService;
+}
--- a/accessible/src/base/nsAccessibilityService.h
+++ b/accessible/src/base/nsAccessibilityService.h
@@ -39,34 +39,48 @@
 #ifndef __nsAccessibilityService_h__
 #define __nsAccessibilityService_h__
 
 #include "nsIAccessibilityService.h"
 
 #include "a11yGeneric.h"
 #include "nsAccDocManager.h"
 
+#include "mozilla/a11y/FocusManager.h"
+
 #include "nsIObserver.h"
 
+namespace mozilla {
+namespace a11y {
+
+/**
+ * Return focus manager.
+ */
+FocusManager* FocusMgr();
+
+} // namespace a11y
+} // namespace mozilla
+
 class nsAccessibilityService : public nsAccDocManager,
+                               public mozilla::a11y::FocusManager,
                                public nsIAccessibilityService,
                                public nsIObserver
 {
 public:
   virtual ~nsAccessibilityService();
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIACCESSIBLERETRIEVAL
   NS_DECL_NSIOBSERVER
 
   // nsIAccessibilityService
   virtual nsAccessible* GetAccessibleInShell(nsINode* aNode,
                                              nsIPresShell* aPresShell);
   virtual nsAccessible* GetRootDocumentAccessible(nsIPresShell* aPresShell,
-                                                  PRBool aCanCreate);
+                                                  bool aCanCreate);
 
   virtual already_AddRefed<nsAccessible>
     CreateHTMLBRAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
   virtual already_AddRefed<nsAccessible>
     CreateHTML4ButtonAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
   virtual already_AddRefed<nsAccessible>
     CreateHTMLButtonAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
   virtual already_AddRefed<nsAccessible>
@@ -141,17 +155,17 @@ public:
 
   virtual void FireAccessibleEvent(PRUint32 aEvent, nsAccessible* aTarget);
 
   // nsAccessibiltiyService
 
   /**
    * Return true if accessibility service has been shutdown.
    */
-  static PRBool IsShutdown() { return gIsShutdown; }
+  static bool IsShutdown() { return gIsShutdown; }
 
   /**
    * Return an accessible for the given DOM node from the cache or create new
    * one.
    *
    * @param  aNode             [in] the given node
    * @param  aPresShell        [in] the pres shell of the node
    * @param  aWeakShell        [in] the weak shell for the pres shell
@@ -203,36 +217,24 @@ private:
   nsAccessibilityService();
   nsAccessibilityService(const nsAccessibilityService&);
   nsAccessibilityService& operator =(const nsAccessibilityService&);
 
 private:
   /**
    * Initialize accessibility service.
    */
-  PRBool Init();
+  bool Init();
 
   /**
    * Shutdowns accessibility service.
    */
   void Shutdown();
 
   /**
-   * Return accessible for HTML area element associated with an image map.
-   *
-   * @param  aImageFrame       [in] image frame
-   * @param  aAreaNode         [in] area node
-   * @param  aWeakShell        [in] presshell of image frame
-   * @param  aImageAccessible  [out, optional] image accessible, isn't addrefed
-   */
-  nsAccessible* GetAreaAccessible(nsIFrame* aImageFrame, nsINode* aAreaNode,
-                                  nsIWeakReference* aWeakShell,
-                                  nsAccessible** aImageAccessible = nsnull);
-
-  /**
    * Create accessible for the element implementing nsIAccessibleProvider
    * interface.
    */
   already_AddRefed<nsAccessible>
     CreateAccessibleByType(nsIContent* aContent, nsIWeakReference* aWeakShell);
 
   /**
    * Create accessible for HTML node by tag name.
@@ -252,35 +254,36 @@ private:
   /**
    * Create accessible for XUL tree element.
    */
   already_AddRefed<nsAccessible>
     CreateAccessibleForXULTree(nsIContent* aContent, nsIWeakReference* aWeakShell);
 #endif
 
   /**
-   * Reference for accessibility service.
+   * Reference for accessibility service instance.
    */
-  static nsAccessibilityService *gAccessibilityService;
+  static nsAccessibilityService* gAccessibilityService;
 
   /**
    * Indicates whether accessibility service was shutdown.
    */
-  static PRBool gIsShutdown;
+  static bool gIsShutdown;
 
   /**
    * Does this content node have a universal ARIA property set on it?
    * A universal ARIA property is one that can be defined on any element even if there is no role.
    *
    * @param aContent The content node to test
    * @return PR_TRUE if there is a universal ARIA property set on the node
    */
-  PRBool HasUniversalAriaProperty(nsIContent *aContent);
+  bool HasUniversalAriaProperty(nsIContent *aContent);
 
   friend nsAccessibilityService* GetAccService();
+  friend mozilla::a11y::FocusManager* mozilla::a11y::FocusMgr();
 
   friend nsresult NS_GetAccessibilityService(nsIAccessibilityService** aResult);
 };
 
 /**
  * Return the accessibility service instance. (Handy global function)
  */
 inline nsAccessibilityService*
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -302,17 +302,17 @@ nsAccessible::Description(nsString& aDes
   if (mContent->IsNodeOfType(nsINode::eTEXT))
     return;
 
   nsTextEquivUtils::
     GetTextEquivFromIDRefs(this, nsGkAtoms::aria_describedby,
                            aDescription);
 
   if (aDescription.IsEmpty()) {
-    PRBool isXUL = mContent->IsXUL();
+    bool isXUL = mContent->IsXUL();
     if (isXUL) {
       // Try XUL <description control="[id]">description text</description>
       XULDescriptionIterator iter(GetDocAccessible(), mContent);
       nsAccessible* descr = nsnull;
       while ((descr = iter.Next()))
         nsTextEquivUtils::AppendTextEquivFromContent(this, descr->GetContent(),
                                                      &aDescription);
       }
@@ -351,17 +351,17 @@ nsAccessible::AccessKey() const
   PRUint32 key = nsCoreUtils::GetAccessKeyFor(mContent);
   if (!key && mContent->IsElement()) {
     nsAccessible* label = nsnull;
 
     // Copy access key from label node.
     if (mContent->IsHTML()) {
       // Unless it is labeled via an ancestor <label>, in which case that would
       // be redundant.
-      HTMLLabelIterator iter(GetDocAccessible(), mContent,
+      HTMLLabelIterator iter(GetDocAccessible(), this,
                              HTMLLabelIterator::eSkipAncestorLabel);
       label = iter.Next();
 
     } else if (mContent->IsXUL()) {
       XULLabelIterator iter(GetDocAccessible(), mContent);
       label = iter.Next();
     }
 
@@ -544,17 +544,17 @@ nsAccessible::GetChildren(nsIArray **aOu
     nsIAccessible* child = GetChildAt(childIdx);
     children->AppendElement(child, PR_FALSE);
   }
 
   NS_ADDREF(*aOutChildren = children);
   return NS_OK;
 }
 
-PRBool
+bool
 nsAccessible::GetAllowsAnonChildAccessibles()
 {
   return PR_TRUE;
 }
 
 /* readonly attribute long childCount; */
 NS_IMETHODIMP
 nsAccessible::GetChildCount(PRInt32 *aChildCount) 
@@ -585,18 +585,18 @@ nsresult nsAccessible::GetTranslatedStri
   if (!gStringBundle || 
     NS_FAILED(gStringBundle->GetStringFromName(PromiseFlatString(aKey).get(), getter_Copies(xsValue)))) 
     return NS_ERROR_FAILURE;
 
   aStringOut.Assign(xsValue);
   return NS_OK;
 }
 
-PRBool
-nsAccessible::IsVisible(PRBool* aIsOffscreen)
+bool
+nsAccessible::IsVisible(bool* aIsOffscreen)
 {
   // We need to know if at least a kMinPixels around the object is visible,
   // otherwise it will be marked states::OFFSCREEN. The states::INVISIBLE flag
   // is for elements which are programmatically hidden.
 
   *aIsOffscreen = PR_TRUE;
   if (IsDefunct())
     return PR_FALSE;
@@ -622,17 +622,17 @@ nsAccessible::IsVisible(PRBool* aIsOffsc
   // and the STATE_OFFSCREEN flag that this is used for only needs to be a rough
   // indicator
   nsSize frameSize = frame->GetSize();
   nsRectVisibility rectVisibility =
     shell->GetRectVisibility(frame, nsRect(nsPoint(0,0), frameSize),
                              nsPresContext::CSSPixelsToAppUnits(kMinPixels));
 
   if (frame->GetRect().IsEmpty()) {
-    PRBool isEmpty = PR_TRUE;
+    bool isEmpty = true;
 
     nsIAtom *frameType = frame->GetType();
     if (frameType == nsGkAtoms::textFrame) {
       // Zero area rects can occur in the first frame of a multi-frame text flow,
       // in which case the rendered text is not empty and the frame should not be marked invisible
       nsAutoString renderedText;
       frame->GetRenderedText (&renderedText, nsnull, nsnull, 0, 1);
       isEmpty = renderedText.IsEmpty();
@@ -665,17 +665,17 @@ PRUint64
 nsAccessible::NativeState()
 {
   PRUint64 state = 0;
 
   nsDocAccessible* document = GetDocAccessible();
   if (!document || !document->IsInDocument(this))
     state |= states::STALE;
 
-  PRBool disabled = PR_FALSE;
+  bool disabled = false;
   if (mContent->IsElement()) {
     nsEventStates elementState = mContent->AsElement()->State();
 
     if (elementState.HasState(NS_EVENT_STATE_INVALID))
       state |= states::INVALID;
 
     if (elementState.HasState(NS_EVENT_STATE_REQUIRED))
       state |= states::REQUIRED;
@@ -688,29 +688,27 @@ nsAccessible::NativeState()
                              eCaseMatters));
   }
 
   // Set unavailable state based on disabled state, otherwise set focus states
   if (disabled) {
     state |= states::UNAVAILABLE;
   }
   else if (mContent->IsElement()) {
-    nsIFrame *frame = GetFrame();
-    if (frame && frame->IsFocusable()) {
+    nsIFrame* frame = GetFrame();
+    if (frame && frame->IsFocusable())
       state |= states::FOCUSABLE;
-    }
-
-    if (gLastFocusedNode == mContent) {
+
+    if (FocusMgr()->IsFocused(this))
       state |= states::FOCUSED;
-    }
   }
 
   // Check if states::INVISIBLE and
   // states::OFFSCREEN flags should be turned on for this object.
-  PRBool isOffscreen;
+  bool isOffscreen;
   if (!IsVisible(&isOffscreen)) {
     state |= states::INVISIBLE;
   }
   if (isOffscreen) {
     state |= states::OFFSCREEN;
   }
 
   nsIFrame *frame = GetFrame();
@@ -741,26 +739,21 @@ nsAccessible::GetFocusedChild(nsIAccessi
 
   NS_IF_ADDREF(*aChild = FocusedChild());
   return NS_OK;
 }
 
 nsAccessible*
 nsAccessible::FocusedChild()
 {
-  if (!gLastFocusedNode)
-    return nsnull;
-  if (gLastFocusedNode == mContent)
-    return this;
-
-  nsAccessible* focusedChild = GetDocAccessible()->GetAccessible(gLastFocusedNode);
-  if (!focusedChild || focusedChild->Parent() != this)
-    return nsnull;
-
-  return focusedChild;
+  nsAccessible* focus = FocusMgr()->FocusedAccessible();
+  if (focus && (focus == this || focus->Parent() == this))
+    return focus;
+
+  return nsnull;
 }
 
 // nsAccessible::ChildAtPoint()
 nsAccessible*
 nsAccessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
                            EWhichChildAtPoint aWhichChild)
 {
   // If we can't find the point in a child, we will return the fallback answer:
@@ -1021,17 +1014,17 @@ nsAccessible::GetBounds(PRInt32* aX, PRI
 // helpers
 
 nsIFrame* nsAccessible::GetBoundsFrame()
 {
   return GetFrame();
 }
 
 /* void removeSelection (); */
-NS_IMETHODIMP nsAccessible::SetSelected(PRBool aSelect)
+NS_IMETHODIMP nsAccessible::SetSelected(bool aSelect)
 {
   // Add or remove selection
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   if (State() & states::SELECTABLE) {
     nsCOMPtr<nsIAccessible> multiSelect =
       nsAccUtils::GetMultiSelectableContainer(mContent);
@@ -1122,17 +1115,17 @@ nsAccessible::TakeFocus()
 }
 
 nsresult
 nsAccessible::GetHTMLName(nsAString& aLabel)
 {
   nsAutoString label;
 
   nsAccessible* labelAcc = nsnull;
-  HTMLLabelIterator iter(GetDocAccessible(), mContent);
+  HTMLLabelIterator iter(GetDocAccessible(), this);
   while ((labelAcc = iter.Next())) {
     nsresult rv = nsTextEquivUtils::
       AppendTextEquivFromContent(this, labelAcc->GetContent(), &label);
     NS_ENSURE_SUCCESS(rv, rv);
 
     label.CompressWhitespace();
   }
 
@@ -1237,17 +1230,17 @@ nsAccessible::HandleAccEvent(AccEvent* a
   NS_ENSURE_TRUE(obsService, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsISimpleEnumerator> observers;
   obsService->EnumerateObservers(NS_ACCESSIBLE_EVENT_TOPIC,
                                  getter_AddRefs(observers));
 
   NS_ENSURE_STATE(observers);
 
-  PRBool hasObservers = PR_FALSE;
+  bool hasObservers = false;
   observers->HasMoreElements(&hasObservers);
   if (hasObservers) {
     nsRefPtr<nsAccEvent> evnt(aEvent->CreateXPCOMObject());
     return obsService->NotifyObservers(evnt, NS_ACCESSIBLE_EVENT_TOPIC, nsnull);
   }
 
   return NS_OK;
 }
@@ -1428,17 +1421,17 @@ nsAccessible::GetAttributesInternal(nsIP
   rv = GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("text-indent"),
                              value);
   if (NS_SUCCEEDED(rv))
     nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textIndent, value);
 
   // Expose draggable object attribute?
   nsCOMPtr<nsIDOMNSHTMLElement> htmlElement = do_QueryInterface(mContent);
   if (htmlElement) {
-    PRBool draggable = PR_FALSE;
+    bool draggable = false;
     htmlElement->GetDraggable(&draggable);
     if (draggable) {
       nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::draggable,
                              NS_LITERAL_STRING("true"));
     }
   }
 
   return NS_OK;
@@ -1526,17 +1519,17 @@ nsAccessible::State()
     if (state & states::FOCUSED) {
       state |= states::SELECTED;
     } else {
       // If focus is in a child of the tab panel surely the tab is selected!
       Relation rel = RelationByType(nsIAccessibleRelation::RELATION_LABEL_FOR);
       nsAccessible* relTarget = nsnull;
       while ((relTarget = rel.Next())) {
         if (relTarget->Role() == nsIAccessibleRole::ROLE_PROPERTYPAGE &&
-            nsCoreUtils::IsAncestorOf(relTarget->GetNode(), gLastFocusedNode))
+            FocusMgr()->IsFocusWithin(relTarget))
           state |= states::SELECTED;
       }
     }
   }
 
   const PRUint32 kExpandCollapseStates = states::COLLAPSED | states::EXPANDED;
   if ((state & kExpandCollapseStates) == kExpandCollapseStates) {
     // Cannot be both expanded and collapsed -- this happens in ARIA expanded
@@ -2010,17 +2003,17 @@ nsAccessible::RelationByType(PRUint32 aT
                                           nsGkAtoms::control));
 
       return rel;
     }
     case nsIAccessibleRelation::RELATION_LABELLED_BY: {
       Relation rel(new IDRefsIterator(mContent,
                                       nsGkAtoms::aria_labelledby));
       if (mContent->IsHTML()) {
-        rel.AppendIter(new HTMLLabelIterator(GetDocAccessible(), mContent));
+        rel.AppendIter(new HTMLLabelIterator(GetDocAccessible(), this));
       } else if (mContent->IsXUL()) {
         rel.AppendIter(new XULLabelIterator(GetDocAccessible(), mContent));
       }
 
       return rel;
     }
     case nsIAccessibleRelation::RELATION_DESCRIBED_BY: {
       Relation rel(new IDRefsIterator(mContent,
@@ -2221,17 +2214,17 @@ nsAccessible::DispatchClickEvent(nsICont
   nsCOMPtr<nsIPresShell> presShell = GetPresShell();
 
   // Scroll into view.
   presShell->ScrollContentIntoView(aContent, NS_PRESSHELL_SCROLL_ANYWHERE,
                                    NS_PRESSHELL_SCROLL_ANYWHERE,
                                    nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
 
   // Fire mouse down and mouse up events.
-  PRBool res = nsCoreUtils::DispatchMouseEvent(NS_MOUSE_BUTTON_DOWN, presShell,
+  bool res = nsCoreUtils::DispatchMouseEvent(NS_MOUSE_BUTTON_DOWN, presShell,
                                                aContent);
   if (!res)
     return;
 
   nsCoreUtils::DispatchMouseEvent(NS_MOUSE_BUTTON_UP, presShell, aContent);
 }
 
 // nsIAccessibleSelectable
@@ -2301,17 +2294,17 @@ NS_IMETHODIMP nsAccessible::RemoveChildF
 {
   if (IsDefunct() || !IsSelect())
     return NS_ERROR_FAILURE;
 
   return aIndex >=0 && RemoveItemFromSelection(aIndex) ?
     NS_OK : NS_ERROR_INVALID_ARG;
 }
 
-NS_IMETHODIMP nsAccessible::IsChildSelected(PRInt32 aIndex, PRBool *aIsSelected)
+NS_IMETHODIMP nsAccessible::IsChildSelected(PRInt32 aIndex, bool *aIsSelected)
 {
   NS_ENSURE_ARG_POINTER(aIsSelected);
   *aIsSelected = PR_FALSE;
 
   if (IsDefunct() || !IsSelect())
     return NS_ERROR_FAILURE;
 
   NS_ENSURE_TRUE(aIndex >= 0, NS_ERROR_FAILURE);
@@ -2326,17 +2319,17 @@ nsAccessible::ClearSelection()
   if (IsDefunct() || !IsSelect())
     return NS_ERROR_FAILURE;
 
   UnselectAll();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAccessible::SelectAllSelection(PRBool* aIsMultiSelect)
+nsAccessible::SelectAllSelection(bool* aIsMultiSelect)
 {
   NS_ENSURE_ARG_POINTER(aIsMultiSelect);
   *aIsMultiSelect = PR_FALSE;
 
   if (IsDefunct() || !IsSelect())
     return NS_ERROR_FAILURE;
 
   *aIsMultiSelect = SelectAll();
@@ -2419,31 +2412,31 @@ nsAccessible::GetAnchor(PRInt32 aIndex, 
     return NS_ERROR_INVALID_ARG;
 
   NS_IF_ADDREF(*aAccessible = AnchorAt(aIndex));
   return NS_OK;
 }
 
 // readonly attribute boolean nsIAccessibleHyperLink::valid
 NS_IMETHODIMP
-nsAccessible::GetValid(PRBool *aValid)
+nsAccessible::GetValid(bool *aValid)
 {
   NS_ENSURE_ARG_POINTER(aValid);
   *aValid = PR_FALSE;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   *aValid = IsLinkValid();
   return NS_OK;
 }
 
 // readonly attribute boolean nsIAccessibleHyperLink::selected
 NS_IMETHODIMP
-nsAccessible::GetSelected(PRBool *aSelected)
+nsAccessible::GetSelected(bool *aSelected)
 {
   NS_ENSURE_ARG_POINTER(aSelected);
   *aSelected = PR_FALSE;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   *aSelected = IsLinkSelected();
@@ -2567,33 +2560,33 @@ nsAccessible::InvalidateChildren()
     child->UnbindFromParent();
   }
 
   mEmbeddedObjCollector = nsnull;
   mChildren.Clear();
   SetChildrenFlag(eChildrenUninitialized);
 }
 
-PRBool
+bool
 nsAccessible::AppendChild(nsAccessible* aChild)
 {
   if (!aChild)
     return PR_FALSE;
 
   if (!mChildren.AppendElement(aChild))
     return PR_FALSE;
 
   if (!nsAccUtils::IsEmbeddedObject(aChild))
     SetChildrenFlag(eMixedChildren);
 
   aChild->BindToParent(this, mChildren.Length() - 1);
   return PR_TRUE;
 }
 
-PRBool
+bool
 nsAccessible::InsertChildAt(PRUint32 aIndex, nsAccessible* aChild)
 {
   if (!aChild)
     return PR_FALSE;
 
   if (!mChildren.InsertElementAt(aIndex, aChild))
     return PR_FALSE;
 
@@ -2606,17 +2599,17 @@ nsAccessible::InsertChildAt(PRUint32 aIn
     SetChildrenFlag(eMixedChildren);
 
   mEmbeddedObjCollector = nsnull;
 
   aChild->BindToParent(this, aIndex);
   return PR_TRUE;
 }
 
-PRBool
+bool
 nsAccessible::RemoveChild(nsAccessible* aChild)
 {
   if (!aChild)
     return PR_FALSE;
 
   if (aChild->mParent != this || aChild->mIndexInParent == -1)
     return PR_FALSE;
 
@@ -2735,16 +2728,24 @@ PRUint32
 nsAccessible::EndOffset()
 {
   NS_PRECONDITION(IsLink(), "EndOffset is called on not hyper link!");
 
   nsHyperTextAccessible* hyperText = mParent ? mParent->AsHyperText() : nsnull;
   return hyperText ? (hyperText->GetChildOffset(this) + 1) : 0;
 }
 
+bool
+nsAccessible::IsLinkSelected()
+{
+  NS_PRECONDITION(IsLink(),
+                  "IsLinkSelected() called on something that is not a hyper link!");
+  return FocusMgr()->IsFocused(this);
+}
+
 PRUint32
 nsAccessible::AnchorCount()
 {
   NS_PRECONDITION(IsLink(), "AnchorCount is called on not hyper link!");
   return 1;
 }
 
 nsAccessible*
@@ -2905,16 +2906,77 @@ nsAccessible::UnselectAll()
   AccIterator iter(this, filters::GetSelected, AccIterator::eTreeNav);
   while ((selected = iter.Next())) {
     success = true;
     selected->SetSelected(PR_FALSE);
   }
   return success;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// Widgets
+
+bool
+nsAccessible::IsWidget() const
+{
+  return false;
+}
+
+bool
+nsAccessible::IsActiveWidget() const
+{
+  return FocusMgr()->IsFocused(this);
+}
+
+bool
+nsAccessible::AreItemsOperable() const
+{
+  return mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_activedescendant);
+}
+
+nsAccessible*
+nsAccessible::CurrentItem()
+{
+  // Check for aria-activedescendant, which changes which element has focus.
+  // For activedescendant, the ARIA spec does not require that the user agent
+  // checks whether pointed node is actually a DOM descendant of the element
+  // with the aria-activedescendant attribute.
+  nsAutoString id;
+  if (mContent->GetAttr(kNameSpaceID_None,
+                        nsGkAtoms::aria_activedescendant, id)) {
+    nsIDocument* DOMDoc = mContent->GetOwnerDoc();
+    dom::Element* activeDescendantElm = DOMDoc->GetElementById(id);
+    if (activeDescendantElm) {
+      nsDocAccessible* document = GetDocAccessible();
+      if (document)
+        return document->GetAccessible(activeDescendantElm);
+    }
+  }
+  return nsnull;
+}
+
+nsAccessible*
+nsAccessible::ContainerWidget() const
+{
+  nsIAtom* idAttribute = mContent->GetIDAttributeName();
+  if (idAttribute) {
+    if (mContent->HasAttr(kNameSpaceID_None, idAttribute)) {
+      nsAccessible* parent = Parent();
+      do {
+        nsIContent* parentContent = parent->GetContent();
+        if (parentContent &&
+            parentContent->HasAttr(kNameSpaceID_None,
+                                   nsGkAtoms::aria_activedescendant)) {
+          return parent;
+        }
+      } while ((parent = parent->Parent()));
+    }
+  }
+  return nsnull;
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessible protected methods
 
 void
 nsAccessible::CacheChildren()
 {
   nsAccTreeWalker walker(mWeakShell, mContent, GetAllowsAnonChildAccessibles());
@@ -3060,17 +3122,17 @@ nsAccessible::GetActionRule(PRUint64 aSt
     return eJumpAction;
 
   // Return "click" action on elements that have an attached popup menu.
   if (mContent->IsXUL())
     if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::popup))
       return eClickAction;
 
   // Has registered 'click' event handler.
-  PRBool isOnclick = nsCoreUtils::HasClickListener(mContent);
+  bool isOnclick = nsCoreUtils::HasClickListener(mContent);
 
   if (isOnclick)
     return eClickAction;
   
   // Get an action based on ARIA role.
   if (mRoleMapEntry &&
       mRoleMapEntry->actionRule != eNoAction)
     return mRoleMapEntry->actionRule;
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -275,19 +275,19 @@ public:
    * transformed. Note, if accessible cares about its parent relation chain
    * itself should override this method to do nothing.
    */
   virtual void InvalidateChildren();
 
   /**
    * Append/insert/remove a child. Return true if operation was successful.
    */
-  virtual PRBool AppendChild(nsAccessible* aChild);
-  virtual PRBool InsertChildAt(PRUint32 aIndex, nsAccessible* aChild);
-  virtual PRBool RemoveChild(nsAccessible* aChild);
+  virtual bool AppendChild(nsAccessible* aChild);
+  virtual bool InsertChildAt(PRUint32 aIndex, nsAccessible* aChild);
+  virtual bool RemoveChild(nsAccessible* aChild);
 
   //////////////////////////////////////////////////////////////////////////////
   // Accessible tree traverse methods
 
   /**
    * Return parent accessible.
    */
   nsAccessible* Parent() const { return mParent; }
@@ -310,17 +310,17 @@ public:
   /**
    * Return index in parent accessible.
    */
   virtual PRInt32 IndexInParent() const;
 
   /**
    * Return true if accessible has children;
    */
-  PRBool HasChildren() { return !!GetChildAt(0); }
+  bool HasChildren() { return !!GetChildAt(0); }
 
   /**
    * Return first/last/next/previous sibling of the accessible.
    */
   inline nsAccessible* NextSibling() const
     {  return GetSiblingAtOffset(1); }
   inline nsAccessible* PrevSibling() const
     { return GetSiblingAtOffset(-1); }
@@ -375,17 +375,17 @@ public:
    * Handle accessible event, i.e. process it, notifies observers and fires
    * platform specific event.
    */
   virtual nsresult HandleAccEvent(AccEvent* aAccEvent);
 
   /**
    * Return true if there are accessible children in anonymous content
    */
-  virtual PRBool GetAllowsAnonChildAccessibles();
+  virtual bool GetAllowsAnonChildAccessibles();
 
   /**
    * Returns text of accessible if accessible has text role otherwise empty
    * string.
    *
    * @param aText         [in] returned text of the accessible
    * @param aStartOffset  [in, optional] start offset inside of the accessible,
    *                        if missed entire text is appended
@@ -397,29 +397,41 @@ public:
 
   /**
    * Assert if child not in parent's cache if the cache was initialized at this
    * point.
    */
   void TestChildCache(nsAccessible* aCachedChild) const;
 
   //////////////////////////////////////////////////////////////////////////////
-  // Downcasting
+  // Downcasting and types
 
   inline bool IsApplication() const { return mFlags & eApplicationAccessible; }
 
+  bool IsAutoComplete() const { return mFlags & eAutoCompleteAccessible; }
+
+  inline bool IsAutoCompletePopup() const { return mFlags & eAutoCompletePopupAccessible; }
+
+  inline bool IsCombobox() const { return mFlags & eComboboxAccessible; }
+
   inline bool IsDoc() const { return mFlags & eDocAccessible; }
   nsDocAccessible* AsDoc();
 
   inline bool IsHyperText() const { return mFlags & eHyperTextAccessible; }
   nsHyperTextAccessible* AsHyperText();
 
   inline bool IsHTMLListItem() const { return mFlags & eHTMLListItemAccessible; }
   nsHTMLLIAccessible* AsHTMLListItem();
 
+  inline bool IsListControl() const { return mFlags & eListControlAccessible; }
+
+  inline bool IsMenuButton() const { return mFlags & eMenuButtonAccessible; }
+
+  inline bool IsMenuPopup() const { return mFlags & eMenuPopupAccessible; }
+
   inline bool IsRoot() const { return mFlags & eRootAccessible; }
   nsRootAccessible* AsRoot();
 
   inline bool IsTextLeaf() const { return mFlags & eTextLeafAccessible; }
   nsTextAccessible* AsTextLeaf();
 
   //////////////////////////////////////////////////////////////////////////////
   // ActionAccessible
@@ -470,22 +482,17 @@ public:
     // In the mean time authors can use role="link" aria-invalid="true"
     // to force it for links they internally know to be invalid
     return (0 == (State() & mozilla::a11y::states::INVALID));
   }
 
   /**
    * Return true if the link currently has the focus.
    */
-  inline bool IsLinkSelected()
-  {
-    NS_PRECONDITION(IsLink(),
-                    "IsLinkSelected() called on something that is not a hyper link!");
-    return gLastFocusedNode == GetNode();
-  }
+  bool IsLinkSelected();
 
   /**
    * Return the number of anchors within the link.
    */
   virtual PRUint32 AnchorCount();
 
   /**
    * Returns an anchor accessible at the given index.
@@ -541,16 +548,48 @@ public:
    */
   virtual bool SelectAll();
 
   /**
    * Unselect all items. Return true if success.
    */
   virtual bool UnselectAll();
 
+  //////////////////////////////////////////////////////////////////////////////
+  // Widgets
+
+  /**
+   * Return true if accessible is a widget, i.e. control or accessible that
+   * manages its items. Note, being a widget the accessible may be a part of
+   * composite widget.
+   */
+  virtual bool IsWidget() const;
+
+  /**
+   * Return true if the widget is active, i.e. has a focus within it.
+   */
+  virtual bool IsActiveWidget() const;
+
+  /**
+   * Return true if the widget has items and items are operable by user and
+   * can be activated.
+   */
+  virtual bool AreItemsOperable() const;
+
+  /**
+   * Return the current item of the widget, i.e. an item that has or will have
+   * keyboard focus when widget gets active.
+   */
+  virtual nsAccessible* CurrentItem();
+
+  /**
+   * Return container widget this accessible belongs to.
+   */
+  virtual nsAccessible* ContainerWidget() const;
+
 protected:
 
   //////////////////////////////////////////////////////////////////////////////
   // Initializing, cache and tree traverse methods
 
   /**
    * Cache accessible children.
    */
@@ -590,34 +629,40 @@ protected:
     { mFlags = (mFlags & ~kChildrenFlagsMask) | aFlag; }
 
   /**
    * Flags describing the accessible itself.
    * @note keep these flags in sync with ChildrenFlags
    */
   enum AccessibleTypes {
     eApplicationAccessible = 1 << 2,
-    eDocAccessible = 1 << 3,
-    eHyperTextAccessible = 1 << 4,
-    eHTMLListItemAccessible = 1 << 5,
-    eRootAccessible = 1 << 6,
-    eTextLeafAccessible = 1 << 7
+    eAutoCompleteAccessible = 1 << 3,
+    eAutoCompletePopupAccessible = 1 << 4,
+    eComboboxAccessible = 1 << 5,
+    eDocAccessible = 1 << 6,
+    eHyperTextAccessible = 1 << 7,
+    eHTMLListItemAccessible = 1 << 8,
+    eListControlAccessible = 1 << 9,
+    eMenuButtonAccessible = 1 << 10,
+    eMenuPopupAccessible = 1 << 11,
+    eRootAccessible = 1 << 12,
+    eTextLeafAccessible = 1 << 13
   };
 
   //////////////////////////////////////////////////////////////////////////////
   // Miscellaneous helpers
 
   /**
    * Return ARIA role (helper method).
    */
   PRUint32 ARIARoleInternal();
 
   virtual nsIFrame* GetBoundsFrame();
   virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
-  PRBool IsVisible(PRBool *aIsOffscreen); 
+  bool IsVisible(bool *aIsOffscreen); 
 
   //////////////////////////////////////////////////////////////////////////////
   // Name helpers
 
   /**
    * Compute the name of HTML node.
    */
   nsresult GetHTMLName(nsAString& aName);
--- a/accessible/src/base/nsApplicationAccessible.cpp
+++ b/accessible/src/base/nsApplicationAccessible.cpp
@@ -169,22 +169,20 @@ nsApplicationAccessible::ChildAtPoint(PR
                                       EWhichChildAtPoint aWhichChild)
 {
   return nsnull;
 }
 
 nsAccessible*
 nsApplicationAccessible::FocusedChild()
 {
-  if (gLastFocusedNode) {
-    nsAccessible* focusedChild =
-      GetAccService()->GetAccessible(gLastFocusedNode);
-    if (focusedChild && focusedChild->Parent() == this)
-      return focusedChild;
-  }
+  nsAccessible* focus = FocusMgr()->FocusedAccessible();
+  if (focus && focus->Parent() == this)
+    return focus;
+
   return nsnull;
 }
 
 Relation
 nsApplicationAccessible::RelationByType(PRUint32 aRelationType)
 {
   return Relation();
 }
@@ -200,17 +198,17 @@ nsApplicationAccessible::GetBounds(PRInt
   NS_ENSURE_ARG_POINTER(aWidth);
   *aWidth = 0;
   NS_ENSURE_ARG_POINTER(aHeight);
   *aHeight = 0;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsApplicationAccessible::SetSelected(PRBool aIsSelected)
+nsApplicationAccessible::SetSelected(bool aIsSelected)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsApplicationAccessible::TakeSelection()
 {
   return NS_OK;
@@ -311,17 +309,17 @@ nsApplicationAccessible::GetPlatformVers
 // nsAccessNode public methods
 
 bool
 nsApplicationAccessible::IsDefunct() const
 {
   return nsAccessibilityService::IsShutdown();
 }
 
-PRBool
+bool
 nsApplicationAccessible::Init()
 {
   mAppInfo = do_GetService("@mozilla.org/xre/app-info;1");
   return PR_TRUE;
 }
 
 void
 nsApplicationAccessible::Shutdown()
@@ -388,17 +386,17 @@ nsApplicationAccessible::CacheChildren()
     do_GetService(NS_WINDOWMEDIATOR_CONTRACTID);
 
   nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
   nsresult rv = windowMediator->GetEnumerator(nsnull,
                                               getter_AddRefs(windowEnumerator));
   if (NS_FAILED(rv))
     return;
 
-  PRBool hasMore = PR_FALSE;
+  bool hasMore = false;
   windowEnumerator->HasMoreElements(&hasMore);
   while (hasMore) {
     nsCOMPtr<nsISupports> window;
     windowEnumerator->GetNext(getter_AddRefs(window));
     nsCOMPtr<nsIDOMWindow> DOMWindow = do_QueryInterface(window);
     if (DOMWindow) {
       nsCOMPtr<nsIDOMDocument> DOMDocument;
       DOMWindow->GetDocument(getter_AddRefs(DOMDocument));
--- a/accessible/src/base/nsApplicationAccessible.h
+++ b/accessible/src/base/nsApplicationAccessible.h
@@ -90,29 +90,29 @@ public:
   NS_IMETHOD GetPreviousSibling(nsIAccessible **aPreviousSibling);
   NS_IMETHOD GetName(nsAString &aName);
   NS_IMETHOD GetValue(nsAString &aValue);
   NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
   NS_IMETHOD GroupPosition(PRInt32 *aGroupLevel, PRInt32 *aSimilarItemsInGroup,
                            PRInt32 *aPositionInGroup);
   NS_IMETHOD GetBounds(PRInt32 *aX, PRInt32 *aY,
                        PRInt32 *aWidth, PRInt32 *aHeight);
-  NS_IMETHOD SetSelected(PRBool aIsSelected);
+  NS_IMETHOD SetSelected(bool aIsSelected);
   NS_IMETHOD TakeSelection();
   NS_IMETHOD TakeFocus();
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString &aName);
   NS_IMETHOD GetActionDescription(PRUint8 aIndex, nsAString &aDescription);
   NS_IMETHOD DoAction(PRUint8 aIndex);
 
   // nsIAccessibleApplication
   NS_DECL_NSIACCESSIBLEAPPLICATION
 
   // nsAccessNode
   virtual bool IsDefunct() const;
-  virtual PRBool Init();
+  virtual bool Init();
   virtual void Shutdown();
   virtual bool IsPrimaryForNode() const;
 
   // nsAccessible
   virtual void ApplyARIAState(PRUint64* aState);
   virtual void Description(nsString& aDescription);
   virtual PRUint32 NativeRole();
   virtual PRUint64 State();
--- a/accessible/src/base/nsBaseWidgetAccessible.h
+++ b/accessible/src/base/nsBaseWidgetAccessible.h
@@ -108,18 +108,18 @@ public:
 protected:
   // nsAccessible
   virtual void BindToParent(nsAccessible* aParent, PRUint32 aIndexInParent);
 
   /**
    * Parent accessible that provides an action for this linkable accessible.
    */
   nsAccessible* mActionAcc;
-  PRPackedBool mIsLink;
-  PRPackedBool mIsOnclick;
+  bool mIsLink;
+  bool mIsOnclick;
 };
 
 /**
  * A simple accessible that gets its enumerated role passed into constructor.
  */ 
 class nsEnumRoleAccessible : public nsAccessibleWrap
 {
 public:
--- a/accessible/src/base/nsCaretAccessible.cpp
+++ b/accessible/src/base/nsCaretAccessible.cpp
@@ -334,17 +334,17 @@ nsCaretAccessible::GetCaretRect(nsIWidge
   NS_ENSURE_TRUE(presShell, caretRect);
 
   nsRefPtr<nsCaret> caret = presShell->GetCaret();
   NS_ENSURE_TRUE(caret, caretRect);
 
   nsCOMPtr<nsISelection> caretSelection(do_QueryReferent(mLastUsedSelection));
   NS_ENSURE_TRUE(caretSelection, caretRect);
   
-  PRBool isVisible;
+  bool isVisible;
   caret->GetCaretVisible(&isVisible);
   if (!isVisible) {
     return nsIntRect();  // Return empty rect
   }
 
   nsRect rect;
   nsIFrame* frame = caret->GetGeometry(caretSelection, &rect);
   if (!frame || rect.IsEmpty()) {
--- a/accessible/src/base/nsCoreUtils.cpp
+++ b/accessible/src/base/nsCoreUtils.cpp
@@ -69,17 +69,17 @@
 #include "mozilla/dom/Element.h"
 
 static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID);
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsCoreUtils
 ////////////////////////////////////////////////////////////////////////////////
 
-PRBool
+bool
 nsCoreUtils::HasClickListener(nsIContent *aContent)
 {
   NS_ENSURE_TRUE(aContent, PR_FALSE);
   nsEventListenerManager* listenerManager =
     aContent->GetListenerManager(PR_FALSE);
 
   return listenerManager &&
     (listenerManager->HasListenersFor(NS_LITERAL_STRING("click")) ||
@@ -145,17 +145,17 @@ nsCoreUtils::DispatchClickEvent(nsITreeB
 
   DispatchMouseEvent(NS_MOUSE_BUTTON_DOWN, cnvdX, cnvdY,
                      tcContent, tcFrame, presShell, rootWidget);
 
   DispatchMouseEvent(NS_MOUSE_BUTTON_UP, cnvdX, cnvdY,
                      tcContent, tcFrame, presShell, rootWidget);
 }
 
-PRBool
+bool
 nsCoreUtils::DispatchMouseEvent(PRUint32 aEventType,
                                 nsIPresShell *aPresShell,
                                 nsIContent *aContent)
 {
   nsIFrame *frame = aContent->GetPrimaryFrame();
   if (!frame)
     return PR_FALSE;
 
@@ -275,17 +275,17 @@ nsCoreUtils::GetRoleContent(nsINode *aNo
         content = do_QueryInterface(docElement);
       }
     }
   }
 
   return content;
 }
 
-PRBool
+bool
 nsCoreUtils::IsAncestorOf(nsINode *aPossibleAncestorNode,
                           nsINode *aPossibleDescendantNode,
                           nsINode *aRootNode)
 {
   NS_ENSURE_TRUE(aPossibleAncestorNode && aPossibleDescendantNode, PR_FALSE);
 
   nsINode *parentNode = aPossibleDescendantNode;
   while ((parentNode = parentNode->GetNodeParent()) &&
@@ -446,31 +446,31 @@ nsCoreUtils::GetDocShellTreeItemFor(nsIN
   nsCOMPtr<nsISupports> container = doc->GetContainer();
   nsIDocShellTreeItem *docShellTreeItem = nsnull;
   if (container)
     CallQueryInterface(container, &docShellTreeItem);
 
   return docShellTreeItem;
 }
 
-PRBool
+bool
 nsCoreUtils::IsRootDocument(nsIDocument *aDocument)
 {
   nsCOMPtr<nsISupports> container = aDocument->GetContainer();
   nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
     do_QueryInterface(container);
   NS_ASSERTION(docShellTreeItem, "No document shell for document!");
 
   nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
   docShellTreeItem->GetParent(getter_AddRefs(parentTreeItem));
 
   return !parentTreeItem;
 }
 
-PRBool
+bool
 nsCoreUtils::IsContentDocument(nsIDocument *aDocument)
 {
   nsCOMPtr<nsISupports> container = aDocument->GetContainer();
   nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
     do_QueryInterface(container);
   NS_ASSERTION(docShellTreeItem, "No document shell tree item for document!");
 
   PRInt32 contentType;
@@ -493,35 +493,35 @@ nsCoreUtils::IsTabDocument(nsIDocument* 
 
   // Parent of docshell for tab document running in chrome process is root.
   nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
   treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
 
   return parentTreeItem == rootTreeItem;
 }
 
-PRBool
+bool
 nsCoreUtils::IsErrorPage(nsIDocument *aDocument)
 {
   nsIURI *uri = aDocument->GetDocumentURI();
-  PRBool isAboutScheme = PR_FALSE;
+  bool isAboutScheme = false;
   uri->SchemeIs("about", &isAboutScheme);
   if (!isAboutScheme)
     return PR_FALSE;
 
   nsCAutoString path;
   uri->GetPath(path);
 
   NS_NAMED_LITERAL_CSTRING(neterror, "neterror");
   NS_NAMED_LITERAL_CSTRING(certerror, "certerror");
 
   return StringBeginsWith(path, neterror) || StringBeginsWith(path, certerror);
 }
 
-PRBool
+bool
 nsCoreUtils::IsCorrectFrameType(nsIFrame *aFrame, nsIAtom *aAtom)
 {
   NS_ASSERTION(aFrame != nsnull,
                "aFrame is null in call to IsCorrectFrameType!");
   NS_ASSERTION(aAtom != nsnull,
                "aAtom is null in call to IsCorrectFrameType!");
   
   return aFrame->GetType() == aAtom;
@@ -542,41 +542,41 @@ nsCoreUtils::GetDOMNodeForContainer(nsID
   if (!doc)
     return nsnull;
 
   nsIDOMNode* node = nsnull;
   CallQueryInterface(doc, &node);
   return node;
 }
 
-PRBool
+bool
 nsCoreUtils::GetID(nsIContent *aContent, nsAString& aID)
 {
   nsIAtom *idAttribute = aContent->GetIDAttributeName();
   return idAttribute ? aContent->GetAttr(kNameSpaceID_None, idAttribute, aID) : PR_FALSE;
 }
 
-PRBool
+bool
 nsCoreUtils::GetUIntAttr(nsIContent *aContent, nsIAtom *aAttr, PRInt32 *aUInt)
 {
   nsAutoString value;
   aContent->GetAttr(kNameSpaceID_None, aAttr, value);
   if (!value.IsEmpty()) {
     PRInt32 error = NS_OK;
     PRInt32 integer = value.ToInteger(&error);
     if (NS_SUCCEEDED(error) && integer > 0) {
       *aUInt = integer;
       return PR_TRUE;
     }
   }
 
   return PR_FALSE;
 }
 
-PRBool
+bool
 nsCoreUtils::IsXLink(nsIContent *aContent)
 {
   if (!aContent)
     return PR_FALSE;
 
   return aContent->AttrValueIs(kNameSpaceID_XLink, nsGkAtoms::type,
                                nsGkAtoms::simple, eCaseMatters) &&
     aContent->HasAttr(kNameSpaceID_XLink, nsGkAtoms::href);
@@ -754,17 +754,17 @@ nsCoreUtils::GetPreviousSensibleColumn(n
     nsCOMPtr<nsITreeColumn> tempColumn;
     prevColumn->GetPrevious(getter_AddRefs(tempColumn));
     prevColumn.swap(tempColumn);
   }
 
   return prevColumn.forget();
 }
 
-PRBool
+bool
 nsCoreUtils::IsColumnHidden(nsITreeColumn *aColumn)
 {
   nsCOMPtr<nsIDOMElement> element;
   aColumn->GetElement(getter_AddRefs(element));
   nsCOMPtr<nsIContent> content = do_QueryInterface(element);
   return content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::hidden,
                               nsGkAtoms::_true, eCaseMatters);
 }
@@ -815,15 +815,15 @@ NS_IMETHODIMP
 nsAccessibleDOMStringList::GetLength(PRUint32 *aLength)
 {
   *aLength = mNames.Length();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAccessibleDOMStringList::Contains(const nsAString& aString, PRBool *aResult)
+nsAccessibleDOMStringList::Contains(const nsAString& aString, bool *aResult)
 {
   *aResult = mNames.Contains(aString);
 
   return NS_OK;
 }
 
--- a/accessible/src/base/nsCoreUtils.h
+++ b/accessible/src/base/nsCoreUtils.h
@@ -59,17 +59,17 @@
  */
 class nsCoreUtils
 {
 public:
   /**
    * Return true if the given node has registered click, mousedown or mouseup
    * event listeners.
    */
-  static PRBool HasClickListener(nsIContent *aContent);
+  static bool HasClickListener(nsIContent *aContent);
 
   /**
    * Dispatch click event to XUL tree cell.
    *
    * @param  aTreeBoxObj  [in] tree box object
    * @param  aRowIndex    [in] row index
    * @param  aColumn      [in] column object
    * @param  aPseudoElm   [in] pseudo elemenet inside the cell, see
@@ -81,17 +81,17 @@ public:
 
   /**
    * Send mouse event to the given element.
    *
    * @param  aEventType  [in] an event type (see nsGUIEvent.h for constants)
    * @param  aPresShell  [in] the presshell for the given element
    * @param  aContent    [in] the element
    */
-  static PRBool DispatchMouseEvent(PRUint32 aEventType,
+  static bool DispatchMouseEvent(PRUint32 aEventType,
                                    nsIPresShell *aPresShell,
                                    nsIContent *aContent);
 
   /**
    * Send mouse event to the given element.
    *
    * @param aEventType   [in] an event type (see nsGUIEvent.h for constants)
    * @param aX           [in] x coordinate in dev pixels
@@ -148,17 +148,17 @@ public:
    *                                   aPossibleDescendantNode
    * @param  aPossibleDescendantNode [in] node to test for descendant-ness of
    *                                   aPossibleAncestorNode
    * @param  aRootNode               [in, optional] the root node that search
    *                                   search should be performed within
    * @return PR_TRUE                  if aPossibleAncestorNode is an ancestor of
    *                                   aPossibleDescendantNode
    */
-   static PRBool IsAncestorOf(nsINode *aPossibleAncestorNode,
+   static bool IsAncestorOf(nsINode *aPossibleAncestorNode,
                               nsINode *aPossibleDescendantNode,
                               nsINode *aRootNode = nsnull);
 
   /**
    * Helper method to scroll range into view, used for implementation of
    * nsIAccessibleText::scrollSubstringTo().
    *
    * @param aFrame        the frame for accessible the range belongs to.
@@ -219,40 +219,40 @@ public:
    * Return document shell tree item for the given DOM node.
    */
   static already_AddRefed<nsIDocShellTreeItem>
     GetDocShellTreeItemFor(nsINode *aNode);
 
   /**
    * Return true if the given document is root document.
    */
-  static PRBool IsRootDocument(nsIDocument *aDocument);
+  static bool IsRootDocument(nsIDocument *aDocument);
 
   /**
    * Return true if the given document is content document (not chrome).
    */
-  static PRBool IsContentDocument(nsIDocument *aDocument);
+  static bool IsContentDocument(nsIDocument *aDocument);
 
   /**
    * Return true if the given document node is for tab document accessible.
    */
   static bool IsTabDocument(nsIDocument* aDocumentNode);
 
   /**
    * Return true if the given document is an error page.
    */
-  static PRBool IsErrorPage(nsIDocument *aDocument);
+  static bool IsErrorPage(nsIDocument *aDocument);
 
   /**
    * Retrun true if the type of given frame equals to the given frame type.
    *
    * @param aFrame  the frame
    * @param aAtom   the frame type
    */
-  static PRBool IsCorrectFrameType(nsIFrame* aFrame, nsIAtom* aAtom);
+  static bool IsCorrectFrameType(nsIFrame* aFrame, nsIAtom* aAtom);
 
   /**
    * Return presShell for the document containing the given DOM node.
    */
   static nsIPresShell *GetPresShellFor(nsINode *aNode)
   {
     nsIDocument *document = aNode->GetOwnerDoc();
     return document ? document->GetShell() : nsnull;
@@ -271,32 +271,32 @@ public:
     GetDOMNodeForContainer(nsIDocShellTreeItem *aContainer);
 
   /**
    * Get the ID for an element, in some types of XML this may not be the ID attribute
    * @param aContent  Node to get the ID for
    * @param aID       Where to put ID string
    * @return          PR_TRUE if there is an ID set for this node
    */
-  static PRBool GetID(nsIContent *aContent, nsAString& aID);
+  static bool GetID(nsIContent *aContent, nsAString& aID);
 
   /**
    * Convert attribute value of the given node to positive integer. If no
    * attribute or wrong value then false is returned.
    */
-  static PRBool GetUIntAttr(nsIContent *aContent, nsIAtom *aAttr,
+  static bool GetUIntAttr(nsIContent *aContent, nsIAtom *aAttr,
                             PRInt32 *aUInt);
 
   /**
    * Check if the given element is XLink.
    *
    * @param aContent  the given element
    * @return          PR_TRUE if the given element is XLink
    */
-  static PRBool IsXLink(nsIContent *aContent);
+  static bool IsXLink(nsIContent *aContent);
 
   /**
    * Returns language for the given node.
    *
    * @param aContent     [in] the given node
    * @param aRootContent [in] container of the given node
    * @param aLanguage    [out] language
    */
@@ -355,22 +355,22 @@ public:
    * Return previous sensible column for the given column.
    */
   static already_AddRefed<nsITreeColumn>
     GetPreviousSensibleColumn(nsITreeColumn *aColumn);
 
   /**
    * Return true if the given column is hidden (i.e. not sensible).
    */
-  static PRBool IsColumnHidden(nsITreeColumn *aColumn);
+  static bool IsColumnHidden(nsITreeColumn *aColumn);
 
   /**
    * Return true if the given node is table header element.
    */
-  static PRBool IsHTMLTableHeader(nsIContent *aContent)
+  static bool IsHTMLTableHeader(nsIContent *aContent)
   {
     return aContent->NodeInfo()->Equals(nsGkAtoms::th) ||
       aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::scope);
   }
 
   /**
    * Check the visibility across both parent content and chrome.
    */
@@ -386,17 +386,17 @@ class nsAccessibleDOMStringList : public
 {
 public:
   nsAccessibleDOMStringList() {};
   virtual ~nsAccessibleDOMStringList() {};
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMDOMSTRINGLIST
 
-  PRBool Add(const nsAString& aName) {
+  bool Add(const nsAString& aName) {
     return mNames.AppendElement(aName) != nsnull;
   }
 
 private:
   nsTArray<nsString> mNames;
 };
 
 #endif
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -290,28 +290,20 @@ nsDocAccessible::Description(nsString& a
 PRUint64
 nsDocAccessible::NativeState()
 {
   // The root content of the document might be removed so that mContent is
   // out of date.
   PRUint64 state = (mContent->GetCurrentDoc() == mDocument) ?
     0 : states::STALE;
 
-#ifdef MOZ_XUL
-  nsCOMPtr<nsIXULDocument> xulDoc(do_QueryInterface(mDocument));
-  if (!xulDoc)
-#endif
-  {
-    // XXX Need to invent better check to see if doc is focusable,
-    // which it should be if it is scrollable. A XUL document could be focusable.
-    // See bug 376803.
-    state |= states::FOCUSABLE;
-    if (gLastFocusedNode == mDocument)
-      state |= states::FOCUSED;
-  }
+  // Document is always focusable.
+  state |= states::FOCUSABLE;
+  if (FocusMgr()->IsFocused(this))
+    state |= states::FOCUSED;
 
   // Expose stale state until the document is ready (DOM is loaded and tree is
   // constructed).
   if (!HasLoadState(eReady))
     state |= states::STALE;
 
   // Expose state busy until the document and all its subdocuments is completely
   // loaded.
@@ -352,34 +344,26 @@ nsDocAccessible::GetAttributes(nsIPersis
     mParent->GetAttributes(aAttributes); // Add parent attributes (override inner)
   }
   return NS_OK;
 }
 
 nsAccessible*
 nsDocAccessible::FocusedChild()
 {
-  // XXXndeakin P3 accessibility shouldn't be caching the focus
-
   // Return an accessible for the current global focus, which does not have to
   // be contained within the current document.
-  return gLastFocusedNode ? GetAccService()->GetAccessible(gLastFocusedNode) :
-    nsnull;
+  return FocusMgr()->FocusedAccessible();
 }
 
 NS_IMETHODIMP nsDocAccessible::TakeFocus()
 {
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  PRUint64 state = NativeState();
-  if (0 == (state & states::FOCUSABLE)) {
-    return NS_ERROR_FAILURE; // Not focusable
-  }
-
   // Focus the document.
   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
   NS_ENSURE_STATE(fm);
 
   nsCOMPtr<nsIDOMElement> newFocus;
   return fm->MoveFocus(mDocument->GetWindow(), nsnull,
                        nsIFocusManager::MOVEFOCUS_ROOT, 0,
                        getter_AddRefs(newFocus));
@@ -550,17 +534,17 @@ NS_IMETHODIMP nsDocAccessible::GetAssoci
   if (!editingSession)
     return NS_OK; // No editing session interface
 
   nsCOMPtr<nsIEditor> editor;
   editingSession->GetEditorForWindow(mDocument->GetWindow(), getter_AddRefs(editor));
   if (!editor) {
     return NS_OK;
   }
-  PRBool isEditable;
+  bool isEditable;
   editor->GetIsDocumentEditable(&isEditable);
   if (isEditable) {
     NS_ADDREF(*aEditor = editor);
   }
   return NS_OK;
 }
 
 // nsDocAccessible public method
@@ -589,17 +573,17 @@ nsDocAccessible::GetAccessible(nsINode* 
 #endif
 
   return accessible;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessNode
 
-PRBool
+bool
 nsDocAccessible::Init()
 {
   NS_LOG_ACCDOCCREATE_FOR("document initialize", mDocument, this)
 
   // Initialize notification controller.
   nsCOMPtr<nsIPresShell> shell(GetPresShell());
   mNotificationController = new NotificationController(this, shell);
   if (!mNotificationController)
@@ -734,17 +718,17 @@ nsresult nsDocAccessible::AddEventListen
   nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem(do_QueryInterface(container));
   NS_ENSURE_TRUE(docShellTreeItem, NS_ERROR_FAILURE);
 
   // Make sure we're a content docshell
   // We don't want to listen to chrome progress
   PRInt32 itemType;
   docShellTreeItem->GetItemType(&itemType);
 
-  PRBool isContent = (itemType == nsIDocShellTreeItem::typeContent);
+  bool isContent = (itemType == nsIDocShellTreeItem::typeContent);
 
   if (isContent) {
     // We're not an editor yet, but we might become one
     nsCOMPtr<nsICommandManager> commandManager = do_GetInterface(docShellTreeItem);
     if (commandManager) {
       commandManager->AddCommandObserver(this, "obs_documentCreated");
     }
   }
@@ -1045,34 +1029,30 @@ nsDocAccessible::AttributeChangedImpl(ns
       aAttribute == nsGkAtoms::aria_label ||
       aAttribute == nsGkAtoms::aria_labelledby) {
     FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE,
                                aContent);
     return;
   }
 
   if (aAttribute == nsGkAtoms::aria_busy) {
-    PRBool isOn = aContent->AttrValueIs(aNameSpaceID, aAttribute,
+    bool isOn = aContent->AttrValueIs(aNameSpaceID, aAttribute,
                                         nsGkAtoms::_true, eCaseMatters);
     nsRefPtr<AccEvent> event = new AccStateChangeEvent(aContent, states::BUSY, isOn);
     FireDelayedAccessibleEvent(event);
     return;
   }
 
   if (aAttribute == nsGkAtoms::selected ||
       aAttribute == nsGkAtoms::aria_selected) {
     // ARIA or XUL selection
 
     nsAccessible *multiSelect =
       nsAccUtils::GetMultiSelectableContainer(aContent);
-    // Multi selects use selection_add and selection_remove
-    // Single select widgets just mirror event_selection for
-    // whatever gets event_focus, which is done in
-    // nsRootAccessible::FireAccessibleFocusEvent()
-    // So right here we make sure only to deal with multi selects
+    // XXX: Multi selects are handled here only (bug 414302).
     if (multiSelect) {
       // Need to find the right event to use here, SELECTION_WITHIN would
       // seem right but we had started using it for something else
       FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_SELECTION_WITHIN,
                                  multiSelect->GetNode(),
                                  AccEvent::eAllowDupes);
 
       static nsIContent::AttrValuesArray strings[] =
@@ -1113,27 +1093,23 @@ nsDocAccessible::ARIAAttributeChanged(ns
 
   if (aAttribute == nsGkAtoms::aria_invalid) {
     nsRefPtr<AccEvent> event =
       new AccStateChangeEvent(aContent, states::INVALID);
     FireDelayedAccessibleEvent(event);
     return;
   }
 
+  // The activedescendant universal property redirects accessible focus events
+  // to the element with the id that activedescendant points to. Make sure
+  // the tree up to date before processing.
   if (aAttribute == nsGkAtoms::aria_activedescendant) {
-    // The activedescendant universal property redirects accessible focus events
-    // to the element with the id that activedescendant points to
-    nsCOMPtr<nsINode> focusedNode = GetCurrentFocus();
-    if (nsCoreUtils::GetRoleContent(focusedNode) == aContent) {
-      nsAccessible* focusedAcc = GetAccService()->GetAccessible(focusedNode);
-      nsRootAccessible* rootAcc = RootAccessible();
-      if (rootAcc && focusedAcc) {
-        rootAcc->FireAccessibleFocusEvent(focusedAcc, nsnull, PR_TRUE);
-      }
-    }
+    mNotificationController->HandleNotification<nsDocAccessible, nsIContent>
+      (this, &nsDocAccessible::ARIAActiveDescendantChanged, aContent);
+
     return;
   }
 
   // For aria drag and drop changes we fire a generic attribute change event;
   // at least until native API comes up with a more meaningful event.
   if (aAttribute == nsGkAtoms::aria_grabbed ||
       aAttribute == nsGkAtoms::aria_dropeffect ||
       aAttribute == nsGkAtoms::aria_hidden ||
@@ -1195,16 +1171,36 @@ nsDocAccessible::ARIAAttributeChanged(ns
         aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::aria_valuetext,
                               nsGkAtoms::_empty, eCaseMatters)))) {
     FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE,
                                aContent);
     return;
   }
 }
 
+void
+nsDocAccessible::ARIAActiveDescendantChanged(nsIContent* aElm)
+{
+  if (FocusMgr()->HasDOMFocus(aElm)) {
+    nsAutoString id;
+    if (aElm->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_activedescendant, id)) {
+      nsIDocument* DOMDoc = aElm->GetOwnerDoc();
+      dom::Element* activeDescendantElm = DOMDoc->GetElementById(id);
+      if (activeDescendantElm) {
+        nsAccessible* activeDescendant = GetAccessible(activeDescendantElm);
+        if (activeDescendant) {
+          FocusMgr()->ActiveItemChanged(activeDescendant, false);
+          A11YDEBUG_FOCUS_ACTIVEITEMCHANGE_CAUSE("ARIA activedescedant changed",
+                                                 activeDescendant)
+        }
+      }
+    }
+  }
+}
+
 void nsDocAccessible::ContentAppended(nsIDocument *aDocument,
                                       nsIContent* aContainer,
                                       nsIContent* aFirstNewContent,
                                       PRInt32 /* unused */)
 {
 }
 
 void nsDocAccessible::ContentStateChanged(nsIDocument* aDocument,
@@ -1357,16 +1353,23 @@ nsDocAccessible::BindToDocument(nsAccess
 }
 
 void
 nsDocAccessible::UnbindFromDocument(nsAccessible* aAccessible)
 {
   NS_ASSERTION(mAccessibleCache.GetWeak(aAccessible->UniqueID()),
                "Unbinding the unbound accessible!");
 
+  // Fire focus event on accessible having DOM focus if active item was removed
+  // from the tree.
+  if (FocusMgr()->IsActiveItem(aAccessible)) {
+    FocusMgr()->ActiveItemChanged(nsnull);
+    A11YDEBUG_FOCUS_ACTIVEITEMCHANGE_CAUSE("tree shutdown", aAccessible)
+  }
+
   // Remove an accessible from node-to-accessible map if it exists there.
   if (aAccessible->IsPrimaryForNode() &&
       mNodeToAccessibleMap.Get(aAccessible->GetNode()) == aAccessible)
     mNodeToAccessibleMap.Remove(aAccessible->GetNode());
 
   void* uniqueID = aAccessible->UniqueID();
 
   NS_ASSERTION(!aAccessible->IsDefunct(), "Shutdown the shutdown accessible!");
@@ -1727,34 +1730,26 @@ nsDocAccessible::FireDelayedAccessibleEv
 void
 nsDocAccessible::ProcessPendingEvent(AccEvent* aEvent)
 {
   nsAccessible* accessible = aEvent->GetAccessible();
   if (!accessible)
     return;
 
   PRUint32 eventType = aEvent->GetEventType();
-
   if (eventType == nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED) {
     nsCOMPtr<nsIAccessibleText> accessibleText = do_QueryObject(accessible);
     PRInt32 caretOffset;
     if (accessibleText &&
         NS_SUCCEEDED(accessibleText->GetCaretOffset(&caretOffset))) {
 #ifdef DEBUG_A11Y
       PRUnichar chAtOffset;
       accessibleText->GetCharacterAtOffset(caretOffset, &chAtOffset);
       printf("\nCaret moved to %d with char %c", caretOffset, chAtOffset);
 #endif
-#ifdef DEBUG_CARET
-      // Test caret line # -- fire an EVENT_ALERT on the focused node so we can watch the
-      // line-number object attribute on it
-      nsAccessible* focusedAcc =
-        GetAccService()->GetAccessible(gLastFocusedNode);
-      nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_ALERT, focusedAcc);
-#endif
       nsRefPtr<AccEvent> caretMoveEvent =
           new AccCaretMoveEvent(accessible, caretOffset);
       if (!caretMoveEvent)
         return;
 
       nsEventShell::FireEvent(caretMoveEvent);
 
       PRInt32 selectionCount;
@@ -1943,20 +1938,21 @@ nsDocAccessible::UpdateTreeInternal(nsAc
       FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_ALERT, node,
                                  AccEvent::eRemoveDupes);
     }
 
     // If focused node has been shown then it means its frame was recreated
     // while it's focused. Fire focus event on new focused accessible. If
     // the queue contains focus event for this node then it's suppressed by
     // this one.
-    if (node == gLastFocusedNode) {
-      FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_FOCUS,
-                                 node, AccEvent::eCoalesceFromSameDocument);
-    }
+    // XXX: do we really want to send focus to focused DOM node not taking into
+    // account active item?
+    if (FocusMgr()->IsFocused(aChild))
+      FocusMgr()->DispatchFocusEvent(this, aChild);
+
   } else {
     // Update the tree for content removal.
     // The accessible parent may differ from container accessible if
     // the parent doesn't have own DOM node like list accessible for HTML
     // selects.
     nsAccessible* parent = aChild->Parent();
     NS_ASSERTION(parent, "No accessible parent?!");
     if (parent)
--- a/accessible/src/base/nsDocAccessible.h
+++ b/accessible/src/base/nsDocAccessible.h
@@ -99,17 +99,17 @@ public:
   // nsIScrollPositionListener
   virtual void ScrollPositionWillChange(nscoord aX, nscoord aY) {}
   virtual void ScrollPositionDidChange(nscoord aX, nscoord aY);
 
   // nsIDocumentObserver
   NS_DECL_NSIDOCUMENTOBSERVER
 
   // nsAccessNode
-  virtual PRBool Init();
+  virtual bool Init();
   virtual void Shutdown();
   virtual nsIFrame* GetFrame() const;
   virtual bool IsDefunct() const;
   virtual nsINode* GetNode() const { return mDocument; }
   virtual nsIDocument* GetDocumentNode() const { return mDocument; }
 
   // nsAccessible
   virtual void Description(nsString& aDescription);
@@ -127,17 +127,17 @@ public:
   // nsIAccessibleText
   NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
 
   // nsDocAccessible
 
   /**
    * Return true if associated DOM document was loaded and isn't unloading.
    */
-  PRBool IsContentLoaded() const
+  bool IsContentLoaded() const
   {
     // eDOMLoaded flag check is used for error pages as workaround to make this
     // method return correct result since error pages do not receive 'pageshow'
     // event and as consequence nsIDocument::IsShowing() returns false.
     return mDocument && mDocument->IsVisible() &&
       (mDocument->IsShowing() || HasLoadState(eDOMLoaded));
   }
 
@@ -300,17 +300,17 @@ public:
 
   /**
    * Return true if the given ID is referred by relation attribute.
    *
    * @note Different elements may share the same ID if they are hosted inside
    *       XBL bindings. Be careful the result of this method may be  senseless
    *       while it's called for XUL elements (where XBL is used widely).
    */
-  PRBool IsDependentID(const nsAString& aID) const
+  bool IsDependentID(const nsAString& aID) const
     { return mDependentIDsHash.Get(aID, nsnull); }
 
   /**
    * Initialize the newly created accessible and put it into document caches.
    *
    * @param  aAccessible    [in] created accessible
    * @param  aRoleMapEntry  [in] the role map entry role the ARIA role or nsnull
    *                          if none
@@ -452,16 +452,21 @@ protected:
      * Fires accessible events when ARIA attribute is changed.
      *
      * @param aContent - node that attribute is changed for
      * @param aAttribute - changed attribute
      */
     void ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute);
 
   /**
+   * Process ARIA active-descendant attribute change.
+   */
+  void ARIAActiveDescendantChanged(nsIContent* aElm);
+
+  /**
    * Process the event when the queue of pending events is untwisted. Fire
    * accessible events as result of the processing.
    */
   void ProcessPendingEvent(AccEvent* aEvent);
 
   /**
    * Process anchor jump notification and fire scrolling end event.
    */
--- a/accessible/src/base/nsEventShell.cpp
+++ b/accessible/src/base/nsEventShell.cpp
@@ -87,10 +87,10 @@ nsEventShell::GetEventAttributes(nsINode
   nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::eventFromInput,
                          sEventFromUserInput ? NS_LITERAL_STRING("true") :
                                                NS_LITERAL_STRING("false"));
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsEventShell: private
 
-PRBool nsEventShell::sEventFromUserInput = PR_FALSE;
+bool nsEventShell::sEventFromUserInput = false;
 nsCOMPtr<nsINode> nsEventShell::sEventTargetNode;
--- a/accessible/src/base/nsEventShell.h
+++ b/accessible/src/base/nsEventShell.h
@@ -71,12 +71,12 @@ public:
    * @param  aNode        [in] the DOM node
    * @param  aAttributes  [in, out] the attributes
    */
   static void GetEventAttributes(nsINode *aNode,
                                  nsIPersistentProperties *aAttributes);
 
 private:
   static nsCOMPtr<nsINode> sEventTargetNode;
-  static PRBool sEventFromUserInput;
+  static bool sEventFromUserInput;
 };
 
 #endif
--- a/accessible/src/base/nsFormControlAccessible.cpp
+++ b/accessible/src/base/nsFormControlAccessible.cpp
@@ -71,16 +71,26 @@ NS_IMPL_QUERY_INTERFACE_INHERITED1(Progr
 template<int Max>
 PRUint32
 ProgressMeterAccessible<Max>::NativeRole()
 {
   return nsIAccessibleRole::ROLE_PROGRESSBAR;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+// ProgressMeterAccessible<Max>: Widgets
+
+template<int Max>
+bool
+ProgressMeterAccessible<Max>::IsWidget() const
+{
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
 // nsIAccessibleValue
 
 template<int Max>
 NS_IMETHODIMP
 ProgressMeterAccessible<Max>::GetValue(nsAString& aValue)
 {
   nsresult rv = nsFormControlAccessible::GetValue(aValue);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -217,8 +227,16 @@ nsRadioButtonAccessible::DoAction(PRUint
 }
 
 PRUint32
 nsRadioButtonAccessible::NativeRole()
 {
   return nsIAccessibleRole::ROLE_RADIOBUTTON;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// nsRadioButtonAccessible: Widgets
+
+bool
+nsRadioButtonAccessible::IsWidget() const
+{
+  return true;
+}
--- a/accessible/src/base/nsFormControlAccessible.h
+++ b/accessible/src/base/nsFormControlAccessible.h
@@ -58,16 +58,19 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIACCESSIBLEVALUE
 
   // nsIAccessible
   NS_IMETHOD GetValue(nsAString &aValue);
 
   // nsAccessible
   virtual PRUint32 NativeRole();
+
+  // Widgets
+  virtual bool IsWidget() const;
 };
 
 /**
   * Generic class used for radio buttons.
   */
 class nsRadioButtonAccessible : public nsFormControlAccessible
 {
 
@@ -80,13 +83,16 @@ public:
 
   // nsAccessible
   virtual PRUint32 NativeRole();
 
   // ActionAccessible
   virtual PRUint8 ActionCount();
 
   enum { eAction_Click = 0 };
+
+  // Widgets
+  virtual bool IsWidget() const;
 };
 
 
 #endif
 
--- a/accessible/src/base/nsOuterDocAccessible.cpp
+++ b/accessible/src/base/nsOuterDocAccessible.cpp
@@ -64,22 +64,16 @@ NS_IMPL_ISUPPORTS_INHERITED0(nsOuterDocA
 // nsAccessible public (DON'T add methods here)
 
 PRUint32
 nsOuterDocAccessible::NativeRole()
 {
   return nsIAccessibleRole::ROLE_INTERNAL_FRAME;
 }
 
-PRUint64
-nsOuterDocAccessible::NativeState()
-{
-  return nsAccessible::NativeState() & ~states::FOCUSABLE;
-}
-
 nsAccessible*
 nsOuterDocAccessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
                                    EWhichChildAtPoint aWhichChild)
 {
   PRInt32 docX = 0, docY = 0, docWidth = 0, docHeight = 0;
   nsresult rv = GetBounds(&docX, &docY, &docWidth, &docHeight);
   NS_ENSURE_SUCCESS(rv, nsnull);
 
@@ -177,17 +171,17 @@ nsOuterDocAccessible::InvalidateChildren
   // notifies nsAccDocManager about this. If presshell is created for existing
   // DOM document (for example when DOM node of outerdoc accessible is shown)
   // then allow nsAccDocManager to handle this case since the document
   // accessible is created and appended as a child when it's requested.
 
   SetChildrenFlag(eChildrenUninitialized);
 }
 
-PRBool
+bool
 nsOuterDocAccessible::AppendChild(nsAccessible *aAccessible)
 {
   // We keep showing the old document for a bit after creating the new one,
   // and while building the new DOM and frame tree. That's done on purpose
   // to avoid weird flashes of default background color.
   // The old viewer will be destroyed after the new one is created.
   // For a11y, it should be safe to shut down the old document now.
   if (mChildren.Length())
@@ -198,30 +192,30 @@ nsOuterDocAccessible::AppendChild(nsAcce
 
   NS_LOG_ACCDOCCREATE("append document to outerdoc",
                       aAccessible->GetDocumentNode())
   NS_LOG_ACCDOCCREATE_ACCADDRESS("outerdoc", this)
 
   return PR_TRUE;
 }
 
-PRBool
+bool
 nsOuterDocAccessible::RemoveChild(nsAccessible *aAccessible)
 {
   nsAccessible *child = mChildren.SafeElementAt(0, nsnull);
   if (child != aAccessible) {
     NS_ERROR("Wrong child to remove!");
     return PR_FALSE;
   }
 
   NS_LOG_ACCDOCDESTROY_FOR("remove document from outerdoc",
                            child->GetDocumentNode(), child)
   NS_LOG_ACCDOCDESTROY_ACCADDRESS("outerdoc", this)
 
-  PRBool wasRemoved = nsAccessible::RemoveChild(child);
+  bool wasRemoved = nsAccessible::RemoveChild(child);
 
   NS_ASSERTION(!mChildren.Length(),
                "This child document of outerdoc accessible wasn't removed!");
 
   return wasRemoved;
 }
 
 
--- a/accessible/src/base/nsOuterDocAccessible.h
+++ b/accessible/src/base/nsOuterDocAccessible.h
@@ -62,24 +62,23 @@ public:
   NS_IMETHOD GetActionDescription(PRUint8 aIndex, nsAString& aDescription);
   NS_IMETHOD DoAction(PRUint8 aIndex);
 
   // nsAccessNode
   virtual void Shutdown();
 
   // nsAccessible
   virtual PRUint32 NativeRole();
-  virtual PRUint64 NativeState();
   virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
   virtual nsAccessible* ChildAtPoint(PRInt32 aX, PRInt32 aY,
                                      EWhichChildAtPoint aWhichChild);
 
   virtual void InvalidateChildren();
-  virtual PRBool AppendChild(nsAccessible *aAccessible);
-  virtual PRBool RemoveChild(nsAccessible *aAccessible);
+  virtual bool AppendChild(nsAccessible *aAccessible);
+  virtual bool RemoveChild(nsAccessible *aAccessible);
 
   // ActionAccessible
   virtual PRUint8 ActionCount();
 
 protected:
   // nsAccessible
   virtual void CacheChildren();
 };
--- a/accessible/src/base/nsRootAccessible.cpp
+++ b/accessible/src/base/nsRootAccessible.cpp
@@ -56,24 +56,21 @@
 #include "nsIDOMEventListener.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIDOMHTMLAnchorElement.h"
 #include "nsIDOMHTMLImageElement.h"
 #include "nsIDOMHTMLInputElement.h"
 #include "nsIDOMHTMLSelectElement.h"
 #include "nsIDOMDataContainerEvent.h"
 #include "nsIDOMNSEvent.h"
-#include "nsIDOMXULMenuListElement.h"
 #include "nsIDOMXULMultSelectCntrlEl.h"
-#include "nsIDOMXULSelectCntrlItemEl.h"
 #include "nsIDOMXULPopupElement.h"
 #include "nsIDocument.h"
 #include "nsEventListenerManager.h"
 #include "nsIFrame.h"
-#include "nsMenuFrame.h"
 #include "nsIHTMLDocument.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsISelectionPrivate.h"
 #include "nsIServiceManager.h"
 #include "nsPIDOMWindow.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsReadableUtils.h"
 #include "nsRootAccessible.h"
@@ -81,17 +78,17 @@
 #include "nsFocusManager.h"
 
 #ifdef MOZ_XUL
 #include "nsXULTreeAccessible.h"
 #include "nsIXULDocument.h"
 #include "nsIXULWindow.h"
 #endif
 
-using namespace mozilla;
+namespace dom = mozilla::dom;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsISupports
 
 // Expanded version of NS_IMPL_ISUPPORTS_INHERITED2 
 // so we can QI directly to concrete nsRootAccessible
 NS_IMPL_QUERY_HEAD(nsRootAccessible)
@@ -218,19 +215,16 @@ nsRootAccessible::NativeState()
 }
 
 const char* const docEvents[] = {
 #ifdef DEBUG_DRAGDROPSTART
   // Capture mouse over events and fire fake DRAGDROPSTART event to simplify
   // debugging a11y objects with event viewers
   "mouseover",
 #endif
-  // capture DOM focus and DOM blur events 
-  "focus",
-  "blur",
   // capture Form change events 
   "select",
   // capture ValueChange events (fired whenever value changes, immediately after, whether focus moves or not)
   "ValueChange",
   // capture AlertActive events (fired whenever alert pops up)
   "AlertActive",
   // add ourself as a TreeViewChanged listener (custom event fired in nsTreeBodyFrame.cpp)
   "TreeViewChanged",
@@ -241,16 +235,17 @@ const char* const docEvents[] = {
   // add ourself as a CheckboxStateChange listener (custom event fired in nsHTMLInputElement.cpp)
   "CheckboxStateChange",
   // add ourself as a RadioStateChange Listener ( custom event fired in in nsHTMLInputElement.cpp  & radio.xml)
   "RadioStateChange",
   "popupshown",
   "popuphiding",
   "DOMMenuInactive",
   "DOMMenuItemActive",
+  "DOMMenuItemInactive",
   "DOMMenuBarActive",
   "DOMMenuBarInactive"
 };
 
 nsresult nsRootAccessible::AddEventListeners()
 {
   // nsIDOMEventTarget interface allows to register event listeners to
   // receive untrusted events (synthetic events generated by untrusted code).
@@ -304,135 +299,16 @@ nsresult nsRootAccessible::RemoveEventLi
 
 nsCaretAccessible*
 nsRootAccessible::GetCaretAccessible()
 {
   return mCaretAccessible;
 }
 
 void
-nsRootAccessible::FireAccessibleFocusEvent(nsAccessible* aFocusAccessible,
-                                           nsIContent* aRealFocusContent,
-                                           PRBool aForceEvent,
-                                           EIsFromUserInput aIsFromUserInput)
-{
-  // Implementors: only fire delayed/async events from this method.
-
-  // Set selection listener for focused element.
-  if (mCaretAccessible && aRealFocusContent)
-    mCaretAccessible->SetControlSelectionListener(aRealFocusContent);
-
-  nsAccessible* focusAccessible = aFocusAccessible;
-
-  // Check for aria-activedescendant, which changes which element has focus.
-  // For activedescendant, the ARIA spec does not require that the user agent
-  // checks whether pointed node is actually a DOM descendant of the element
-  // with the aria-activedescendant attribute.
-  nsIContent* content = focusAccessible->GetContent();
-  if (content) {
-    nsAutoString id;
-    if (content->GetAttr(kNameSpaceID_None,
-                         nsGkAtoms::aria_activedescendant, id)) {
-      nsIDocument* DOMDoc = content->GetOwnerDoc();
-      nsIContent* activeDescendantContent = DOMDoc->GetElementById(id);
-
-      // If aria-activedescendant is set to nonexistant ID, then treat as focus
-      // on the activedescendant container (which has real DOM focus).
-      if (activeDescendantContent) {
-        nsAccessible* activeDescendant = 
-          GetAccService()->GetAccessible(activeDescendantContent);
-        if (activeDescendant) {
-          focusAccessible = activeDescendant;
-        }
-      }
-    }
-  }
-
-  // Fire focus only if it changes, but always fire focus events when
-  // aForceEvent == PR_TRUE
-  nsINode* focusNode = focusAccessible->GetNode();
-  if (gLastFocusedNode == focusNode && !aForceEvent)
-    return;
-
-  nsDocAccessible* focusDocument = focusAccessible->GetDocAccessible();
-  NS_ASSERTION(focusDocument, "No document while accessible is in document?!");
-
-  // Fire menu start/end events for ARIA menus.
-  if (focusAccessible->ARIARole() == nsIAccessibleRole::ROLE_MENUITEM) {
-    // The focus is inside a menu.
-    if (!mCurrentARIAMenubar) {
-      // Entering ARIA menu. Fire menu start event.
-      nsAccessible* menuBarAccessible =
-        nsAccUtils::GetAncestorWithRole(focusAccessible,
-                                        nsIAccessibleRole::ROLE_MENUBAR);
-      if (menuBarAccessible) {
-        mCurrentARIAMenubar = menuBarAccessible->GetNode();
-        if (mCurrentARIAMenubar) {
-          nsRefPtr<AccEvent> menuStartEvent =
-            new AccEvent(nsIAccessibleEvent::EVENT_MENU_START,
-                         menuBarAccessible, aIsFromUserInput,
-                         AccEvent::eAllowDupes);
-          if (menuStartEvent)
-            focusDocument->FireDelayedAccessibleEvent(menuStartEvent);
-        }
-      }
-    }
-  }
-  else if (mCurrentARIAMenubar) {
-    // Focus left a menu. Fire menu end event.
-    nsRefPtr<AccEvent> menuEndEvent =
-      new AccEvent(nsIAccessibleEvent::EVENT_MENU_END, mCurrentARIAMenubar,
-                   aIsFromUserInput, AccEvent::eAllowDupes);
-    if (menuEndEvent) {
-      focusDocument->FireDelayedAccessibleEvent(menuEndEvent);
-    }
-    mCurrentARIAMenubar = nsnull;
-  }
-
-  NS_IF_RELEASE(gLastFocusedNode);
-  gLastFocusedNode = focusNode;
-  NS_IF_ADDREF(gLastFocusedNode);
-
-  // Coalesce focus events from the same document, because DOM focus event might
-  // be fired for the document node and then for the focused DOM element.
-  nsRefPtr<AccEvent> focusEvent =
-    new AccEvent(nsIAccessibleEvent::EVENT_FOCUS, focusAccessible,
-                 aIsFromUserInput, AccEvent::eCoalesceFromSameDocument);
-  focusDocument->FireDelayedAccessibleEvent(focusEvent);
-}
-
-void
-nsRootAccessible::FireCurrentFocusEvent()
-{
-  if (IsDefunct())
-    return;
-
-  // Simulate a focus event so that we can reuse code that fires focus for
-  // container children like treeitems.
-  nsCOMPtr<nsINode> focusedNode = GetCurrentFocus();
-  if (!focusedNode) {
-    return; // No current focus
-  }
-
-  nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(mDocument);
-  if (domDoc) {
-    nsCOMPtr<nsIDOMEvent> event;
-    if (NS_SUCCEEDED(domDoc->CreateEvent(NS_LITERAL_STRING("Events"),
-                                         getter_AddRefs(event))) &&
-        NS_SUCCEEDED(event->InitEvent(NS_LITERAL_STRING("focus"), PR_TRUE, PR_TRUE))) {
-
-      nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
-      nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(focusedNode));
-      privateEvent->SetTarget(target);
-      HandleEvent(event);
-    }
-  }
-}
-
-void
 nsRootAccessible::DocumentActivated(nsDocAccessible* aDocument)
 {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIDOMEventListener
 
 NS_IMETHODIMP
@@ -492,40 +368,34 @@ nsRootAccessible::ProcessDOMEvent(nsIDOM
   nsAutoString eventType;
   aDOMEvent->GetType(eventType);
 
   nsCOMPtr<nsIWeakReference> weakShell =
     nsCoreUtils::GetWeakShellFor(origTargetNode);
   if (!weakShell)
     return;
 
-  nsAccessible* accessible =
-    GetAccService()->GetAccessibleOrContainer(origTargetNode, weakShell);
-
   if (eventType.EqualsLiteral("popuphiding")) {
-    HandlePopupHidingEvent(origTargetNode, accessible);
+    HandlePopupHidingEvent(origTargetNode);
     return;
   }
 
+  nsAccessible* accessible =
+    GetAccService()->GetAccessibleOrContainer(origTargetNode, weakShell);
   if (!accessible)
     return;
 
   nsDocAccessible* targetDocument = accessible->GetDocAccessible();
   NS_ASSERTION(targetDocument, "No document while accessible is in document?!");
 
   nsINode* targetNode = accessible->GetNode();
-  nsIContent* targetContent = targetNode->IsElement() ?
-    targetNode->AsElement() : nsnull;
-  nsIContent* origTargetContent = origTargetNode->IsElement() ?
-    origTargetNode->AsElement() : nsnull;
 
 #ifdef MOZ_XUL
-  PRBool isTree = targetContent ?
-    targetContent->NodeInfo()->Equals(nsGkAtoms::tree, kNameSpaceID_XUL) :
-    PR_FALSE;
+  bool isTree = targetNode->IsElement() &&
+    targetNode->AsElement()->NodeInfo()->Equals(nsGkAtoms::tree, kNameSpaceID_XUL);
 
   if (isTree) {
     nsRefPtr<nsXULTreeAccessible> treeAcc = do_QueryObject(accessible);
     NS_ASSERTION(treeAcc,
                  "Accessible for xul:tree isn't nsXULTreeAccessible.");
 
     if (treeAcc) {
       if (eventType.EqualsLiteral("TreeViewChanged")) {
@@ -548,75 +418,66 @@ nsRootAccessible::ProcessDOMEvent(nsIDOM
 
   if (eventType.EqualsLiteral("RadioStateChange")) {
     PRUint64 state = accessible->State();
 
     // radiogroup in prefWindow is exposed as a list,
     // and panebutton is exposed as XULListitem in A11y.
     // nsXULListitemAccessible::GetStateInternal uses STATE_SELECTED in this case,
     // so we need to check states::SELECTED also.
-    PRBool isEnabled = (state & (states::CHECKED | states::SELECTED)) != 0;
+    bool isEnabled = (state & (states::CHECKED | states::SELECTED)) != 0;
 
     nsRefPtr<AccEvent> accEvent =
       new AccStateChangeEvent(accessible, states::CHECKED, isEnabled);
     nsEventShell::FireEvent(accEvent);
 
-    if (isEnabled)
-      FireAccessibleFocusEvent(accessible, origTargetContent);
+    if (isEnabled) {
+      FocusMgr()->ActiveItemChanged(accessible);
+      A11YDEBUG_FOCUS_ACTIVEITEMCHANGE_CAUSE("RadioStateChange", accessible)
+    }
 
     return;
   }
 
   if (eventType.EqualsLiteral("CheckboxStateChange")) {
     PRUint64 state = accessible->State();
 
-    PRBool isEnabled = !!(state & states::CHECKED);
+    bool isEnabled = !!(state & states::CHECKED);
 
     nsRefPtr<AccEvent> accEvent =
       new AccStateChangeEvent(accessible, states::CHECKED, isEnabled);
 
     nsEventShell::FireEvent(accEvent);
     return;
   }
 
   nsAccessible *treeItemAccessible = nsnull;
 #ifdef MOZ_XUL
   // If it's a tree element, need the currently selected item
   if (isTree) {
-    nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelect =
-      do_QueryInterface(targetNode);
-    if (multiSelect) {
-      PRInt32 treeIndex = -1;
-      multiSelect->GetCurrentIndex(&treeIndex);
-      if (treeIndex >= 0) {
-        nsRefPtr<nsXULTreeAccessible> treeAcc = do_QueryObject(accessible);
-        if (treeAcc) {
-          treeItemAccessible = treeAcc->GetTreeItemAccessible(treeIndex);
-          if (treeItemAccessible)
-            accessible = treeItemAccessible;
-        }
-      }
-    }
+    treeItemAccessible = accessible->CurrentItem();
+    if (treeItemAccessible)
+      accessible = treeItemAccessible;
   }
 #endif
 
 #ifdef MOZ_XUL
   if (treeItemAccessible && eventType.EqualsLiteral("OpenStateChange")) {
     PRUint64 state = accessible->State();
-    PRBool isEnabled = (state & states::EXPANDED) != 0;
+    bool isEnabled = (state & states::EXPANDED) != 0;
 
     nsRefPtr<AccEvent> accEvent =
       new AccStateChangeEvent(accessible, states::EXPANDED, isEnabled);
     nsEventShell::FireEvent(accEvent);
     return;
   }
 
   if (treeItemAccessible && eventType.EqualsLiteral("select")) {
     // If multiselect tree, we should fire selectionadd or selection removed
-    if (gLastFocusedNode == targetNode) {
+    if (FocusMgr()->HasDOMFocus(targetNode)) {
       nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSel =
         do_QueryInterface(targetNode);
       nsAutoString selType;
       multiSel->GetSelType(selType);
       if (selType.IsEmpty() || !selType.EqualsLiteral("single")) {
         // XXX: We need to fire EVENT_SELECTION_ADD and EVENT_SELECTION_REMOVE
         // for each tree item. Perhaps each tree item will need to cache its
         // selection state and fire an event after a DOM "select" event when
@@ -628,127 +489,66 @@ nsRootAccessible::ProcessDOMEvent(nsIDOM
 
       nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_SELECTION,
                               treeItemAccessible);
       return;
     }
   }
   else
 #endif
-  if (eventType.EqualsLiteral("focus")) {
-    // Keep a reference to the target node. We might want to change
-    // it to the individual radio button or selected item, and send
-    // the focus event to that.
-    nsCOMPtr<nsINode> focusedItem = targetNode;
-    if (!treeItemAccessible) {
-      nsCOMPtr<nsIDOMXULSelectControlElement> selectControl =
-        do_QueryInterface(targetNode);
-      if (selectControl) {
-        nsCOMPtr<nsIDOMXULMenuListElement> menuList =
-          do_QueryInterface(targetNode);
-        if (!menuList) {
-          // Don't do this for menu lists, the items only get focused
-          // when the list is open, based on DOMMenuitemActive events
-          nsCOMPtr<nsIDOMXULSelectControlItemElement> selectedItem;
-          selectControl->GetSelectedItem(getter_AddRefs(selectedItem));
-          if (selectedItem)
-            focusedItem = do_QueryInterface(selectedItem);
-
-          if (!focusedItem)
-            return;
-
-          accessible = GetAccService()->GetAccessibleInWeakShell(focusedItem,
-                                                                 weakShell);
-          if (!accessible)
-            return;
-        }
-      }
-    }
-    FireAccessibleFocusEvent(accessible, origTargetContent);
-  }
-  else if (eventType.EqualsLiteral("blur")) {
-    NS_IF_RELEASE(gLastFocusedNode);
-  }
-  else if (eventType.EqualsLiteral("AlertActive")) { 
+  if (eventType.EqualsLiteral("AlertActive")) {
     nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_ALERT, accessible);
   }
   else if (eventType.EqualsLiteral("popupshown")) {
     HandlePopupShownEvent(accessible);
   }
   else if (eventType.EqualsLiteral("DOMMenuInactive")) {
     if (accessible->Role() == nsIAccessibleRole::ROLE_MENUPOPUP) {
       nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END,
                               accessible);
     }
   }
   else if (eventType.EqualsLiteral("DOMMenuItemActive")) {
-    PRBool fireFocus = PR_FALSE;
-    if (!treeItemAccessible) {
-#ifdef MOZ_XUL
-      if (isTree) {
-        return; // Tree with nothing selected
-      }
-#endif
-
-      nsMenuFrame* menuFrame = do_QueryFrame(accessible->GetFrame());
-      if (menuFrame)
-        fireFocus = PR_TRUE;
-      // QI failed for nsMenuFrame means it's not on menu bar
-      if (menuFrame && menuFrame->IsOnMenuBar() &&
-                       !menuFrame->IsOnActiveMenuBar()) {
-        // It is a top level menuitem. Only fire a focus event when the menu bar
-        // is active.
-        return;
-      } else {
-        nsAccessible* container = accessible->Parent();
-        if (!container)
-          return;
-        // It is not top level menuitem
-        // Only fire focus event if it is not inside collapsed popup
-        // and not a listitem of a combo box
-        if (container->State() & states::COLLAPSED) {
-          nsAccessible* containerParent = container->Parent();
-          if (!containerParent)
-            return;
-          if (containerParent->Role() != nsIAccessibleRole::ROLE_COMBOBOX) {
-            return;
-          }
-        }
-      }
-    }
-    if (!fireFocus) {
-      nsCOMPtr<nsINode> realFocusedNode = GetCurrentFocus();
-      nsIContent* realFocusedContent =
-        realFocusedNode->IsElement() ? realFocusedNode->AsElement() : nsnull;
-      nsIContent* containerContent = targetContent;
-      while (containerContent) {
-        nsCOMPtr<nsIDOMXULPopupElement> popup = do_QueryInterface(containerContent);
-        if (popup || containerContent == realFocusedContent) { 
-          // If we're inside the focus or a popup we can fire focus events
-          // for the changed active item
-          fireFocus = PR_TRUE;
-          break;
-        }
-        containerContent = containerContent->GetParent();
-      }
-    }
-    if (fireFocus) {
-      // Always asynch, always from user input.
-      FireAccessibleFocusEvent(accessible, origTargetContent, PR_TRUE,
-                               eFromUserInput);
+    FocusMgr()->ActiveItemChanged(accessible);
+    A11YDEBUG_FOCUS_ACTIVEITEMCHANGE_CAUSE("DOMMenuItemActive", accessible)
+  }
+  else if (eventType.EqualsLiteral("DOMMenuItemInactive")) {
+    // Process DOMMenuItemInactive event for autocomplete only because this is
+    // unique widget that may acquire focus from autocomplete popup while popup
+    // stays open and has no active item. In case of XUL tree autocomplete
+    // popup this event is fired for tree accessible.
+    nsAccessible* widget =
+      accessible->IsWidget() ? accessible : accessible->ContainerWidget();
+    if (widget && widget->IsAutoCompletePopup()) {
+      FocusMgr()->ActiveItemChanged(nsnull);
+      A11YDEBUG_FOCUS_ACTIVEITEMCHANGE_CAUSE("DOMMenuItemInactive", accessible)
     }
   }
   else if (eventType.EqualsLiteral("DOMMenuBarActive")) {  // Always from user input
     nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENU_START,
                             accessible, eFromUserInput);
+
+    // Notify of active item change when menubar gets active and if it has
+    // current item. This is a case of mouseover (set current menuitem) and
+    // mouse click (activate the menubar). If menubar doesn't have current item
+    // (can be a case of menubar activation from keyboard) then ignore this
+    // notification because later we'll receive DOMMenuItemActive event after
+    // current menuitem is set.
+    nsAccessible* activeItem = accessible->CurrentItem();
+    if (activeItem) {
+      FocusMgr()->ActiveItemChanged(activeItem);
+      A11YDEBUG_FOCUS_ACTIVEITEMCHANGE_CAUSE("DOMMenuBarActive", accessible)
+    }
   }
   else if (eventType.EqualsLiteral("DOMMenuBarInactive")) {  // Always from user input
     nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENU_END,
                             accessible, eFromUserInput);
-    FireCurrentFocusEvent();
+
+    FocusMgr()->ActiveItemChanged(nsnull);
+    A11YDEBUG_FOCUS_ACTIVEITEMCHANGE_CAUSE("DOMMenuBarInactive", accessible)
   }
   else if (eventType.EqualsLiteral("ValueChange")) {
     targetDocument->
       FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE,
                                  targetNode, AccEvent::eRemoveDupes);
   }
 #ifdef DEBUG_DRAGDROPSTART
   else if (eventType.EqualsLiteral("mouseover")) {
@@ -764,18 +564,16 @@ nsRootAccessible::ProcessDOMEvent(nsIDOM
 
 void
 nsRootAccessible::Shutdown()
 {
   // Called manually or by nsAccessNode::LastRelease()
   if (!mWeakShell)
     return;  // Already shutdown
 
-  mCurrentARIAMenubar = nsnull;
-
   nsDocAccessibleWrap::Shutdown();
 }
 
 // nsRootAccessible protected member
 already_AddRefed<nsIDocShellTreeItem>
 nsRootAccessible::GetContentDocShell(nsIDocShellTreeItem *aStart)
 {
   if (!aStart) {
@@ -881,47 +679,116 @@ nsRootAccessible::HandlePopupShownEvent(
         new AccStateChangeEvent(combobox, states::EXPANDED, PR_TRUE);
       if (event)
         nsEventShell::FireEvent(event);
     }
   }
 }
 
 void
-nsRootAccessible::HandlePopupHidingEvent(nsINode* aNode,
-                                         nsAccessible* aAccessible)
+nsRootAccessible::HandlePopupHidingEvent(nsINode* aPopupNode)
 {
-  // If accessible focus was on or inside popup that closes, then restore it
-  // to true current focus. This is the case when we've been getting
-  // DOMMenuItemActive events inside of a combo box that closes. The real focus
-  // is on the combo box. It's also the case when a popup gets focus in ATK --
-  // when it closes we need to fire an event to restore focus to where it was.
+  // Get popup accessible. There are cases when popup element isn't accessible
+  // but an underlying widget is and behaves like popup, an example is
+  // autocomplete popups.
+  nsDocAccessible* document = nsAccUtils::GetDocAccessibleFor(aPopupNode);
+  if (!document)
+    return;
+
+  nsAccessible* popup = document->GetAccessible(aPopupNode);
+  if (!popup) {
+    nsAccessible* popupContainer = document->GetContainerAccessible(aPopupNode);
+    if (!popupContainer)
+      return;
 
-  if (gLastFocusedNode &&
-      nsCoreUtils::IsAncestorOf(aNode, gLastFocusedNode)) {
-    // Focus was on or inside of a popup that's being hidden
-    FireCurrentFocusEvent();
+    PRInt32 childCount = popupContainer->GetChildCount();
+    for (PRInt32 idx = 0; idx < childCount; idx++) {
+      nsAccessible* child = popupContainer->GetChildAt(idx);
+      if (child->IsAutoCompletePopup()) {
+        popup = child;
+        break;
+      }
+    }
+
+    // No popup no events. Focus is managed by DOM. This is a case for
+    // menupopups of menus on Linux since there are no accessible for popups.
+    if (!popup)
+      return;
   }
 
-  // Fire expanded state change event for comboboxes and autocompletes.
-  if (!aAccessible ||
-      aAccessible->Role() != nsIAccessibleRole::ROLE_COMBOBOX_LIST)
-    return;
+  // In case of autocompletes and comboboxes fire state change event for
+  // expanded state. Note, HTML form autocomplete isn't a subject of state
+  // change event because they aren't autocompletes strictly speaking.
+  // When popup closes (except nested popups and menus) then fire focus event to
+  // where it was. The focus event is expected even if popup didn't take a focus.
+
+  static const PRUint32 kNotifyOfFocus = 1;
+  static const PRUint32 kNotifyOfState = 2;
+  PRUint32 notifyOf = 0;
+
+  // HTML select is target of popuphidding event. Otherwise get container
+  // widget. No container widget means this is either tooltip or menupopup.
+  // No events in the former case.
+  nsAccessible* widget = nsnull;
+  if (popup->IsCombobox()) {
+    widget = popup;
+  } else {
+    widget = popup->ContainerWidget();
+    if (!widget) {
+      if (!popup->IsMenuPopup())
+        return;
+
+      widget = popup;
+    }
+  }
+
+  if (popup->IsAutoCompletePopup()) {
+    // No focus event for autocomplete because it's managed by
+    // DOMMenuItemInactive events.
+    if (widget->IsAutoComplete())
+      notifyOf = kNotifyOfState;
 
-  nsAccessible* combobox = aAccessible->Parent();
-  if (!combobox)
-    return;
+  } else if (widget->IsCombobox()) {
+    // Fire focus for active combobox, otherwise the focus is managed by DOM
+    // focus notifications. Always fire state change event.
+    if (widget->IsActiveWidget())
+      notifyOf = kNotifyOfFocus;
+    notifyOf |= kNotifyOfState;
+
+  } else if (widget->IsMenuButton()) {
+    // Can be a part of autocomplete.
+    nsAccessible* compositeWidget = widget->ContainerWidget();
+    if (compositeWidget && compositeWidget->IsAutoComplete()) {
+      widget = compositeWidget;
+      notifyOf = kNotifyOfState;
+    }
+
+    // Autocomplete (like searchbar) can be inactive when popup hiddens
+    notifyOf |= kNotifyOfFocus;
 
-  PRUint32 comboboxRole = combobox->Role();
-  if (comboboxRole == nsIAccessibleRole::ROLE_COMBOBOX ||
-      comboboxRole == nsIAccessibleRole::ROLE_AUTOCOMPLETE) {
+  } else if (widget == popup) {
+    // Top level context menus and alerts.
+    // Ignore submenus and menubar. When submenu is closed then sumbenu
+    // container menuitem takes a focus via DOMMenuItemActive notification.
+    // For menubars processing we listen DOMMenubarActive/Inactive
+    // notifications.
+    notifyOf = kNotifyOfFocus;
+  }
+
+  // Restore focus to where it was.
+  if (notifyOf & kNotifyOfFocus) {
+    FocusMgr()->ActiveItemChanged(nsnull);
+    A11YDEBUG_FOCUS_ACTIVEITEMCHANGE_CAUSE("popuphiding", popup)
+  }
+
+  // Fire expanded state change event.
+  if (notifyOf & kNotifyOfState) {
     nsRefPtr<AccEvent> event =
-      new AccStateChangeEvent(combobox, states::EXPANDED, PR_FALSE);
-    if (event)
-      nsEventShell::FireEvent(event);
+      new AccStateChangeEvent(widget, states::EXPANDED, PR_FALSE);
+    document->FireDelayedAccessibleEvent(event);
   }
 }
 
 #ifdef MOZ_XUL
 void
 nsRootAccessible::HandleTreeRowCountChangedEvent(nsIDOMEvent* aEvent,
                                                  nsXULTreeAccessible* aAccessible)
 {
--- a/accessible/src/base/nsRootAccessible.h
+++ b/accessible/src/base/nsRootAccessible.h
@@ -85,57 +85,24 @@ public:
   // nsAccessible
   virtual Relation RelationByType(PRUint32 aType);
   virtual PRUint32 NativeRole();
   virtual PRUint64 NativeState();
 
   // nsRootAccessible
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ROOTACCESSIBLE_IMPL_CID)
 
-  /**
-   * Fire an accessible focus event for the focused accessible and attach a new
-   * selection listener to real focused element, if necessary.
-   *
-   * @param  aFocusAccessible   [in] the accessible which has received focus
-   * @param  aRealFocusContent  [in] the actual DOM element which has received
-   *                              focus (see @note section)
-   * @param  aForceEvent        [in, optional] fire a focus event even if
-   *                              the last focused item was the same
-   * @param  aIsFromUserInput   [in, optional] specifies whether the event is
-   *                              from user input
-   *
-   * @note  Use the originally focused node where the selection lives as real
-   *         focus node. For example, use the anonymous HTML:input instead of
-   *         the containing XUL:textbox. In this case, sometimes it is a later
-   *         focus event which points to the actual anonymous child with focus,
-   *         so to be safe we need to reset the selection listener every time.
-   *         This happens because when some bindings handle focus, they
-   *         retarget focus to the appropriate child inside of themselves, but
-   *         DOM focus stays outside on that binding parent.
-   */
-  void FireAccessibleFocusEvent(nsAccessible* aFocusAccessible,
-                                nsIContent* aRealFocusContent,
-                                PRBool aForceEvent = PR_FALSE,
-                                EIsFromUserInput aIsFromUserInput = eAutoDetect);
-
-    /**
-      * Fire an accessible focus event for the current focused node,
-      * if there is a focus.
-      */
-    void FireCurrentFocusEvent();
-
     nsCaretAccessible *GetCaretAccessible();
 
   /**
    * Notify that the sub document presshell was activated.
    */
   virtual void DocumentActivated(nsDocAccessible* aDocument);
 
 protected:
-  NS_DECL_RUNNABLEMETHOD(nsRootAccessible, FireCurrentFocusEvent)
 
   /**
    * Add/remove DOM event listeners.
    */
   virtual nsresult AddEventListeners();
   virtual nsresult RemoveEventListeners();
 
   /**
@@ -146,30 +113,29 @@ protected:
   /**
    * Process "popupshown" event. Used by HandleEvent().
    */
   void HandlePopupShownEvent(nsAccessible* aAccessible);
 
   /*
    * Process "popuphiding" event. Used by HandleEvent().
    */
-  void HandlePopupHidingEvent(nsINode* aNode, nsAccessible* aAccessible);
+  void HandlePopupHidingEvent(nsINode* aNode);
 
 #ifdef MOZ_XUL
     void HandleTreeRowCountChangedEvent(nsIDOMEvent* aEvent,
                                         nsXULTreeAccessible* aAccessible);
     void HandleTreeInvalidatedEvent(nsIDOMEvent* aEvent,
                                     nsXULTreeAccessible* aAccessible);
 
     PRUint32 GetChromeFlags();
 #endif
     already_AddRefed<nsIDocShellTreeItem>
            GetContentDocShell(nsIDocShellTreeItem *aStart);
     nsRefPtr<nsCaretAccessible> mCaretAccessible;
-  nsCOMPtr<nsINode> mCurrentARIAMenubar;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsRootAccessible, NS_ROOTACCESSIBLE_IMPL_CID)
 
 inline nsRootAccessible*
 nsAccessible::AsRoot()
 {
   return mFlags & eRootAccessible ?
--- a/accessible/src/base/nsTextAttrs.cpp
+++ b/accessible/src/base/nsTextAttrs.cpp
@@ -77,17 +77,17 @@ static nsCSSTextAttrMapItem gCSSTextAttr
   { "text-decoration",   "underline",     &nsGkAtoms::textUnderlineStyle,    "solid" },
   { "vertical-align",    kAnyValue,       &nsGkAtoms::textPosition,          kCopyValue }
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsTextAttrs
 
 nsTextAttrsMgr::nsTextAttrsMgr(nsHyperTextAccessible *aHyperTextAcc,
-                               PRBool aIncludeDefAttrs,
+                               bool aIncludeDefAttrs,
                                nsAccessible *aOffsetAcc,
                                PRInt32 aOffsetAccIdx) :
   mHyperTextAcc(aHyperTextAcc), mIncludeDefAttrs(aIncludeDefAttrs),
   mOffsetAcc(aOffsetAcc), mOffsetAccIdx(aOffsetAccIdx)
 {
 }
 
 nsresult
@@ -225,17 +225,17 @@ nsTextAttrsMgr::GetRange(const nsTArray<
     // Stop on embedded accessible since embedded accessibles are combined into
     // own range.
     if (nsAccUtils::IsEmbeddedObject(currAcc))
       break;
 
     nsIContent *currElm = nsCoreUtils::GetDOMElementFor(currAcc->GetContent());
     NS_ENSURE_STATE(currElm);
 
-    PRBool offsetFound = PR_FALSE;
+    bool offsetFound = false;
     for (PRUint32 attrIdx = 0; attrIdx < attrLen; attrIdx++) {
       nsITextAttr *textAttr = aTextAttrArray[attrIdx];
       if (!textAttr->Equal(currElm)) {
         offsetFound = PR_TRUE;
         break;
       }
     }
 
@@ -250,17 +250,17 @@ nsTextAttrsMgr::GetRange(const nsTArray<
   for (PRInt32 childIdx = mOffsetAccIdx + 1; childIdx < childLen; childIdx++) {
     nsAccessible *currAcc = mHyperTextAcc->GetChildAt(childIdx);
     if (nsAccUtils::IsEmbeddedObject(currAcc))
       break;
 
     nsIContent *currElm = nsCoreUtils::GetDOMElementFor(currAcc->GetContent());
     NS_ENSURE_STATE(currElm);
 
-    PRBool offsetFound = PR_FALSE;
+    bool offsetFound = false;
     for (PRUint32 attrIdx = 0; attrIdx < attrLen; attrIdx++) {
       nsITextAttr *textAttr = aTextAttrArray[attrIdx];
 
       // Alter the end offset when text attribute changes its value and stop
       // the search.
       if (!textAttr->Equal(currElm)) {
         offsetFound = PR_TRUE;
         break;
@@ -285,29 +285,29 @@ nsLangTextAttr::nsLangTextAttr(nsHyperTe
 {
   nsresult rv = aRootAcc->GetLanguage(mRootNativeValue);
   mIsRootDefined = NS_SUCCEEDED(rv) && !mRootNativeValue.IsEmpty();
 
   if (aContent)
     mIsDefined = GetLang(aContent, mNativeValue);
 }
 
-PRBool
+bool
 nsLangTextAttr::GetValueFor(nsIContent *aElm, nsAutoString *aValue)
 {
   return GetLang(aElm, *aValue);
 }
 
 void
 nsLangTextAttr::Format(const nsAutoString& aValue, nsAString& aFormattedValue)
 {
   aFormattedValue = aValue;
 }
 
-PRBool
+bool
 nsLangTextAttr::GetLang(nsIContent *aContent, nsAString& aLang)
 {
   nsCoreUtils::GetLanguageFor(aContent, mRootContent, aLang);
   return !aLang.IsEmpty();
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -325,17 +325,17 @@ nsCSSTextAttr::nsCSSTextAttr(PRUint32 aI
 }
 
 nsIAtom*
 nsCSSTextAttr::GetName() const
 {
   return *gCSSTextAttrsMap[mIndex].mAttrName;
 }
 
-PRBool
+bool
 nsCSSTextAttr::GetValueFor(nsIContent *aContent, nsAutoString *aValue)
 {
   nsCOMPtr<nsIDOMCSSStyleDeclaration> currStyleDecl =
     nsCoreUtils::GetComputedStyleDeclaration(EmptyString(), aContent);
   if (!currStyleDecl)
     return PR_FALSE;
 
   NS_ConvertASCIItoUTF16 cssName(gCSSTextAttrsMap[mIndex].mCSSName);
@@ -369,17 +369,17 @@ nsCSSTextAttr::Format(const nsAutoString
 nsBGColorTextAttr::nsBGColorTextAttr(nsIFrame *aRootFrame, nsIFrame *aFrame) :
   nsTextAttr<nscolor>(aFrame == nsnull), mRootFrame(aRootFrame)
 {
   mIsRootDefined = GetColor(mRootFrame, &mRootNativeValue);
   if (aFrame)
     mIsDefined = GetColor(aFrame, &mNativeValue);
 }
 
-PRBool
+bool
 nsBGColorTextAttr::GetValueFor(nsIContent *aContent, nscolor *aValue)
 {
   nsIFrame *frame = aContent->GetPrimaryFrame();
   if (!frame)
     return PR_FALSE;
 
   return GetColor(frame, aValue);
 }
@@ -395,17 +395,17 @@ nsBGColorTextAttr::Format(const nscolor&
   value.AppendInt(NS_GET_G(aValue));
   value.AppendLiteral(", ");
   value.AppendInt(NS_GET_B(aValue));
   value.Append(')');
 
   aFormattedValue = value;
 }
 
-PRBool
+bool
 nsBGColorTextAttr::GetColor(nsIFrame *aFrame, nscolor *aColor)
 {
   const nsStyleBackground *styleBackground = aFrame->GetStyleBackground();
 
   if (NS_GET_A(styleBackground->mBackgroundColor) > 0) {
     *aColor = styleBackground->mBackgroundColor;
     return PR_TRUE;
   }
@@ -439,17 +439,17 @@ nsFontSizeTextAttr::nsFontSizeTextAttr(n
   mIsRootDefined = PR_TRUE;
 
   if (aFrame) {
     mNativeValue = GetFontSize(aFrame);
     mIsDefined = PR_TRUE;
   }
 }
 
-PRBool
+bool
 nsFontSizeTextAttr::GetValueFor(nsIContent *aContent, nscoord *aValue)
 {
   nsIFrame *frame = aContent->GetPrimaryFrame();
   if (!frame)
     return PR_FALSE;
   
   *aValue = GetFontSize(frame);
   return PR_TRUE;
@@ -496,17 +496,17 @@ nsFontWeightTextAttr::nsFontWeightTextAt
   mIsRootDefined = PR_TRUE;
 
   if (aFrame) {
     mNativeValue = GetFontWeight(aFrame);
     mIsDefined = PR_TRUE;
   }
 }
 
-PRBool
+bool
 nsFontWeightTextAttr::GetValueFor(nsIContent *aContent, PRInt32 *aValue)
 {
   nsIFrame *frame = aContent->GetPrimaryFrame();
   if (!frame)
     return PR_FALSE;
 
   *aValue = GetFontWeight(frame);
   return PR_TRUE;
--- a/accessible/src/base/nsTextAttrs.h
+++ b/accessible/src/base/nsTextAttrs.h
@@ -75,17 +75,17 @@ public:
    * @param aHyperTextNode   DOM node of the given hyper text accessbile
    * @param aIncludeDefAttrs [optional] indicates whether default text
    *                         attributes should be included into list of exposed
    *                         text attributes.
    * @param oOffsetNode      [optional] DOM node represents hyper text offset
    *                         inside hyper text accessible
    */
   nsTextAttrsMgr(nsHyperTextAccessible *aHyperTextAcc,
-                 PRBool aIncludeDefAttrs = PR_TRUE,
+                 bool aIncludeDefAttrs = true,
                  nsAccessible *aOffsetAcc = nsnull,
                  PRInt32 aOffsetAccIdx = -1);
 
   /*
    * Return text attributes and hyper text offsets where these attributes are
    * applied. Offsets are calculated in the case of non default attributes.
    *
    * @note In the case of default attributes pointers on hyper text offsets
@@ -111,17 +111,17 @@ protected:
    * @param aEndHTOffset    [in, out] the end offset
    */
    nsresult GetRange(const nsTArray<nsITextAttr*>& aTextAttrArray,
                      PRInt32 *aStartHTOffset, PRInt32 *aEndHTOffset);
 
 private:
   nsRefPtr<nsHyperTextAccessible> mHyperTextAcc;
 
-  PRBool mIncludeDefAttrs;
+  bool mIncludeDefAttrs;
 
   nsRefPtr<nsAccessible> mOffsetAcc;
   PRInt32 mOffsetAccIdx;
 };
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // Private implementation details
@@ -143,44 +143,44 @@ public:
    * value flag is setted.
    * 
    * @param aValue                [in, out] the value of text attribute
    * @param aIncludeDefAttrValue  [in] include default attribute value flag
    * @return                      true if text attribute value differs from
    *                              default or include default attribute value
    *                              flag is applied
    */
-  virtual PRBool GetValue(nsAString& aValue, PRBool aIncludeDefAttrValue) = 0;
+  virtual bool GetValue(nsAString& aValue, bool aIncludeDefAttrValue) = 0;
 
   /**
    * Return true if the text attribute value on the given element equals with
    * predefined attribute value.
    */
-  virtual PRBool Equal(nsIContent *aContent) = 0;
+  virtual bool Equal(nsIContent *aContent) = 0;
 };
 
 
 /**
  * Base class to work with text attributes. See derived classes below.
  */
 template<class T>
 class nsTextAttr : public nsITextAttr
 {
 public:
-  nsTextAttr(PRBool aGetRootValue) : mGetRootValue(aGetRootValue) {}
+  nsTextAttr(bool aGetRootValue) : mGetRootValue(aGetRootValue) {}
 
   // nsITextAttr
-  virtual PRBool GetValue(nsAString& aValue, PRBool aIncludeDefAttrValue)
+  virtual bool GetValue(nsAString& aValue, bool aIncludeDefAttrValue)
   {
     if (mGetRootValue) {
       Format(mRootNativeValue, aValue);
       return mIsRootDefined;
     }
 
-    PRBool isDefined = mIsDefined;
+    bool isDefined = mIsDefined;
     T* nativeValue = &mNativeValue;
 
     if (!isDefined) {
       if (aIncludeDefAttrValue) {
         isDefined = mIsRootDefined;
         nativeValue = &mRootNativeValue;
       }
     } else if (!aIncludeDefAttrValue) {
@@ -189,54 +189,54 @@ public:
 
     if (!isDefined)
       return PR_FALSE;
 
     Format(*nativeValue, aValue);
     return PR_TRUE;
   }
 
-  virtual PRBool Equal(nsIContent *aContent)
+  virtual bool Equal(nsIContent *aContent)
   {
     T nativeValue;
-    PRBool isDefined = GetValueFor(aContent, &nativeValue);
+    bool isDefined = GetValueFor(aContent, &nativeValue);
 
     if (!mIsDefined && !isDefined)
       return PR_TRUE;
 
     if (mIsDefined && isDefined)
       return nativeValue == mNativeValue;
 
     if (mIsDefined)
       return mNativeValue == mRootNativeValue;
 
     return nativeValue == mRootNativeValue;
   }
 
 protected:
 
   // Return native value for the given DOM element.
-  virtual PRBool GetValueFor(nsIContent *aContent, T *aValue) = 0;
+  virtual bool GetValueFor(nsIContent *aContent, T *aValue) = 0;
 
   // Format native value to text attribute value.
   virtual void Format(const T& aValue, nsAString& aFormattedValue) = 0;
 
   // Indicates if root value should be exposed.
-  PRBool mGetRootValue;
+  bool mGetRootValue;
 
   // Native value and flag indicating if the value is defined (initialized in
   // derived classes). Note, undefined native value means it is inherited
   // from root.
   T mNativeValue;
-  PRBool mIsDefined;
+  bool mIsDefined;
 
   // Native root value and flag indicating if the value is defined  (initialized
   // in derived classes).
   T mRootNativeValue;
-  PRBool mIsRootDefined;
+  bool mIsRootDefined;
 };
 
 
 /**
  * Class is used for the work with 'language' text attribute in nsTextAttrsMgr
  * class.
  */
 class nsLangTextAttr : public nsTextAttr<nsAutoString>
@@ -246,21 +246,21 @@ public:
                  nsIContent *aContent);
 
   // nsITextAttr
   virtual nsIAtom *GetName() const { return nsGkAtoms::language; }
 
 protected:
 
   // nsTextAttr
-  virtual PRBool GetValueFor(nsIContent *aElm, nsAutoString *aValue);
+  virtual bool GetValueFor(nsIContent *aElm, nsAutoString *aValue);
   virtual void Format(const nsAutoString& aValue, nsAString& aFormattedValue);
 
 private:
-  PRBool GetLang(nsIContent *aContent, nsAString& aLang);
+  bool GetLang(nsIContent *aContent, nsAString& aLang);
   nsCOMPtr<nsIContent> mRootContent;
 };
 
 
 /**
  * Class is used for the work with CSS based text attributes in nsTextAttrsMgr
  * class.
  */
@@ -271,17 +271,17 @@ public:
                 nsIContent *aContent);
 
   // nsITextAttr
   virtual nsIAtom *GetName() const;
 
 protected:
 
   // nsTextAttr
-  virtual PRBool GetValueFor(nsIContent *aContent, nsAutoString *aValue);
+  virtual bool GetValueFor(nsIContent *aContent, nsAutoString *aValue);
   virtual void Format(const nsAutoString& aValue, nsAString& aFormattedValue);
 
 private:
   PRInt32 mIndex;
 };
 
 
 /**
@@ -293,21 +293,21 @@ class nsBGColorTextAttr : public nsTextA
 public:
   nsBGColorTextAttr(nsIFrame *aRootFrame, nsIFrame *aFrame);
 
   // nsITextAttr
   virtual nsIAtom *GetName() const { return nsGkAtoms::backgroundColor; }
 
 protected:
   // nsTextAttr
-  virtual PRBool GetValueFor(nsIContent *aContent, nscolor *aValue);
+  virtual bool GetValueFor(nsIContent *aContent, nscolor *aValue);
   virtual void Format(const nscolor& aValue, nsAString& aFormattedValue);
 
 private:
-  PRBool GetColor(nsIFrame *aFrame, nscolor *aColor);
+  bool GetColor(nsIFrame *aFrame, nscolor *aColor);
   nsIFrame *mRootFrame;
 };
 
 
 /**
  * Class is used for the work with "font-size" text attribute in nsTextAttrsMgr
  * class.
  */
@@ -317,17 +317,17 @@ public:
   nsFontSizeTextAttr(nsIFrame *aRootFrame, nsIFrame *aFrame);
 
   // nsITextAttr
   virtual nsIAtom *GetName() const { return nsGkAtoms::font_size; }
 
 protected:
 
   // nsTextAttr
-  virtual PRBool GetValueFor(nsIContent *aContent, nscoord *aValue);
+  virtual bool GetValueFor(nsIContent *aContent, nscoord *aValue);
   virtual void Format(const nscoord& aValue, nsAString& aFormattedValue);
 
 private:
 
   /**
    * Return font size for the given frame.
    *
    * @param aFrame      [in] the given frame to query font-size
@@ -349,17 +349,17 @@ public:
   nsFontWeightTextAttr(nsIFrame *aRootFrame, nsIFrame *aFrame);
 
   // nsITextAttr
   virtual nsIAtom *GetName() const { return nsGkAtoms::fontWeight; }
 
 protected:
 
   // nsTextAttr
-  virtual PRBool GetValueFor(nsIContent *aElm, PRInt32 *aValue);
+  virtual bool GetValueFor(nsIContent *aElm, PRInt32 *aValue);
   virtual void Format(const PRInt32& aValue, nsAString& aFormattedValue);
 
 private:
 
   /**
    * Return font weight for the given frame.
    *
    * @param aFrame      [in] the given frame to query font weight
--- a/accessible/src/base/nsTextEquivUtils.cpp
+++ b/accessible/src/base/nsTextEquivUtils.cpp
@@ -124,20 +124,20 @@ nsTextEquivUtils::AppendTextEquivFromCon
     gInitiatorAcc = nsnull;
     return NS_ERROR_UNEXPECTED;
   }
 
   // If the given content is not visible or isn't accessible then go down
   // through the DOM subtree otherwise go down through accessible subtree and
   // calculate the flat string.
   nsIFrame *frame = aContent->GetPrimaryFrame();
-  PRBool isVisible = frame && frame->GetStyleVisibility()->IsVisible();
+  bool isVisible = frame && frame->GetStyleVisibility()->IsVisible();
 
   nsresult rv = NS_ERROR_FAILURE;
-  PRBool goThroughDOMSubtree = PR_TRUE;
+  bool goThroughDOMSubtree = true;
 
   if (isVisible) {
     nsAccessible *accessible =
       GetAccService()->GetAccessibleInWeakShell(aContent, shell);
     if (accessible) {
       rv = AppendFromAccessible(accessible, aString);
       goThroughDOMSubtree = PR_FALSE;
     }
@@ -150,17 +150,17 @@ nsTextEquivUtils::AppendTextEquivFromCon
   return rv;
 }
 
 nsresult
 nsTextEquivUtils::AppendTextEquivFromTextContent(nsIContent *aContent,
                                                  nsAString *aString)
 {
   if (aContent->IsNodeOfType(nsINode::eTEXT)) {
-    PRBool isHTMLBlock = PR_FALSE;
+    bool isHTMLBlock = false;
 
     nsIContent *parentContent = aContent->GetParent();
     if (parentContent) {
       nsIFrame *frame = parentContent->GetPrimaryFrame();
       if (frame) {
         // If this text is inside a block level frame (as opposed to span
         // level), we need to add spaces around that block's text, so we don't
         // get words jammed together in final name.
@@ -233,17 +233,17 @@ nsTextEquivUtils::AppendFromAccessible(n
     if (rv != NS_OK_NO_NAME_CLAUSE_HANDLED)
       return rv;
   }
 
   nsAutoString text;
   nsresult rv = aAccessible->GetName(text);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRBool isEmptyTextEquiv = PR_TRUE;
+  bool isEmptyTextEquiv = true;
 
   // If the name is from tooltip then append it to result string in the end
   // (see h. step of name computation guide).
   if (rv != NS_OK_NAME_FROM_TOOLTIP)
     isEmptyTextEquiv = !AppendString(aString, text);
 
   // Implementation of f. step.
   rv = AppendFromValue(aAccessible, aString);
@@ -371,46 +371,46 @@ nsTextEquivUtils::AppendFromDOMNode(nsIC
     }
 
     AppendString(aString, textEquivalent);
   }
 
   return AppendFromDOMChildren(aContent, aString);
 }
 
-PRBool
+bool
 nsTextEquivUtils::AppendString(nsAString *aString,
                                const nsAString& aTextEquivalent)
 {
   // Insert spaces to insure that words from controls aren't jammed together.
   if (aTextEquivalent.IsEmpty())
     return PR_FALSE;
 
   if (!aString->IsEmpty())
     aString->Append(PRUnichar(' '));
 
   aString->Append(aTextEquivalent);
   return PR_TRUE;
 }
 
-PRBool
+bool
 nsTextEquivUtils::IsWhitespaceString(const nsSubstring& aString)
 {
   nsSubstring::const_char_iterator iterBegin, iterEnd;
 
   aString.BeginReading(iterBegin);
   aString.EndReading(iterEnd);
 
   while (iterBegin != iterEnd && IsWhitespace(*iterBegin))
     ++iterBegin;
 
   return iterBegin == iterEnd;
 }
 
-PRBool
+bool
 nsTextEquivUtils::IsWhitespace(PRUnichar aChar)
 {
   return aChar == ' ' || aChar == '\n' ||
     aChar == '\r' || aChar == '\t' || aChar == 0xa0;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Name rules to role map.
--- a/accessible/src/base/nsTextEquivUtils.h
+++ b/accessible/src/base/nsTextEquivUtils.h
@@ -151,30 +151,30 @@ private:
    * allowed.
    */
   static nsresult AppendFromDOMNode(nsIContent *aContent, nsAString *aString);
 
   /**
    * Concatenates strings and appends space between them. Returns true if
    * text equivalent string was appended.
    */
-  static PRBool AppendString(nsAString *aString,
+  static bool AppendString(nsAString *aString,
                              const nsAString& aTextEquivalent);
 
   /**
    * Returns true if the given string is empty or contains whitespace symbols
    * only. In contrast to nsWhitespaceTokenizer class it takes into account
    * non-breaking space (0xa0).
    */
-  static PRBool IsWhitespaceString(const nsSubstring& aString);
+  static bool IsWhitespaceString(const nsSubstring& aString);
 
   /**
    * Returns true if the given character is whitespace symbol.
    */
-  static PRBool IsWhitespace(PRUnichar aChar);
+  static bool IsWhitespace(PRUnichar aChar);
 
   /**
    * Map array from roles to name rules (constants of ETextEquivRule).
    */
   static PRUint32 gRoleToNameRulesMap[];
 
   /**
    * The accessible for which we are computing a text equivalent. It is useful
--- a/accessible/src/html/nsHTMLFormControlAccessible.cpp
+++ b/accessible/src/html/nsHTMLFormControlAccessible.cpp
@@ -114,17 +114,17 @@ nsHTMLCheckboxAccessible::DoAction(PRUin
 }
 
 PRUint64
 nsHTMLCheckboxAccessible::NativeState()
 {
   PRUint64 state = nsFormControlAccessible::NativeState();
 
   state |= states::CHECKABLE;
-  PRBool checkState = PR_FALSE;   // Radio buttons and check boxes can be checked or mixed
+  bool checkState = false;   // Radio buttons and check boxes can be checked or mixed
 
   nsCOMPtr<nsIDOMHTMLInputElement> htmlCheckboxElement =
     do_QueryInterface(mContent);
            
   if (htmlCheckboxElement) {
     htmlCheckboxElement->GetIndeterminate(&checkState);
 
     if (checkState) {
@@ -135,33 +135,43 @@ nsHTMLCheckboxAccessible::NativeState()
       if (checkState)
         state |= states::CHECKED;
     }
   }
   return state;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+// nsHTMLCheckboxAccessible: Widgets
+
+bool
+nsHTMLCheckboxAccessible::IsWidget() const
+{
+  return true;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
 // nsHTMLRadioButtonAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsHTMLRadioButtonAccessible::
   nsHTMLRadioButtonAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
   nsRadioButtonAccessible(aContent, aShell)
 {
 }
 
 PRUint64
 nsHTMLRadioButtonAccessible::NativeState()
 {
   PRUint64 state = nsAccessibleWrap::NativeState();
 
   state |= states::CHECKABLE;
   
-  PRBool checked = PR_FALSE;   // Radio buttons and check boxes can be checked
+  bool checked = false;   // Radio buttons and check boxes can be checked
 
   nsCOMPtr<nsIDOMHTMLInputElement> htmlRadioElement =
     do_QueryInterface(mContent);
   if (htmlRadioElement)
     htmlRadioElement->GetChecked(&checked);
 
   if (checked)
     state |= states::CHECKED;
@@ -263,18 +273,18 @@ nsHTMLButtonAccessible::DoAction(PRUint8
   return NS_OK;
 }
 
 PRUint64
 nsHTMLButtonAccessible::NativeState()
 {
   PRUint64 state = nsHyperTextAccessibleWrap::NativeState();
 
-  if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
-                            nsGkAtoms::submit, eIgnoreCase))
+  nsEventStates elmState = mContent->AsElement()->State();
+  if (elmState.HasState(NS_EVENT_STATE_DEFAULT))
     state |= states::DEFAULT;
 
   return state;
 }
 
 PRUint32
 nsHTMLButtonAccessible::NativeRole()
 {
@@ -309,16 +319,25 @@ nsHTMLButtonAccessible::GetNameInternal(
   }
 
   name.CompressWhitespace();
   aName = name;
 
   return NS_OK;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLButtonAccessible: Widgets
+
+bool
+nsHTMLButtonAccessible::IsWidget() const
+{
+  return true;
+}
+
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTML4ButtonAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsHTML4ButtonAccessible::
   nsHTML4ButtonAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
   nsHyperTextAccessibleWrap(aContent, aShell)
@@ -358,23 +377,32 @@ nsHTML4ButtonAccessible::NativeRole()
 
 PRUint64
 nsHTML4ButtonAccessible::NativeState()
 {
   PRUint64 state = nsHyperTextAccessibleWrap::NativeState();
 
   state |= states::FOCUSABLE;
 
-  if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
-                            nsGkAtoms::submit, eIgnoreCase))
+  nsEventStates elmState = mContent->AsElement()->State();
+  if (elmState.HasState(NS_EVENT_STATE_DEFAULT))
     state |= states::DEFAULT;
 
   return state;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// nsHTML4ButtonAccessible: Widgets
+
+bool
+nsHTML4ButtonAccessible::IsWidget() const
+{
+  return true;
+}
+
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLTextFieldAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsHTMLTextFieldAccessible::
   nsHTMLTextFieldAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
   nsHyperTextAccessibleWrap(aContent, aShell)
@@ -458,50 +486,39 @@ nsHTMLTextFieldAccessible::NativeState()
 {
   PRUint64 state = nsHyperTextAccessibleWrap::NativeState();
 
   // can be focusable, focused, protected. readonly, unavailable, selected
   if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
                             nsGkAtoms::password, eIgnoreCase)) {
     state |= states::PROTECTED;
   }
-  else {
-    nsAccessible* parent = Parent();
-    if (parent && parent->Role() == nsIAccessibleRole::ROLE_AUTOCOMPLETE)
-      state |= states::HASPOPUP;
-  }
 
   if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::readonly)) {
     state |= states::READONLY;
   }
 
+  // Is it an <input> or a <textarea> ?
   nsCOMPtr<nsIDOMHTMLInputElement> htmlInput(do_QueryInterface(mContent));
-  // Is it an <input> or a <textarea> ?
-  if (htmlInput) {
-    state |= states::SINGLE_LINE;
-  }
-  else {
-    state |= states::MULTI_LINE;
-  }
+  state |= htmlInput ? states::SINGLE_LINE : states::MULTI_LINE;
 
-  if (!(state & states::EDITABLE))
+  if (!(state & states::EDITABLE) ||
+      (state & (states::PROTECTED | states::MULTI_LINE)))
     return state;
 
-  nsCOMPtr<nsIContent> bindingContent = mContent->GetBindingParent();
-  if (bindingContent &&
-      bindingContent->NodeInfo()->Equals(nsGkAtoms::textbox,
-                                         kNameSpaceID_XUL)) {
-     if (bindingContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
-                                     nsGkAtoms::autocomplete,
-                                     eIgnoreCase)) {
-       // If parent is XUL textbox and value of @type attribute is "autocomplete",
-       // then this accessible supports autocompletion.
-       state |= states::SUPPORTS_AUTOCOMPLETION;
-     }
-  } else if (gIsFormFillEnabled && htmlInput && !(state & states::PROTECTED)) {
+  // Expose autocomplete states if this input is part of autocomplete widget.
+  nsAccessible* widget = ContainerWidget();
+  if (widget && widget-IsAutoComplete()) {
+    state |= states::HASPOPUP | states::SUPPORTS_AUTOCOMPLETION;
+    return state;
+  }
+
+  // No parent can mean a fake widget created for XUL textbox. If accessible
+  // is unattached from tree then we don't care.
+  if (mParent && gIsFormFillEnabled) {
     // 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;
     mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::autocomplete,
                       autocomplete);
@@ -556,31 +573,48 @@ NS_IMETHODIMP nsHTMLTextFieldAccessible:
   nsCOMPtr<nsIDOMNSEditableElement> editableElt(do_QueryInterface(mContent));
   NS_ENSURE_TRUE(editableElt, NS_ERROR_FAILURE);
 
   // nsGenericHTMLElement::GetEditor has a security check.
   // Make sure we're not restricted by the permissions of
   // whatever script is currently running.
   nsCOMPtr<nsIJSContextStack> stack =
     do_GetService("@mozilla.org/js/xpc/ContextStack;1");
-  PRBool pushed = stack && NS_SUCCEEDED(stack->Push(nsnull));
+  bool pushed = stack && NS_SUCCEEDED(stack->Push(nsnull));
 
   nsCOMPtr<nsIEditor> editor;
   nsresult rv = editableElt->GetEditor(aEditor);
 
   if (pushed) {
     JSContext* cx;
     stack->Pop(&cx);
     NS_ASSERTION(!cx, "context should be null");
   }
 
   return rv;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+// nsHTMLTextFieldAccessible: Widgets
+
+bool
+nsHTMLTextFieldAccessible::IsWidget() const
+{
+  return true;
+}
+
+nsAccessible*
+nsHTMLTextFieldAccessible::ContainerWidget() const
+{
+  return mParent && mParent->Role() == nsIAccessibleRole::ROLE_AUTOCOMPLETE ?
+    mParent : nsnull;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
 // nsHTMLGroupboxAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsHTMLGroupboxAccessible::
   nsHTMLGroupboxAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
   nsHyperTextAccessibleWrap(aContent, aShell)
 {
 }
--- a/accessible/src/html/nsHTMLFormControlAccessible.h
+++ b/accessible/src/html/nsHTMLFormControlAccessible.h
@@ -63,16 +63,19 @@ public:
   NS_IMETHOD DoAction(PRUint8 index);
 
   // nsAccessible
   virtual PRUint32 NativeRole();
   virtual PRUint64 NativeState();
 
   // ActionAccessible
   virtual PRUint8 ActionCount();
+
+  // Widgets
+  virtual bool IsWidget() const;
 };
 
 
 /**
  * Accessible for HTML input@type="radio" element.
  */
 class nsHTMLRadioButtonAccessible : public nsRadioButtonAccessible
 {
@@ -105,16 +108,19 @@ public:
 
   // nsAccessible
   virtual nsresult GetNameInternal(nsAString& aName);
   virtual PRUint32 NativeRole();
   virtual PRUint64 NativeState();
 
   // ActionAccessible
   virtual PRUint8 ActionCount();
+
+  // Widgets
+  virtual bool IsWidget() const;
 };
 
 
 /**
  * Accessible for HTML button element.
  */
 class nsHTML4ButtonAccessible : public nsHyperTextAccessibleWrap
 {
@@ -129,16 +135,19 @@ public:
   NS_IMETHOD DoAction(PRUint8 index);
 
   // nsAccessible
   virtual PRUint32 NativeRole();
   virtual PRUint64 NativeState();
 
   // ActionAccessible
   virtual PRUint8 ActionCount();
+
+  // Widgets
+  virtual bool IsWidget() const;
 };
 
 
 /**
  * Accessible for HTML input@type="text" element.
  */
 class nsHTMLTextFieldAccessible : public nsHyperTextAccessibleWrap
 {
@@ -161,16 +170,20 @@ public:
   // nsAccessible
   virtual void ApplyARIAState(PRUint64* aState);
   virtual nsresult GetNameInternal(nsAString& aName);
   virtual PRUint32 NativeRole();
   virtual PRUint64 NativeState();
 
   // ActionAccessible
   virtual PRUint8 ActionCount();
+
+  // Widgets
+  virtual bool IsWidget() const;
+  virtual nsAccessible* ContainerWidget() const;
 };
 
 
 /**
  * Accessible for HTML fieldset element.
  */
 class nsHTMLGroupboxAccessible : public nsHyperTextAccessibleWrap
 {
--- a/accessible/src/html/nsHTMLImageAccessible.cpp
+++ b/accessible/src/html/nsHTMLImageAccessible.cpp
@@ -85,29 +85,29 @@ nsHTMLImageAccessible::NativeState()
     content->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
                         getter_AddRefs(imageRequest));
 
   nsCOMPtr<imgIContainer> imgContainer;
   if (imageRequest)
     imageRequest->GetImage(getter_AddRefs(imgContainer));
 
   if (imgContainer) {
-    PRBool animated;
+    bool animated;
     imgContainer->GetAnimated(&animated);
     if (animated)
       state |= states::ANIMATED;
   }
 
   return state;
 }
 
 nsresult
 nsHTMLImageAccessible::GetNameInternal(nsAString& aName)
 {
-  PRBool hasAltAttrib =
+  bool hasAltAttrib =
     mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName);
   if (!aName.IsEmpty())
     return NS_OK;
 
   nsresult rv = nsAccessible::GetNameInternal(aName);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aName.IsEmpty() && hasAltAttrib) {
@@ -216,25 +216,25 @@ nsHTMLImageAccessible::GetAttributesInte
     nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::src, src);
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Private methods
 
-PRBool
+bool
 nsHTMLImageAccessible::HasLongDesc()
 {
   if (IsDefunct())
     return PR_FALSE;
 
   return mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::longdesc);
 }
 
-PRBool
+bool
 nsHTMLImageAccessible::IsValidLongDescIndex(PRUint8 aIndex)
 {
   if (!HasLongDesc())
     return PR_FALSE;
 
   return aIndex == nsLinkableAccessible::ActionCount();
 }
--- a/accessible/src/html/nsHTMLImageAccessible.h
+++ b/accessible/src/html/nsHTMLImageAccessible.h
@@ -73,24 +73,24 @@ public:
   virtual PRUint8 ActionCount();
 
 private:
   /**
    * Determine if this image accessible has a longdesc attribute.
    *
    * @returns  true if the longdesc attribute is present.
    */
-  PRBool HasLongDesc();
+  bool HasLongDesc();
   
   /**
    * Used by GetActionName and DoAction to ensure the index for opening the
    * longdesc URL is valid.
    * It is always assumed that the highest possible index opens the longdesc.
    *
    * @param aIndex  The 0-based index to be tested.
    *
    * @returns  true if index is valid for longdesc action.
    */
-  PRBool IsValidLongDescIndex(PRUint8 aIndex);
+  bool IsValidLongDescIndex(PRUint8 aIndex);
 };
 
 #endif
 
--- a/accessible/src/html/nsHTMLImageMapAccessible.cpp
+++ b/accessible/src/html/nsHTMLImageMapAccessible.cpp
@@ -196,17 +196,17 @@ nsHTMLAreaAccessible::GetBounds(PRInt32 
   // Essentially this uses GetRect on mAreas of nsImageMap from nsImageFrame.
   nsPresContext *presContext = GetPresContext();
   NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
 
   nsIFrame *frame = GetFrame();
   NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
   nsImageFrame *imageFrame = do_QueryFrame(frame);
 
-  nsImageMap* map = imageFrame->GetImageMap(presContext);
+  nsImageMap* map = imageFrame->GetImageMap();
   NS_ENSURE_TRUE(map, NS_ERROR_FAILURE);
 
   nsRect rect;
   nsresult rv = map->GetBoundsForAreaContent(mContent, rect);
   NS_ENSURE_SUCCESS(rv, rv);
 
   *aX = presContext->AppUnitsToDevPixels(rect.x);
   *aY = presContext->AppUnitsToDevPixels(rect.y);
--- a/accessible/src/html/nsHTMLLinkAccessible.cpp
+++ b/accessible/src/html/nsHTMLLinkAccessible.cpp
@@ -173,17 +173,17 @@ already_AddRefed<nsIURI>
 nsHTMLLinkAccessible::AnchorURIAt(PRUint32 aAnchorIndex)
 {
   return aAnchorIndex == 0 ? mContent->GetHrefURI() : nsnull;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Protected members
 
-PRBool
+bool
 nsHTMLLinkAccessible::IsLinked()
 {
   if (IsDefunct())
     return PR_FALSE;
 
   nsEventStates state = mContent->AsElement()->State();
   return state.HasAtLeastOneOfStates(NS_EVENT_STATE_VISITED |
                                      NS_EVENT_STATE_UNVISITED);
--- a/accessible/src/html/nsHTMLLinkAccessible.h
+++ b/accessible/src/html/nsHTMLLinkAccessible.h
@@ -67,12 +67,12 @@ public:
   virtual already_AddRefed<nsIURI> AnchorURIAt(PRUint32 aAnchorIndex);
 
 protected:
   enum { eAction_Jump = 0 };
 
   /**
    * Returns true if the link has href attribute.
    */
-  PRBool IsLinked();
+  bool IsLinked();
 };
 
 #endif  
--- a/accessible/src/html/nsHTMLSelectAccessible.cpp
+++ b/accessible/src/html/nsHTMLSelectAccessible.cpp
@@ -62,38 +62,26 @@ using namespace mozilla::a11y;
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLSelectListAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsHTMLSelectListAccessible::
   nsHTMLSelectListAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
   nsAccessibleWrap(aContent, aShell)
 {
+  mFlags |= eListControlAccessible;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLSelectListAccessible: nsAccessible public
 
 PRUint64
 nsHTMLSelectListAccessible::NativeState()
 {
   PRUint64 state = nsAccessibleWrap::NativeState();
-
-  // As a nsHTMLSelectListAccessible we can have the following states:
-  //   states::MULTISELECTABLE, states::EXTSELECTABLE
-
-  if (state & states::FOCUSED) {
-    // Treat first focusable option node as actual focus, in order
-    // to avoid confusing JAWS, which needs focus on the option
-    nsCOMPtr<nsIContent> focusedOption =
-      nsHTMLSelectOptionAccessible::GetFocusedOption(mContent);
-    if (focusedOption) { // Clear focused state since it is on option
-      state &= ~states::FOCUSED;
-    }
-  }
   if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::multiple))
     state |= states::MULTISELECTABLE | states::EXTSELECTABLE;
 
   return state;
 }
 
 PRUint32
 nsHTMLSelectListAccessible::NativeRole()
@@ -123,16 +111,52 @@ nsHTMLSelectListAccessible::SelectAll()
 bool
 nsHTMLSelectListAccessible::UnselectAll()
 {
   return mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::multiple) ?
            nsAccessibleWrap::UnselectAll() : false;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+// nsHTMLSelectListAccessible: Widgets
+
+bool
+nsHTMLSelectListAccessible::IsWidget() const
+{
+  return true;
+}
+
+bool
+nsHTMLSelectListAccessible::IsActiveWidget() const
+{
+  return FocusMgr()->HasDOMFocus(mContent);
+}
+
+bool
+nsHTMLSelectListAccessible::AreItemsOperable() const
+{
+  return true;
+}
+
+nsAccessible*
+nsHTMLSelectListAccessible::CurrentItem()
+{
+  nsIListControlFrame* listControlFrame = do_QueryFrame(GetFrame());
+  if (listControlFrame) {
+    nsCOMPtr<nsIContent> activeOptionNode = listControlFrame->GetCurrentOption();
+    if (activeOptionNode) {
+      nsDocAccessible* document = GetDocAccessible();
+      if (document)
+        return document->GetAccessible(activeOptionNode);
+    }
+  }
+  return nsnull;
+}
+
+////////////////////////////////////////////////////////////////////////////////
 // nsHTMLSelectListAccessible: nsAccessible protected
 
 void
 nsHTMLSelectListAccessible::CacheChildren()
 {
   // Cache accessibles for <optgroup> and <option> DOM decendents as children,
   // as well as the accessibles for them. Avoid whitespace text nodes. We want
   // to count all the <optgroup>s and <option>s as children because we want
@@ -247,44 +271,30 @@ nsHTMLSelectOptionAccessible::NativeStat
   // As a nsHTMLSelectOptionAccessible we can have the following states:
   // SELECTABLE, SELECTED, FOCUSED, FOCUSABLE, OFFSCREEN
   // Upcall to nsAccessible, but skip nsHyperTextAccessible impl
   // because we don't want EDITABLE or SELECTABLE_TEXT
   PRUint64 state = nsAccessible::NativeState();
 
   PRUint64 selectState = 0;
   nsIContent* selectContent = GetSelectState(&selectState);
-  if (selectState & states::INVISIBLE)
+  if (!selectContent || selectState & states::INVISIBLE)
     return state;
 
-  NS_ENSURE_TRUE(selectContent, NS_ERROR_FAILURE);
-
-  // Is disabled?
-  if (0 == (state & states::UNAVAILABLE)) {
+  // Focusable and selectable
+  if (!(state & states::UNAVAILABLE))
     state |= (states::FOCUSABLE | states::SELECTABLE);
-    // When the list is focused but no option is actually focused,
-    // Firefox draws a focus ring around the first non-disabled option.
-    // We need to indicate states::FOCUSED in that case, because it
-    // prevents JAWS from ignoring the list
-    // GetFocusedOption() ensures that an option node is
-    // returned in this case, as long as some focusable option exists
-    // in the listbox
-    nsCOMPtr<nsIContent> focusedOption = GetFocusedOption(selectContent);
-    if (focusedOption == mContent)
-      state |= states::FOCUSED;
-  }
 
   // Are we selected?
-  PRBool isSelected = PR_FALSE;
+  bool isSelected = false;
   nsCOMPtr<nsIDOMHTMLOptionElement> option(do_QueryInterface(mContent));
   if (option) {
     option->GetSelected(&isSelected);
     if (isSelected)
       state |= states::SELECTED;
-
   }
 
   if (selectState & states::OFFSCREEN) {
     state |= states::OFFSCREEN;
   }
   else if (selectState & states::COLLAPSED) {
     // <select> is COLLAPSED: add OFFSCREEN, if not the currently
     // visible option
@@ -333,17 +343,17 @@ nsHTMLSelectOptionAccessible::GetLevelIn
 
 void
 nsHTMLSelectOptionAccessible::GetPositionAndSizeInternal(PRInt32 *aPosInSet,
                                                          PRInt32 *aSetSize)
 {
   nsIContent *parentContent = mContent->GetParent();
 
   PRInt32 posInSet = 0, setSize = 0;
-  PRBool isContentFound = PR_FALSE;
+  bool isContentFound = false;
 
   PRUint32 childCount = parentContent->GetChildCount();
   for (PRUint32 childIdx = 0; childIdx < childCount; childIdx++) {
     nsIContent *childContent = parentContent->GetChildAt(childIdx);
     if (childContent->NodeInfo()->Equals(mContent->NodeInfo())) {
       if (!isContentFound) {
         if (childContent == mContent)
           isContentFound = PR_TRUE;
@@ -372,152 +382,58 @@ NS_IMETHODIMP nsHTMLSelectOptionAccessib
 }
 
 PRUint8
 nsHTMLSelectOptionAccessible::ActionCount()
 {
   return 1;
 }
 
-NS_IMETHODIMP nsHTMLSelectOptionAccessible::DoAction(PRUint8 index)
+NS_IMETHODIMP
+nsHTMLSelectOptionAccessible::DoAction(PRUint8 aIndex)
 {
-  if (index == eAction_Select) {   // default action
-    nsCOMPtr<nsIDOMHTMLOptionElement> newHTMLOption(do_QueryInterface(mContent));
-    if (!newHTMLOption) 
-      return NS_ERROR_FAILURE;
-    // Clear old selection
-    nsAccessible* parent = Parent();
-    if (!parent)
-      return NS_OK;
-
-    nsCOMPtr<nsIContent> oldHTMLOptionContent =
-      GetFocusedOption(parent->GetContent());
-    nsCOMPtr<nsIDOMHTMLOptionElement> oldHTMLOption =
-      do_QueryInterface(oldHTMLOptionContent);
-    if (oldHTMLOption)
-      oldHTMLOption->SetSelected(PR_FALSE);
-    // Set new selection
-    newHTMLOption->SetSelected(PR_TRUE);
+  if (aIndex != eAction_Select)
+    return NS_ERROR_INVALID_ARG;
 
-    // If combo box, and open, close it
-    // First, get the <select> widgets list control frame
-    nsIContent *selectContent = mContent;
-    do {
-      selectContent = selectContent->GetParent();
-      nsCOMPtr<nsIDOMHTMLSelectElement> selectControl =
-        do_QueryInterface(selectContent);
-      if (selectControl)
-        break;
-
-    } while (selectContent);
-
-    nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
-    nsCOMPtr<nsIDOMHTMLOptionElement> option(do_QueryInterface(mContent));
-
-    if (!selectContent || !presShell || !option)
-      return NS_ERROR_FAILURE;
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
 
-    nsIFrame *selectFrame = selectContent->GetPrimaryFrame();
-    nsIComboboxControlFrame *comboBoxFrame = do_QueryFrame(selectFrame);
-    if (comboBoxFrame) {
-      nsIFrame *listFrame = comboBoxFrame->GetDropDown();
-      if (comboBoxFrame->IsDroppedDown() && listFrame) {
-        // use this list control frame to roll up the list
-        nsIListControlFrame *listControlFrame = do_QueryFrame(listFrame);
-        if (listControlFrame) {
-          PRInt32 newIndex = 0;
-          option->GetIndex(&newIndex);
-          listControlFrame->ComboboxFinish(newIndex);
-        }
-      }
-    }
-    return NS_OK;
-  }
-
-  return NS_ERROR_INVALID_ARG;
+  DoCommand();
+  return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHTMLSelectOptionAccessible::SetSelected(PRBool aSelect)
+nsHTMLSelectOptionAccessible::SetSelected(bool aSelect)
 {
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIDOMHTMLOptionElement> optionElm(do_QueryInterface(mContent));
   return optionElm->SetSelected(aSelect);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsHTMLSelectOptionAccessible: static methods
-
-/**
-  * Helper method for getting the focused DOM Node from our parent(list) node. We
-  *  need to use the frame to get the focused option because for some reason we
-  *  weren't getting the proper notification when the focus changed using the DOM
-  */
-already_AddRefed<nsIContent>
-nsHTMLSelectOptionAccessible::GetFocusedOption(nsIContent *aListNode)
-{
-  NS_ASSERTION(aListNode, "Called GetFocusedOptionNode without a valid list node");
-
-  nsIFrame *frame = aListNode->GetPrimaryFrame();
-  if (!frame)
-    return nsnull;
-
-  PRInt32 focusedOptionIndex = 0;
-
-  // Get options
-  nsCOMPtr<nsIDOMHTMLSelectElement> selectElement(do_QueryInterface(aListNode));
-  NS_ASSERTION(selectElement, "No select element where it should be");
+// nsHTMLSelectOptionAccessible: Widgets
 
-  nsCOMPtr<nsIDOMHTMLOptionsCollection> options;
-  nsresult rv = selectElement->GetOptions(getter_AddRefs(options));
-  
-  if (NS_SUCCEEDED(rv)) {
-    nsIListControlFrame *listFrame = do_QueryFrame(frame);
-    if (listFrame) {
-      // Get what's focused in listbox by asking frame for "selected item". 
-      // Can't use dom interface for this, because it will always return the first selected item
-      // when there is more than 1 item selected. We need the focused item, not
-      // the first selected item.
-      focusedOptionIndex = listFrame->GetSelectedIndex();
-      if (focusedOptionIndex == -1) {
-        nsCOMPtr<nsIDOMNode> nextOption;
-        while (PR_TRUE) {
-          ++ focusedOptionIndex;
-          options->Item(focusedOptionIndex, getter_AddRefs(nextOption));
-          nsCOMPtr<nsIDOMHTMLOptionElement> optionElement = do_QueryInterface(nextOption);
-          if (!optionElement) {
-            break;
-          }
-          PRBool disabled;
-          optionElement->GetDisabled(&disabled);
-          if (!disabled) {
-            break;
-          }
-        }
-      }
-    }
-    else  // Combo boxes can only have 1 selected option, so they can use the dom interface for this
-      rv = selectElement->GetSelectedIndex(&focusedOptionIndex);
+nsAccessible*
+nsHTMLSelectOptionAccessible::ContainerWidget() const
+{
+  if (mParent && mParent->IsListControl()) {
+    nsAccessible* grandParent = mParent->Parent();
+    if (grandParent && grandParent->IsCombobox())
+      return grandParent;
+
+    return mParent;
   }
-
-  // Either use options and focused index, or default return null
-  if (NS_SUCCEEDED(rv) && options && focusedOptionIndex >= 0) {  // Something is focused
-    nsCOMPtr<nsIDOMNode> focusedOptionNode;
-    options->Item(focusedOptionIndex, getter_AddRefs(focusedOptionNode));
-    nsIContent *focusedOption = nsnull;
-    if (focusedOptionNode)
-      CallQueryInterface(focusedOptionNode, &focusedOption);
-    return focusedOption;
-  }
-
   return nsnull;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLSelectOptionAccessible: static methods
+
 void
 nsHTMLSelectOptionAccessible::SelectionChangedIfOption(nsIContent *aPossibleOptionNode)
 {
   if (!aPossibleOptionNode ||
       aPossibleOptionNode->Tag() != nsGkAtoms::option ||
       !aPossibleOptionNode->IsHTML()) {
     return;
   }
@@ -639,16 +555,17 @@ nsHTMLSelectOptGroupAccessible::CacheChi
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLComboboxAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsHTMLComboboxAccessible::
   nsHTMLComboboxAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
   nsAccessibleWrap(aContent, aShell)
 {
+  mFlags |= eComboboxAccessible;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLComboboxAccessible: nsAccessible
 
 PRUint32
 nsHTMLComboboxAccessible::NativeRole()
 {
@@ -713,97 +630,64 @@ nsHTMLComboboxAccessible::NativeState()
 {
   // As a nsHTMLComboboxAccessible we can have the following states:
   // FOCUSED, FOCUSABLE, HASPOPUP, EXPANDED, COLLAPSED
   // Get focus status from base class
   PRUint64 state = nsAccessible::NativeState();
 
   nsIFrame *frame = GetBoundsFrame();
   nsIComboboxControlFrame *comboFrame = do_QueryFrame(frame);
-  if (comboFrame && comboFrame->IsDroppedDown()) {
+  if (comboFrame && comboFrame->IsDroppedDown())
     state |= states::EXPANDED;
-  }
-  else {
-    state &= ~states::FOCUSED; // Focus is on an option
+  else
     state |= states::COLLAPSED;
-  }
 
-  state |= states::HASPOPUP | states::FOCUSABLE;
-
+  state |= states::HASPOPUP;
   return state;
 }
 
 void
 nsHTMLComboboxAccessible::Description(nsString& aDescription)
 {
   aDescription.Truncate();
   // First check to see if combo box itself has a description, perhaps through
   // tooltip (title attribute) or via aria-describedby
   nsAccessible::Description(aDescription);
   if (!aDescription.IsEmpty())
     return;
-  // Use description of currently focused option
-  nsAccessible *option = GetFocusedOptionAccessible();
+
+  // Otherwise use description of selected option.
+  nsAccessible* option = SelectedOption();
   if (option)
     option->Description(aDescription);
 }
 
-nsAccessible *
-nsHTMLComboboxAccessible::GetFocusedOptionAccessible()
-{
-  if (IsDefunct())
-    return nsnull;
-
-  nsCOMPtr<nsIContent> focusedOption =
-    nsHTMLSelectOptionAccessible::GetFocusedOption(mContent);
-  if (!focusedOption) {
-    return nsnull;
-  }
-
-  return GetAccService()->GetAccessibleInWeakShell(focusedOption,
-                                                   mWeakShell);
-}
-
-/**
-  * MSAA/ATK accessible value != HTML value, especially not in combo boxes.
-  * Our accessible value is the text label for of our ( first ) selected child.
-  * The easiest way to get this is from the first child which is the readonly textfield.
-  */
 NS_IMETHODIMP nsHTMLComboboxAccessible::GetValue(nsAString& aValue)
 {
-  // Use accessible name of currently focused option.
-  nsAccessible *option = GetFocusedOptionAccessible();
+  // Use accessible name of selected option.
+  nsAccessible* option = SelectedOption();
   return option ? option->GetName(aValue) : NS_OK;
 }
 
 PRUint8
 nsHTMLComboboxAccessible::ActionCount()
 {
   return 1;
 }
 
-/**
-  * Programmaticaly toggle the combo box
-  */
-NS_IMETHODIMP nsHTMLComboboxAccessible::DoAction(PRUint8 aIndex)
+NS_IMETHODIMP
+nsHTMLComboboxAccessible::DoAction(PRUint8 aIndex)
 {
-  if (aIndex != nsHTMLComboboxAccessible::eAction_Click) {
+  if (aIndex != eAction_Click)
     return NS_ERROR_INVALID_ARG;
-  }
-  nsIFrame *frame = GetFrame();
-  if (!frame) {
+
+  if (IsDefunct())
     return NS_ERROR_FAILURE;
-  }
-  nsIComboboxControlFrame *comboFrame = do_QueryFrame(frame);
-  if (!comboFrame) {
-    return NS_ERROR_FAILURE;
-  }
-  // Reverse whether it's dropped down or not
-  comboFrame->ShowDropDown(!comboFrame->IsDroppedDown());
 
+  DoCommand();
   return NS_OK;
 }
 
 /**
   * Our action name is the reverse of our state: 
   *     if we are closed -> open is our name.
   *     if we are open -> closed is our name.
   * Uses the frame to get the state, updated on every click
@@ -824,16 +708,73 @@ NS_IMETHODIMP nsHTMLComboboxAccessible::
   if (comboFrame->IsDroppedDown())
     aName.AssignLiteral("close"); 
   else
     aName.AssignLiteral("open"); 
 
   return NS_OK;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLComboboxAccessible: Widgets
+
+bool
+nsHTMLComboboxAccessible::IsWidget() const
+{
+  return true;
+}
+
+bool
+nsHTMLComboboxAccessible::IsActiveWidget() const
+{
+  return FocusMgr()->HasDOMFocus(mContent);
+}
+
+bool
+nsHTMLComboboxAccessible::AreItemsOperable() const
+{
+  nsIComboboxControlFrame* comboboxFrame = do_QueryFrame(GetFrame());
+  return comboboxFrame && comboboxFrame->IsDroppedDown();
+}
+
+nsAccessible*
+nsHTMLComboboxAccessible::CurrentItem()
+{
+  // No current item for collapsed combobox.
+  return SelectedOption(true);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLComboboxAccessible: protected
+
+nsAccessible*
+nsHTMLComboboxAccessible::SelectedOption(bool aIgnoreIfCollapsed) const
+{
+  nsIFrame* frame = GetFrame();
+  nsIComboboxControlFrame* comboboxFrame = do_QueryFrame(frame);
+  if (comboboxFrame) {
+    if (aIgnoreIfCollapsed && !comboboxFrame->IsDroppedDown())
+      return nsnull;
+
+    frame = comboboxFrame->GetDropDown();
+  }
+
+  nsIListControlFrame* listControlFrame = do_QueryFrame(frame);
+  if (listControlFrame) {
+    nsCOMPtr<nsIContent> activeOptionNode = listControlFrame->GetCurrentOption();
+    if (activeOptionNode) {
+      nsDocAccessible* document = GetDocAccessible();
+      if (document)
+        return document->GetAccessible(activeOptionNode);
+    }
+  }
+
+  return nsnull;
+}
+
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLComboboxListAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsHTMLComboboxListAccessible::
   nsHTMLComboboxListAccessible(nsIAccessible *aParent, nsIContent *aContent,
                                nsIWeakReference *aShell) :
--- a/accessible/src/html/nsHTMLSelectAccessible.h
+++ b/accessible/src/html/nsHTMLSelectAccessible.h
@@ -75,16 +75,22 @@ public:
   virtual PRUint32 NativeRole();
   virtual PRUint64 NativeState();
 
   // SelectAccessible
   virtual bool IsSelect();
   virtual bool SelectAll();
   virtual bool UnselectAll();
 
+  // Widgets
+  virtual bool IsWidget() const;
+  virtual bool IsActiveWidget() const;
+  virtual bool AreItemsOperable() const;
+  virtual nsAccessible* CurrentItem();
+
 protected:
 
   // nsAccessible
   virtual void CacheChildren();
 
   // nsHTMLSelectListAccessible
 
   /**
@@ -102,34 +108,32 @@ public:
   enum { eAction_Select = 0 };  
   
   nsHTMLSelectOptionAccessible(nsIContent *aContent, nsIWeakReference *aShell);
   virtual ~nsHTMLSelectOptionAccessible() {}
 
   // nsIAccessible
   NS_IMETHOD DoAction(PRUint8 index);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
-  NS_IMETHOD SetSelected(PRBool aSelect);
+  NS_IMETHOD SetSelected(bool aSelect);
 
   // nsAccessible
   virtual nsresult GetNameInternal(nsAString& aName);
   virtual PRUint32 NativeRole();
   virtual PRUint64 NativeState();
 
   virtual PRInt32 GetLevelInternal();
   virtual void GetPositionAndSizeInternal(PRInt32 *aPosInSet,
                                           PRInt32 *aSetSize);
 
   // ActionAccessible
   virtual PRUint8 ActionCount();
 
-  /**
-   * Return focused option if any.
-   */
-  static already_AddRefed<nsIContent> GetFocusedOption(nsIContent *aListNode);
+  // Widgets
+  virtual nsAccessible* ContainerWidget() const;
 
   static void SelectionChangedIfOption(nsIContent *aPossibleOption);
 
 protected:
   // nsAccessible
   virtual nsIFrame* GetBoundsFrame();
 
 private:
@@ -197,26 +201,30 @@ public:
   virtual void Description(nsString& aDescription);
   virtual PRUint32 NativeRole();
   virtual PRUint64 NativeState();
   virtual void InvalidateChildren();
 
   // ActionAccessible
   virtual PRUint8 ActionCount();
 
+  // Widgets
+  virtual bool IsWidget() const;
+  virtual bool IsActiveWidget() const;
+  virtual bool AreItemsOperable() const;
+  virtual nsAccessible* CurrentItem();
+
 protected:
   // nsAccessible
   virtual void CacheChildren();
 
-  // nsHTMLComboboxAccessible
-
   /**
-   * Return focused option accessible.
+   * Return selected option.
    */
-  nsAccessible *GetFocusedOptionAccessible();
+  nsAccessible* SelectedOption(bool aIgnoreIfCollapsed = false) const;
 
 private:
   nsRefPtr<nsHTMLComboboxListAccessible> mListAccessible;
 };
 
 /*
  * A class that represents the window that lives to the right
  * of the drop down button inside the Select. This is the window
--- a/accessible/src/html/nsHTMLTableAccessible.cpp
+++ b/accessible/src/html/nsHTMLTableAccessible.cpp
@@ -101,17 +101,17 @@ nsHTMLTableCellAccessible::NativeState()
 {
   PRUint64 state = nsHyperTextAccessibleWrap::NativeState();
 
   nsIFrame *frame = mContent->GetPrimaryFrame();
   NS_ASSERTION(frame, "No frame for valid cell accessible!");
 
   if (frame) {
     state |= states::SELECTABLE;
-    PRBool isSelected = PR_FALSE;
+    bool isSelected = false;
     frame->GetSelected(&isSelected);
     if (isSelected)
       state |= states::SELECTED;
   }
 
   return state;
 }
 
@@ -240,17 +240,17 @@ nsHTMLTableCellAccessible::GetRowHeaderC
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   return GetHeaderCells(nsAccUtils::eRowHeaderCells, aHeaderCells);
 }
 
 NS_IMETHODIMP
-nsHTMLTableCellAccessible::IsSelected(PRBool *aIsSelected)
+nsHTMLTableCellAccessible::IsSelected(bool *aIsSelected)
 {
   NS_ENSURE_ARG_POINTER(aIsSelected);
   *aIsSelected = PR_FALSE;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   PRInt32 rowIdx = -1, colIdx = -1;
@@ -487,17 +487,17 @@ nsHTMLTableAccessible::GetNameInternal(n
 }
 
 nsresult
 nsHTMLTableAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
 {
   nsresult rv = nsAccessibleWrap::GetAttributesInternal(aAttributes);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRBool isProbablyForLayout;
+  bool isProbablyForLayout;
   IsProbablyForLayout(&isProbablyForLayout);
   if (isProbablyForLayout) {
     nsAutoString oldValueUnused;
     aAttributes->SetStringProperty(NS_LITERAL_CSTRING("layout-guess"),
                                    NS_LITERAL_STRING("true"), oldValueUnused);
   }
   
   return NS_OK;
@@ -584,17 +584,17 @@ nsHTMLTableAccessible::GetSelectedCellCo
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsITableLayout *tableLayout = GetTableLayout();
   NS_ENSURE_STATE(tableLayout);
 
   nsCOMPtr<nsIDOMElement> domElement;
   PRInt32 startRowIndex = 0, startColIndex = 0,
     rowSpan, colSpan, actualRowSpan, actualColSpan;
-  PRBool isSelected = PR_FALSE;
+  bool isSelected = false;
 
   PRInt32 rowIndex;
   for (rowIndex = 0; rowIndex < rowCount; rowIndex++) {
     PRInt32 columnIndex;
     for (columnIndex = 0; columnIndex < columnCount; columnIndex++) {
       rv = tableLayout->GetCellDataAt(rowIndex, columnIndex,
                                       *getter_AddRefs(domElement),
                                       startRowIndex, startColIndex,
@@ -619,17 +619,17 @@ nsHTMLTableAccessible::GetSelectedColumn
   *aCount = 0;
 
   PRInt32 count = 0;
   nsresult rv = GetColumnCount(&count);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32 index;
   for (index = 0; index < count; index++) {
-    PRBool state = PR_FALSE;
+    bool state = false;
     rv = IsColumnSelected(index, &state);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (state)
       (*aCount)++;
   }
 
   return NS_OK;
@@ -642,17 +642,17 @@ nsHTMLTableAccessible::GetSelectedRowCou
   *aCount = 0;
 
   PRInt32 count = 0;
   nsresult rv = GetRowCount(&count);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32 index;
   for (index = 0; index < count; index++) {
-    PRBool state = PR_FALSE;
+    bool state = false;
     rv = IsRowSelected(index, &state);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (state)
       (*aCount)++;
   }
 
   return NS_OK;
@@ -677,17 +677,17 @@ nsHTMLTableAccessible::GetSelectedCells(
 
   nsCOMPtr<nsIMutableArray> selCells =
     do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIDOMElement> cellElement;
   PRInt32 startRowIndex = 0, startColIndex = 0,
     rowSpan, colSpan, actualRowSpan, actualColSpan;
-  PRBool isSelected = PR_FALSE;
+  bool isSelected = false;
 
   PRInt32 rowIndex, index;
   for (rowIndex = 0, index = 0; rowIndex < rowCount; rowIndex++) {
     PRInt32 columnIndex;
     for (columnIndex = 0; columnIndex < columnCount; columnIndex++, index++) {
       rv = tableLayout->GetCellDataAt(rowIndex, columnIndex,
                                       *getter_AddRefs(cellElement),
                                       startRowIndex, startColIndex,
@@ -727,20 +727,20 @@ nsHTMLTableAccessible::GetSelectedCellIn
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsITableLayout *tableLayout = GetTableLayout();
   NS_ENSURE_STATE(tableLayout);
 
   nsCOMPtr<nsIDOMElement> domElement;
   PRInt32 startRowIndex = 0, startColIndex = 0,
     rowSpan, colSpan, actualRowSpan, actualColSpan;
-  PRBool isSelected = PR_FALSE;
+  bool isSelected = false;
 
   PRInt32 cellsCount = columnCount * rowCount;
-  nsAutoArrayPtr<PRBool> states(new PRBool[cellsCount]);
+  nsAutoArrayPtr<bool> states(new bool[cellsCount]);
   NS_ENSURE_TRUE(states, NS_ERROR_OUT_OF_MEMORY);
 
   PRInt32 rowIndex, index;
   for (rowIndex = 0, index = 0; rowIndex < rowCount; rowIndex++) {
     PRInt32 columnIndex;
     for (columnIndex = 0; columnIndex < columnCount; columnIndex++, index++) {
       rv = tableLayout->GetCellDataAt(rowIndex, columnIndex,
                                       *getter_AddRefs(domElement),
@@ -784,17 +784,17 @@ nsHTMLTableAccessible::GetSelectedColumn
                                                 PRInt32 **aColumns)
 {
   nsresult rv = NS_OK;
 
   PRInt32 columnCount;
   rv = GetColumnCount(&columnCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRBool *states = new PRBool[columnCount];
+  bool *states = new bool[columnCount];
   NS_ENSURE_TRUE(states, NS_ERROR_OUT_OF_MEMORY);
 
   *aNumColumns = 0;
   PRInt32 index;
   for (index = 0; index < columnCount; index++) {
     rv = IsColumnSelected(index, &states[index]);
     NS_ENSURE_SUCCESS(rv, rv);
 
@@ -826,17 +826,17 @@ nsHTMLTableAccessible::GetSelectedRowInd
                                              PRInt32 **aRows)
 {
   nsresult rv = NS_OK;
 
   PRInt32 rowCount;
   rv = GetRowCount(&rowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRBool *states = new PRBool[rowCount];
+  bool *states = new bool[rowCount];
   NS_ENSURE_TRUE(states, NS_ERROR_OUT_OF_MEMORY);
 
   *aNumRows = 0;
   PRInt32 index;
   for (index = 0; index < rowCount; index++) {
     rv = IsRowSelected(index, &states[index]);
     NS_ENSURE_SUCCESS(rv, rv);
 
@@ -965,17 +965,17 @@ nsHTMLTableAccessible::GetColumnExtentAt
                                          PRInt32 aColumnIndex,
                                          PRInt32 *aExtentCount)
 {
   nsITableLayout *tableLayout = GetTableLayout();
   NS_ENSURE_STATE(tableLayout);
 
   nsCOMPtr<nsIDOMElement> domElement;
   PRInt32 startRowIndex, startColIndex, rowSpan, colSpan, actualRowSpan;
-  PRBool isSelected;
+  bool isSelected;
 
   nsresult rv = tableLayout->
     GetCellDataAt(aRowIndex, aColumnIndex, *getter_AddRefs(domElement),
                   startRowIndex, startColIndex, rowSpan, colSpan,
                   actualRowSpan, *aExtentCount, isSelected);
 
   return (rv == NS_TABLELAYOUT_CELL_NOT_FOUND) ? NS_ERROR_INVALID_ARG : NS_OK;
 }
@@ -984,17 +984,17 @@ NS_IMETHODIMP
 nsHTMLTableAccessible::GetRowExtentAt(PRInt32 aRowIndex, PRInt32 aColumnIndex,
                                       PRInt32 *aExtentCount)
 {
   nsITableLayout *tableLayout = GetTableLayout();
   NS_ENSURE_STATE(tableLayout);
 
   nsCOMPtr<nsIDOMElement> domElement;
   PRInt32 startRowIndex, startColIndex, rowSpan, colSpan, actualColSpan;
-  PRBool isSelected;
+  bool isSelected;
 
   nsresult rv = tableLayout->
     GetCellDataAt(aRowIndex, aColumnIndex, *getter_AddRefs(domElement),
                   startRowIndex, startColIndex, rowSpan, colSpan,
                   *aExtentCount, actualColSpan, isSelected);
 
   return (rv == NS_TABLELAYOUT_CELL_NOT_FOUND) ? NS_ERROR_INVALID_ARG : NS_OK;
 }
@@ -1007,78 +1007,78 @@ nsHTMLTableAccessible::GetColumnDescript
 
 NS_IMETHODIMP
 nsHTMLTableAccessible::GetRowDescription(PRInt32 aRow, nsAString &_retval)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
-nsHTMLTableAccessible::IsColumnSelected(PRInt32 aColumn, PRBool *aIsSelected)
+nsHTMLTableAccessible::IsColumnSelected(PRInt32 aColumn, bool *aIsSelected)
 {
   NS_ENSURE_ARG_POINTER(aIsSelected);
   *aIsSelected = PR_FALSE;
 
   PRInt32 colCount = 0;
   nsresult rv = GetColumnCount(&colCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aColumn < 0 || aColumn >= colCount)
     return NS_ERROR_INVALID_ARG;
 
   PRInt32 rowCount = 0;
   rv = GetRowCount(&rowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   for (PRInt32 rowIdx = 0; rowIdx < rowCount; rowIdx++) {
-    PRBool isSelected = PR_FALSE;
+    bool isSelected = false;
     rv = IsCellSelected(rowIdx, aColumn, &isSelected);
     if (NS_SUCCEEDED(rv)) {
       *aIsSelected = isSelected;
       if (!isSelected)
         break;
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHTMLTableAccessible::IsRowSelected(PRInt32 aRow, PRBool *aIsSelected)
+nsHTMLTableAccessible::IsRowSelected(PRInt32 aRow, bool *aIsSelected)
 {
   NS_ENSURE_ARG_POINTER(aIsSelected);
   *aIsSelected = PR_FALSE;
 
   PRInt32 rowCount = 0;
   nsresult rv = GetRowCount(&rowCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (aRow < 0 || aRow >= rowCount)
     return NS_ERROR_INVALID_ARG;
 
   PRInt32 colCount = 0;
   rv = GetColumnCount(&colCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   for (PRInt32 colIdx = 0; colIdx < colCount; colIdx++) {
-    PRBool isSelected = PR_FALSE;
+    bool isSelected = false;
     rv = IsCellSelected(aRow, colIdx, &isSelected);
     if (NS_SUCCEEDED(rv)) {
       *aIsSelected = isSelected;
       if (!isSelected)
         break;
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLTableAccessible::IsCellSelected(PRInt32 aRow, PRInt32 aColumn,
-                                      PRBool *aIsSelected)
+                                      bool *aIsSelected)
 {
   NS_ENSURE_ARG_POINTER(aIsSelected);
   *aIsSelected = PR_FALSE;
 
   nsITableLayout *tableLayout = GetTableLayout();
   NS_ENSURE_STATE(tableLayout);
 
   nsCOMPtr<nsIDOMElement> domElement;
@@ -1150,25 +1150,25 @@ nsHTMLTableAccessible::UnselectColumn(PR
                                      nsISelectionPrivate::TABLESELECTION_COLUMN,
                                      PR_FALSE);
 }
 
 nsresult
 nsHTMLTableAccessible::AddRowOrColumnToSelection(PRInt32 aIndex,
                                                  PRUint32 aTarget)
 {
-  PRBool doSelectRow = (aTarget == nsISelectionPrivate::TABLESELECTION_ROW);
+  bool doSelectRow = (aTarget == nsISelectionPrivate::TABLESELECTION_ROW);
 
   nsITableLayout *tableLayout = GetTableLayout();
   NS_ENSURE_STATE(tableLayout);
 
   nsCOMPtr<nsIDOMElement> cellElm;
   PRInt32 startRowIdx, startColIdx, rowSpan, colSpan,
     actualRowSpan, actualColSpan;
-  PRBool isSelected = PR_FALSE;
+  bool isSelected = false;
 
   nsresult rv = NS_OK;
   PRInt32 count = 0;
   if (doSelectRow)
     rv = GetColumnCount(&count);
   else
     rv = GetRowCount(&count);
 
@@ -1196,26 +1196,26 @@ nsHTMLTableAccessible::AddRowOrColumnToS
   }
 
   return NS_OK;
 }
 
 nsresult
 nsHTMLTableAccessible::RemoveRowsOrColumnsFromSelection(PRInt32 aIndex,
                                                         PRUint32 aTarget,
-                                                        PRBool aIsOuter)
+                                                        bool aIsOuter)
 {
   nsITableLayout *tableLayout = GetTableLayout();
   NS_ENSURE_STATE(tableLayout);
 
   nsCOMPtr<nsIPresShell> presShell(GetPresShell());
   nsRefPtr<nsFrameSelection> tableSelection =
     const_cast<nsFrameSelection*>(presShell->ConstFrameSelection());
 
-  PRBool doUnselectRow = (aTarget == nsISelectionPrivate::TABLESELECTION_ROW);
+  bool doUnselectRow = (aTarget == nsISelectionPrivate::TABLESELECTION_ROW);
   PRInt32 count = 0;
   nsresult rv = doUnselectRow ? GetColumnCount(&count) : GetRowCount(&count);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32 startRowIdx = doUnselectRow ? aIndex : 0;
   PRInt32 endRowIdx = doUnselectRow ? aIndex : count - 1;
   PRInt32 startColIdx = doUnselectRow ? 0 : aIndex;
   PRInt32 endColIdx = doUnselectRow ? count - 1 : aIndex;
@@ -1243,17 +1243,17 @@ nsHTMLTableAccessible::GetTableLayout()
 
 nsresult
 nsHTMLTableAccessible::GetCellAt(PRInt32        aRowIndex,
                                  PRInt32        aColIndex,
                                  nsIDOMElement* &aCell)
 {
   PRInt32 startRowIndex = 0, startColIndex = 0,
           rowSpan, colSpan, actualRowSpan, actualColSpan;
-  PRBool isSelected;
+  bool isSelected;
 
   nsITableLayout *tableLayout = GetTableLayout();
   NS_ENSURE_STATE(tableLayout);
 
   nsresult rv = tableLayout->
     GetCellDataAt(aRowIndex, aColIndex, aCell, startRowIndex, startColIndex,
                   rowSpan, colSpan, actualRowSpan, actualColSpan, isSelected);
 
@@ -1285,29 +1285,29 @@ nsHTMLTableAccessible::Description(nsStr
         mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::summary,
                           aDescription);
       }
     }
   }
 
 #ifdef SHOW_LAYOUT_HEURISTIC
   if (aDescription.IsEmpty()) {
-    PRBool isProbablyForLayout;
+    bool isProbablyForLayout;
     IsProbablyForLayout(&isProbablyForLayout);
     aDescription = mLayoutHeuristic;
   }
 #ifdef DEBUG_A11Y
   printf("\nTABLE: %s\n", NS_ConvertUTF16toUTF8(mLayoutHeuristic).get());
 #endif
 #endif
 }
 
-PRBool
+bool
 nsHTMLTableAccessible::HasDescendant(const nsAString& aTagName,
-                                     PRBool aAllowEmpty)
+                                     bool aAllowEmpty)
 {
   nsCOMPtr<nsIDOMElement> tableElt(do_QueryInterface(mContent));
   NS_ENSURE_TRUE(tableElt, PR_FALSE);
 
   nsCOMPtr<nsIDOMNodeList> nodeList;
   tableElt->GetElementsByTagName(aTagName, getter_AddRefs(nodeList));
   NS_ENSURE_TRUE(nodeList, PR_FALSE);
 
@@ -1336,17 +1336,17 @@ nsHTMLTableAccessible::HasDescendant(con
   // caption element only. On another hand we create accessible object for
   // the first entry of caption element (see
   // nsHTMLTableAccessible::CacheChildren).
   nodeList->Item(1, getter_AddRefs(foundItem));
   return !!foundItem;
 }
 
 NS_IMETHODIMP
-nsHTMLTableAccessible::IsProbablyForLayout(PRBool *aIsProbablyForLayout)
+nsHTMLTableAccessible::IsProbablyForLayout(bool *aIsProbablyForLayout)
 {
   // Implement a heuristic to determine if table is most likely used for layout
   // XXX do we want to look for rowspan or colspan, especialy that span all but a couple cells
   // at the beginning or end of a row/col, and especially when they occur at the edge of a table?
   // XXX expose this info via object attributes to AT-SPI
 
   // 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
@@ -1355,72 +1355,104 @@ nsHTMLTableAccessible::IsProbablyForLayo
 #define RETURN_LAYOUT_ANSWER(isLayout, heuristic) \
   { *aIsProbablyForLayout = isLayout; \
     mLayoutHeuristic = isLayout ? NS_LITERAL_STRING("layout table: ") : NS_LITERAL_STRING("data table: "); \
     mLayoutHeuristic += NS_LITERAL_STRING(heuristic); return NS_OK; }
 #else
 #define RETURN_LAYOUT_ANSWER(isLayout, heuristic) { *aIsProbablyForLayout = isLayout; return NS_OK; }
 #endif
 
-  *aIsProbablyForLayout = PR_FALSE;
+  *aIsProbablyForLayout = false;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   nsDocAccessible *docAccessible = GetDocAccessible();
   if (docAccessible) {
     PRUint64 docState = docAccessible->State();
     if (docState & states::EDITABLE) {  // Need to see all elements while document is being edited
-      RETURN_LAYOUT_ANSWER(PR_FALSE, "In editable document");
+      RETURN_LAYOUT_ANSWER(false, "In editable document");
     }
   }
 
   // Check to see if an ARIA role overrides the role from native markup,
   // but for which we still expose table semantics (treegrid, for example).
-  PRBool hasNonTableRole = (Role() != nsIAccessibleRole::ROLE_TABLE);
+  bool hasNonTableRole = (Role() != nsIAccessibleRole::ROLE_TABLE);
   if (hasNonTableRole) {
-    RETURN_LAYOUT_ANSWER(PR_FALSE, "Has role attribute");
+    RETURN_LAYOUT_ANSWER(false, "Has role attribute");
   }
 
   if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::role)) {
     // Role attribute is present, but overridden roles have already been dealt with.
     // Only landmarks and other roles that don't override the role from native
     // markup are left to deal with here.
-    RETURN_LAYOUT_ANSWER(PR_FALSE, "Has role attribute, weak role, and role is table");
+    RETURN_LAYOUT_ANSWER(false, "Has role attribute, weak role, and role is table");
   }
-  
-  // Check for legitimate data table elements or attributes
+
+  // Check for legitimate data table attributes.
   nsAutoString summary;
-  if ((mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::summary, summary) &&
-       !summary.IsEmpty()) || 
-      HasDescendant(NS_LITERAL_STRING("caption"), PR_FALSE) ||
-      HasDescendant(NS_LITERAL_STRING("th")) ||
-      HasDescendant(NS_LITERAL_STRING("thead")) ||
-      HasDescendant(NS_LITERAL_STRING("tfoot")) ||
-      HasDescendant(NS_LITERAL_STRING("colgroup"))) {
-    RETURN_LAYOUT_ANSWER(PR_FALSE, "Has caption, summary, th, thead, tfoot or colgroup -- legitimate table structures");
+  if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::summary, summary) &&
+      !summary.IsEmpty())
+    RETURN_LAYOUT_ANSWER(false, "Has summary -- legitimate table structures");
+
+  // Check for legitimate data table elements.
+  nsAccessible* caption = FirstChild();
+  if (caption && caption->Role() == nsIAccessibleRole::ROLE_CAPTION &&
+      caption->HasChildren()) {
+    RETURN_LAYOUT_ANSWER(false,
+                               "Not empty caption -- legitimate table structures");
   }
+
+  for (nsIContent* childElm = mContent->GetFirstChild(); childElm;
+       childElm = childElm->GetNextSibling()) {
+    if (!childElm->IsHTML())
+      continue;
+
+    if (childElm->Tag() == nsGkAtoms::col ||
+        childElm->Tag() == nsGkAtoms::colgroup ||
+        childElm->Tag() == nsGkAtoms::tfoot ||
+        childElm->Tag() == nsGkAtoms::thead) {
+      RETURN_LAYOUT_ANSWER(false,
+                           "Has col, colgroup, tfoot or thead -- legitimate table structures");
+    }
+
+    if (childElm->Tag() == nsGkAtoms::tbody) {
+      for (nsIContent* rowElm = childElm->GetFirstChild(); rowElm;
+           rowElm = rowElm->GetNextSibling()) {
+        if (rowElm->IsHTML() && rowElm->Tag() == nsGkAtoms::tr) {
+          for (nsIContent* cellElm = rowElm->GetFirstChild(); cellElm;
+               cellElm = cellElm->GetNextSibling()) {
+            if (cellElm->IsHTML() && cellElm->Tag() == nsGkAtoms::th) {
+              RETURN_LAYOUT_ANSWER(false,
+                                   "Has th -- legitimate table structures");
+            }
+          }
+        }
+      }
+    }
+  }
+
   if (HasDescendant(NS_LITERAL_STRING("table"))) {
-    RETURN_LAYOUT_ANSWER(PR_TRUE, "Has a nested table within it");
+    RETURN_LAYOUT_ANSWER(true, "Has a nested table within it");
   }
   
   // If only 1 column or only 1 row, it's for layout
   PRInt32 columns, rows;
   GetColumnCount(&columns);
   if (columns <=1) {
-    RETURN_LAYOUT_ANSWER(PR_TRUE, "Has only 1 column");
+    RETURN_LAYOUT_ANSWER(true, "Has only 1 column");
   }
   GetRowCount(&rows);
   if (rows <=1) {
-    RETURN_LAYOUT_ANSWER(PR_TRUE, "Has only 1 row");
+    RETURN_LAYOUT_ANSWER(true, "Has only 1 row");
   }
 
   // Check for many columns
   if (columns >= 5) {
-    RETURN_LAYOUT_ANSWER(PR_FALSE, ">=5 columns");
+    RETURN_LAYOUT_ANSWER(false, ">=5 columns");
   }
   
   // Now we know there are 2-4 columns and 2 or more rows
   // Check to see if there are visible borders on the cells
   // XXX currently, we just check the first cell -- do we really need to do more?
   nsCOMPtr<nsIDOMElement> cellElement;
   nsresult rv = GetCellAt(0, 0, *getter_AddRefs(cellElement));
   NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
@@ -1429,17 +1461,17 @@ nsHTMLTableAccessible::IsProbablyForLayo
   NS_ENSURE_TRUE(cellContent, NS_ERROR_FAILURE);
   nsIFrame *cellFrame = cellContent->GetPrimaryFrame();
   if (!cellFrame) {
     return NS_OK;
   }
   nsMargin border;
   cellFrame->GetBorder(border);
   if (border.top && border.bottom && border.left && border.right) {
-    RETURN_LAYOUT_ANSWER(PR_FALSE, "Has nonzero border-width on table cell");
+    RETURN_LAYOUT_ANSWER(false, "Has nonzero border-width on table cell");
   }
 
   /**
    * Rules for non-bordered tables with 2-4 columns and 2+ rows from here on forward
    */
 
   // Check for styled background color across the row
   // Alternating background color is a common way 
@@ -1457,31 +1489,31 @@ nsHTMLTableAccessible::IsProbablyForLayo
 
     nsCOMPtr<nsIDOMCSSStyleDeclaration> styleDecl =
       nsCoreUtils::GetComputedStyleDeclaration(EmptyString(), rowContent);
     NS_ENSURE_TRUE(styleDecl, NS_ERROR_FAILURE);
 
     lastRowColor = color;
     styleDecl->GetPropertyValue(NS_LITERAL_STRING("background-color"), color);
     if (rowCount > 0 && PR_FALSE == lastRowColor.Equals(color)) {
-      RETURN_LAYOUT_ANSWER(PR_FALSE, "2 styles of row background color, non-bordered");
+      RETURN_LAYOUT_ANSWER(false, "2 styles of row background color, non-bordered");
     }
   }
 
   // Check for many rows
   const PRInt32 kMaxLayoutRows = 20;
   if (rows > kMaxLayoutRows) { // A ton of rows, this is probably for data
-    RETURN_LAYOUT_ANSWER(PR_FALSE, ">= kMaxLayoutRows (20) and non-bordered");
+    RETURN_LAYOUT_ANSWER(false, ">= kMaxLayoutRows (20) and non-bordered");
   }
 
   // Check for very wide table
   nsAutoString styledWidth;
   GetComputedStyleValue(EmptyString(), NS_LITERAL_STRING("width"), styledWidth);
   if (styledWidth.EqualsLiteral("100%")) {
-    RETURN_LAYOUT_ANSWER(PR_TRUE, "<=4 columns and 100% width");
+    RETURN_LAYOUT_ANSWER(true, "<=4 columns and 100% width");
   }
   if (styledWidth.Find(NS_LITERAL_STRING("px"))) { // Hardcoded in pixels
     nsIFrame *tableFrame = GetFrame();
     NS_ENSURE_TRUE(tableFrame , NS_ERROR_FAILURE);
     nsSize tableSize  = tableFrame->GetSize();
 
     nsDocAccessible *docAccessible = GetDocAccessible();
     NS_ENSURE_TRUE(docAccessible, NS_ERROR_FAILURE);
@@ -1489,34 +1521,34 @@ nsHTMLTableAccessible::IsProbablyForLayo
     NS_ENSURE_TRUE(docFrame , NS_ERROR_FAILURE);
 
     nsSize docSize = docFrame->GetSize();
     if (docSize.width > 0) {
       PRInt32 percentageOfDocWidth = (100 * tableSize.width) / docSize.width;
       if (percentageOfDocWidth > 95) {
         // 3-4 columns, no borders, not a lot of rows, and 95% of the doc's width
         // Probably for layout
-        RETURN_LAYOUT_ANSWER(PR_TRUE, "<=4 columns, width hardcoded in pixels and 95% of document width");
+        RETURN_LAYOUT_ANSWER(true, "<=4 columns, width hardcoded in pixels and 95% of document width");
       }
     }
   }
 
   // Two column rules
   if (rows * columns <= 10) {
-    RETURN_LAYOUT_ANSWER(PR_TRUE, "2-4 columns, 10 cells or less, non-bordered");
+    RETURN_LAYOUT_ANSWER(true, "2-4 columns, 10 cells or less, non-bordered");
   }
 
   if (HasDescendant(NS_LITERAL_STRING("embed")) ||
       HasDescendant(NS_LITERAL_STRING("object")) ||
       HasDescendant(NS_LITERAL_STRING("applet")) ||
       HasDescendant(NS_LITERAL_STRING("iframe"))) {
-    RETURN_LAYOUT_ANSWER(PR_TRUE, "Has no borders, and has iframe, object, applet or iframe, typical of advertisements");
+    RETURN_LAYOUT_ANSWER(true, "Has no borders, and has iframe, object, applet or iframe, typical of advertisements");
   }
 
-  RETURN_LAYOUT_ANSWER(PR_FALSE, "no layout factor strong enough, so will guess data");
+  RETURN_LAYOUT_ANSWER(false, "no layout factor strong enough, so will guess data");
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLCaptionAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 Relation
--- a/accessible/src/html/nsHTMLTableAccessible.h
+++ b/accessible/src/html/nsHTMLTableAccessible.h
@@ -181,26 +181,26 @@ protected:
    * @param  aIndex    [in] row or column index
    * @param  aTarget   [in] indicates whether row or column should unselected
    * @param  aIsOuter  [in] indicates whether all rows or column excepting
    *                    the given one should be unselected or the given one
    *                    should be unselected only
    */
   nsresult RemoveRowsOrColumnsFromSelection(PRInt32 aIndex,
                                             PRUint32 aTarget,
-                                            PRBool aIsOuter);
+                                            bool aIsOuter);
 
   /**
    * Return true if table has an element with the given tag name.
    *
    * @param  aTagName     [in] tag name of searched element
    * @param  aAllowEmpty  [in, optional] points if found element can be empty
    *                       or contain whitespace text only.
    */
-  PRBool HasDescendant(const nsAString& aTagName, PRBool aAllowEmpty = PR_TRUE);
+  bool HasDescendant(const nsAString& aTagName, bool aAllowEmpty = true);
 
 #ifdef SHOW_LAYOUT_HEURISTIC
   nsString mLayoutHeuristic;
 #endif
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsHTMLTableAccessible,
                               NS_TABLEACCESSIBLE_IMPL_CID)
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -282,17 +282,17 @@ nsHyperTextAccessible::GetPosAndText(PRI
   }
   if (aEndOffset == nsIAccessibleText::TEXT_OFFSET_CARET) {
     GetCaretOffset(&aEndOffset);
   }
 
   PRInt32 startOffset = aStartOffset;
   PRInt32 endOffset = aEndOffset;
   // XXX this prevents text interface usage on <input type="password">
-  PRBool isPassword = (Role() == nsIAccessibleRole::ROLE_PASSWORD_TEXT);
+  bool isPassword = (Role() == nsIAccessibleRole::ROLE_PASSWORD_TEXT);
 
   // Clear out parameters and set up loop
   if (aText) {
     aText->Truncate();
   }
   if (endOffset < 0) {
     const PRInt32 kMaxTextLength = 32767;
     endOffset = kMaxTextLength; // Max end offset
@@ -547,17 +547,17 @@ NS_IMETHODIMP nsHyperTextAccessible::Get
 
   return NS_ERROR_INVALID_ARG;
 }
 
 nsAccessible*
 nsHyperTextAccessible::DOMPointToHypertextOffset(nsINode *aNode,
                                                  PRInt32 aNodeOffset,
                                                  PRInt32 *aHyperTextOffset,
-                                                 PRBool aIsEndOffset)
+                                                 bool aIsEndOffset)
 {
   if (!aHyperTextOffset)
     return nsnull;
   *aHyperTextOffset = 0;
 
   if (!aNode)
     return nsnull;
 
@@ -716,17 +716,17 @@ nsHyperTextAccessible::HypertextOffsetsT
   *aEndOffset = -1;
 
   // If the given offsets are 0 and associated editor is empty then return
   // collapsed range with editor root element as range container.
   if (aStartHTOffset == 0 && aEndHTOffset == 0) {
     nsCOMPtr<nsIEditor> editor;
     GetAssociatedEditor(getter_AddRefs(editor));
     if (editor) {
-      PRBool isEmpty = PR_FALSE;
+      bool isEmpty = false;
       editor->GetDocumentIsEmpty(&isEmpty);
       if (isEmpty) {
         nsCOMPtr<nsIDOMElement> editorRootElm;
         editor->GetRootElement(getter_AddRefs(editorRootElm));
 
         nsCOMPtr<nsIDOMNode> editorRoot(do_QueryInterface(editorRootElm));
         if (editorRoot) {
           *aStartOffset = *aEndOffset = 0;
@@ -774,22 +774,22 @@ nsHyperTextAccessible::HypertextOffsetsT
 
 PRInt32
 nsHyperTextAccessible::GetRelativeOffset(nsIPresShell *aPresShell,
                                          nsIFrame *aFromFrame,
                                          PRInt32 aFromOffset,
                                          nsAccessible *aFromAccessible,
                                          nsSelectionAmount aAmount,
                                          nsDirection aDirection,
-                                         PRBool aNeedsStart)
+                                         bool aNeedsStart)
 {
-  const PRBool kIsJumpLinesOk = PR_TRUE;          // okay to jump lines
-  const PRBool kIsScrollViewAStop = PR_FALSE;     // do not stop at scroll views
-  const PRBool kIsKeyboardSelect = PR_TRUE;       // is keyboard selection
-  const PRBool kIsVisualBidi = PR_FALSE;          // use visual order for bidi text
+  const bool kIsJumpLinesOk = true;          // okay to jump lines
+  const bool kIsScrollViewAStop = false;     // do not stop at scroll views
+  const bool kIsKeyboardSelect = true;       // is keyboard selection
+  const bool kIsVisualBidi = false;          // use visual order for bidi text
 
   EWordMovementType wordMovementType = aNeedsStart ? eStartWord : eEndWord;
   if (aAmount == eSelectLine) {
     aAmount = (aDirection == eDirNext) ? eSelectEndLine : eSelectBeginLine;
   }
 
   // Ask layout for the new node and offset, after moving the appropriate amount
   nsPeekOffsetStruct pos;
@@ -923,17 +923,17 @@ nsresult nsHyperTextAccessible::GetTextH
       }
     }
   }
   else if (aOffset < 0) {
     return NS_ERROR_FAILURE;
   }
 
   nsSelectionAmount amount;
-  PRBool needsStart = PR_FALSE;
+  bool needsStart = false;
   switch (aBoundaryType) {
     case BOUNDARY_CHAR:
       amount = eSelectCluster;
       if (aType == eGetAt)
         aType = eGetAfter; // Avoid returning 2 characters
       break;
 
     case BOUNDARY_WORD_START:
@@ -1103,17 +1103,17 @@ NS_IMETHODIMP nsHyperTextAccessible::Get
 }
 
 // nsIPersistentProperties
 // nsIAccessibleText::getTextAttributes(in boolean includeDefAttrs,
 //                                      in long offset,
 //                                      out long rangeStartOffset,
 //                                      out long rangeEndOffset);
 NS_IMETHODIMP
-nsHyperTextAccessible::GetTextAttributes(PRBool aIncludeDefAttrs,
+nsHyperTextAccessible::GetTextAttributes(bool aIncludeDefAttrs,
                                          PRInt32 aOffset,
                                          PRInt32 *aStartOffset,
                                          PRInt32 *aEndOffset,
                                          nsIPersistentProperties **aAttributes)
 {
   // 1. Get each attribute and its ranges one after another.
   // 2. As we get each new attribute, we pass the current start and end offsets
   //    as in/out parameters. In other words, as attributes are collected,
@@ -1237,17 +1237,17 @@ nsHyperTextAccessible::GetAttributesInte
   // use 'display' attribute instead.
   nsIFrame *frame = GetFrame();
   if (frame && frame->GetType() == nsGkAtoms::blockFrame) {
     nsAutoString oldValueUnused;
     aAttributes->SetStringProperty(NS_LITERAL_CSTRING("formatting"), NS_LITERAL_STRING("block"),
                                    oldValueUnused);
   }
 
-  if (gLastFocusedNode == GetNode()) {
+  if (FocusMgr()->IsFocused(this)) {
     PRInt32 lineNumber = GetCaretLineNumber();
     if (lineNumber >= 1) {
       nsAutoString strLineNumber;
       strLineNumber.AppendInt(lineNumber);
       nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::lineNumber,
                              strLineNumber);
     }
   }
@@ -1623,23 +1623,19 @@ nsHyperTextAccessible::SetCaretOffset(PR
  */
 NS_IMETHODIMP
 nsHyperTextAccessible::GetCaretOffset(PRInt32 *aCaretOffset)
 {
   *aCaretOffset = -1;
 
   // No caret if the focused node is not inside this DOM node and this DOM node
   // is not inside of focused node.
-
-  nsINode* thisNode = GetNode();
-  PRBool isInsideOfFocusedNode =
-    nsCoreUtils::IsAncestorOf(gLastFocusedNode, thisNode);
-
-  if (!isInsideOfFocusedNode && thisNode != gLastFocusedNode &&
-      !nsCoreUtils::IsAncestorOf(thisNode, gLastFocusedNode))
+  FocusManager::FocusDisposition focusDisp =
+    FocusMgr()->IsInOrContainsFocus(this);
+  if (focusDisp == FocusManager::eNone)
     return NS_OK;
 
   // Turn the focus node and offset of the selection into caret hypretext
   // offset.
   nsCOMPtr<nsISelection> domSel;
   nsresult rv = GetSelections(nsISelectionController::SELECTION_NORMAL,
                               nsnull, getter_AddRefs(domSel));
   NS_ENSURE_SUCCESS(rv, rv);
@@ -1650,20 +1646,21 @@ nsHyperTextAccessible::GetCaretOffset(PR
 
   PRInt32 focusOffset;
   rv = domSel->GetFocusOffset(&focusOffset);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // No caret if this DOM node is inside of focused node but the selection's
   // focus point is not inside of this DOM node.
   nsCOMPtr<nsINode> focusNode(do_QueryInterface(focusDOMNode));
-  if (isInsideOfFocusedNode) {
+  if (focusDisp == FocusManager::eContainedByFocus) {
     nsINode *resultNode =
       nsCoreUtils::GetDOMNodeFromDOMPoint(focusNode, focusOffset);
 
+    nsINode* thisNode = GetNode();
     if (resultNode != thisNode &&
         !nsCoreUtils::IsAncestorOf(thisNode, resultNode))
       return NS_OK;
   }
 
   DOMPointToHypertextOffset(focusNode, focusOffset, aCaretOffset);
   return NS_OK;
 }
@@ -1803,17 +1800,17 @@ nsHyperTextAccessible::GetSelections(PRI
     nsCOMPtr<nsIDOMNode> startDOMNode(do_QueryInterface(startNode));
     nsresult rv = privSel->
       GetRangesForIntervalCOMArray(startDOMNode, 0, startDOMNode, childCount,
                                    PR_TRUE, aRanges);
     NS_ENSURE_SUCCESS(rv, rv);
     // Remove collapsed ranges
     PRInt32 numRanges = aRanges->Count();
     for (PRInt32 count = 0; count < numRanges; count ++) {
-      PRBool isCollapsed;
+      bool isCollapsed;
       (*aRanges)[count]->GetCollapsed(&isCollapsed);
       if (isCollapsed) {
         aRanges->RemoveObjectAt(count);
         -- numRanges;
         -- count;
       }
     }
   }
@@ -1902,17 +1899,17 @@ nsHyperTextAccessible::SetSelectionBound
                                           PRInt32 aEndOffset)
 {
   nsCOMPtr<nsISelection> domSel;
   nsresult rv = GetSelections(nsISelectionController::SELECTION_NORMAL,
                               nsnull, getter_AddRefs(domSel));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Caret is a collapsed selection
-  PRBool isOnlyCaret = (aStartOffset == aEndOffset);
+  bool isOnlyCaret = (aStartOffset == aEndOffset);
 
   PRInt32 rangeCount;
   domSel->GetRangeCount(&rangeCount);
   nsCOMPtr<nsIDOMRange> range;
   if (aSelectionNum == rangeCount) { // Add a range
     range = do_CreateInstance(kRangeCID);
     NS_ENSURE_TRUE(range, NS_ERROR_OUT_OF_MEMORY);
   }
@@ -2026,17 +2023,17 @@ nsHyperTextAccessible::ScrollSubstringTo
 
   rv = HypertextOffsetsToDOMRange(aStartIndex, aEndIndex,
                                   getter_AddRefs(startNode), &startOffset,
                                   getter_AddRefs(endNode), &endOffset);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsPresContext *presContext = frame->PresContext();
 
-  PRBool initialScrolled = PR_FALSE;
+  bool initialScrolled = false;
   nsIFrame *parentFrame = frame;
   while ((parentFrame = parentFrame->GetParent())) {
     nsIScrollableFrame *scrollableFrame = do_QueryFrame(parentFrame);
     if (scrollableFrame) {
       if (!initialScrolled) {
         // Scroll substring to the given point. Turn the point into percents
         // relative scrollable area to use nsCoreUtils::ScrollSubstringTo.
         nsIntRect frameRect = parentFrame->GetScreenRectExternal();
@@ -2081,17 +2078,17 @@ nsHyperTextAccessible::ScrollSubstringTo
 void
 nsHyperTextAccessible::InvalidateChildren()
 {
   mOffsets.Clear();
 
   nsAccessibleWrap::InvalidateChildren();
 }
 
-PRBool
+bool
 nsHyperTextAccessible::RemoveChild(nsAccessible* aAccessible)
 {
   PRInt32 childIndex = aAccessible->IndexInParent();
   PRInt32 count = mOffsets.Length() - childIndex;
   if (count > 0)
     mOffsets.RemoveElementsAt(childIndex, count);
 
   return nsAccessible::RemoveChild(aAccessible);
@@ -2177,17 +2174,17 @@ nsHyperTextAccessible::GetCharAt(PRInt32
   if (aEndOffset)
     *aEndOffset = aChar.IsEmpty() ? offset : offset + 1;
 
   return true;
 }
 
 PRInt32
 nsHyperTextAccessible::GetChildOffset(PRUint32 aChildIndex,
-                                      PRBool aInvalidateAfter)
+                                      bool aInvalidateAfter)
 {
   if (aChildIndex == 0) {
     if (aInvalidateAfter)
       mOffsets.Clear();
 
     return aChildIndex;
   }
 
@@ -2305,18 +2302,18 @@ nsHyperTextAccessible::GetDOMPointByFram
 
   NS_IF_ADDREF(*aNode = node);
   return NS_OK;
 }
 
 // nsHyperTextAccessible
 nsresult
 nsHyperTextAccessible::DOMRangeBoundToHypertextOffset(nsIDOMRange *aRange,
-                                                      PRBool aIsStartBound,
-                                                      PRBool aIsStartHTOffset,
+                                                      bool aIsStartBound,
+                                                      bool aIsStartHTOffset,
                                                       PRInt32 *aHTOffset)
 {
   nsCOMPtr<nsIDOMNode> DOMNode;
   PRInt32 nodeOffset = 0;
 
   nsresult rv;
   if (aIsStartBound) {
     rv = aRange->GetStartContainer(getter_AddRefs(DOMNode));
--- a/accessible/src/html/nsHyperTextAccessible.h
+++ b/accessible/src/html/nsHyperTextAccessible.h
@@ -85,17 +85,17 @@ public:
 
   // nsAccessible
   virtual PRInt32 GetLevelInternal();
   virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
   virtual PRUint32 NativeRole();
   virtual PRUint64 NativeState();
 
   virtual void InvalidateChildren();
-  virtual PRBool RemoveChild(nsAccessible* aAccessible);
+  virtual bool RemoveChild(nsAccessible* aAccessible);
 
   // nsHyperTextAccessible (static helper method)
 
   // Convert content offset to rendered text offset  
   static nsresult ContentToRenderedOffset(nsIFrame *aFrame, PRInt32 aContentOffset,
                                           PRUint32 *aRenderedOffset);
   
   // Convert rendered text offset to content offset
@@ -164,17 +164,17 @@ public:
     *
     * @return               the accessible child which contained the offset, if
     *                       it is within the current nsHyperTextAccessible,
     *                       otherwise nsnull
     */
   nsAccessible *DOMPointToHypertextOffset(nsINode *aNode,
                                           PRInt32 aNodeOffset,
                                           PRInt32 *aHypertextOffset,
-                                          PRBool aIsEndOffset = PR_FALSE);
+                                          bool aIsEndOffset = false);
 
   /**
    * Turn a hypertext offsets into DOM point.
    *
    * @param  aHTOffset  [in] the given start hypertext offset
    * @param  aNode      [out] start node
    * @param  aOffset    [out] offset inside the start node
    */
@@ -228,27 +228,27 @@ public:
    * Return text offset of the given child accessible within hypertext
    * accessible.
    *
    * @param  aChild           [in] accessible child to get text offset for
    * @param  aInvalidateAfter [in, optional] indicates whether invalidate
    *                           cached offsets for next siblings of the child
    */
   PRInt32 GetChildOffset(nsAccessible* aChild,
-                         PRBool aInvalidateAfter = PR_FALSE)
+                         bool aInvalidateAfter = false)
   {
     PRInt32 index = GetIndexOf(aChild);
     return index == -1 ? -1 : GetChildOffset(index, aInvalidateAfter);
   }
 
   /**
    * Return text offset for the child accessible index.
    */
   PRInt32 GetChildOffset(PRUint32 aChildIndex,
-                         PRBool aInvalidateAfter = PR_FALSE);
+                         bool aInvalidateAfter = false);
 
   /**
    * Return child accessible at the given text offset.
    *
    * @param  aOffset  [in] the given text offset
    */
   PRInt32 GetChildIndexAtOffset(PRUint32 aOffset);
 
@@ -308,17 +308,17 @@ protected:
     * @param  aDirection       forward or backward?
     * @param  aNeedsStart      for word and line cases, are we basing this on
     *                          the start or end?
     * @return                  the resulting offset into this hypertext
     */
   PRInt32 GetRelativeOffset(nsIPresShell *aPresShell, nsIFrame *aFromFrame,
                             PRInt32 aFromOffset, nsAccessible *aFromAccessible,
                             nsSelectionAmount aAmount, nsDirection aDirection,
-                            PRBool aNeedsStart);
+                            bool aNeedsStart);
 
   /**
     * Provides information for substring that is defined by the given start
     * and end offsets for this hyper text.
     *
     * @param  aStartOffset  [inout] the start offset into the hyper text. This
     *                       is also an out parameter used to return the offset
     *                       into the start frame's rendered text content
@@ -392,18 +392,18 @@ protected:
    * @param aRange          [in] the given range
    * @param aIsStartBound   [in] specifies whether the required range bound is
    *                        start bound
    * @param aIsStartOffset  [in] the offset type, used when the range bound is
    *                        outside of hyper text
    * @param aHTOffset       [out] the result offset
    */
   nsresult DOMRangeBoundToHypertextOffset(nsIDOMRange *aRange,
-                                          PRBool aIsStartBound,
-                                          PRBool aIsStartOffset,
+                                          bool aIsStartBound,
+                                          bool aIsStartOffset,
                                           PRInt32 *aHTOffset);
 
   /**
    * Set 'misspelled' text attribute and return range offsets where the
    * attibute is stretched. If the text is not misspelled at the given offset
    * then we expose only range offsets where text is not misspelled. The method
    * is used by GetTextAttributes() method.
    *
--- a/accessible/src/mac/mozAccessibleWrapper.h
+++ b/accessible/src/mac/mozAccessibleWrapper.h
@@ -76,16 +76,16 @@ struct AccessibleWrapper {
 
     NS_OBJC_END_TRY_ABORT_BLOCK;
   }
 
   mozAccessible* getNativeObject () {
     return object;
   }
  
-  PRBool isIgnored () {
+  bool isIgnored () {
     NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
 
-    return (PRBool)[object accessibilityIsIgnored];
+    return (bool)[object accessibilityIsIgnored];
 
     NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(PR_FALSE);
   }
 };
--- a/accessible/src/mac/mozTextAccessible.mm
+++ b/accessible/src/mac/mozTextAccessible.mm
@@ -77,17 +77,21 @@ extern const NSString *kTopLevelUIElemen
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
   if ([attribute isEqualToString:NSAccessibilityNumberOfCharactersAttribute])
     return [NSNumber numberWithInt:[self textLength]];
   if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute])
     return [self selectedTextRange];
   if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute])
     return [self selectedText];
-  
+  // Apple's SpeechSynthesisServer expects AXValue to return an AXStaticText
+  // object's AXSelectedText attribute.  See bug 674612.
+  if ([attribute isEqualToString:NSAccessibilityValueAttribute])
+    return [self selectedText];
+
   // let mozAccessible handle all other attributes
   return [super accessibilityAttributeValue:attribute];
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
 }
 
 - (BOOL)accessibilityIsAttributeSettable:(NSString*)attribute
 {
--- a/accessible/src/mac/nsAccessibleWrap.h
+++ b/accessible/src/mac/nsAccessibleWrap.h
@@ -59,53 +59,53 @@ struct AccessibleWrapper;
 
 class nsAccessibleWrap : public nsAccessible
 {
   public: // construction, destruction
     nsAccessibleWrap(nsIContent *aContent, nsIWeakReference *aShell);
     virtual ~nsAccessibleWrap();
     
     // creates the native accessible connected to this one.
-    virtual PRBool Init ();
+    virtual bool Init ();
     
     // get the native obj-c object (mozAccessible)
     NS_IMETHOD GetNativeInterface (void **aOutAccessible);
     
     // the objective-c |Class| type that this accessible's native object
     // should be instantied with.   used on runtime to determine the
     // right type for this accessible's associated native object.
     virtual Class GetNativeType ();
 
     virtual void Shutdown ();
     virtual void InvalidateChildren();
 
     virtual nsresult HandleAccEvent(AccEvent* aEvent);
 
     // ignored means that the accessible might still have children, but is not displayed
     // to the user. it also has no native accessible object represented for it.
-    PRBool IsIgnored();
+    bool IsIgnored();
     
-    PRInt32 GetUnignoredChildCount(PRBool aDeepCount);
+    PRInt32 GetUnignoredChildCount(bool aDeepCount);
     
-    PRBool HasPopup () {
+    bool HasPopup () {
       return (NativeState() & mozilla::a11y::states::HASPOPUP);
     }
     
     // return this accessible's all children, adhering to "flat" accessibles by not returning their children.
     void GetUnignoredChildren(nsTArray<nsRefPtr<nsAccessibleWrap> > &aChildrenArray);
     virtual already_AddRefed<nsIAccessible> GetUnignoredParent();
     
   protected:
 
     virtual nsresult FirePlatformEvent(AccEvent* aEvent);
 
   /**
    * Return true if the parent doesn't have children to expose to AT.
    */
-  PRBool AncestorIsFlat();
+  bool AncestorIsFlat();
 
     // Wrapper around our native object.
     AccessibleWrapper *mNativeWrapper;
 };
 
 // Define unsupported wrap classes here
 typedef class nsHTMLTableCellAccessible    nsHTMLTableCellAccessibleWrap;
 typedef class nsHTMLTableAccessible        nsHTMLTableAccessibleWrap;
--- a/accessible/src/mac/nsAccessibleWrap.mm
+++ b/accessible/src/mac/nsAccessibleWrap.mm
@@ -55,17 +55,17 @@ nsAccessibleWrap::
 nsAccessibleWrap::~nsAccessibleWrap()
 {
   if (mNativeWrapper) {
     delete mNativeWrapper;
     mNativeWrapper = nsnull;
   }
 }
 
-PRBool
+bool
 nsAccessibleWrap::Init () 
 {
   if (!nsAccessible::Init())
     return PR_FALSE;
 
   if (!mNativeWrapper && !AncestorIsFlat()) {
     // Create our native object using the class type specified in GetNativeType().
     mNativeWrapper = new AccessibleWrapper (this, GetNativeType());
@@ -206,17 +206,17 @@ nsAccessibleWrap::InvalidateChildren()
     [object invalidateChildren];
   }
   nsAccessible::InvalidateChildren();
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 PRInt32
-nsAccessibleWrap::GetUnignoredChildCount(PRBool aDeepCount)
+nsAccessibleWrap::GetUnignoredChildCount(bool aDeepCount)
 {
   // if we're flat, we have no children.
   if (nsAccUtils::MustPrune(this))
     return 0;
 
   PRInt32 resultChildCount = 0;
 
   PRInt32 childCount = GetChildCount();
@@ -243,17 +243,17 @@ nsAccessibleWrap::GetUnignoredChildCount
     }
   } 
   
   return resultChildCount;
 }
 
 // if we for some reason have no native accessible, we should be skipped over (and traversed)
 // when fetching all unignored children, etc.  when counting unignored children, we will not be counted.
-PRBool 
+bool 
 nsAccessibleWrap::IsIgnored() 
 {
   return (mNativeWrapper == nsnull) || mNativeWrapper->isIgnored();
 }
 
 void
 nsAccessibleWrap::GetUnignoredChildren(nsTArray<nsRefPtr<nsAccessibleWrap> > &aChildrenArray)
 {
@@ -297,17 +297,17 @@ nsAccessibleWrap::GetUnignoredParent()
   NS_IF_ADDREF(outValue = parentWrap);
   
   return outValue;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessibleWrap protected
 
-PRBool
+bool
 nsAccessibleWrap::AncestorIsFlat()
 {
   // We don't create a native object if we're child of a "flat" accessible;
   // for example, on OS X buttons shouldn't have any children, because that
   // makes the OS confused. 
   //
   // To maintain a scripting environment where the XPCOM accessible hierarchy
   // look the same on all platforms, we still let the C++ objects be created
--- a/accessible/src/mac/nsDocAccessibleWrap.h
+++ b/accessible/src/mac/nsDocAccessibleWrap.h
@@ -48,12 +48,12 @@ public:
                       nsIWeakReference *aShell);
   virtual ~nsDocAccessibleWrap();
 
   // nsIAccessNode
 
   /**
    * Creates the native accessible connected to this one.
    */
-  virtual PRBool Init();
+  virtual bool Init();
 };
 
 #endif
--- a/accessible/src/mac/nsDocAccessibleWrap.mm
+++ b/accessible/src/mac/nsDocAccessibleWrap.mm
@@ -45,17 +45,17 @@ nsDocAccessibleWrap::
   nsDocAccessible(aDocument, aRootContent, aShell)
 {
 }
 
 nsDocAccessibleWrap::~nsDocAccessibleWrap()
 {
 }
 
-PRBool
+bool
 nsDocAccessibleWrap::Init () 
 {
   if (!nsDocAccessible::Init())
     return PR_FALSE;
 
   NS_ASSERTION(!mNativeWrapper, "nsDocAccessibleWrap::Init() called more than once!");
 
   if (!mNativeWrapper) {
--- a/accessible/src/msaa/CAccessibleTable.cpp
+++ b/accessible/src/msaa/CAccessibleTable.cpp
@@ -44,31 +44,35 @@
 #include "AccessibleTable_i.c"
 #include "AccessibleTable2_i.c"
 
 #include "nsIAccessible.h"
 #include "nsIAccessibleTable.h"
 #include "nsIWinAccessNode.h"
 #include "nsAccessNodeWrap.h"
 #include "nsWinUtils.h"
+#include "Statistics.h"
 
 #include "nsCOMPtr.h"
 #include "nsString.h"
 
+using namespace mozilla::a11y;
+
 #define CANT_QUERY_ASSERTION_MSG \
 "Subclass of CAccessibleTable doesn't implement nsIAccessibleTable"\
 
 // IUnknown
 
 STDMETHODIMP
 CAccessibleTable::QueryInterface(REFIID iid, void** ppv)
 {
   *ppv = NULL;
 
   if (IID_IAccessibleTable == iid) {
+    statistics::IAccessibleTableUsed();
     *ppv = static_cast<IAccessibleTable*>(this);
     (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
     return S_OK;
   }
 
   if (IID_IAccessibleTable2 == iid) {
     *ppv = static_cast<IAccessibleTable2*>(this);
     (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
@@ -520,17 +524,17 @@ CAccessibleTable::get_isColumnSelected(l
 __try {
   *aIsSelected = false;
 
   nsCOMPtr<nsIAccessibleTable> tableAcc(do_QueryObject(this));
   NS_ASSERTION(tableAcc, CANT_QUERY_ASSERTION_MSG);
   if (!tableAcc)
     return E_FAIL;
 
-  PRBool isSelected = PR_FALSE;
+  bool isSelected = false;
   nsresult rv = tableAcc->IsColumnSelected(aColumn, &isSelected);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   *aIsSelected = isSelected;
   return S_OK;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
@@ -543,17 +547,17 @@ CAccessibleTable::get_isRowSelected(long
 __try {
   *aIsSelected = false;
 
   nsCOMPtr<nsIAccessibleTable> tableAcc(do_QueryObject(this));
   NS_ASSERTION(tableAcc, CANT_QUERY_ASSERTION_MSG);
   if (!tableAcc)
     return E_FAIL;
 
-  PRBool isSelected = PR_FALSE;
+  bool isSelected = false;
   nsresult rv = tableAcc->IsRowSelected(aRow, &isSelected);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   *aIsSelected = isSelected;
   return S_OK;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
@@ -566,17 +570,17 @@ CAccessibleTable::get_isSelected(long aR
 __try {
   *aIsSelected = false;
 
   nsCOMPtr<nsIAccessibleTable> tableAcc(do_QueryObject(this));
   NS_ASSERTION(tableAcc, CANT_QUERY_ASSERTION_MSG);
   if (!tableAcc)
     return E_FAIL;
 
-  PRBool isSelected = PR_FALSE;
+  bool isSelected = false;
   nsresult rv = tableAcc->IsCellSelected(aRow, aColumn, &isSelected);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   *aIsSelected = isSelected;
   return S_OK;
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
@@ -676,17 +680,17 @@ CAccessibleTable::get_rowColumnExtentsAt
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   PRInt32 columnExtents = 0;
   rv = tableAcc->GetColumnExtentAt(rowIdx, columnIdx, &columnExtents);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
-  PRBool isSelected = PR_FALSE;
+  bool isSelected = false;
   rv = tableAcc->IsCellSelected(rowIdx, columnIdx, &isSelected);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   *aRow = rowIdx;
   *aColumn = columnIdx;
   *aRowExtents = rowExtents;
   *aColumnExtents = columnExtents;
--- a/accessible/src/msaa/CAccessibleTableCell.cpp
+++ b/accessible/src/msaa/CAccessibleTableCell.cpp
@@ -292,17 +292,17 @@ CAccessibleTableCell::get_rowColumnExten
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   PRInt32 spannedColumns = 0;
   rv = tableCell->GetColumnExtent(&spannedColumns);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
-  PRBool isSel = PR_FALSE;
+  bool isSel = false;
   rv = tableCell->IsSelected(&isSel);
   if (NS_FAILED(rv))
     return GetHRESULT(rv);
 
   *row = rowIdx;
   *column = columnIdx;
   *rowExtents = spannedRows;
   *columnExtents = spannedColumns;
@@ -320,17 +320,17 @@ CAccessibleTableCell::get_isSelected(boo
 __try {
   *isSelected = false;
 
   nsCOMPtr<nsIAccessibleTableCell> tableCell(do_QueryObject(this));
   NS_ASSERTION(tableCell, TABLECELL_INTERFACE_UNSUPPORTED_MSG);
   if (!tableCell)
     return E_FAIL;
 
-  PRBool isSel = PR_FALSE;
+  bool isSel = false;
   nsresult rv = tableCell->IsSelected(&isSel);
   if (NS_SUCCEEDED(rv)) {
     *isSelected = isSel;
     return S_OK;
   }
 
   return GetHRESULT(rv);
 
--- a/accessible/src/msaa/CAccessibleText.cpp
+++ b/accessible/src/msaa/CAccessibleText.cpp
@@ -513,17 +513,17 @@ CAccessibleText::get_oldText(IA2TextSegm
 
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
 // CAccessibleText
 
 HRESULT
-CAccessibleText::GetModifiedText(PRBool aGetInsertedText,
+CAccessibleText::GetModifiedText(bool aGetInsertedText,
                                  IA2TextSegment *aText)
 {
   PRUint32 startOffset = 0, endOffset = 0;
   nsAutoString text;
 
   nsresult rv = GetModifiedText(aGetInsertedText, text,
                                 &startOffset, &endOffset);
   if (NS_FAILED(rv))
--- a/accessible/src/msaa/CAccessibleText.h
+++ b/accessible/src/msaa/CAccessibleText.h
@@ -146,22 +146,22 @@ public:
 
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_oldText(
       /* [retval][out] */ IA2TextSegment *oldText);
 
   // nsISupports
   NS_IMETHOD QueryInterface(const nsIID& uuid, void** result) = 0;
 
 protected:
-  virtual nsresult GetModifiedText(PRBool aGetInsertedText, nsAString& aText,
+  virtual nsresult GetModifiedText(bool aGetInsertedText, nsAString& aText,
                                    PRUint32 *aStartOffset,
                                    PRUint32 *aEndOffset) = 0;
 
 private:
-  HRESULT GetModifiedText(PRBool aGetInsertedText, IA2TextSegment *aNewText);
+  HRESULT GetModifiedText(bool aGetInsertedText, IA2TextSegment *aNewText);
   nsAccessibleTextBoundary GetGeckoTextBoundary(enum IA2TextBoundaryType coordinateType);
 };
 
 
 #define FORWARD_IACCESSIBLETEXT(Class)                                         \
 virtual HRESULT STDMETHODCALLTYPE addSelection(long startOffset,               \
                                                long endOffset)                 \
 {                                                                              \
--- a/accessible/src/msaa/nsAccessNodeWrap.cpp
+++ b/accessible/src/msaa/nsAccessNodeWrap.cpp
@@ -41,40 +41,42 @@
 #include "AccessibleApplication.h"
 #include "ISimpleDOMNode_i.c"
 
 #include "nsAccessibilityService.h"
 #include "nsApplicationAccessibleWrap.h"
 #include "nsCoreUtils.h"
 #include "nsRootAccessible.h"
 #include "nsWinUtils.h"
+#include "Statistics.h"
 
 #include "nsAttrName.h"
 #include "nsIDocument.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMNSHTMLElement.h"
 #include "nsIFrame.h"
 #include "nsINameSpaceManager.h"
 #include "nsPIDOMWindow.h"
 #include "nsIServiceManager.h"
 
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
+using namespace mozilla::a11y;
 
 /// the accessible library and cached methods
 HINSTANCE nsAccessNodeWrap::gmAccLib = nsnull;
 HINSTANCE nsAccessNodeWrap::gmUserLib = nsnull;
 LPFNACCESSIBLEOBJECTFROMWINDOW nsAccessNodeWrap::gmAccessibleObjectFromWindow = nsnull;
 LPFNLRESULTFROMOBJECT nsAccessNodeWrap::gmLresultFromObject = NULL;
 LPFNNOTIFYWINEVENT nsAccessNodeWrap::gmNotifyWinEvent = nsnull;
 LPFNGETGUITHREADINFO nsAccessNodeWrap::gmGetGUIThreadInfo = nsnull;
 
 // Used to determine whether an IAccessible2 compatible screen reader is loaded.
-PRBool nsAccessNodeWrap::gIsIA2Disabled = PR_FALSE;
+bool nsAccessNodeWrap::gIsIA2Disabled = false;
 
 AccTextChangeEvent* nsAccessNodeWrap::gTextEvent = nsnull;
 
 // Pref to disallow CtrlTab preview functionality if JAWS or Window-Eyes are
 // running.
 #define CTRLTAB_DISALLOW_FOR_SCREEN_READERS_PREF "browser.ctrlTab.disallowForScreenReaders"
 
 
@@ -115,21 +117,24 @@ nsAccessNodeWrap::QueryNativeInterface(R
 //-----------------------------------------------------
 // IUnknown interface methods - see iunknown.h for documentation
 //-----------------------------------------------------
 
 STDMETHODIMP nsAccessNodeWrap::QueryInterface(REFIID iid, void** ppv)
 {
   *ppv = nsnull;
 
-  if (IID_IUnknown == iid || IID_ISimpleDOMNode == iid)
+  if (IID_IUnknown == iid) {
     *ppv = static_cast<ISimpleDOMNode*>(this);
-
-  if (nsnull == *ppv)
+  } else if (IID_ISimpleDOMNode == iid) {
+    statistics::ISimpleDOMUsed();
+    *ppv = static_cast<ISimpleDOMNode*>(this);
+  } else {
     return E_NOINTERFACE;      //iid not supported.
+  }
    
   (reinterpret_cast<IUnknown*>(*ppv))->AddRef(); 
   return S_OK;
 }
 
 STDMETHODIMP
 nsAccessNodeWrap::QueryService(REFGUID guidService, REFIID iid, void** ppv)
 {
@@ -661,17 +666,17 @@ GetHRESULT(nsresult aResult)
     case NS_ERROR_NOT_IMPLEMENTED:
       return E_NOTIMPL;
 
     default:
       return E_FAIL;
   }
 }
 
-PRBool nsAccessNodeWrap::IsOnlyMsaaCompatibleJawsPresent()
+bool nsAccessNodeWrap::IsOnlyMsaaCompatibleJawsPresent()
 {
   HMODULE jhookhandle = ::GetModuleHandleW(kJAWSModuleHandle);
   if (!jhookhandle)
     return PR_FALSE;  // No JAWS, or some other screen reader, use IA2
 
   PRUnichar fileName[MAX_PATH];
   ::GetModuleFileNameW(jhookhandle, fileName, MAX_PATH);
 
--- a/accessible/src/msaa/nsAccessNodeWrap.h
+++ b/accessible/src/msaa/nsAccessNodeWrap.h
@@ -154,17 +154,17 @@ public: // construction, destruction
     static HINSTANCE gmUserLib;
     static LPFNACCESSIBLEOBJECTFROMWINDOW gmAccessibleObjectFromWindow;
     static LPFNLRESULTFROMOBJECT gmLresultFromObject;
     static LPFNNOTIFYWINEVENT gmNotifyWinEvent;
     static LPFNGETGUITHREADINFO gmGetGUIThreadInfo;
 
     static int FilterA11yExceptions(unsigned int aCode, EXCEPTION_POINTERS *aExceptionInfo);
 
-    static PRBool IsOnlyMsaaCompatibleJawsPresent();
+    static bool IsOnlyMsaaCompatibleJawsPresent();
 
     static void TurnOffNewTabSwitchingForJawsAndWE();
 
     static void DoATSpecificProcessing();
 
   static STDMETHODIMP_(LRESULT) LresultFromObject(REFIID riid, WPARAM wParam, LPUNKNOWN pAcc);
 
   static LRESULT CALLBACK WindowProc(HWND hWnd, UINT Msg,
@@ -181,17 +181,17 @@ protected:
    * @note ISimpleDOMNode is returned addrefed
    */
   ISimpleDOMNode *MakeAccessNode(nsINode *aNode);
 
     /**
      * Used to determine whether an IAccessible2 compatible screen reader is
      * loaded. Currently used for JAWS versions older than 8.0.2173.
      */
-     static PRBool gIsIA2Disabled;
+     static bool gIsIA2Disabled;
 
     /**
      * It is used in nsHyperTextAccessibleWrap for IA2::newText/oldText
      * implementation.
      */
     static AccTextChangeEvent* gTextEvent;
 };
 
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -1612,17 +1612,17 @@ nsAccessibleWrap::GetHWNDFor(nsAccessibl
 {
   if (aAccessible) {
     // Popup lives in own windows, use its HWND until the popup window is
     // hidden to make old JAWS versions work with collapsed comboboxes (see
     // discussion in bug 379678).
     nsIFrame* frame = aAccessible->GetFrame();
     if (frame) {
       nsIWidget* widget = frame->GetNearestWidget();
-      PRBool isVisible = PR_FALSE;
+      bool isVisible = false;
       widget->IsVisible(isVisible);
       if (isVisible) {
         nsCOMPtr<nsIPresShell> shell(aAccessible->GetPresShell());
         nsIViewManager* vm = shell->GetViewManager();
         if (vm) {
           nsCOMPtr<nsIWidget> rootWidget;
           vm->GetRootWidget(getter_AddRefs(rootWidget));
           // Make sure the accessible belongs to popup. If not then use
@@ -1657,17 +1657,17 @@ nsAccessibleWrap::ConvertToIA2Attributes
   aAttributes->Enumerate(getter_AddRefs(propEnum));
   if (!propEnum)
     return E_FAIL;
 
   nsAutoString strAttrs;
 
   const char kCharsToEscape[] = ":;=,\\";
 
-  PRBool hasMore = PR_FALSE;
+  bool hasMore = false;
   while (NS_SUCCEEDED(propEnum->HasMoreElements(&hasMore)) && hasMore) {
     nsCOMPtr<nsISupports> propSupports;
     propEnum->GetNext(getter_AddRefs(propSupports));
 
     nsCOMPtr<nsIPropertyElement> propElem(do_QueryInterface(propSupports));
     if (!propElem)
       return E_FAIL;
 
--- a/accessible/src/msaa/nsDocAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsDocAccessibleWrap.cpp
@@ -38,27 +38,30 @@
 
 #include "mozilla/dom/TabChild.h"
 
 #include "nsDocAccessibleWrap.h"
 #include "ISimpleDOMDocument_i.c"
 #include "nsIAccessibilityService.h"
 #include "nsRootAccessible.h"
 #include "nsWinUtils.h"
+#include "Statistics.h"
 
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeNode.h"
 #include "nsIFrame.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsISelectionController.h"
 #include "nsIServiceManager.h"
 #include "nsIURI.h"
 #include "nsIViewManager.h"
 #include "nsIWebNavigation.h"
 
+using namespace mozilla::a11y;
+
 /* For documentation of the accessibility architecture, 
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsDocAccessibleWrap
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -86,22 +89,21 @@ STDMETHODIMP_(ULONG) nsDocAccessibleWrap
   return nsAccessNode::Release();
 }
 
 // Microsoft COM QueryInterface
 STDMETHODIMP nsDocAccessibleWrap::QueryInterface(REFIID iid, void** ppv)
 {
   *ppv = NULL;
 
-  if (IID_ISimpleDOMDocument == iid)
-    *ppv = static_cast<ISimpleDOMDocument*>(this);
+  if (IID_ISimpleDOMDocument != iid)
+    return nsHyperTextAccessibleWrap::QueryInterface(iid, ppv);
 
-  if (NULL == *ppv)
-    return nsHyperTextAccessibleWrap::QueryInterface(iid, ppv);
-    
+  statistics::ISimpleDOMUsed();
+  *ppv = static_cast<ISimpleDOMDocument*>(this);
   (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
   return S_OK;
 }
 
 STDMETHODIMP nsDocAccessibleWrap::get_URL(/* [out] */ BSTR __RPC_FAR *aURL)
 {
 __try {
   *aURL = NULL;
@@ -282,17 +284,17 @@ nsDocAccessibleWrap::DoInitialUpdate()
 
       mozilla::WindowsHandle nativeData = nsnull;
       if (tabChild)
         tabChild->SendGetWidgetNativeData(&nativeData);
       else
         nativeData = reinterpret_cast<mozilla::WindowsHandle>(
           rootDocument->GetNativeWindow());
 
-      PRBool isActive = PR_TRUE;
+      bool isActive = true;
       PRInt32 x = CW_USEDEFAULT, y = CW_USEDEFAULT, width = 0, height = 0;
       if (nsWinUtils::IsWindowEmulationFor(kDolphinModuleHandle)) {
         GetBounds(&x, &y, &width, &height);
         PRInt32 rootX = 0, rootY = 0, rootWidth = 0, rootHeight = 0;
         rootDocument->GetBounds(&rootX, &rootY, &rootWidth, &rootHeight);
         x = rootX - x;
         y -= rootY;
 
--- a/accessible/src/msaa/nsHyperTextAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsHyperTextAccessibleWrap.cpp
@@ -73,29 +73,29 @@ nsHyperTextAccessibleWrap::HandleAccEven
       }
     }
   }
 
   return nsHyperTextAccessible::HandleAccEvent(aEvent);
 }
 
 nsresult
-nsHyperTextAccessibleWrap::GetModifiedText(PRBool aGetInsertedText,
+nsHyperTextAccessibleWrap::GetModifiedText(bool aGetInsertedText,
                                            nsAString& aText,
                                            PRUint32 *aStartOffset,
                                            PRUint32 *aEndOffset)
 {
   aText.Truncate();
   *aStartOffset = 0;
   *aEndOffset = 0;
 
   if (!gTextEvent)
     return NS_OK;
 
-  PRBool isInserted = gTextEvent->IsTextInserted();
+  bool isInserted = gTextEvent->IsTextInserted();
   if (aGetInsertedText != isInserted)
     return NS_OK;
 
   nsAccessible *targetAcc = gTextEvent->GetAccessible();
   if (targetAcc != this)
     return NS_OK;
 
   *aStartOffset = gTextEvent->GetStartOffset();
--- a/accessible/src/msaa/nsHyperTextAccessibleWrap.h
+++ b/accessible/src/msaa/nsHyperTextAccessibleWrap.h
@@ -59,15 +59,15 @@ public:
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsAccessible
   virtual nsresult HandleAccEvent(AccEvent* aEvent);
 
 protected:
-  virtual nsresult GetModifiedText(PRBool aGetInsertedText, nsAString& aText,
+  virtual nsresult GetModifiedText(bool aGetInsertedText, nsAString& aText,
                                    PRUint32 *aStartOffset,
                                    PRUint32 *aEndOffset);
 };
 
 #endif
 
--- a/accessible/src/msaa/nsTextAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsTextAccessibleWrap.cpp
@@ -36,23 +36,26 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsTextAccessibleWrap.h"
 #include "ISimpleDOMText_i.c"
 
 #include "nsCoreUtils.h"
 #include "nsDocAccessible.h"
+#include "Statistics.h"
 #include "nsIFrame.h"
 #include "nsFontMetrics.h"
 #include "nsPresContext.h"
 #include "nsLayoutUtils.h"
 
 #include "gfxFont.h"
 
+using namespace mozilla::a11y;
+
 ////////////////////////////////////////////////////////////////////////////////
 // nsTextAccessibleWrap Accessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsTextAccessibleWrap::
   nsTextAccessibleWrap(nsIContent *aContent, nsIWeakReference *aShell) :
   nsTextAccessible(aContent, aShell)
 {
@@ -67,21 +70,24 @@ STDMETHODIMP_(ULONG) nsTextAccessibleWra
 {
   return nsAccessNode::Release();
 }
 
 STDMETHODIMP nsTextAccessibleWrap::QueryInterface(REFIID iid, void** ppv)
 {
   *ppv = nsnull;
 
-  if (IID_IUnknown == iid || IID_ISimpleDOMText == iid)
+  if (IID_IUnknown == iid) {
     *ppv = static_cast<ISimpleDOMText*>(this);
-
-  if (nsnull == *ppv)
+  } else if (IID_ISimpleDOMText == iid) {
+    statistics::ISimpleDOMUsed();
+    *ppv = static_cast<ISimpleDOMText*>(this);
+  } else {
     return nsAccessibleWrap::QueryInterface(iid, ppv);
+  }
    
   (reinterpret_cast<IUnknown*>(*ppv))->AddRef(); 
   return S_OK;
 }
 
 STDMETHODIMP nsTextAccessibleWrap::get_domText( 
     /* [retval][out] */ BSTR __RPC_FAR *aDomText)
 {
@@ -184,17 +190,17 @@ STDMETHODIMP nsTextAccessibleWrap::scrol
   if (NS_FAILED(rv))
     return E_FAIL;
 } __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 nsIFrame* nsTextAccessibleWrap::GetPointFromOffset(nsIFrame *aContainingFrame, 
                                                    PRInt32 aOffset, 
-                                                   PRBool aPreferNext, 
+                                                   bool aPreferNext, 
                                                    nsPoint& aOutPoint)
 {
   nsIFrame *textFrame = nsnull;
   PRInt32 outOffset;
   aContainingFrame->GetChildFrameContainingOffset(aOffset, aPreferNext, &outOffset, &textFrame);
   if (!textFrame) {
     return nsnull;
   }
--- a/accessible/src/msaa/nsTextAccessibleWrap.h
+++ b/accessible/src/msaa/nsTextAccessibleWrap.h
@@ -86,13 +86,13 @@ public:
     
   protected:
     nsresult GetCharacterExtents(PRInt32 aStartOffset, PRInt32 aEndOffset,
                                  PRInt32* aX, PRInt32* aY, 
                                  PRInt32* aWidth, PRInt32* aHeight);
 
     // Return child frame containing offset on success
     nsIFrame* GetPointFromOffset(nsIFrame *aContainingFrame,
-                                 PRInt32 aOffset, PRBool aPreferNext, nsPoint& aOutPoint);
+                                 PRInt32 aOffset, bool aPreferNext, nsPoint& aOutPoint);
 };
 
 #endif
 
--- a/accessible/src/xforms/nsXFormsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsAccessible.cpp
@@ -155,29 +155,29 @@ nsXFormsAccessible::GetValue(nsAString& 
 
 PRUint64
 nsXFormsAccessible::NativeState()
 {
   NS_ENSURE_TRUE(sXFormsService, 0);
 
   nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
 
-  PRBool isRelevant = PR_FALSE;
+  bool isRelevant = false;
   nsresult rv = sXFormsService->IsRelevant(DOMNode, &isRelevant);
   NS_ENSURE_SUCCESS(rv, 0);
 
-  PRBool isReadonly = PR_FALSE;
+  bool isReadonly = false;
   rv = sXFormsService->IsReadonly(DOMNode, &isReadonly);
   NS_ENSURE_SUCCESS(rv, 0);
 
-  PRBool isRequired = PR_FALSE;
+  bool isRequired = false;
   rv = sXFormsService->IsRequired(DOMNode, &isRequired);
   NS_ENSURE_SUCCESS(rv, 0);
 
-  PRBool isValid = PR_FALSE;
+  bool isValid = false;
   rv = sXFormsService->IsValid(DOMNode, &isValid);
   NS_ENSURE_SUCCESS(rv, 0);
 
   PRUint64 states = nsHyperTextAccessibleWrap::NativeState();
 
   if (!isRelevant)
     states |= states::UNAVAILABLE;
 
@@ -206,17 +206,17 @@ nsXFormsAccessible::Description(nsString
   nsTextEquivUtils::
     GetTextEquivFromIDRefs(this, nsGkAtoms::aria_describedby,
                            aDescription);
 
   if (aDescription.IsEmpty())
     GetBoundChildElementValue(NS_LITERAL_STRING("hint"), aDescription);
 }
 
-PRBool
+bool
 nsXFormsAccessible::GetAllowsAnonChildAccessibles()
 {
   return PR_FALSE;
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXFormsContainerAccessible
@@ -229,17 +229,17 @@ nsXFormsContainerAccessible::
 }
 
 PRUint32
 nsXFormsContainerAccessible::NativeRole()
 {
   return nsIAccessibleRole::ROLE_GROUPING;
 }
 
-PRBool
+bool
 nsXFormsContainerAccessible::GetAllowsAnonChildAccessibles()
 {
   return PR_TRUE;
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXFormsEditableAccessible
@@ -253,22 +253,22 @@ nsXFormsEditableAccessible::
 
 PRUint64
 nsXFormsEditableAccessible::NativeState()
 {
   PRUint64 state = nsXFormsAccessible::NativeState();
 
   nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
 
-  PRBool isReadonly = PR_FALSE;
+  bool isReadonly = false;
   nsresult rv = sXFormsService->IsReadonly(DOMNode, &isReadonly);
   NS_ENSURE_SUCCESS(rv, state);
 
   if (!isReadonly) {
-    PRBool isRelevant = PR_FALSE;
+    bool isRelevant = false;
     rv = sXFormsService->IsRelevant(DOMNode, &isRelevant);
     NS_ENSURE_SUCCESS(rv, state);
     if (isRelevant) {
       state |= states::EDITABLE | states::SELECTABLE_TEXT;
     }
   }
 
   nsCOMPtr<nsIEditor> editor;
@@ -468,17 +468,17 @@ nsXFormsSelectableAccessible::IsItemSele
   nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
   if (mIsSelect1Element) {
     nsCOMPtr<nsIDOMNode> selItemDOMNode;
     sXFormsService->GetSelectedItemForSelect1(DOMNode,
                                               getter_AddRefs(selItemDOMNode));
     return selItemDOMNode == itemDOMNode;
   }
 
-  PRBool isSelected = PR_FALSE;
+  bool isSelected = false;
   sXFormsService->IsSelectItemSelected(DOMNode, itemDOMNode, &isSelected);
   return isSelected;
 }
 
 bool
 nsXFormsSelectableAccessible::UnselectAll()
 {
   nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
@@ -578,17 +578,17 @@ nsXFormsSelectableItemAccessible::IsSele
       continue;
 
     nsCOMPtr<nsIDOMNode> select(do_QueryInterface(parent));
     if (!select)
       continue;
 
     nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
     if (nodeinfo->Equals(nsGkAtoms::select)) {
-      PRBool isSelected = PR_FALSE;
+      bool isSelected = false;
       rv = sXFormsService->IsSelectItemSelected(select, DOMNode, &isSelected);
       return NS_SUCCEEDED(rv) && isSelected;
     }
 
     if (nodeinfo->Equals(nsGkAtoms::select1)) {
       nsCOMPtr<nsIDOMNode> selitem;
       rv = sXFormsService->GetSelectedItemForSelect1(select,
                                                      getter_AddRefs(selitem));
--- a/accessible/src/xforms/nsXFormsAccessible.h
+++ b/accessible/src/xforms/nsXFormsAccessible.h
@@ -85,17 +85,17 @@ public:
   virtual nsresult GetNameInternal(nsAString& aName);
 
   // Returns state of xforms element taking into account state of instance node
   // that it is bound to.
   virtual PRUint64 NativeState();
 
   // Denies accessible nodes in anonymous content of xforms element by
   // always returning PR_FALSE value.
-  virtual PRBool GetAllowsAnonChildAccessibles();
+  virtual bool GetAllowsAnonChildAccessibles();
 
 protected:
   // Returns value of first child xforms element by tagname that is bound to
   // instance node.
   nsresult GetBoundChildElementValue(const nsAString& aTagName,
                                      nsAString& aValue);
 
   // Cache accessible child item/choices elements. For example, the method is
@@ -126,17 +126,17 @@ class nsXFormsContainerAccessible : publ
 public:
   nsXFormsContainerAccessible(nsIContent *aContent, nsIWeakReference *aShell);
 
   // nsAccessible
   virtual PRUint32 NativeRole();
 
   // Allows accessible nodes in anonymous content of xforms element by
   // always returning PR_TRUE value.
-  virtual PRBool GetAllowsAnonChildAccessibles();
+  virtual bool GetAllowsAnonChildAccessibles();
 };
 
 
 /**
  * The class is base for accessible objects for XForms elements that have
  * editable area.
  */
 class nsXFormsEditableAccessible : public nsXFormsAccessible
@@ -171,17 +171,17 @@ public:
   virtual bool RemoveItemFromSelection(PRUint32 aIndex);
   virtual bool SelectAll();
   virtual bool UnselectAll();
 
 protected:
   nsIContent* GetItemByIndex(PRUint32* aIndex,
                              nsAccessible* aAccessible = nsnull);
 
-  PRBool mIsSelect1Element;
+  bool mIsSelect1Element;
 };
 
 
 /**
  * The class is base for accessible objects for XForms item elements.
  */
 class nsXFormsSelectableItemAccessible : public nsXFormsAccessible
 {
--- a/accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsFormControlsAccessible.cpp
@@ -570,30 +570,30 @@ nsXFormsSelectComboboxAccessible::Native
   return nsIAccessibleRole::ROLE_COMBOBOX;
 }
 
 PRUint64
 nsXFormsSelectComboboxAccessible::NativeState()
 {
   PRUint64 state = nsXFormsSelectableAccessible::NativeState();
 
-  PRBool isOpen = PR_FALSE;
+  bool isOpen = false;
   nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
   nsresult rv = sXFormsService->IsDropmarkerOpen(DOMNode, &isOpen);
   NS_ENSURE_SUCCESS(rv, state);
 
   if (isOpen)
     state |= states::EXPANDED;
   else
     state |= states::COLLAPSED;
 
   return state | states::HASPOPUP | states::FOCUSABLE;
 }
 
-PRBool
+bool
 nsXFormsSelectComboboxAccessible::GetAllowsAnonChildAccessibles()
 {
   return PR_TRUE;
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXFormsItemComboboxAccessible
--- a/accessible/src/xforms/nsXFormsFormControlsAccessible.h
+++ b/accessible/src/xforms/nsXFormsFormControlsAccessible.h
@@ -292,17 +292,17 @@ class nsXFormsSelectComboboxAccessible :
 {
 public:
   nsXFormsSelectComboboxAccessible(nsIContent *aContent,
                                    nsIWeakReference *aShell);
 
   // nsAccessible
   virtual PRUint32 NativeRole();
   virtual PRUint64 NativeState();
-  virtual PRBool GetAllowsAnonChildAccessibles();
+  virtual bool GetAllowsAnonChildAccessibles();
 };
 
 
 /**
  * Accessible object for xforms:item element when it is represented by a
  * listitem. This occurs when the item is contained in a xforms:select with
  * minimal appearance. Such a xforms:select is represented by a combobox.
  */
--- a/accessible/src/xforms/nsXFormsWidgetsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsWidgetsAccessible.cpp
@@ -57,17 +57,17 @@ PRUint32
 nsXFormsDropmarkerWidgetAccessible::NativeRole()
 {
   return nsIAccessibleRole::ROLE_PUSHBUTTON;
 }
 
 PRUint64
 nsXFormsDropmarkerWidgetAccessible::NativeState()
 {
-  PRBool isOpen = PR_FALSE;
+  bool isOpen = false;
   nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
   nsresult rv = sXFormsService->IsDropmarkerOpen(DOMNode, &isOpen);
   NS_ENSURE_SUCCESS(rv, 0);
 
   return isOpen ? states::PRESSED: 0;
 }
 
 PRUint8
@@ -78,17 +78,17 @@ nsXFormsDropmarkerWidgetAccessible::Acti
 
 NS_IMETHODIMP
 nsXFormsDropmarkerWidgetAccessible::GetActionName(PRUint8 aIndex,
                                                   nsAString& aName)
 {
   if (aIndex != eAction_Click)
     return NS_ERROR_INVALID_ARG;
 
-  PRBool isOpen = PR_FALSE;
+  bool isOpen = false;
   nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
   nsresult rv = sXFormsService->IsDropmarkerOpen(DOMNode, &isOpen);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (isOpen)
     aName.AssignLiteral("close");
   else
     aName.AssignLiteral("open");
@@ -141,17 +141,17 @@ nsXFormsComboboxPopupWidgetAccessible::N
   return nsIAccessibleRole::ROLE_LIST;
 }
 
 PRUint64
 nsXFormsComboboxPopupWidgetAccessible::NativeState()
 {
   PRUint64 state = nsXFormsAccessible::NativeState();
 
-  PRBool isOpen = PR_FALSE;
+  bool isOpen = false;
   nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
   nsresult rv = sXFormsService->IsDropmarkerOpen(DOMNode, &isOpen);
   NS_ENSURE_SUCCESS(rv, state);
 
   state |= states::FOCUSABLE;
 
   if (isOpen)
     state = states::FLOATING;
--- a/accessible/src/xpcom/nsAccEvent.cpp
+++ b/accessible/src/xpcom/nsAccEvent.cpp
@@ -42,17 +42,17 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccEvent
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_IMPL_ISUPPORTS1(nsAccEvent, nsIAccessibleEvent)
 
 NS_IMETHODIMP
-nsAccEvent::GetIsFromUserInput(PRBool* aIsFromUserInput)
+nsAccEvent::GetIsFromUserInput(bool* aIsFromUserInput)
 {
   *aIsFromUserInput = mEvent->IsFromUserInput();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccEvent::GetEventType(PRUint32* aEventType)
 {
@@ -109,30 +109,30 @@ nsAccStateChangeEvent::GetState(PRUint32
   PRUint64 state = static_cast<AccStateChangeEvent*>(mEvent.get())->GetState();
   nsAccUtils::To32States(state, &state1, &state2);
 
   *aState = state1 | state2; // only one state is not 0
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAccStateChangeEvent::IsExtraState(PRBool* aIsExtraState)
+nsAccStateChangeEvent::IsExtraState(bool* aIsExtraState)
 {
   NS_ENSURE_ARG_POINTER(aIsExtraState);
 
   PRUint32 state1 = 0, state2 = 0;
   PRUint64 state = static_cast<AccStateChangeEvent*>(mEvent.get())->GetState();
   nsAccUtils::To32States(state, &state1, &state2);
 
   *aIsExtraState = (state2 != 0);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAccStateChangeEvent::IsEnabled(PRBool* aIsEnabled)
+nsAccStateChangeEvent::IsEnabled(bool* aIsEnabled)
 {
   NS_ENSURE_ARG_POINTER(aIsEnabled);
   *aIsEnabled = static_cast<AccStateChangeEvent*>(mEvent.get())->IsStateEnabled();
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccTextChangeEvent
@@ -153,17 +153,17 @@ NS_IMETHODIMP
 nsAccTextChangeEvent::GetLength(PRUint32* aLength)
 {
   NS_ENSURE_ARG_POINTER(aLength);
   *aLength = static_cast<AccTextChangeEvent*>(mEvent.get())->GetLength();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsAccTextChangeEvent::IsInserted(PRBool* aIsInserted)
+nsAccTextChangeEvent::IsInserted(bool* aIsInserted)
 {
   NS_ENSURE_ARG_POINTER(aIsInserted);
   *aIsInserted = static_cast<AccTextChangeEvent*>(mEvent.get())->IsTextInserted();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccTextChangeEvent::GetModifiedText(nsAString& aModifiedText)
--- a/accessible/src/xul/Makefile.in
+++ b/accessible/src/xul/Makefile.in
@@ -67,9 +67,11 @@ CPPSRCS = \
 FORCE_STATIC_LIB = 1
 
 include $(topsrcdir)/config/rules.mk
 
 LOCAL_INCLUDES = \
   -I$(srcdir) \
   -I$(srcdir)/../base \
   -I$(srcdir)/../html \
+  -I$(srcdir)/../../../layout/generic \
+  -I$(srcdir)/../../../layout/xul/base/src \
   $(NULL)
--- a/accessible/src/xul/nsXULAlertAccessible.cpp
+++ b/accessible/src/xul/nsXULAlertAccessible.cpp
@@ -68,8 +68,26 @@ nsXULAlertAccessible::NativeState()
 NS_IMETHODIMP
 nsXULAlertAccessible::GetName(nsAString& aName)
 {
   // Screen readers need to read contents of alert, not the accessible name.
   // If we have both some screen readers will read the alert twice.
   aName.Truncate();
   return NS_OK;
 }
+
+////////////////////////////////////////////////////////////////////////////////
+// Widgets
+
+bool
+nsXULAlertAccessible::IsWidget() const
+{
+  return true;
+}
+
+nsAccessible*
+nsXULAlertAccessible::ContainerWidget() const
+{
+  // If a part of colorpicker widget.
+  if (mParent && mParent->IsMenuButton())
+    return mParent;
+  return nsnull;
+}
--- a/accessible/src/xul/nsXULAlertAccessible.h
+++ b/accessible/src/xul/nsXULAlertAccessible.h
@@ -52,11 +52,15 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIAccessible
   NS_IMETHOD GetName(nsAString& aName);
 
   // nsAccessible
   virtual PRUint32 NativeRole();
   virtual PRUint64 NativeState();
+
+  // Widgets
+  virtual bool IsWidget() const;
+  virtual nsAccessible* ContainerWidget() const;
 };
 
-#endif  
+#endif
--- a/accessible/src/xul/nsXULColorPickerAccessible.cpp
+++ b/accessible/src/xul/nsXULColorPickerAccessible.cpp
@@ -40,16 +40,17 @@
 
 #include "States.h"
 #include "nsAccUtils.h"
 #include "nsAccTreeWalker.h"
 #include "nsCoreUtils.h"
 #include "nsDocAccessible.h"
 
 #include "nsIDOMElement.h"
+#include "nsMenuPopupFrame.h"
 
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULColorPickerTileAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsXULColorPickerTileAccessible::
@@ -80,46 +81,50 @@ PRUint32
 nsXULColorPickerTileAccessible::NativeRole()
 {
   return nsIAccessibleRole::ROLE_PUSHBUTTON;
 }
 
 PRUint64
 nsXULColorPickerTileAccessible::NativeState()
 {
-  // Possible states: focused, focusable, selected.
-
-  // get focus and disable status from base class
-  PRUint64 states = nsAccessibleWrap::NativeState();
-
-  states |= states::FOCUSABLE;
+  PRUint64 state = nsAccessibleWrap::NativeState();
+  if (!(state & states::UNAVAILABLE))
+    state |= states::FOCUSABLE | states::SELECTABLE;
 
-  // Focused?
-  PRBool isFocused = mContent->HasAttr(kNameSpaceID_None,
-                                       nsGkAtoms::hover);
-  if (isFocused)
-    states |= states::FOCUSED;
+  if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::selected))
+    state |= states::SELECTED;
 
-  PRBool isSelected = mContent->HasAttr(kNameSpaceID_None,
-                                        nsGkAtoms::selected);
-  if (isSelected)
-    states |= states::SELECTED;
-
-  return states;
+  return state;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// nsXULColorPickerTileAccessible: Widgets
+
+nsAccessible*
+nsXULColorPickerTileAccessible::ContainerWidget() const
+{
+  nsAccessible* parent = Parent();
+  if (parent) {
+    nsAccessible* grandParent = parent->Parent();
+    if (grandParent && grandParent->IsMenuButton())
+      return grandParent;
+  }
+  return nsnull;
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULColorPickerAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsXULColorPickerAccessible::
   nsXULColorPickerAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
   nsXULColorPickerTileAccessible(aContent, aShell)
 {
+  mFlags |= eMenuButtonAccessible;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULColorPickerAccessible: nsAccessible
 
 PRUint64
 nsXULColorPickerAccessible::NativeState()
 {
@@ -135,16 +140,42 @@ nsXULColorPickerAccessible::NativeState(
 
 PRUint32
 nsXULColorPickerAccessible::NativeRole()
 {
   return nsIAccessibleRole::ROLE_BUTTONDROPDOWNGRID;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+// nsXULColorPickerAccessible: Widgets
+
+bool
+nsXULColorPickerAccessible::IsWidget() const
+{
+  return true;
+}
+
+bool
+nsXULColorPickerAccessible::IsActiveWidget() const
+{
+  return FocusMgr()->HasDOMFocus(mContent);
+}
+
+bool
+nsXULColorPickerAccessible::AreItemsOperable() const
+{
+  nsAccessible* menuPopup = mChildren.SafeElementAt(0, nsnull);
+  if (menuPopup) {
+    nsMenuPopupFrame* menuPopupFrame = do_QueryFrame(menuPopup->GetFrame());
+    return menuPopupFrame && menuPopupFrame->IsOpen();
+  }
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
 // nsXULColorPickerAccessible: protected nsAccessible
 
 void
 nsXULColorPickerAccessible::CacheChildren()
 {
   nsAccTreeWalker walker(mWeakShell, mContent, PR_TRUE);
 
   nsAccessible* child = nsnull;
--- a/accessible/src/xul/nsXULColorPickerAccessible.h
+++ b/accessible/src/xul/nsXULColorPickerAccessible.h
@@ -34,17 +34,16 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef _nsXULColorPickerAccessible_H_
 #define _nsXULColorPickerAccessible_H_
 
-// NOTE: alphabetically ordered
 #include "nsAccessibleWrap.h"
 
 /**
  * Used for color button in colorpicker palette.
  */
 class nsXULColorPickerTileAccessible : public nsAccessibleWrap
 {
 public:
@@ -52,30 +51,38 @@ public:
                                  nsIWeakReference *aShell);
 
   // nsIAccessible
   NS_IMETHOD GetValue(nsAString& _retval);
 
   // nsAccessible
   virtual PRUint32 NativeRole();
   virtual PRUint64 NativeState();
+
+  // Widgets
+  virtual nsAccessible* ContainerWidget() const;
 };
 
 
 /**
  * Used for colorpicker button (xul:colorpicker@type="button").
  */
 class nsXULColorPickerAccessible : public nsXULColorPickerTileAccessible
 {
 public:
   nsXULColorPickerAccessible(nsIContent *aContent, nsIWeakReference *aShell);
 
   // nsAccessible
   virtual PRUint32 NativeRole();
   virtual PRUint64 NativeState();
 
+  // Widgets
+  virtual bool IsWidget() const;
+  virtual bool IsActiveWidget() const;
+  virtual bool AreItemsOperable() const;
+
 protected:
 
   // nsAccessible
   virtual void CacheChildren();
 };
 
 #endif  
--- a/accessible/src/xul/nsXULComboboxAccessible.cpp
+++ b/accessible/src/xul/nsXULComboboxAccessible.cpp
@@ -39,36 +39,41 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsXULComboboxAccessible.h"
 
 #include "States.h"
 #include "nsAccessibilityService.h"
 #include "nsCoreUtils.h"
 
+#include "nsIAutoCompleteInput.h"
 #include "nsIDOMXULMenuListElement.h"
 #include "nsIDOMXULSelectCntrlItemEl.h"
 
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULComboboxAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsXULComboboxAccessible::
   nsXULComboboxAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
   nsAccessibleWrap(aContent, aShell)
 {
+  if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
+                            nsGkAtoms::autocomplete, eIgnoreCase))
+    mFlags |= eAutoCompleteAccessible;
+  else
+    mFlags |= eComboboxAccessible;
 }
 
 PRUint32
 nsXULComboboxAccessible::NativeRole()
 {
-  if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
-                            nsGkAtoms::autocomplete, eIgnoreCase))
+  if (IsAutoComplete())
     return nsIAccessibleRole::ROLE_AUTOCOMPLETE;
   return nsIAccessibleRole::ROLE_COMBOBOX;
 }
 
 PRUint64
 nsXULComboboxAccessible::NativeState()
 {
   // As a nsComboboxAccessible we can have the following states:
@@ -78,17 +83,17 @@ nsXULComboboxAccessible::NativeState()
   //     STATE_EXPANDED
   //     STATE_COLLAPSED
 
   // Get focus status from base class
   PRUint64 states = nsAccessible::NativeState();
 
   nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mContent));
   if (menuList) {
-    PRBool isOpen;
+    bool isOpen;
     menuList->GetOpen(&isOpen);
     if (isOpen) {
       states |= states::EXPANDED;
     }
     else {
       states |= states::COLLAPSED;
     }
   }
@@ -130,17 +135,17 @@ nsXULComboboxAccessible::Description(nsS
   if (focusedOptionContent) {
     nsAccessible* focusedOptionAcc = GetAccService()->
       GetAccessibleInWeakShell(focusedOptionContent, mWeakShell);
     if (focusedOptionAcc)
       focusedOptionAcc->Description(aDescription);
   }
 }
 
-PRBool
+bool
 nsXULComboboxAccessible::GetAllowsAnonChildAccessibles()
 {
   if (mContent->NodeInfo()->Equals(nsGkAtoms::textbox, kNameSpaceID_XUL) ||
       mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::editable,
                             nsGkAtoms::_true, eIgnoreCase)) {
     // Both the XUL <textbox type="autocomplete"> and <menulist editable="true"> widgets
     // use nsXULComboboxAccessible. We need to walk the anonymous children for these
     // so that the entry field is a child
@@ -168,17 +173,17 @@ nsXULComboboxAccessible::DoAction(PRUint
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   // Programmaticaly toggle the combo box.
   nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mContent));
   if (!menuList) {
     return NS_ERROR_FAILURE;
   }
-  PRBool isDroppedDown;
+  bool isDroppedDown;
   menuList->GetOpen(&isDroppedDown);
   return menuList->SetOpen(!isDroppedDown);
 }
 
 NS_IMETHODIMP
 nsXULComboboxAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
 {
   if (aIndex != nsXULComboboxAccessible::eAction_Click) {
@@ -192,17 +197,62 @@ nsXULComboboxAccessible::GetActionName(P
   //     if we are close -> open is our name.
   //     if we are open -> close is our name.
   // Uses the frame to get the state, updated on every click.
 
   nsCOMPtr<nsIDOMXULMenuListElement> menuList(do_QueryInterface(mContent));
   if (!menuList) {
     return NS_ERROR_FAILURE;
   }
-  PRBool isDroppedDown;
+  bool isDroppedDown;
   menuList->GetOpen(&isDroppedDown);
   if (isDroppedDown)
     aName.AssignLiteral("close"); 
   else
     aName.AssignLiteral("open"); 
 
   return NS_OK;
 }
+
+////////////////////////////////////////////////////////////////////////////////
+// Widgets
+
+bool
+nsXULComboboxAccessible::IsActiveWidget() const
+{
+  if (IsAutoComplete() ||
+     mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::editable,
+                           nsGkAtoms::_true, eIgnoreCase)) {
+    PRInt32 childCount = mChildren.Length();
+    for (PRInt32 idx = 0; idx < childCount; idx++) {
+      nsAccessible* child = mChildren[idx];
+      if (child->Role() == nsIAccessibleRole::ROLE_ENTRY)
+        return FocusMgr()->HasDOMFocus(child->GetContent());
+    }
+    return false;
+  }
+
+  return FocusMgr()->HasDOMFocus(mContent);
+}
+
+bool
+nsXULComboboxAccessible::AreItemsOperable() const
+{
+  if (IsAutoComplete()) {
+    nsCOMPtr<nsIAutoCompleteInput> autoCompleteInputElm =
+      do_QueryInterface(mContent);
+    if (autoCompleteInputElm) {
+      bool isOpen = false;
+      autoCompleteInputElm->GetPopupOpen(&isOpen);
+      return isOpen;
+    }
+    return false;
+  }
+
+  nsCOMPtr<nsIDOMXULMenuListElement> menuListElm = do_QueryInterface(mContent);
+  if (menuListElm) {
+    bool isOpen = false;
+    menuListElm->GetOpen(&isOpen);
+    return isOpen;
+  }
+
+  return false;
+}
--- a/accessible/src/xul/nsXULComboboxAccessible.h
+++ b/accessible/src/xul/nsXULComboboxAccessible.h
@@ -35,17 +35,16 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef __nsXULComboboxAccessible_h__
 #define __nsXULComboboxAccessible_h__
 
-#include "nsCOMPtr.h"
 #include "nsXULMenuAccessible.h"
 
 /**
  * Used for XUL comboboxes like xul:menulist and autocomplete textbox.
  */
 class nsXULComboboxAccessible : public nsAccessibleWrap
 {
 public:
@@ -57,15 +56,19 @@ public:
   NS_IMETHOD GetValue(nsAString& aValue);
   NS_IMETHOD DoAction(PRUint8 aIndex);
   NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
 
   // nsAccessible
   virtual void Description(nsString& aDescription);
   virtual PRUint32 NativeRole();
   virtual PRUint64 NativeState();
-  virtual PRBool GetAllowsAnonChildAccessibles();
+  virtual bool GetAllowsAnonChildAccessibles();
 
   // ActionAccessible
   virtual PRUint8 ActionCount();