Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Wed, 05 Oct 2011 19:31:59 -0700
changeset 112095 f606d92ca592497db15f59e0b25dfd2cd5368ed8
parent 112089 0a8cd435a41a12d550c395a253b85a8d2cd38bd4 (current diff)
parent 79807 4a69b3fdd602624c4d7d6aca74b7d4836d1e90de (diff)
child 112096 7ee944b1fb20bcd536455ddcfb6705560c7daf08
push id239
push userakeybl@mozilla.com
push dateThu, 03 Jan 2013 21:54:43 +0000
treeherdermozilla-release@3a7b66445659 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone10.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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 is