[JAEGER] Merge from Tracemonkey.
authorDavid Mandelin <dmandelin@mozilla.com>
Mon, 30 Aug 2010 11:38:48 -0700
changeset 53527 867a8622a35f44537bc9cc81b1ac0d6d18493374
parent 53526 9356a1b434a7f18904c6d4b0141219a180522c1d (current diff)
parent 52501 be9979b4c10b517edf4dc5020a214e0aff17c0cd (diff)
child 53528 b4703950e81810a9fc08d603bb321bdcef609fd3
child 53529 34f563050477cbe978ef8f3e4a7bba0d4b2ca143
push idunknown
push userunknown
push dateunknown
milestone2.0b5pre
[JAEGER] Merge from Tracemonkey.
accessible/src/base/nsAccEvent.cpp
accessible/src/base/nsAccEvent.h
content/base/public/nsContentUtils.h
content/base/src/nsContentUtils.cpp
content/base/src/nsFrameMessageManager.cpp
content/canvas/src/CustomQS_Canvas2D.h
content/canvas/src/NativeJSContext.cpp
content/canvas/src/NativeJSContext.h
content/canvas/test/webgl/conformance/00_test_list.txt
content/canvas/test/webgl/conformance/origin-clean-conformance.html
content/canvas/test/webgl/more/00_test_list.txt
content/canvas/test/webgl/test_list.txt
content/events/src/nsEventListenerManager.cpp
content/events/test/Makefile.in
content/html/content/src/nsHTMLMediaError.cpp
content/html/content/src/nsHTMLMediaError.h
content/html/content/src/nsHTMLTimeRanges.cpp
content/html/content/src/nsHTMLTimeRanges.h
content/html/content/src/nsIConstraintValidation.h
content/html/document/src/nsHTMLDocument.cpp
content/html/document/src/nsHTMLDocument.h
dom/base/nsDOMClassInfo.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/indexedDB/IDBCursor.cpp
dom/indexedDB/IDBObjectStore.cpp
dom/interfaces/html/nsIDOMHTMLMediaError.idl
dom/interfaces/html/nsIDOMHTMLTimeRanges.idl
js/jetpack/JetpackChild.cpp
js/src/config/rules.mk
js/src/configure.in
js/src/js.msg
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jsfun.cpp
js/src/json.cpp
js/src/json.h
js/src/jstl.h
js/src/jstracer.cpp
js/src/jstracer.h
js/src/trace-test/tests/basic/testStackQuotaExhausted.js
js/src/xpconnect/loader/mozJSComponentLoader.cpp
js/src/xpconnect/src/dom_quickstubs.qsconf
js/src/xpconnect/src/nsXPConnect.cpp
js/src/xpconnect/src/qsgen.py
js/src/xpconnect/src/xpccomponents.cpp
js/src/xpconnect/src/xpcconvert.cpp
js/src/xpconnect/src/xpcprivate.h
js/src/xpconnect/src/xpcquickstubs.cpp
js/src/xpconnect/src/xpcquickstubs.h
js/src/xpconnect/src/xpcthreadcontext.cpp
js/src/xpconnect/src/xpcvariant.cpp
js/src/xpconnect/src/xpcwrappedjsclass.cpp
js/src/xpconnect/src/xpcwrappednative.cpp
modules/libpref/src/init/all.js
testing/mochitest/runtests.py
toolkit/mozapps/extensions/test/xpcshell/data/test_bug404024.xml
toolkit/mozapps/extensions/test/xpcshell/data/test_bug417606.xml
toolkit/mozapps/extensions/test/xpcshell/test_bug404024.js
toolkit/mozapps/extensions/test/xpcshell/test_bug417606.js
toolkit/themes/gnomestripe/global/headsUpDisplay.css
toolkit/themes/pinstripe/global/headsUpDisplay.css
toolkit/themes/winstripe/global/headsUpDisplay.css
widget/src/gtk2/keysym2ucs.c
widget/src/gtk2/keysym2ucs.h
--- a/.hgignore
+++ b/.hgignore
@@ -4,17 +4,17 @@
 ~$
 \.py(c|o)$
 (?i)(^|/)TAGS$
 (^|/)ID$
 (^|/)\.DS_Store$
 
 # User files that may appear at the root
 ^\.mozconfig
-^mozconfig
+^mozconfig$
 ^configure$
 ^config\.cache$
 ^config\.log$
 
 # Empty marker file that's generated when we check out NSS
 ^security/manager/\.nss\.checkout$
 
 # Build directories
--- a/.hgtags
+++ b/.hgtags
@@ -47,8 +47,9 @@ a732c6d3c078f80635255c78bfaadffa5828a8a5
 925595f3c08634cc42e33158ea6858bb55623ef7 last-mozilla-central
 dba2abb7db57078c5a4810884834d3056a5d56c2 last-mozilla-central
 138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R9
 138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R10
 138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R11
 0327e126ea245112c0aa7283fee154e084866fb5 bsmedberg-static-xpcom-registration-base
 0327e126ea245112c0aa7283fee154e084866fb5 bsmedberg-static-xpcom-registration-base
 2f83edbbeef0de7dd901411d270da61106c8afae bsmedberg-static-xpcom-registration-base
+138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R12
--- a/accessible/build/Makefile.in
+++ b/accessible/build/Makefile.in
@@ -54,16 +54,17 @@ LIBXUL_LIBRARY	= 1
 
 CPPSRCS		= nsAccessibilityFactory.cpp
 
 LOCAL_INCLUDES	= -I$(srcdir)/../src
 
 SHARED_LIBRARY_LIBS = \
 	../src/base/$(LIB_PREFIX)accessibility_base_s.$(LIB_SUFFIX) \
 	../src/html/$(LIB_PREFIX)accessibility_html_s.$(LIB_SUFFIX) \
+	../src/xpcom/$(LIB_PREFIX)accessibility_xpcom_s.$(LIB_SUFFIX) \
 	../src/$(LIB_PREFIX)accessibility_toolkit_s.$(LIB_SUFFIX) \
 	$(NULL)
 
 ifdef MOZ_XUL
 SHARED_LIBRARY_LIBS += ../src/xul/$(LIB_PREFIX)accessibility_xul_s.$(LIB_SUFFIX)
 endif
 
 ifndef DISABLE_XFORMS_HOOKS
--- a/accessible/public/nsIAccessibleEvent.idl
+++ b/accessible/public/nsIAccessibleEvent.idl
@@ -54,17 +54,17 @@ interface nsIDOMNode;
  * the event and its target. To listen to in-process accessibility invents,
  * make your object an nsIObserver, and listen for accessible-event by 
  * using code something like this:
  *   nsCOMPtr<nsIObserverService> observerService = 
  *     do_GetService("@mozilla.org/observer-service;1", &rv);
  *   if (NS_SUCCEEDED(rv)) 
  *     rv = observerService->AddObserver(this, "accessible-event", PR_TRUE);
  */
-[scriptable, uuid(c68b4386-dca7-4b88-8988-7a95ce7be92f)]
+[scriptable, uuid(fd1378c5-c606-4a5e-a321-8e7fc107e5cf)]
 interface nsIAccessibleEvent : nsISupports
 {
   /**
    * An object has been created.
    */
   const unsigned long EVENT_SHOW = 0x0001;
 
   /**
@@ -471,17 +471,17 @@ interface nsIAccessibleEvent : nsISuppor
    * May return null if accessible for event has been shut down
    */
   readonly attribute nsIDOMNode DOMNode;
 
   /**
    * Returns true if the event was caused by explicit user input,
    * as opposed to purely originating from a timer or mouse movement
    */
-  attribute boolean isFromUserInput;
+  readonly attribute boolean isFromUserInput;
 };
 
 
 [scriptable, uuid(9addd25d-8fa1-415e-94ec-6038f220d3e4)]
 interface nsIAccessibleStateChangeEvent : nsISupports
 {
   /**
    * Returns the state of accessible (see constants declared
--- a/accessible/src/Makefile.in
+++ b/accessible/src/Makefile.in
@@ -57,16 +57,17 @@ endif
 endif
 endif
 
 DIRS += $(PLATFORM_DIR)
 
 DIRS += \
   base \
   html \
+  xpcom \
   $(null)
 
 ifdef MOZ_XUL
 DIRS +=   xul
 endif
 
 ifndef DISABLE_XFORMS_HOOKS
 DIRS +=   xforms
--- a/accessible/src/atk/nsAccessibleWrap.cpp
+++ b/accessible/src/atk/nsAccessibleWrap.cpp
@@ -1045,26 +1045,26 @@ nsAccessibleWrap *GetAccessibleWrap(AtkO
 
     if (tmpAppAccWrap != tmpAccWrap && !tmpAccWrap->IsValidObject())
         return nsnull;
 
     return tmpAccWrap;
 }
 
 nsresult
-nsAccessibleWrap::HandleAccEvent(nsAccEvent *aEvent)
+nsAccessibleWrap::HandleAccEvent(AccEvent* aEvent)
 {
     nsresult rv = nsAccessible::HandleAccEvent(aEvent);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return FirePlatformEvent(aEvent);
 }
 
 nsresult
-nsAccessibleWrap::FirePlatformEvent(nsAccEvent *aEvent)
+nsAccessibleWrap::FirePlatformEvent(AccEvent* aEvent)
 {
     nsAccessible *accessible = aEvent->GetAccessible();
     NS_ENSURE_TRUE(accessible, NS_ERROR_FAILURE);
 
     PRUint32 type = aEvent->GetEventType();
 
     AtkObject *atkObj = nsAccessibleWrap::GetAtkObject(accessible);
 
@@ -1092,20 +1092,20 @@ nsAccessibleWrap::FirePlatformEvent(nsAc
 
     case nsIAccessibleEvent::EVENT_FOCUS:
       {
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_FOCUS\n"));
         nsRefPtr<nsRootAccessible> rootAccWrap = accWrap->GetRootAccessible();
         if (rootAccWrap && rootAccWrap->mActivated) {
             atk_focus_tracker_notify(atkObj);
             // Fire state change event for focus
-            nsRefPtr<nsAccEvent> stateChangeEvent =
-              new nsAccStateChangeEvent(accessible,
-                                        nsIAccessibleStates::STATE_FOCUSED,
-                                        PR_FALSE, PR_TRUE);
+            nsRefPtr<AccEvent> stateChangeEvent =
+              new AccStateChangeEvent(accessible,
+                                      nsIAccessibleStates::STATE_FOCUSED,
+                                      PR_FALSE, PR_TRUE);
             return FireAtkStateChangeEvent(stateChangeEvent, atkObj);
         }
       } break;
 
     case nsIAccessibleEvent::EVENT_VALUE_CHANGE:
       {
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_VALUE_CHANGE\n"));
         nsCOMPtr<nsIAccessibleValue> value(do_QueryObject(accessible));
@@ -1125,17 +1125,17 @@ nsAccessibleWrap::FirePlatformEvent(nsAc
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_SELECTION_CHANGED\n"));
         g_signal_emit_by_name(atkObj, "text_selection_changed");
         break;
 
     case nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED:
       {
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_CARET_MOVED\n"));
 
-        nsAccCaretMoveEvent *caretMoveEvent = downcast_accEvent(aEvent);
+        AccCaretMoveEvent* caretMoveEvent = downcast_accEvent(aEvent);
         NS_ASSERTION(caretMoveEvent, "Event needs event data");
         if (!caretMoveEvent)
             break;
 
         PRInt32 caretOffset = caretMoveEvent->GetCaretOffset();
 
         MAI_LOG_DEBUG(("\n\nCaret postion: %d", caretOffset));
         g_signal_emit_by_name(atkObj,
@@ -1154,34 +1154,34 @@ nsAccessibleWrap::FirePlatformEvent(nsAc
     case nsIAccessibleEvent::EVENT_TABLE_MODEL_CHANGED:
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_MODEL_CHANGED\n"));
         g_signal_emit_by_name(atkObj, "model_changed");
         break;
 
     case nsIAccessibleEvent::EVENT_TABLE_ROW_INSERT:
       {
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_ROW_INSERT\n"));
-        nsAccTableChangeEvent *tableEvent = downcast_accEvent(aEvent);
+        AccTableChangeEvent* tableEvent = downcast_accEvent(aEvent);
         NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE);
 
         PRInt32 rowIndex = tableEvent->GetIndex();
         PRInt32 numRows = tableEvent->GetCount();
 
         g_signal_emit_by_name(atkObj,
                               "row_inserted",
                               // After which the rows are inserted
                               rowIndex,
                               // The number of the inserted
                               numRows);
      } break;
 
    case nsIAccessibleEvent::EVENT_TABLE_ROW_DELETE:
      {
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_ROW_DELETE\n"));
-        nsAccTableChangeEvent *tableEvent = downcast_accEvent(aEvent);
+        AccTableChangeEvent* tableEvent = downcast_accEvent(aEvent);
         NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE);
 
         PRInt32 rowIndex = tableEvent->GetIndex();
         PRInt32 numRows = tableEvent->GetCount();
 
         g_signal_emit_by_name(atkObj,
                               "row_deleted",
                               // After which the rows are deleted
@@ -1195,34 +1195,34 @@ nsAccessibleWrap::FirePlatformEvent(nsAc
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_ROW_REORDER\n"));
         g_signal_emit_by_name(atkObj, "row_reordered");
         break;
       }
 
     case nsIAccessibleEvent::EVENT_TABLE_COLUMN_INSERT:
       {
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_COLUMN_INSERT\n"));
-        nsAccTableChangeEvent *tableEvent = downcast_accEvent(aEvent);
+        AccTableChangeEvent* tableEvent = downcast_accEvent(aEvent);
         NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE);
 
         PRInt32 colIndex = tableEvent->GetIndex();
         PRInt32 numCols = tableEvent->GetCount();
 
         g_signal_emit_by_name(atkObj,
                               "column_inserted",
                               // After which the columns are inserted
                               colIndex,
                               // The number of the inserted
                               numCols);
       } break;
 
     case nsIAccessibleEvent::EVENT_TABLE_COLUMN_DELETE:
       {
         MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_COLUMN_DELETE\n"));
-        nsAccTableChangeEvent *tableEvent = downcast_accEvent(aEvent);
+        AccTableChangeEvent* tableEvent = downcast_accEvent(aEvent);
         NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE);
 
         PRInt32 colIndex = tableEvent->GetIndex();
         PRInt32 numCols = tableEvent->GetCount();
 
         g_signal_emit_by_name(atkObj,
                               "column_deleted",
                               // After which the columns are deleted
@@ -1315,22 +1315,22 @@ nsAccessibleWrap::FirePlatformEvent(nsAc
         atk_object_notify_state_change(atkObj, ATK_STATE_SHOWING, PR_FALSE);
         break;
     }
 
     return NS_OK;
 }
 
 nsresult
-nsAccessibleWrap::FireAtkStateChangeEvent(nsAccEvent *aEvent,
+nsAccessibleWrap::FireAtkStateChangeEvent(AccEvent* aEvent,
                                           AtkObject *aObject)
 {
     MAI_LOG_DEBUG(("\n\nReceived: EVENT_STATE_CHANGE\n"));
 
-    nsAccStateChangeEvent *event = downcast_accEvent(aEvent);
+    AccStateChangeEvent* event = downcast_accEvent(aEvent);
     NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);
 
     PRUint32 state = event->GetState();
     PRBool isExtra = event->IsExtraState();
     PRBool isEnabled = event->IsStateEnabled();
 
     PRInt32 stateIndex = AtkStateMap::GetStateIndexFor(state);
     if (stateIndex >= 0) {
@@ -1351,22 +1351,22 @@ nsAccessibleWrap::FireAtkStateChangeEven
                                            isEnabled);
         }
     }
 
     return NS_OK;
 }
 
 nsresult
-nsAccessibleWrap::FireAtkTextChangedEvent(nsAccEvent *aEvent,
+nsAccessibleWrap::FireAtkTextChangedEvent(AccEvent* aEvent,
                                           AtkObject *aObject)
 {
     MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_REMOVED/INSERTED\n"));
 
-    nsAccTextChangeEvent *event = downcast_accEvent(aEvent);
+    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();
 
@@ -1374,17 +1374,17 @@ nsAccessibleWrap::FireAtkTextChangedEven
                                     isFromUserInput ? "" : kNonUserInputEvent, NULL);
     g_signal_emit_by_name(aObject, signal_name, start, length);
     g_free (signal_name);
 
     return NS_OK;
 }
 
 nsresult
-nsAccessibleWrap::FireAtkShowHideEvent(nsAccEvent *aEvent,
+nsAccessibleWrap::FireAtkShowHideEvent(AccEvent* aEvent,
                                        AtkObject *aObject, PRBool aIsAdded)
 {
     if (aIsAdded)
         MAI_LOG_DEBUG(("\n\nReceived: Show event\n"));
     else
         MAI_LOG_DEBUG(("\n\nReceived: Hide event\n"));
 
     PRInt32 indexInParent = getIndexInParentCB(aObject);
--- a/accessible/src/atk/nsAccessibleWrap.h
+++ b/accessible/src/atk/nsAccessibleWrap.h
@@ -95,17 +95,17 @@ public:
 #ifdef MAI_LOGGING
     virtual void DumpnsAccessibleWrapInfo(int aDepth) {}
     static PRInt32 mAccWrapCreated;
     static PRInt32 mAccWrapDeleted;
 #endif
 
     // return the atk object for this nsAccessibleWrap
     NS_IMETHOD GetNativeInterface(void **aOutAccessible);
-    virtual nsresult HandleAccEvent(nsAccEvent *aEvent);
+    virtual nsresult HandleAccEvent(AccEvent* aEvent);
 
     AtkObject * GetAtkObject(void);
     static AtkObject * GetAtkObject(nsIAccessible * acc);
 
     PRBool IsValidObject();
     
     // get/set the MaiHyperlink object for this nsAccessibleWrap
     MaiHyperlink* GetMaiHyperlink(PRBool aCreate = PR_TRUE);
@@ -113,21 +113,21 @@ public:
 
     static const char * ReturnString(nsAString &aString) {
       static nsCString returnedString;
       returnedString = NS_ConvertUTF16toUTF8(aString);
       return returnedString.get();
     }
 
 protected:
-    virtual nsresult FirePlatformEvent(nsAccEvent *aEvent);
+    virtual nsresult FirePlatformEvent(AccEvent* aEvent);
 
-    nsresult FireAtkStateChangeEvent(nsAccEvent *aEvent, AtkObject *aObject);
-    nsresult FireAtkTextChangedEvent(nsAccEvent *aEvent, AtkObject *aObject);
-    nsresult FireAtkShowHideEvent(nsAccEvent *aEvent, AtkObject *aObject,
+    nsresult FireAtkStateChangeEvent(AccEvent* aEvent, AtkObject *aObject);
+    nsresult FireAtkTextChangedEvent(AccEvent* aEvent, AtkObject *aObject);
+    nsresult FireAtkShowHideEvent(AccEvent* aEvent, AtkObject *aObject,
                                   PRBool aIsAdded);
 
     AtkObject *mAtkObject;
 
 private:
     PRUint16 CreateMaiInterfaces(void);
 };
 
rename from accessible/src/base/nsAccEvent.cpp
rename to accessible/src/base/AccEvent.cpp
--- a/accessible/src/base/nsAccEvent.cpp
+++ b/accessible/src/base/AccEvent.cpp
@@ -15,189 +15,138 @@
  * The Original Code is mozilla.org code.
  *
  * The Initial Developer of the Original Code is
  * Netscape Communications Corporation.
  * Portions created by the Initial Developer are Copyright (C) 2003
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
- *   Original Author: Aaron Leventhal (aaronl@netscape.com)
+ *   Aaron Leventhal <aaronl@netscape.com> <original author>
+ *   Alexander Surkov <surkov.alexander@gmail.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either of the GNU General Public License Version 2 or later (the "GPL"),
  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
  * 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 "nsAccEvent.h"
+#include "AccEvent.h"
 
 #include "nsAccessibilityService.h"
 #include "nsAccUtils.h"
 #include "nsApplicationAccessibleWrap.h"
 #include "nsDocAccessible.h"
 #include "nsIAccessibleText.h"
 #ifdef MOZ_XUL
 #include "nsXULTreeAccessible.h"
 #endif
+#include "nsAccEvent.h"
 
 #include "nsIDOMDocument.h"
 #include "nsIEventStateManager.h"
 #include "nsIServiceManager.h"
 #ifdef MOZ_XUL
 #include "nsIDOMXULMultSelectCntrlEl.h"
 #endif
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsAccEvent
+// AccEvent
 ////////////////////////////////////////////////////////////////////////////////
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsAccEvent. nsISupports
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(nsAccEvent)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsAccEvent)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mAccessible)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsAccEvent)
-  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mAccessible");
-  cb.NoteXPCOMChild(static_cast<nsIAccessible*>(tmp->mAccessible));
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+// AccEvent constructors
 
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsAccEvent)
-  NS_INTERFACE_MAP_ENTRY(nsIAccessibleEvent)
-  NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(nsAccEvent)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(nsAccEvent)
-
-////////////////////////////////////////////////////////////////////////////////
-// nsAccEvent. Constructors
-
-nsAccEvent::nsAccEvent(PRUint32 aEventType, nsAccessible *aAccessible,
-                       PRBool aIsAsync, EIsFromUserInput aIsFromUserInput,
-                       EEventRule aEventRule) :
+AccEvent::AccEvent(PRUint32 aEventType, nsAccessible* aAccessible,
+                   PRBool aIsAsync, EIsFromUserInput aIsFromUserInput,
+                   EEventRule aEventRule) :
   mEventType(aEventType), mEventRule(aEventRule), mIsAsync(aIsAsync),
   mAccessible(aAccessible)
 {
   CaptureIsFromUserInput(aIsFromUserInput);
 }
 
-nsAccEvent::nsAccEvent(PRUint32 aEventType, nsINode *aNode,
-                       PRBool aIsAsync, EIsFromUserInput aIsFromUserInput,
-                       EEventRule aEventRule) :
+AccEvent::AccEvent(PRUint32 aEventType, nsINode* aNode,
+                   PRBool aIsAsync, EIsFromUserInput aIsFromUserInput,
+                   EEventRule aEventRule) :
   mEventType(aEventType), mEventRule(aEventRule), mIsAsync(aIsAsync),
   mNode(aNode)
 {
   CaptureIsFromUserInput(aIsFromUserInput);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsAccEvent: nsIAccessibleEvent
-
-NS_IMETHODIMP
-nsAccEvent::GetIsFromUserInput(PRBool *aIsFromUserInput)
-{
-  *aIsFromUserInput = mIsFromUserInput;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccEvent::SetIsFromUserInput(PRBool aIsFromUserInput)
-{
-  mIsFromUserInput = aIsFromUserInput;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccEvent::GetEventType(PRUint32 *aEventType)
-{
-  *aEventType = mEventType;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccEvent::GetAccessible(nsIAccessible **aAccessible)
-{
-  NS_ENSURE_ARG_POINTER(aAccessible);
-  *aAccessible = nsnull;
-
-  NS_IF_ADDREF(*aAccessible = GetAccessible());
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccEvent::GetDOMNode(nsIDOMNode **aDOMNode)
-{
-  NS_ENSURE_ARG_POINTER(aDOMNode);
-  *aDOMNode = nsnull;
-
-  if (!mNode)
-    mNode = GetNode();
-
-  if (mNode)
-    CallQueryInterface(mNode, aDOMNode);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccEvent::GetAccessibleDocument(nsIAccessibleDocument **aDocAccessible)
-{
-  NS_ENSURE_ARG_POINTER(aDocAccessible);
-
-  NS_IF_ADDREF(*aDocAccessible = GetDocAccessible());
-  return NS_OK;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// nsAccEvent: public methods
+// AccEvent public methods
 
 nsAccessible *
-nsAccEvent::GetAccessible()
+AccEvent::GetAccessible()
 {
   if (!mAccessible)
     mAccessible = GetAccessibleForNode();
 
   return mAccessible;
 }
 
 nsINode*
-nsAccEvent::GetNode()
+AccEvent::GetNode()
 {
   if (!mNode && mAccessible)
     mNode = mAccessible->GetNode();
 
   return mNode;
 }
 
 nsDocAccessible*
-nsAccEvent::GetDocAccessible()
+AccEvent::GetDocAccessible()
 {
   nsINode *node = GetNode();
   if (node)
     return GetAccService()->GetDocAccessible(node->GetOwnerDoc());
 
   return nsnull;
 }
 
+already_AddRefed<nsAccEvent>
+AccEvent::CreateXPCOMObject()
+{
+  nsAccEvent* event = new nsAccEvent(this);
+  NS_IF_ADDREF(event);
+  return event;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
-// nsAccEvent: protected methods
+// AccEvent cycle collection
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(AccEvent)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(AccEvent)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mAccessible)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(AccEvent)
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mAccessible");
+  cb.NoteXPCOMChild(static_cast<nsIAccessible*>(tmp->mAccessible));
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AccEvent, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AccEvent, Release)
+
+////////////////////////////////////////////////////////////////////////////////
+// AccEvent protected methods
 
 nsAccessible *
-nsAccEvent::GetAccessibleForNode() const
+AccEvent::GetAccessibleForNode() const
 {
   if (!mNode)
     return nsnull;
 
   nsAccessible *accessible = GetAccService()->GetAccessible(mNode);
 
 #ifdef MOZ_XUL
   // hack for xul tree table. We need a better way for firing delayed event
@@ -222,17 +171,17 @@ nsAccEvent::GetAccessibleForNode() const
     }
   }
 #endif
 
   return accessible;
 }
 
 void
-nsAccEvent::CaptureIsFromUserInput(EIsFromUserInput aIsFromUserInput)
+AccEvent::CaptureIsFromUserInput(EIsFromUserInput aIsFromUserInput)
 {
   nsINode *targetNode = GetNode();
 
 #ifdef DEBUG
   if (!targetNode) {
     // XXX: remove this hack during reorganization of 506907. Meanwhile we
     // want to get rid an assertion for application accessible events which
     // don't have DOM node (see bug 506206).
@@ -264,252 +213,190 @@ nsAccEvent::CaptureIsFromUserInput(EIsFr
     return;
   }
 
   mIsFromUserInput = esm->IsHandlingUserInputExternal();
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsAccReorderEvent
+// AccReorderEvent
 ////////////////////////////////////////////////////////////////////////////////
 
-NS_IMPL_ISUPPORTS_INHERITED0(nsAccReorderEvent, nsAccEvent)
-
-nsAccReorderEvent::nsAccReorderEvent(nsAccessible *aAccTarget,
-                                     PRBool aIsAsynch,
-                                     PRBool aIsUnconditional,
-                                     nsINode *aReasonNode) :
-  nsAccEvent(::nsIAccessibleEvent::EVENT_REORDER, aAccTarget,
-             aIsAsynch, eAutoDetect, nsAccEvent::eCoalesceFromSameSubtree),
+AccReorderEvent::
+  AccReorderEvent(nsAccessible* aAccTarget, PRBool aIsAsynch,
+                  PRBool aIsUnconditional, nsINode* aReasonNode) :
+  AccEvent(::nsIAccessibleEvent::EVENT_REORDER, aAccTarget,
+           aIsAsynch, eAutoDetect, AccEvent::eCoalesceFromSameSubtree),
   mUnconditionalEvent(aIsUnconditional), mReasonNode(aReasonNode)
 {
 }
 
 PRBool
-nsAccReorderEvent::IsUnconditionalEvent()
+AccReorderEvent::IsUnconditionalEvent()
 {
   return mUnconditionalEvent;
 }
 
 PRBool
-nsAccReorderEvent::HasAccessibleInReasonSubtree()
+AccReorderEvent::HasAccessibleInReasonSubtree()
 {
   if (!mReasonNode)
     return PR_FALSE;
 
   nsAccessible *accessible = GetAccService()->GetAccessible(mReasonNode);
   return accessible || nsAccUtils::HasAccessibleChildren(mReasonNode);
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsAccStateChangeEvent
+// AccStateChangeEvent
 ////////////////////////////////////////////////////////////////////////////////
 
-NS_IMPL_ISUPPORTS_INHERITED1(nsAccStateChangeEvent, nsAccEvent,
-                             nsIAccessibleStateChangeEvent)
-
 // 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).
-nsAccStateChangeEvent::
-  nsAccStateChangeEvent(nsAccessible *aAccessible,
-                        PRUint32 aState, PRBool aIsExtraState,
-                        PRBool aIsEnabled, PRBool aIsAsynch,
-                        EIsFromUserInput aIsFromUserInput):
-  nsAccEvent(nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible, aIsAsynch,
-             aIsFromUserInput, eAllowDupes),
+AccStateChangeEvent::
+  AccStateChangeEvent(nsAccessible* aAccessible,
+                      PRUint32 aState, PRBool aIsExtraState,
+                      PRBool aIsEnabled, PRBool aIsAsynch,
+                      EIsFromUserInput aIsFromUserInput):
+  AccEvent(nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible, aIsAsynch,
+           aIsFromUserInput, eAllowDupes),
   mState(aState), mIsExtraState(aIsExtraState), mIsEnabled(aIsEnabled)
 {
 }
 
-nsAccStateChangeEvent::
-  nsAccStateChangeEvent(nsINode *aNode, PRUint32 aState, PRBool aIsExtraState,
-                        PRBool aIsEnabled):
-  nsAccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aNode),
+AccStateChangeEvent::
+  AccStateChangeEvent(nsINode* aNode, PRUint32 aState, PRBool aIsExtraState,
+                      PRBool aIsEnabled):
+  AccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aNode),
   mState(aState), mIsExtraState(aIsExtraState), mIsEnabled(aIsEnabled)
 {
 }
 
-nsAccStateChangeEvent::
-  nsAccStateChangeEvent(nsINode *aNode, PRUint32 aState, PRBool aIsExtraState) :
-  nsAccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aNode),
+AccStateChangeEvent::
+  AccStateChangeEvent(nsINode* aNode, PRUint32 aState, PRBool aIsExtraState) :
+  AccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aNode),
   mState(aState), mIsExtraState(aIsExtraState)
 {
   // Use GetAccessibleForNode() because we do not want to store an accessible
   // since it leads to problems with delayed events in the case when
   // an accessible gets reorder event before delayed event is processed.
   nsAccessible *accessible = GetAccessibleForNode();
   if (accessible) {
     PRUint32 state = 0, extraState = 0;
     accessible->GetState(&state, mIsExtraState ? &extraState : nsnull);
     mIsEnabled = ((mIsExtraState ? extraState : state) & mState) != 0;
   } else {
     mIsEnabled = PR_FALSE;
   }
 }
 
-NS_IMETHODIMP
-nsAccStateChangeEvent::GetState(PRUint32 *aState)
+already_AddRefed<nsAccEvent>
+AccStateChangeEvent::CreateXPCOMObject()
 {
-  NS_ENSURE_ARG_POINTER(aState);
-  *aState = mState;
-  return NS_OK;
+  nsAccEvent* event = new nsAccStateChangeEvent(this);
+  NS_IF_ADDREF(event);
+  return event;
 }
 
-NS_IMETHODIMP
-nsAccStateChangeEvent::IsExtraState(PRBool *aIsExtraState)
-{
-  NS_ENSURE_ARG_POINTER(aIsExtraState);
-  *aIsExtraState = mIsExtraState;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccStateChangeEvent::IsEnabled(PRBool *aIsEnabled)
-{
-  NS_ENSURE_ARG_POINTER(aIsEnabled);
-  *aIsEnabled = mIsEnabled;
-  return NS_OK;
-}
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsAccTextChangeEvent
+// AccTextChangeEvent
 ////////////////////////////////////////////////////////////////////////////////
 
-NS_IMPL_ISUPPORTS_INHERITED1(nsAccTextChangeEvent, nsAccEvent,
-                             nsIAccessibleTextChangeEvent)
-
 // Note: we pass in eAllowDupes to the base class because we don't support text
 // events coalescence. We fire delayed text change events in nsDocAccessible but
 // 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)
-nsAccTextChangeEvent::
-  nsAccTextChangeEvent(nsAccessible *aAccessible, PRInt32 aStart,
-                       nsAString& aModifiedText, PRBool aIsInserted,
-                       PRBool aIsAsynch, EIsFromUserInput aIsFromUserInput)
-  : nsAccEvent(aIsInserted ?
-               static_cast<PRUint32>(nsIAccessibleEvent::EVENT_TEXT_INSERTED) :
-               static_cast<PRUint32>(nsIAccessibleEvent::EVENT_TEXT_REMOVED),
-               aAccessible, aIsAsynch, aIsFromUserInput, eAllowDupes)
+AccTextChangeEvent::
+  AccTextChangeEvent(nsAccessible* aAccessible, PRInt32 aStart,
+                     nsAString& aModifiedText, PRBool aIsInserted,
+                     PRBool aIsAsynch, EIsFromUserInput aIsFromUserInput)
+  : AccEvent(aIsInserted ?
+             static_cast<PRUint32>(nsIAccessibleEvent::EVENT_TEXT_INSERTED) :
+             static_cast<PRUint32>(nsIAccessibleEvent::EVENT_TEXT_REMOVED),
+             aAccessible, aIsAsynch, aIsFromUserInput, eAllowDupes)
   , mStart(aStart)
   , mIsInserted(aIsInserted)
   , mModifiedText(aModifiedText)
 {
 }
 
-NS_IMETHODIMP
-nsAccTextChangeEvent::GetStart(PRInt32 *aStart)
-{
-  NS_ENSURE_ARG_POINTER(aStart);
-  *aStart = mStart;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccTextChangeEvent::GetLength(PRUint32 *aLength)
+already_AddRefed<nsAccEvent>
+AccTextChangeEvent::CreateXPCOMObject()
 {
-  NS_ENSURE_ARG_POINTER(aLength);
-  *aLength = GetLength();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccTextChangeEvent::IsInserted(PRBool *aIsInserted)
-{
-  NS_ENSURE_ARG_POINTER(aIsInserted);
-  *aIsInserted = mIsInserted;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsAccTextChangeEvent::GetModifiedText(nsAString& aModifiedText)
-{
-  aModifiedText = mModifiedText;
-  return NS_OK;
+  nsAccEvent* event = new nsAccTextChangeEvent(this);
+  NS_IF_ADDREF(event);
+  return event;
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // AccHideEvent
 ////////////////////////////////////////////////////////////////////////////////
 
 AccHideEvent::
   AccHideEvent(nsAccessible* aTarget, nsINode* aTargetNode,
                PRBool aIsAsynch, EIsFromUserInput aIsFromUserInput) :
-  nsAccEvent(nsIAccessibleEvent::EVENT_HIDE, aTarget, aIsAsynch,
-             aIsFromUserInput, eCoalesceFromSameSubtree)
+  AccEvent(nsIAccessibleEvent::EVENT_HIDE, aTarget, aIsAsynch,
+           aIsFromUserInput, eCoalesceFromSameSubtree)
 {
   mNode = aTargetNode;
   mParent = mAccessible->GetCachedParent();
   mNextSibling = mAccessible->GetCachedNextSibling();
   mPrevSibling = mAccessible->GetCachedPrevSibling();
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsAccCaretMoveEvent
+// AccCaretMoveEvent
 ////////////////////////////////////////////////////////////////////////////////
 
-NS_IMPL_ISUPPORTS_INHERITED1(nsAccCaretMoveEvent, nsAccEvent,
-                             nsIAccessibleCaretMoveEvent)
-
-nsAccCaretMoveEvent::
-  nsAccCaretMoveEvent(nsAccessible *aAccessible, PRInt32 aCaretOffset) :
-  nsAccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED, aAccessible, PR_TRUE), // Currently always asynch
+AccCaretMoveEvent::
+  AccCaretMoveEvent(nsAccessible* aAccessible, PRInt32 aCaretOffset) :
+  AccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED, aAccessible, PR_TRUE), // Currently always asynch
   mCaretOffset(aCaretOffset)
 {
 }
 
-nsAccCaretMoveEvent::
-  nsAccCaretMoveEvent(nsINode *aNode) :
-  nsAccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED, aNode, PR_TRUE), // Currently always asynch
+AccCaretMoveEvent::
+  AccCaretMoveEvent(nsINode* aNode) :
+  AccEvent(::nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED, aNode, PR_TRUE), // Currently always asynch
   mCaretOffset(-1)
 {
 }
 
-NS_IMETHODIMP
-nsAccCaretMoveEvent::GetCaretOffset(PRInt32* aCaretOffset)
+already_AddRefed<nsAccEvent>
+AccCaretMoveEvent::CreateXPCOMObject()
 {
-  NS_ENSURE_ARG_POINTER(aCaretOffset);
+  nsAccEvent* event = new nsAccCaretMoveEvent(this);
+  NS_IF_ADDREF(event);
+  return event;
+}
 
-  *aCaretOffset = mCaretOffset;
-  return NS_OK;
-}
 
 ////////////////////////////////////////////////////////////////////////////////
-// nsAccTableChangeEvent
+// AccTableChangeEvent
 ////////////////////////////////////////////////////////////////////////////////
 
-NS_IMPL_ISUPPORTS_INHERITED1(nsAccTableChangeEvent, nsAccEvent,
-                             nsIAccessibleTableChangeEvent)
-
-nsAccTableChangeEvent::
-  nsAccTableChangeEvent(nsAccessible *aAccessible, PRUint32 aEventType,
-                        PRInt32 aRowOrColIndex, PRInt32 aNumRowsOrCols, PRBool aIsAsynch):
-  nsAccEvent(aEventType, aAccessible, aIsAsynch), 
+AccTableChangeEvent::
+  AccTableChangeEvent(nsAccessible* aAccessible, PRUint32 aEventType,
+                      PRInt32 aRowOrColIndex, PRInt32 aNumRowsOrCols,
+                      PRBool aIsAsynch) :
+  AccEvent(aEventType, aAccessible, aIsAsynch),
   mRowOrColIndex(aRowOrColIndex), mNumRowsOrCols(aNumRowsOrCols)
 {
 }
 
-NS_IMETHODIMP
-nsAccTableChangeEvent::GetRowOrColIndex(PRInt32* aRowOrColIndex)
+already_AddRefed<nsAccEvent>
+AccTableChangeEvent::CreateXPCOMObject()
 {
-  NS_ENSURE_ARG_POINTER(aRowOrColIndex);
-
-  *aRowOrColIndex = mRowOrColIndex;
-  return NS_OK;
+  nsAccEvent* event = new nsAccTableChangeEvent(this);
+  NS_IF_ADDREF(event);
+  return event;
 }
 
-NS_IMETHODIMP
-nsAccTableChangeEvent::GetNumRowsOrCols(PRInt32* aNumRowsOrCols)
-{
-  NS_ENSURE_ARG_POINTER(aNumRowsOrCols);
-
-  *aNumRowsOrCols = mNumRowsOrCols;
-  return NS_OK;
-}
-
rename from accessible/src/base/nsAccEvent.h
rename to accessible/src/base/AccEvent.h
--- a/accessible/src/base/nsAccEvent.h
+++ b/accessible/src/base/AccEvent.h
@@ -33,40 +33,39 @@
  * 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 _nsAccEvent_H_
-#define _nsAccEvent_H_
-
-#include "nsIAccessibleEvent.h"
+#ifndef _AccEvent_H_
+#define _AccEvent_H_
 
 #include "nsAccessible.h"
 
+class nsAccEvent;
 class nsDocAccessible;
 
 // Constants used to point whether the event is from user input.
 enum EIsFromUserInput
 {
   // eNoUserInput: event is not from user input
   eNoUserInput = 0,
   // eFromUserInput: event is from user input
   eFromUserInput = 1,
   // eAutoDetect: the value should be obtained from event state manager
   eAutoDetect = -1
 };
 
 /**
  * Generic accessible event.
  */
-class nsAccEvent: public nsIAccessibleEvent
+class AccEvent
 {
 public:
 
   // Rule for accessible events.
   // The rule will be applied when flushing pending events.
   enum EEventRule {
      // eAllowDupes : More than one event of the same type is allowed.
      //    This event will always be emitted.
@@ -85,100 +84,106 @@ public:
      //    will be emitted.
      eRemoveDupes,
 
      // eDoNotEmit : This event is confirmed as a duplicate, do not emit it.
      eDoNotEmit
   };
 
   // Initialize with an nsIAccessible
-  nsAccEvent(PRUint32 aEventType, nsAccessible *aAccessible,
-             PRBool aIsAsynch = PR_FALSE,
-             EIsFromUserInput aIsFromUserInput = eAutoDetect,
-             EEventRule aEventRule = eRemoveDupes);
+  AccEvent(PRUint32 aEventType, nsAccessible* aAccessible,
+           PRBool aIsAsynch = PR_FALSE,
+           EIsFromUserInput aIsFromUserInput = eAutoDetect,
+           EEventRule aEventRule = eRemoveDupes);
   // Initialize with an nsIDOMNode
-  nsAccEvent(PRUint32 aEventType, nsINode *aNode, PRBool aIsAsynch = PR_FALSE,
-             EIsFromUserInput aIsFromUserInput = eAutoDetect,
-             EEventRule aEventRule = eRemoveDupes);
-  virtual ~nsAccEvent() {}
+  AccEvent(PRUint32 aEventType, nsINode* aNode, PRBool aIsAsynch = PR_FALSE,
+           EIsFromUserInput aIsFromUserInput = eAutoDetect,
+           EEventRule aEventRule = eRemoveDupes);
+  virtual ~AccEvent() {}
 
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_CLASS(nsAccEvent)
-
-  NS_DECL_NSIACCESSIBLEEVENT
-
-  // nsAccEvent
+  // AccEvent
   PRUint32 GetEventType() const { return mEventType; }
   EEventRule GetEventRule() const { return mEventRule; }
   PRBool IsAsync() const { return mIsAsync; }
   PRBool IsFromUserInput() const { return mIsFromUserInput; }
 
   nsAccessible *GetAccessible();
   nsDocAccessible* GetDocAccessible();
   nsINode* GetNode();
 
+  /**
+   * Create and return an XPCOM object for accessible event object.
+   */
+  virtual already_AddRefed<nsAccEvent> CreateXPCOMObject();
+
+  /**
+   * Down casting.
+   */
   enum EventGroup {
     eGenericEvent,
     eReorderEvent,
     eStateChangeEvent,
     eTextChangeEvent,
     eHideEvent,
     eCaretMoveEvent,
     eTableChangeEvent
   };
 
   static const EventGroup kEventGroup = eGenericEvent;
   virtual unsigned int GetEventGroups() const
   {
     return 1U << eGenericEvent;
   }
 
+  /**
+   * Reference counting and cycle collection.
+   */
+  NS_INLINE_DECL_REFCOUNTING(AccEvent)
+  NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(AccEvent)
+
 protected:
   /**
    * Get an accessible from event target node.
    */
   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;
-
   PRUint32 mEventType;
   EEventRule mEventRule;
   PRPackedBool mIsAsync;
   nsRefPtr<nsAccessible> mAccessible;
   nsCOMPtr<nsINode> mNode;
 
   friend class nsAccEventQueue;
 };
 
 
 /**
  * Accessible reorder event.
  */
-class nsAccReorderEvent : public nsAccEvent
+class AccReorderEvent : public AccEvent
 {
 public:
-  nsAccReorderEvent(nsAccessible *aAccTarget, PRBool aIsAsynch,
-                    PRBool aIsUnconditional, nsINode *aReasonNode);
+  AccReorderEvent(nsAccessible* aAccTarget, PRBool aIsAsynch,
+                  PRBool aIsUnconditional, nsINode* aReasonNode);
 
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsAccEvent
+  // AccEvent
   static const EventGroup kEventGroup = eReorderEvent;
   virtual unsigned int GetEventGroups() const
   {
-    return nsAccEvent::GetEventGroups() | (1U << eReorderEvent);
+    return AccEvent::GetEventGroups() | (1U << eReorderEvent);
   }
 
-  // nsAccReorderEvent
+  // AccReorderEvent
   /**
    * Return true if event is unconditional, i.e. must be fired.
    */
   PRBool IsUnconditionalEvent();
 
   /**
    * Return true if changed DOM node has accessible in its tree.
    */
@@ -188,188 +193,182 @@ private:
   PRBool mUnconditionalEvent;
   nsCOMPtr<nsINode> mReasonNode;
 };
 
 
 /**
  * Accessible state change event.
  */
-class nsAccStateChangeEvent: public nsAccEvent,
-                             public nsIAccessibleStateChangeEvent
+class AccStateChangeEvent: public AccEvent
 {
 public:
-  nsAccStateChangeEvent(nsAccessible *aAccessible,
-                        PRUint32 aState, PRBool aIsExtraState,
-                        PRBool aIsEnabled, PRBool aIsAsynch = PR_FALSE,
-                        EIsFromUserInput aIsFromUserInput = eAutoDetect);
+  AccStateChangeEvent(nsAccessible* aAccessible,
+                      PRUint32 aState, PRBool aIsExtraState,
+                      PRBool aIsEnabled, PRBool aIsAsynch = PR_FALSE,
+                      EIsFromUserInput aIsFromUserInput = eAutoDetect);
 
-  nsAccStateChangeEvent(nsINode *aNode, PRUint32 aState, PRBool aIsExtraState,
-                        PRBool aIsEnabled);
-
-  nsAccStateChangeEvent(nsINode *aNode, PRUint32 aState, PRBool aIsExtraState);
+  AccStateChangeEvent(nsINode* aNode, PRUint32 aState, PRBool aIsExtraState,
+                      PRBool aIsEnabled);
 
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSIACCESSIBLESTATECHANGEEVENT
+  AccStateChangeEvent(nsINode* aNode, PRUint32 aState, PRBool aIsExtraState);
 
-  // nsAccEvent
+  // AccEvent
+  virtual already_AddRefed<nsAccEvent> CreateXPCOMObject();
+
   static const EventGroup kEventGroup = eStateChangeEvent;
   virtual unsigned int GetEventGroups() const
   {
-    return nsAccEvent::GetEventGroups() | (1U << eStateChangeEvent);
+    return AccEvent::GetEventGroups() | (1U << eStateChangeEvent);
   }
 
-  // nsAccStateChangeEvent
+  // AccStateChangeEvent
   PRUint32 GetState() const { return mState; }
   PRBool IsExtraState() const { return mIsExtraState; }
   PRBool IsStateEnabled() const { return mIsEnabled; }
 
 private:
   PRUint32 mState;
   PRBool mIsExtraState;
   PRBool mIsEnabled;
 };
 
 
 /**
  * Accessible text change event.
  */
-class nsAccTextChangeEvent: public nsAccEvent,
-                            public nsIAccessibleTextChangeEvent
+class AccTextChangeEvent: public AccEvent
 {
 public:
-  nsAccTextChangeEvent(nsAccessible *aAccessible, PRInt32 aStart,
-                       nsAString& aModifiedText,
-                       PRBool aIsInserted, PRBool aIsAsynch = PR_FALSE,
-                       EIsFromUserInput aIsFromUserInput = eAutoDetect);
+  AccTextChangeEvent(nsAccessible* aAccessible, PRInt32 aStart,
+                     nsAString& aModifiedText,
+                     PRBool aIsInserted, PRBool aIsAsynch = PR_FALSE,
+                     EIsFromUserInput aIsFromUserInput = eAutoDetect);
 
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSIACCESSIBLETEXTCHANGEEVENT
+  // AccEvent
+  virtual already_AddRefed<nsAccEvent> CreateXPCOMObject();
 
-  // nsAccEvent
   static const EventGroup kEventGroup = eTextChangeEvent;
   virtual unsigned int GetEventGroups() const
   {
-    return nsAccEvent::GetEventGroups() | (1U << eTextChangeEvent);
+    return AccEvent::GetEventGroups() | (1U << eTextChangeEvent);
   }
 
-  // nsAccTextChangeEvent
+  // AccTextChangeEvent
   PRInt32 GetStartOffset() const { return mStart; }
   PRUint32 GetLength() const { return mModifiedText.Length(); }
   PRBool IsTextInserted() const { return mIsInserted; }
+  void GetModifiedText(nsAString& aModifiedText)
+    { aModifiedText = mModifiedText; }
 
 private:
   PRInt32 mStart;
   PRBool mIsInserted;
   nsString mModifiedText;
 
   friend class nsAccEventQueue;
 };
 
 
 /**
  * Accessible hide events.
  */
-class AccHideEvent : public nsAccEvent
+class AccHideEvent : public AccEvent
 {
 public:
   AccHideEvent(nsAccessible* aTarget, nsINode* aTargetNode,
                PRBool aIsAsynch, EIsFromUserInput aIsFromUserInput);
 
-  // nsAccEvent
+  // Event
   static const EventGroup kEventGroup = eHideEvent;
   virtual unsigned int GetEventGroups() const
   {
-    return nsAccEvent::GetEventGroups() | (1U << eHideEvent);
+    return AccEvent::GetEventGroups() | (1U << eHideEvent);
   }
 
 protected:
   nsRefPtr<nsAccessible> mParent;
   nsRefPtr<nsAccessible> mNextSibling;
   nsRefPtr<nsAccessible> mPrevSibling;
-  nsRefPtr<nsAccTextChangeEvent> mTextChangeEvent;
+  nsRefPtr<AccTextChangeEvent> mTextChangeEvent;
 
   friend class nsAccEventQueue;
 };
 
 
 /**
  * Accessible caret move event.
  */
-class nsAccCaretMoveEvent: public nsAccEvent,
-                           public nsIAccessibleCaretMoveEvent
+class AccCaretMoveEvent: public AccEvent
 {
 public:
-  nsAccCaretMoveEvent(nsAccessible *aAccessible, PRInt32 aCaretOffset);
-  nsAccCaretMoveEvent(nsINode *aNode);
+  AccCaretMoveEvent(nsAccessible* aAccessible, PRInt32 aCaretOffset);
+  AccCaretMoveEvent(nsINode* aNode);
 
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSIACCESSIBLECARETMOVEEVENT
+  // AccEvent
+  virtual already_AddRefed<nsAccEvent> CreateXPCOMObject();
 
-  // nsAccEvent
   static const EventGroup kEventGroup = eCaretMoveEvent;
   virtual unsigned int GetEventGroups() const
   {
-    return nsAccEvent::GetEventGroups() | (1U << eCaretMoveEvent);
+    return AccEvent::GetEventGroups() | (1U << eCaretMoveEvent);
   }
 
-  // nsAccCaretMoveEvent
+  // AccCaretMoveEvent
   PRInt32 GetCaretOffset() const { return mCaretOffset; }
 
 private:
   PRInt32 mCaretOffset;
 };
 
 
 /**
  * Accessible table change event.
  */
-class nsAccTableChangeEvent : public nsAccEvent,
-                              public nsIAccessibleTableChangeEvent
+class AccTableChangeEvent : public AccEvent
 {
 public:
-  nsAccTableChangeEvent(nsAccessible *aAccessible, PRUint32 aEventType,
-                        PRInt32 aRowOrColIndex, PRInt32 aNumRowsOrCols,
-                        PRBool aIsAsynch);
+  AccTableChangeEvent(nsAccessible* aAccessible, PRUint32 aEventType,
+                      PRInt32 aRowOrColIndex, PRInt32 aNumRowsOrCols,
+                      PRBool aIsAsynch);
 
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSIACCESSIBLETABLECHANGEEVENT
+  // AccEvent
+  virtual already_AddRefed<nsAccEvent> CreateXPCOMObject();
 
-  // nsAccEvent
   static const EventGroup kEventGroup = eTableChangeEvent;
   virtual unsigned int GetEventGroups() const
   {
-    return nsAccEvent::GetEventGroups() | (1U << eTableChangeEvent);
+    return AccEvent::GetEventGroups() | (1U << eTableChangeEvent);
   }
 
-  // nsAccTableChangeEvent
+  // AccTableChangeEvent
   PRUint32 GetIndex() const { return mRowOrColIndex; }
   PRUint32 GetCount() const { return mNumRowsOrCols; }
 
 private:
   PRUint32 mRowOrColIndex;   // the start row/column after which the rows are inserted/deleted.
   PRUint32 mNumRowsOrCols;   // the number of inserted/deleted rows/columns
 };
 
 
 /**
  * Downcast the generic accessible event object to derived type.
  */
 class downcast_accEvent
 {
 public:
-  downcast_accEvent(nsAccEvent *e) : mRawPtr(e) { }
+  downcast_accEvent(AccEvent* e) : mRawPtr(e) { }
 
   template<class Destination>
   operator Destination*() {
     if (!mRawPtr)
       return nsnull;
 
     return mRawPtr->GetEventGroups() & (1U << Destination::kEventGroup) ?
       static_cast<Destination*>(mRawPtr) : nsnull;
   }
 
 private:
-  nsAccEvent *mRawPtr;
+  AccEvent* mRawPtr;
 };
 
 #endif
 
--- a/accessible/src/base/Makefile.in
+++ b/accessible/src/base/Makefile.in
@@ -44,22 +44,22 @@ include $(DEPTH)/config/autoconf.mk
 
 MODULE = accessibility
 LIBRARY_NAME = accessibility_base_s
 LIBXUL_LIBRARY = 1
 
 
 CPPSRCS = \
   AccCollector.cpp \
+  AccEvent.cpp \
   AccGroupInfo.cpp \
   AccIterator.cpp \
   filters.cpp \
   nsAccDocManager.cpp \
   nsAccessNode.cpp \
-  nsAccEvent.cpp \
   nsARIAGridAccessible.cpp \
   nsARIAMap.cpp \
   nsDocAccessible.cpp \
   nsOuterDocAccessible.cpp \
   nsAccessibilityAtoms.cpp \
   nsCoreUtils.cpp \
   nsAccUtils.cpp \
   nsRelUtils.cpp \
@@ -86,16 +86,17 @@ EXPORTS = \
 
 # 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
 
 LOCAL_INCLUDES += \
   -I$(srcdir) \
+  -I$(srcdir)/../xpcom \
   -I$(srcdir)/../html \
   -I$(srcdir)/../xul \
   -I$(srcdir)/../../../layout/generic \
   -I$(srcdir)/../../../layout/xul/base/src \
   $(NULL)
 
 ifndef DISABLE_XFORMS_HOOKS
 LOCAL_INCLUDES += -I$(srcdir)/../xforms
--- a/accessible/src/base/nsAccDocManager.cpp
+++ b/accessible/src/base/nsAccDocManager.cpp
@@ -230,26 +230,26 @@ nsAccDocManager::OnStateChange(nsIWebPro
   PRUint32 loadType;
   docShell->GetLoadType(&loadType);
   if (loadType == LOAD_RELOAD_NORMAL ||
       loadType == LOAD_RELOAD_BYPASS_CACHE ||
       loadType == LOAD_RELOAD_BYPASS_PROXY ||
       loadType == LOAD_RELOAD_BYPASS_PROXY_AND_CACHE) {
 
     // Fire reload event.
-    nsRefPtr<nsAccEvent> reloadEvent =
-      new nsAccEvent(nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD, docAcc);
+    nsRefPtr<AccEvent> reloadEvent =
+      new AccEvent(nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD, docAcc);
     nsEventShell::FireEvent(reloadEvent);
   }
 
   // Fire state busy change event. Use delayed event since we don't care
   // actually if event isn't delivered when the document goes away like a shot.
-  nsRefPtr<nsAccEvent> stateEvent =
-    new nsAccStateChangeEvent(document, nsIAccessibleStates::STATE_BUSY,
-                              PR_FALSE, PR_TRUE);
+  nsRefPtr<AccEvent> stateEvent =
+    new AccStateChangeEvent(document, nsIAccessibleStates::STATE_BUSY,
+                            PR_FALSE, PR_TRUE);
   docAcc->FireDelayedAccessibleEvent(stateEvent);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccDocManager::OnProgressChange(nsIWebProgress *aWebProgress,
                                   nsIRequest *aRequest,
@@ -373,24 +373,24 @@ nsAccDocManager::HandleDOMDocumentLoad(n
       docAcc->InvalidateCacheSubtree(nsnull,
                                      nsIAccessibilityService::NODE_SIGNIFICANT_CHANGE);
     }
     return;
   }
 
   // Fire complete/load stopped if the load event type is given.
   if (aLoadEventType) {
-    nsRefPtr<nsAccEvent> loadEvent = new nsAccEvent(aLoadEventType, aDocument);
+    nsRefPtr<AccEvent> loadEvent = new AccEvent(aLoadEventType, aDocument);
     docAcc->FireDelayedAccessibleEvent(loadEvent);
   }
 
   // Fire busy state change event.
-  nsRefPtr<nsAccEvent> stateEvent =
-    new nsAccStateChangeEvent(aDocument, nsIAccessibleStates::STATE_BUSY,
-                              PR_FALSE, PR_FALSE);
+  nsRefPtr<AccEvent> stateEvent =
+    new AccStateChangeEvent(aDocument, nsIAccessibleStates::STATE_BUSY,
+                            PR_FALSE, PR_FALSE);
   docAcc->FireDelayedAccessibleEvent(stateEvent);
 }
 
 PRBool
 nsAccDocManager::IsEventTargetDocument(nsIDocument *aDocument) const
 {
   nsCOMPtr<nsISupports> container = aDocument->GetContainer();
   nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
--- a/accessible/src/base/nsAccDocManager.h
+++ b/accessible/src/base/nsAccDocManager.h
@@ -381,17 +381,17 @@ private:
   PRUint32 type = aEvent->GetEventType();                                      \
   if (type == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED) {               \
     strEventType.AssignLiteral("load stopped");                                \
   } else if (type == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE) {       \
     strEventType.AssignLiteral("load complete");                               \
   } else if (type == nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD) {              \
       strEventType.AssignLiteral("reload");                                    \
   } else if (type == nsIAccessibleEvent::EVENT_STATE_CHANGE) {                 \
-    nsAccStateChangeEvent *event = downcast_accEvent(aEvent);                  \
+    AccStateChangeEvent* event = downcast_accEvent(aEvent);                    \
     if (event->GetState() == nsIAccessibleStates::STATE_BUSY) {                \
       strEventType.AssignLiteral("busy ");                                     \
       if (event->IsStateEnabled())                                             \
         strEventType.AppendLiteral("true");                                    \
       else                                                                     \
         strEventType.AppendLiteral("false");                                   \
     }                                                                          \
   }
--- a/accessible/src/base/nsAccUtils.cpp
+++ b/accessible/src/base/nsAccUtils.cpp
@@ -740,16 +740,19 @@ nsAccUtils::GetHeaderCellsFor(nsIAccessi
 
     nsCOMPtr<nsIAccessible> cell;
     rv = aTable->GetCellAt(curRowIdx, curColIdx, getter_AddRefs(cell));
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIAccessibleTableCell> tableCellAcc =
       do_QueryInterface(cell);
 
+    // GetCellAt should always return an nsIAccessibleTableCell (XXX Bug 587529)
+    NS_ENSURE_STATE(tableCellAcc);
+
     PRInt32 origIdx = 1;
     if (moveToLeft)
       rv = tableCellAcc->GetColumnIndex(&origIdx);
     else
       rv = tableCellAcc->GetRowIndex(&origIdx);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (origIdx == index) {
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -43,16 +43,17 @@
 
 #include "AccGroupInfo.h"
 #include "AccIterator.h"
 #include "nsAccUtils.h"
 #include "nsARIAMap.h"
 #include "nsDocAccessible.h"
 #include "nsEventShell.h"
 
+#include "nsAccEvent.h"
 #include "nsAccessibilityService.h"
 #include "nsAccTreeWalker.h"
 #include "nsRelUtils.h"
 #include "nsTextEquivUtils.h"
 
 #include "nsIDOMElement.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMDocumentXBL.h"
@@ -1235,25 +1236,38 @@ nsAccessible::GetXULName(nsAString& aLab
     }
     parent = parent->GetParent();
   }
 
   return nsTextEquivUtils::GetNameFromSubtree(this, aLabel);
 }
 
 nsresult
-nsAccessible::HandleAccEvent(nsAccEvent *aEvent)
+nsAccessible::HandleAccEvent(AccEvent* aEvent)
 {
   NS_ENSURE_ARG_POINTER(aEvent);
 
   nsCOMPtr<nsIObserverService> obsService =
     mozilla::services::GetObserverService();
   NS_ENSURE_TRUE(obsService, NS_ERROR_FAILURE);
 
-  return obsService->NotifyObservers(aEvent, NS_ACCESSIBLE_EVENT_TOPIC, nsnull);
+  nsCOMPtr<nsISimpleEnumerator> observers;
+  obsService->EnumerateObservers(NS_ACCESSIBLE_EVENT_TOPIC,
+                                 getter_AddRefs(observers));
+
+  NS_ENSURE_STATE(observers);
+
+  PRBool hasObservers = PR_FALSE;
+  observers->HasMoreElements(&hasObservers);
+  if (hasObservers) {
+    nsRefPtr<nsAccEvent> evnt(aEvent->CreateXPCOMObject());
+    return obsService->NotifyObservers(evnt, NS_ACCESSIBLE_EVENT_TOPIC, nsnull);
+  }
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccessible::GetRole(PRUint32 *aRole)
 {
   NS_ENSURE_ARG_POINTER(aRole);
   *aRole = nsIAccessibleRole::ROLE_NOTHING;
 
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -50,17 +50,17 @@
 
 #include "nsStringGlue.h"
 #include "nsTArray.h"
 #include "nsRefPtrHashtable.h"
 
 class AccGroupInfo;
 class EmbeddedObjCollector;
 class nsAccessible;
-class nsAccEvent;
+class AccEvent;
 struct nsRoleMapEntry;
 
 struct nsRect;
 class nsIContent;
 class nsIFrame;
 class nsIAtom;
 class nsIView;
 
@@ -298,17 +298,17 @@ public:
 
   //////////////////////////////////////////////////////////////////////////////
   // Miscellaneous methods
 
   /**
    * Handle accessible event, i.e. process it, notifies observers and fires
    * platform specific event.
    */
-  virtual nsresult HandleAccEvent(nsAccEvent *aAccEvent);
+  virtual nsresult HandleAccEvent(AccEvent* aAccEvent);
 
   /**
    * Return true if there are accessible children in anonymous content
    */
   virtual PRBool GetAllowsAnonChildAccessibles();
 
   /**
    * Returns text of accessible if accessible has text role otherwise empty
@@ -449,17 +449,17 @@ protected:
   /**
    * Fires platform accessible event. It's notification method only. It does
    * change nothing on Gecko side. Don't use it until you're sure what you do
    * (see example in XUL tree accessible), use nsEventShell::FireEvent()
    * instead. MUST be overridden in wrap classes.
    *
    * @param aEvent  the accessible event to fire.
    */
-  virtual nsresult FirePlatformEvent(nsAccEvent *aEvent) = 0;
+  virtual nsresult FirePlatformEvent(AccEvent* aEvent) = 0;
 
   // Data Members
   nsRefPtr<nsAccessible> mParent;
   nsTArray<nsRefPtr<nsAccessible> > mChildren;
   PRInt32 mIndexInParent;
 
   enum ChildrenFlags {
     eChildrenUninitialized = 0x00,
--- a/accessible/src/base/nsCaretAccessible.cpp
+++ b/accessible/src/base/nsCaretAccessible.cpp
@@ -259,18 +259,17 @@ nsCaretAccessible::NormalSelectionChange
     textAcc->GetSelectionCount(&selectionCount);   // Don't swallow similar events when selecting text
     if (!selectionCount) {
       return NS_OK;  // Swallow duplicate caret event
     }
   }
   mLastCaretOffset = caretOffset;
   mLastTextAccessible.swap(textAcc);
 
-  nsRefPtr<nsAccEvent> event =
-    new nsAccCaretMoveEvent(textNode);
+  nsRefPtr<AccEvent> event = new AccCaretMoveEvent(textNode);
   NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
 
   return mRootAccessible->FireDelayedAccessibleEvent(event);
 }
 
 nsresult
 nsCaretAccessible::SpellcheckSelectionChanged(nsIDOMDocument *aDoc,
                                               nsISelection *aSel)
@@ -280,19 +279,19 @@ nsCaretAccessible::SpellcheckSelectionCh
   // the same accessible for newly appended range of the selection (for every
   // misspelled word). If spellchecking is disabled (for example,
   // @spellcheck="false" on html:body) then we won't fire any event.
 
   nsRefPtr<nsHyperTextAccessible> textAcc =
     nsAccUtils::GetTextAccessibleFromSelection(aSel);
   NS_ENSURE_STATE(textAcc);
 
-  nsRefPtr<nsAccEvent> event =
-    new nsAccEvent(nsIAccessibleEvent::EVENT_TEXT_ATTRIBUTE_CHANGED,
-                   textAcc, nsnull);
+  nsRefPtr<AccEvent> event =
+    new AccEvent(nsIAccessibleEvent::EVENT_TEXT_ATTRIBUTE_CHANGED,
+                 textAcc, nsnull);
 
   nsEventShell::FireEvent(event);
   return NS_OK;
 }
 
 nsIntRect
 nsCaretAccessible::GetCaretRect(nsIWidget **aOutWidget)
 {
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -68,20 +68,23 @@
 #include "nsIPresShell.h"
 #include "nsIServiceManager.h"
 #include "nsIViewManager.h"
 #include "nsIScrollableFrame.h"
 #include "nsUnicharUtils.h"
 #include "nsIURI.h"
 #include "nsIWebNavigation.h"
 #include "nsFocusManager.h"
+#include "mozilla/dom/Element.h"
 #ifdef MOZ_XUL
 #include "nsIXULDocument.h"
 #endif
 
+namespace dom = mozilla::dom;
+
 ////////////////////////////////////////////////////////////////////////////////
 // Static member initialization
 
 PRUint32 nsDocAccessible::gLastFocusedAccessiblesState = 0;
 nsIAtom *nsDocAccessible::gLastFocusedFrameType = nsnull;
 
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -603,18 +606,18 @@ nsDocAccessible::Init()
   mEventQueue = new nsAccEventQueue(this);
   if (!mEventQueue)
     return PR_FALSE;
 
   AddEventListeners();
 
   // Fire reorder event to notify new accessible document has been created and
   // attached to the tree.
-  nsRefPtr<nsAccEvent> reorderEvent =
-    new nsAccReorderEvent(mParent, PR_FALSE, PR_TRUE, mDocument);
+  nsRefPtr<AccEvent> reorderEvent =
+    new AccReorderEvent(mParent, PR_FALSE, PR_TRUE, mDocument);
   if (!reorderEvent)
     return PR_FALSE;
 
   FireDelayedAccessibleEvent(reorderEvent);
   return PR_TRUE;
 }
 
 void
@@ -870,55 +873,57 @@ void nsDocAccessible::ScrollPositionDidC
 // nsIObserver
 
 NS_IMETHODIMP nsDocAccessible::Observe(nsISupports *aSubject, const char *aTopic,
                                        const PRUnichar *aData)
 {
   if (!nsCRT::strcmp(aTopic,"obs_documentCreated")) {    
     // State editable will now be set, readonly is now clear
     // Normally we only fire delayed events created from the node, not an
-    // accessible object. See the nsAccStateChangeEvent constructor for details
+    // accessible object. See the AccStateChangeEvent constructor for details
     // about this exceptional case.
-    nsRefPtr<nsAccEvent> event =
-      new nsAccStateChangeEvent(this, nsIAccessibleStates::EXT_STATE_EDITABLE,
-                                PR_TRUE, PR_TRUE);
+    nsRefPtr<AccEvent> event =
+      new AccStateChangeEvent(this, nsIAccessibleStates::EXT_STATE_EDITABLE,
+                              PR_TRUE, PR_TRUE);
     FireDelayedAccessibleEvent(event);
   }
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIDocumentObserver
 
 NS_IMPL_NSIDOCUMENTOBSERVER_CORE_STUB(nsDocAccessible)
 NS_IMPL_NSIDOCUMENTOBSERVER_LOAD_STUB(nsDocAccessible)
 NS_IMPL_NSIDOCUMENTOBSERVER_STYLE_STUB(nsDocAccessible)
 
 void
 nsDocAccessible::AttributeWillChange(nsIDocument *aDocument,
-                                     nsIContent* aContent, PRInt32 aNameSpaceID,
+                                     dom::Element* aElement,
+                                     PRInt32 aNameSpaceID,
                                      nsIAtom* aAttribute, PRInt32 aModType)
 {
   // XXX TODO: bugs 381599 467143 472142 472143
   // Here we will want to cache whatever state we are potentially interested in,
   // such as the existence of aria-pressed for button (so we know if we need to
   // newly expose it as a toggle button) etc.
 }
 
 void
-nsDocAccessible::AttributeChanged(nsIDocument *aDocument, nsIContent* aContent,
+nsDocAccessible::AttributeChanged(nsIDocument *aDocument,
+                                  dom::Element* aElement,
                                   PRInt32 aNameSpaceID, nsIAtom* aAttribute,
                                   PRInt32 aModType)
 {
-  AttributeChangedImpl(aContent, aNameSpaceID, aAttribute);
+  AttributeChangedImpl(aElement, aNameSpaceID, aAttribute);
 
   // If it was the focused node, cache the new state
-  if (aContent == gLastFocusedNode) {
-    nsAccessible *focusedAccessible = GetAccService()->GetAccessible(aContent);
+  if (aElement == gLastFocusedNode) {
+    nsAccessible *focusedAccessible = GetAccService()->GetAccessible(aElement);
     if (focusedAccessible)
       gLastFocusedAccessiblesState = nsAccUtils::State(focusedAccessible);
   }
 }
 
 // nsDocAccessible protected member
 void
 nsDocAccessible::AttributeChangedImpl(nsIContent* aContent, PRInt32 aNameSpaceID, nsIAtom* aAttribute)
@@ -962,27 +967,27 @@ nsDocAccessible::AttributeChangedImpl(ns
 
     // Note. Checking the XUL or HTML namespace would not seem to gain us
     // anything, because disabled attribute really is going to mean the same
     // thing in any namespace.
 
     // Note. We use the attribute instead of the disabled state bit because
     // ARIA's aria-disabled does not affect the disabled state bit.
 
-    nsRefPtr<nsAccEvent> enabledChangeEvent =
-      new nsAccStateChangeEvent(aContent,
-                                nsIAccessibleStates::EXT_STATE_ENABLED,
-                                PR_TRUE);
+    nsRefPtr<AccEvent> enabledChangeEvent =
+      new AccStateChangeEvent(aContent,
+                              nsIAccessibleStates::EXT_STATE_ENABLED,
+                              PR_TRUE);
 
     FireDelayedAccessibleEvent(enabledChangeEvent);
 
-    nsRefPtr<nsAccEvent> sensitiveChangeEvent =
-      new nsAccStateChangeEvent(aContent,
-                                nsIAccessibleStates::EXT_STATE_SENSITIVE,
-                                PR_TRUE);
+    nsRefPtr<AccEvent> sensitiveChangeEvent =
+      new AccStateChangeEvent(aContent,
+                              nsIAccessibleStates::EXT_STATE_SENSITIVE,
+                              PR_TRUE);
 
     FireDelayedAccessibleEvent(sensitiveChangeEvent);
     return;
   }
 
   // Check for namespaced ARIA attribute
   if (aNameSpaceID == kNameSpaceID_None) {
     // Check for hyphenated aria-foo property?
@@ -1023,63 +1028,61 @@ nsDocAccessible::AttributeChangedImpl(ns
     // whatever gets event_focus, which is done in
     // nsRootAccessible::FireAccessibleFocusEvent()
     // So right here we make sure only to deal with multi selects
     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(),
-                                 nsAccEvent::eAllowDupes);
+                                 AccEvent::eAllowDupes);
 
       static nsIContent::AttrValuesArray strings[] =
         {&nsAccessibilityAtoms::_empty, &nsAccessibilityAtoms::_false, nsnull};
       if (aContent->FindAttrValueIn(kNameSpaceID_None, aAttribute,
                                     strings, eCaseMatters) >= 0) {
         FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_SELECTION_REMOVE,
                                    aContent);
         return;
       }
 
       FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_SELECTION_ADD,
                                  aContent);
     }
   }
 
   if (aAttribute == nsAccessibilityAtoms::contenteditable) {
-    nsRefPtr<nsAccEvent> editableChangeEvent =
-      new nsAccStateChangeEvent(aContent,
-                                nsIAccessibleStates::EXT_STATE_EDITABLE,
-                                PR_TRUE);
+    nsRefPtr<AccEvent> editableChangeEvent =
+      new AccStateChangeEvent(aContent,
+                              nsIAccessibleStates::EXT_STATE_EDITABLE,
+                              PR_TRUE);
     FireDelayedAccessibleEvent(editableChangeEvent);
     return;
   }
 }
 
 // nsDocAccessible protected member
 void
 nsDocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute)
 {
   // Note: For universal/global ARIA states and properties we don't care if
   // there is an ARIA role present or not.
 
   if (aAttribute == nsAccessibilityAtoms::aria_required) {
-    nsRefPtr<nsAccEvent> event =
-      new nsAccStateChangeEvent(aContent,
-                                nsIAccessibleStates::STATE_REQUIRED,
-                                PR_FALSE);
+    nsRefPtr<AccEvent> event =
+      new AccStateChangeEvent(aContent, nsIAccessibleStates::STATE_REQUIRED,
+                              PR_FALSE);
     FireDelayedAccessibleEvent(event);
     return;
   }
 
   if (aAttribute == nsAccessibilityAtoms::aria_invalid) {
-    nsRefPtr<nsAccEvent> event =
-      new nsAccStateChangeEvent(aContent,
-                                nsIAccessibleStates::STATE_INVALID,
-                                PR_FALSE);
+    nsRefPtr<AccEvent> event =
+      new AccStateChangeEvent(aContent, nsIAccessibleStates::STATE_INVALID,
+                              PR_FALSE);
     FireDelayedAccessibleEvent(event);
     return;
   }
 
   if (aAttribute == nsAccessibilityAtoms::aria_activedescendant) {
     // The activedescendant universal property redirects accessible focus events
     // to the element with the id that activedescendant points to
     nsCOMPtr<nsINode> focusedNode = GetCurrentFocus();
@@ -1097,20 +1100,19 @@ nsDocAccessible::ARIAAttributeChanged(ns
   if (aAttribute == nsAccessibilityAtoms::aria_grabbed ||
       aAttribute == nsAccessibilityAtoms::aria_dropeffect) {
     FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_OBJECT_ATTRIBUTE_CHANGED,
                                aContent);
   }
 
   // We treat aria-expanded as a global ARIA state for historical reasons
   if (aAttribute == nsAccessibilityAtoms::aria_expanded) {
-    nsRefPtr<nsAccEvent> event =
-      new nsAccStateChangeEvent(aContent,
-                                nsIAccessibleStates::STATE_EXPANDED,
-                                PR_FALSE);
+    nsRefPtr<AccEvent> event =
+      new AccStateChangeEvent(aContent, nsIAccessibleStates::STATE_EXPANDED,
+                              PR_FALSE);
     FireDelayedAccessibleEvent(event);
     return;
   }
 
   if (!aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::role)) {
     // We don't care about these other ARIA attribute changes unless there is
     // an ARIA role set for the element
     // XXX: we should check the role map to see if the changed property is
@@ -1119,46 +1121,44 @@ nsDocAccessible::ARIAAttributeChanged(ns
   }
 
   // The following ARIA attributes only take affect when dynamic content role is present
   if (aAttribute == nsAccessibilityAtoms::aria_checked ||
       aAttribute == nsAccessibilityAtoms::aria_pressed) {
     const PRUint32 kState = (aAttribute == nsAccessibilityAtoms::aria_checked) ?
                             nsIAccessibleStates::STATE_CHECKED : 
                             nsIAccessibleStates::STATE_PRESSED;
-    nsRefPtr<nsAccEvent> event =
-      new nsAccStateChangeEvent(aContent, kState, PR_FALSE);
+    nsRefPtr<AccEvent> event =
+      new AccStateChangeEvent(aContent, kState, PR_FALSE);
     FireDelayedAccessibleEvent(event);
     if (aContent == gLastFocusedNode) {
       // State changes for MIXED state currently only supported for focused item, because
       // otherwise we would need access to the old attribute value in this listener.
       // This is because we don't know if the previous value of aria-checked or aria-pressed was "mixed"
       // without caching that info.
       nsAccessible *accessible = event->GetAccessible();
       if (accessible) {
         PRBool wasMixed = (gLastFocusedAccessiblesState & nsIAccessibleStates::STATE_MIXED) != 0;
         PRBool isMixed  =
           (nsAccUtils::State(accessible) & nsIAccessibleStates::STATE_MIXED) != 0;
         if (wasMixed != isMixed) {
-          nsRefPtr<nsAccEvent> event =
-            new nsAccStateChangeEvent(aContent,
-                                      nsIAccessibleStates::STATE_MIXED,
-                                      PR_FALSE, isMixed);
+          nsRefPtr<AccEvent> event =
+            new AccStateChangeEvent(aContent, nsIAccessibleStates::STATE_MIXED,
+                                    PR_FALSE, isMixed);
           FireDelayedAccessibleEvent(event);
         }
       }
     }
     return;
   }
 
   if (aAttribute == nsAccessibilityAtoms::aria_readonly) {
-    nsRefPtr<nsAccEvent> event =
-      new nsAccStateChangeEvent(aContent,
-                                nsIAccessibleStates::STATE_READONLY,
-                                PR_FALSE);
+    nsRefPtr<AccEvent> event =
+      new AccStateChangeEvent(aContent, nsIAccessibleStates::STATE_READONLY,
+                              PR_FALSE);
     FireDelayedAccessibleEvent(event);
     return;
   }
 
   // Fire value change event whenever aria-valuetext is changed, or
   // when aria-valuenow is changed and aria-valuetext is empty
   if (aAttribute == nsAccessibilityAtoms::aria_valuetext ||      
       (aAttribute == nsAccessibilityAtoms::aria_valuenow &&
@@ -1267,17 +1267,17 @@ nsDocAccessible::ParentChainChanged(nsIC
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessible
 
 #ifdef DEBUG_ACCDOCMGR
 nsresult
-nsDocAccessible::HandleAccEvent(nsAccEvent *aAccEvent)
+nsDocAccessible::HandleAccEvent(AccEvent* aAccEvent)
 {
   NS_LOG_ACCDOCLOAD_HANDLEEVENT(aAccEvent)
 
   return nsHyperTextAccessible::HandleAccEvent(aAccEvent);
 
 }
 #endif
 
@@ -1290,19 +1290,19 @@ nsDocAccessible::HandleAccEvent(nsAccEve
 
 void
 nsDocAccessible::FireValueChangeForTextFields(nsAccessible *aAccessible)
 {
   if (nsAccUtils::Role(aAccessible) != nsIAccessibleRole::ROLE_ENTRY)
     return;
 
   // Dependent value change event for text changes in textfields
-  nsRefPtr<nsAccEvent> valueChangeEvent =
-    new nsAccEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, aAccessible,
-                   PR_FALSE, eAutoDetect, nsAccEvent::eRemoveDupes);
+  nsRefPtr<AccEvent> valueChangeEvent =
+    new AccEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, aAccessible,
+                 PR_FALSE, eAutoDetect, AccEvent::eRemoveDupes);
   FireDelayedAccessibleEvent(valueChangeEvent);
 }
 
 void
 nsDocAccessible::FireTextChangeEventForText(nsIContent *aContent,
                                             CharacterDataChangeInfo* aInfo,
                                             PRBool aIsInserted)
 {
@@ -1345,27 +1345,27 @@ nsDocAccessible::FireTextChangeEventForT
   rv = accessible->AppendTextTo(text, textOffset, contentLength);
   if (NS_FAILED(rv))
     return;
 
   if (text.IsEmpty())
     return;
 
   // Normally we only fire delayed events created from the node, not an
-  // accessible object. See the nsAccTextChangeEvent constructor for details
+  // accessible object. See the AccTextChangeEvent constructor for details
   // about this exceptional case.
-  nsRefPtr<nsAccEvent> event =
-    new nsAccTextChangeEvent(textAccessible, offset + textOffset, text,
-                             aIsInserted, PR_FALSE);
+  nsRefPtr<AccEvent> event =
+    new AccTextChangeEvent(textAccessible, offset + textOffset, text,
+                           aIsInserted, PR_FALSE);
   FireDelayedAccessibleEvent(event);
 
   FireValueChangeForTextFields(textAccessible);
 }
 
-already_AddRefed<nsAccEvent>
+already_AddRefed<AccEvent>
 nsDocAccessible::CreateTextChangeEventForNode(nsAccessible *aContainerAccessible,
                                               nsIContent *aChangeNode,
                                               nsAccessible *aChangeChild,
                                               PRBool aIsInserting,
                                               PRBool aIsAsynch,
                                               EIsFromUserInput aIsFromUserInput)
 {
   nsRefPtr<nsHyperTextAccessible> textAccessible =
@@ -1422,53 +1422,53 @@ nsDocAccessible::CreateTextChangeEventFo
 
       nextChild->AppendTextTo(text, 0, PR_UINT32_MAX);
     }
   }
 
   if (text.IsEmpty())
     return nsnull;
 
-  nsAccEvent *event =
-    new nsAccTextChangeEvent(aContainerAccessible, offset, text,
-                             aIsInserting, aIsAsynch, aIsFromUserInput);
+  AccEvent* event = new AccTextChangeEvent(aContainerAccessible, offset, text,
+                                           aIsInserting, aIsAsynch,
+                                           aIsFromUserInput);
   NS_IF_ADDREF(event);
 
   return event;
 }
 
 // nsDocAccessible public member
 nsresult
 nsDocAccessible::FireDelayedAccessibleEvent(PRUint32 aEventType, nsINode *aNode,
-                                            nsAccEvent::EEventRule aAllowDupes,
+                                            AccEvent::EEventRule aAllowDupes,
                                             PRBool aIsAsynch,
                                             EIsFromUserInput aIsFromUserInput)
 {
-  nsRefPtr<nsAccEvent> event =
-    new nsAccEvent(aEventType, aNode, aIsAsynch, aIsFromUserInput, aAllowDupes);
+  nsRefPtr<AccEvent> event =
+    new AccEvent(aEventType, aNode, aIsAsynch, aIsFromUserInput, aAllowDupes);
   NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
 
   return FireDelayedAccessibleEvent(event);
 }
 
 // nsDocAccessible public member
 nsresult
-nsDocAccessible::FireDelayedAccessibleEvent(nsAccEvent *aEvent)
+nsDocAccessible::FireDelayedAccessibleEvent(AccEvent* aEvent)
 {
   NS_ENSURE_ARG(aEvent);
   NS_LOG_ACCDOCLOAD_FIREEVENT(aEvent)
 
   if (mEventQueue)
     mEventQueue->Push(aEvent);
 
   return NS_OK;
 }
 
 void
-nsDocAccessible::ProcessPendingEvent(nsAccEvent *aEvent)
+nsDocAccessible::ProcessPendingEvent(AccEvent* aEvent)
 {  
   nsAccessible *accessible = aEvent->GetAccessible();
   nsINode *node = aEvent->GetNode();
 
   PRUint32 eventType = aEvent->GetEventType();
   EIsFromUserInput isFromUserInput =
     aEvent->IsFromUserInput() ? eFromUserInput : eNoUserInput;
 
@@ -1525,17 +1525,17 @@ nsDocAccessible::ProcessPendingEvent(nsA
 
     // Also fire text changes if the node being created could affect the text in an nsIAccessibleText parent.
     // When a node is being made visible or is inserted, the text in an ancestor hyper text will gain characters
     // At this point we now have the frame and accessible for this node if there is one. That is why we
     // wait to fire this here, instead of in InvalidateCacheSubtree(), where we wouldn't be able to calculate
     // the offset, length and text for the text change.
     if (node && node != mDocument) {
       nsCOMPtr<nsIContent> content(do_QueryInterface(node));
-      nsRefPtr<nsAccEvent> textChangeEvent =
+      nsRefPtr<AccEvent> textChangeEvent =
         CreateTextChangeEventForNode(containerAccessible, content, accessible,
                                      PR_TRUE, PR_TRUE, isFromUserInput);
       if (textChangeEvent) {
         // XXX Queue them up and merge the text change events
         // XXX We need a way to ignore SplitNode and JoinNode() when they
         // do not affect the text within the hypertext
         nsEventShell::FireEvent(textChangeEvent);
       }
@@ -1559,18 +1559,18 @@ nsDocAccessible::ProcessPendingEvent(nsA
 #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<nsAccEvent> caretMoveEvent =
-          new nsAccCaretMoveEvent(accessible, caretOffset);
+        nsRefPtr<AccEvent> caretMoveEvent =
+          new AccCaretMoveEvent(accessible, caretOffset);
         if (!caretMoveEvent)
           return;
 
         nsEventShell::FireEvent(caretMoveEvent);
 
         PRInt32 selectionCount;
         accessibleText->GetSelectionCount(&selectionCount);
         if (selectionCount) {  // There's a selection so fire selection change as well
@@ -1578,17 +1578,17 @@ nsDocAccessible::ProcessPendingEvent(nsA
                                   accessible, PR_TRUE);
         }
       } 
     }
     else if (eventType == nsIAccessibleEvent::EVENT_REORDER) {
       // Fire reorder event if it's unconditional (see InvalidateCacheSubtree
       // method) or if changed node (that is the reason of this reorder event)
       // is accessible or has accessible children.
-      nsAccReorderEvent *reorderEvent = downcast_accEvent(aEvent);
+      AccReorderEvent* reorderEvent = downcast_accEvent(aEvent);
       if (reorderEvent->IsUnconditionalEvent() ||
           reorderEvent->HasAccessibleInReasonSubtree()) {
         nsEventShell::FireEvent(aEvent);
       }
     }
     else {
       nsEventShell::FireEvent(aEvent);
 
@@ -1847,34 +1847,34 @@ nsDocAccessible::InvalidateCacheSubtree(
     // Fire EVENT_SHOW, EVENT_MENUPOPUP_START for newly visible content.
 
     // Fire after a short timer, because we want to make sure the view has been
     // updated to make this accessible content visible. If we don't wait,
     // the assistive technology may receive the event and then retrieve
     // nsIAccessibleStates::STATE_INVISIBLE for the event's accessible object.
 
     FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_SHOW, childNode,
-                               nsAccEvent::eCoalesceFromSameSubtree,
+                               AccEvent::eCoalesceFromSameSubtree,
                                isAsynch);
 
     // Check to see change occurred in an ARIA menu, and fire
     // an EVENT_MENUPOPUP_START if it did.
     nsRoleMapEntry *roleMapEntry = nsAccUtils::GetRoleMapEntry(childNode);
     if (roleMapEntry && roleMapEntry->role == nsIAccessibleRole::ROLE_MENUPOPUP) {
       FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_START,
-                                 childNode, nsAccEvent::eRemoveDupes,
+                                 childNode, AccEvent::eRemoveDupes,
                                  isAsynch);
     }
 
     // Check to see if change occurred inside an alert, and fire an EVENT_ALERT if it did
     nsIContent *ancestor = aChild;
     while (PR_TRUE) {
       if (roleMapEntry && roleMapEntry->role == nsIAccessibleRole::ROLE_ALERT) {
         FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_ALERT, ancestor,
-                                   nsAccEvent::eRemoveDupes, isAsynch);
+                                   AccEvent::eRemoveDupes, isAsynch);
         break;
       }
       ancestor = ancestor->GetParent();
       if (!ancestor)
         break;
 
       roleMapEntry = nsAccUtils::GetRoleMapEntry(ancestor);
     }
@@ -1892,20 +1892,19 @@ nsDocAccessible::InvalidateCacheSubtree(
   // changed node (because its frame might not be constructed yet). In this case
   // we fire a conditional reorder event, so that we will later check whether
   // the changed node is accessible or has accessible children.
   // Filtering/coalescing of these events happens during the queue flush.
 
   PRBool isUnconditionalEvent = childAccessible ||
     aChild && nsAccUtils::HasAccessibleChildren(childNode);
 
-  nsRefPtr<nsAccEvent> reorderEvent =
-    new nsAccReorderEvent(containerAccessible, isAsynch,
-                          isUnconditionalEvent,
-                          aChild ? aChild : nsnull);
+  nsRefPtr<AccEvent> reorderEvent =
+    new AccReorderEvent(containerAccessible, isAsynch, isUnconditionalEvent,
+                        aChild ? aChild : nsnull);
   NS_ENSURE_TRUE(reorderEvent,);
 
   FireDelayedAccessibleEvent(reorderEvent);
 }
 
 nsresult
 nsDocAccessible::FireShowHideEvents(nsINode *aNode,
                                     PRBool aAvoidOnThisNode,
@@ -1925,28 +1924,28 @@ nsDocAccessible::FireShowHideEvents(nsIN
       // Allow creation of new accessibles for show events
       accessible = GetAccService()->GetAccessible(aNode);
     }
   }
 
   if (accessible) {
     // Found an accessible, so fire the show/hide on it and don't look further
     // into this subtree.
-    nsRefPtr<nsAccEvent> event;
+    nsRefPtr<AccEvent> event;
     if (aDelayedOrNormal == eDelayedEvent &&
         aEventType == nsIAccessibleEvent::EVENT_HIDE) {
       // Use AccHideEvent for delayed hide events to coalesce text change events
       // caused by these hide events.
       event = new AccHideEvent(accessible, accessible->GetNode(),
                                aIsAsyncChange, aIsFromUserInput);
 
     } else {
-      event = new nsAccEvent(aEventType, accessible, aIsAsyncChange,
-                             aIsFromUserInput,
-                             nsAccEvent::eCoalesceFromSameSubtree);
+      event = new AccEvent(aEventType, accessible, aIsAsyncChange,
+                           aIsFromUserInput,
+                           AccEvent::eCoalesceFromSameSubtree);
     }
     NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
 
     if (aDelayedOrNormal == eDelayedEvent)
       return FireDelayedAccessibleEvent(event);
 
     nsEventShell::FireEvent(event);
     return NS_OK;
--- a/accessible/src/base/nsDocAccessible.h
+++ b/accessible/src/base/nsDocAccessible.h
@@ -112,17 +112,17 @@ public:
   // nsAccessible
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
   virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState);
 
   virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
 
 #ifdef DEBUG_ACCDOCMGR
-  virtual nsresult HandleAccEvent(nsAccEvent *aAccEvent);
+  virtual nsresult HandleAccEvent(AccEvent* aAccEvent);
 #endif
 
   // nsIAccessibleText
   NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
 
   // nsDocAccessible
 
   /**
@@ -146,26 +146,26 @@ public:
    *
    * @param aEventType   [in] the nsIAccessibleEvent event type
    * @param aDOMNode     [in] DOM node the accesible event should be fired for
    * @param aAllowDupes  [in] rule to process an event (see EEventRule constants)
    * @param aIsAsynch    [in] set to PR_TRUE if this is not being called from
    *                      code synchronous with a DOM event
    */
   nsresult FireDelayedAccessibleEvent(PRUint32 aEventType, nsINode *aNode,
-                                      nsAccEvent::EEventRule aAllowDupes = nsAccEvent::eRemoveDupes,
+                                      AccEvent::EEventRule aAllowDupes = AccEvent::eRemoveDupes,
                                       PRBool aIsAsynch = PR_FALSE,
                                       EIsFromUserInput aIsFromUserInput = eAutoDetect);
 
   /**
    * Fire accessible event after timeout.
    *
    * @param aEvent  [in] the event to fire
    */
-  nsresult FireDelayedAccessibleEvent(nsAccEvent *aEvent);
+  nsresult FireDelayedAccessibleEvent(AccEvent* aEvent);
 
   /**
    * Find the accessible object in the accessibility cache that corresponds to
    * the given node or the first ancestor of it that has an accessible object
    * associated with it. Clear that accessible object's parent's cache of
    * accessible children and remove the accessible object and any descendants
    * from the accessible cache. Fires proper events. New accessible objects will
    * be created and cached again on demand.
@@ -202,17 +202,17 @@ public:
    * Remove the given accessible from document cache.
    */
   void RemoveAccessNodeFromCache(nsAccessible *aAccessible);
 
   /**
    * Process the event when the queue of pending events is untwisted. Fire
    * accessible events as result of the processing.
    */
-  void ProcessPendingEvent(nsAccEvent* aEvent);
+  void ProcessPendingEvent(AccEvent* aEvent);
 
 protected:
 
     virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
     virtual nsresult AddEventListeners();
     virtual nsresult RemoveEventListeners();
     void AddScrollListener();
     void RemoveScrollListener();
@@ -271,17 +271,17 @@ protected:
    *                                 removed, or shown/hidden
    * @param  aAccessible           [in] the accessible for that node, or nsnull
    *                                 if none exists
    * @param  aIsInserting          [in] is aChangeNode being created or shown
    *                                 (vs. removed or hidden)
    * @param  aIsAsync              [in] whether casual change is async
    * @param  aIsFromUserInput      [in] the event is known to be from user input
    */
-  already_AddRefed<nsAccEvent>
+  already_AddRefed<AccEvent>
     CreateTextChangeEventForNode(nsAccessible *aContainerAccessible,
                                  nsIContent *aChangeNode,
                                  nsAccessible *aAccessible,
                                  PRBool aIsInserting,
                                  PRBool aIsAsynch,
                                  EIsFromUserInput aIsFromUserInput = eAutoDetect);
 
   /**
--- a/accessible/src/base/nsEventShell.cpp
+++ b/accessible/src/base/nsEventShell.cpp
@@ -42,17 +42,17 @@
 #include "nsCoreUtils.h"
 #include "nsDocAccessible.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsEventShell
 ////////////////////////////////////////////////////////////////////////////////
 
 void
-nsEventShell::FireEvent(nsAccEvent *aEvent)
+nsEventShell::FireEvent(AccEvent* aEvent)
 {
   if (!aEvent)
     return;
 
   nsAccessible *accessible = aEvent->GetAccessible();
   NS_ENSURE_TRUE(accessible,);
 
   nsINode* node = aEvent->GetNode();
@@ -67,18 +67,18 @@ nsEventShell::FireEvent(nsAccEvent *aEve
 }
 
 void
 nsEventShell::FireEvent(PRUint32 aEventType, nsAccessible *aAccessible,
                         PRBool aIsAsynch, EIsFromUserInput aIsFromUserInput)
 {
   NS_ENSURE_TRUE(aAccessible,);
 
-  nsRefPtr<nsAccEvent> event = new nsAccEvent(aEventType, aAccessible,
-                                              aIsAsynch, aIsFromUserInput);
+  nsRefPtr<AccEvent> event = new AccEvent(aEventType, aAccessible,
+                                          aIsAsynch, aIsFromUserInput);
 
   FireEvent(event);
 }
 
 void 
 nsEventShell::GetEventAttributes(nsINode *aNode,
                                  nsIPersistentProperties *aAttributes)
 {
@@ -118,37 +118,32 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(nsAccEven
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsAccEventQueue)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsAccEventQueue)
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mDocument");
   cb.NoteXPCOMChild(static_cast<nsIAccessible*>(tmp->mDocument.get()));
-
-  PRUint32 i, length = tmp->mEvents.Length();
-  for (i = 0; i < length; ++i) {
-    NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEvents[i]");
-    cb.NoteXPCOMChild(tmp->mEvents[i].get());
-  }
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY_MEMBER(mEvents, AccEvent)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsAccEventQueue)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDocument)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(mEvents)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsAccEventQueue)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsAccEventQueue)
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccEventQueue: public
 
 void
-nsAccEventQueue::Push(nsAccEvent *aEvent)
+nsAccEventQueue::Push(AccEvent* aEvent)
 {
   mEvents.AppendElement(aEvent);
 
   // Filter events.
   CoalesceEvents();
 
   // Associate text change with hide event if it wasn't stolen from hiding
   // siblings during coalescence.
@@ -198,25 +193,25 @@ nsAccEventQueue::WillRefresh(mozilla::Ti
 {
   // If the document accessible is now shut down, don't fire events in it
   // anymore.
   if (!mDocument)
     return;
 
   // Process only currently queued events. Newly appended events during events
   // flushing won't be processed.
-  nsTArray < nsRefPtr<nsAccEvent> > events;
+  nsTArray < nsRefPtr<AccEvent> > events;
   events.SwapElements(mEvents);
   PRUint32 length = events.Length();
   NS_ASSERTION(length, "How did we get here without events to fire?");
 
   for (PRUint32 index = 0; index < length; index ++) {
 
-    nsAccEvent *accEvent = events[index];
-    if (accEvent->mEventRule != nsAccEvent::eDoNotEmit) {
+    AccEvent* accEvent = events[index];
+    if (accEvent->mEventRule != AccEvent::eDoNotEmit) {
       mDocument->ProcessPendingEvent(accEvent);
 
       AccHideEvent* hideEvent = downcast_accEvent(accEvent);
       if (hideEvent) {
         if (hideEvent->mTextChangeEvent)
           mDocument->ProcessPendingEvent(hideEvent->mTextChangeEvent);
       }
     }
@@ -235,28 +230,28 @@ nsAccEventQueue::WillRefresh(mozilla::Ti
   }
 }
 
 void
 nsAccEventQueue::CoalesceEvents()
 {
   PRUint32 numQueuedEvents = mEvents.Length();
   PRInt32 tail = numQueuedEvents - 1;
-  nsAccEvent* tailEvent = mEvents[tail];
+  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 nsAccEvent::eCoalesceFromSameSubtree:
+    case AccEvent::eCoalesceFromSameSubtree:
     {
       for (PRInt32 index = tail - 1; index >= 0; index--) {
-        nsAccEvent* thisEvent = mEvents[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
         // coalesce them.
         if (!thisEvent->mNode ||
@@ -275,17 +270,17 @@ nsAccEventQueue::CoalesceEvents()
         // Coalesce hide events for sibling targets.
         if (tailEvent->mEventType == nsIAccessibleEvent::EVENT_HIDE) {
           AccHideEvent* tailHideEvent = downcast_accEvent(tailEvent);
           AccHideEvent* thisHideEvent = downcast_accEvent(thisEvent);
           if (thisHideEvent->mParent == tailHideEvent->mParent) {
             tailEvent->mEventRule = thisEvent->mEventRule;
 
             // Coalesce text change events for hide events.
-            if (tailEvent->mEventRule != nsAccEvent::eDoNotEmit)
+            if (tailEvent->mEventRule != AccEvent::eDoNotEmit)
               CoalesceTextChangeEventsFor(tailHideEvent, thisHideEvent);
 
             return;
           }
         }
 
         // Ignore events unattached from DOM since we don't coalesce them.
         if (!thisEvent->mNode->IsInDoc())
@@ -297,28 +292,28 @@ nsAccEventQueue::CoalesceEvents()
           tailEvent->mEventRule = thisEvent->mEventRule;
           return;
         }
 
         // Specifies if this event target can be descendant of tail node.
         PRBool thisCanBeDescendantOfTail = PR_FALSE;
 
         // Coalesce depending on whether this event was coalesced or not.
-        if (thisEvent->mEventRule == nsAccEvent::eDoNotEmit) {
+        if (thisEvent->mEventRule == AccEvent::eDoNotEmit) {
           // If this event was coalesced then do not emit tail event iff tail
           // event has the same target or its target is contained by this event
           // target. Note, we don't need to check whether tail event target
           // contains this event target since this event was coalesced already.
 
           // As well we don't need to apply the calculated rule for siblings of
           // tail node because tail event rule was applied to possible tail
           // node siblings while this event was coalesced.
 
           if (thisEvent->mNode == tailEvent->mNode) {
-            thisEvent->mEventRule = nsAccEvent::eDoNotEmit;
+            thisEvent->mEventRule = AccEvent::eDoNotEmit;
             return;
           }
 
         } else {
           // If this event wasn't coalesced already then try to coalesce it or
           // tail event. If this event is coalesced by tail event then continue
           // search through events other events that can be coalesced by tail
           // event.
@@ -326,21 +321,21 @@ nsAccEventQueue::CoalesceEvents()
           // If tail and this events have the same target then coalesce tail
           // event because more early event we should fire early and then stop
           // processing.
           if (thisEvent->mNode == tailEvent->mNode) {
             // Coalesce reorder events by special way since reorder events can
             // be conditional events (be or not be fired in the end).
             if (thisEvent->mEventType == nsIAccessibleEvent::EVENT_REORDER) {
               CoalesceReorderEventsFromSameSource(thisEvent, tailEvent);
-              if (tailEvent->mEventRule != nsAccEvent::eDoNotEmit)
+              if (tailEvent->mEventRule != AccEvent::eDoNotEmit)
                 continue;
             }
             else {
-              tailEvent->mEventRule = nsAccEvent::eDoNotEmit;
+              tailEvent->mEventRule = AccEvent::eDoNotEmit;
             }
 
             return;
           }
 
           // This and tail events can be anywhere in the tree, make assumptions
           // for mutation events.
 
@@ -362,23 +357,23 @@ nsAccEventQueue::CoalesceEvents()
         // Note: more older hide event target (thisNode) can't contain recent
         // hide event target (tailNode), i.e. be ancestor of tailNode. Skip
         // this check for hide events.
         if (tailEvent->mEventType != nsIAccessibleEvent::EVENT_HIDE &&
             nsCoreUtils::IsAncestorOf(thisEvent->mNode, tailEvent->mNode)) {
 
           if (thisEvent->mEventType == nsIAccessibleEvent::EVENT_REORDER) {
             CoalesceReorderEventsFromSameTree(thisEvent, tailEvent);
-            if (tailEvent->mEventRule != nsAccEvent::eDoNotEmit)
+            if (tailEvent->mEventRule != AccEvent::eDoNotEmit)
               continue;
 
             return;
           }
 
-          tailEvent->mEventRule = nsAccEvent::eDoNotEmit;
+          tailEvent->mEventRule = AccEvent::eDoNotEmit;
           return;
         }
 
 #ifdef DEBUG
         if (tailEvent->mEventType == nsIAccessibleEvent::EVENT_HIDE &&
             nsCoreUtils::IsAncestorOf(thisEvent->mNode, tailEvent->mNode)) {
           NS_NOTREACHED("More older hide event target is an ancestor of recent hide event target!");
         }
@@ -386,135 +381,135 @@ nsAccEventQueue::CoalesceEvents()
 
         // If this node is a descendant of tail node then coalesce this event,
         // check other events in the queue.
         if (thisCanBeDescendantOfTail &&
             nsCoreUtils::IsAncestorOf(tailEvent->mNode, thisEvent->mNode)) {
 
           if (thisEvent->mEventType == nsIAccessibleEvent::EVENT_REORDER) {
             CoalesceReorderEventsFromSameTree(tailEvent, thisEvent);
-            if (tailEvent->mEventRule != nsAccEvent::eDoNotEmit)
+            if (tailEvent->mEventRule != AccEvent::eDoNotEmit)
               continue;
 
             return;
           }
 
           // Do not emit thisEvent, also apply this result to sibling nodes of
           // thisNode.
-          thisEvent->mEventRule = nsAccEvent::eDoNotEmit;
+          thisEvent->mEventRule = AccEvent::eDoNotEmit;
           ApplyToSiblings(0, index, thisEvent->mEventType,
-                          thisEvent->mNode, nsAccEvent::eDoNotEmit);
+                          thisEvent->mNode, AccEvent::eDoNotEmit);
           continue;
         }
 
 #ifdef DEBUG
         if (!thisCanBeDescendantOfTail &&
             nsCoreUtils::IsAncestorOf(tailEvent->mNode, thisEvent->mNode)) {
           NS_NOTREACHED("Older event target is a descendant of recent event target!");
         }
 #endif
 
       } // for (index)
 
     } break; // case eCoalesceFromSameSubtree
 
-    case nsAccEvent::eCoalesceFromSameDocument:
+    case AccEvent::eCoalesceFromSameDocument:
     {
       // 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.
       for (PRInt32 index = tail - 1; index >= 0; index--) {
-        nsAccEvent* thisEvent = mEvents[index];
+        AccEvent* thisEvent = mEvents[index];
         if (thisEvent->mEventType == tailEvent->mEventType &&
             thisEvent->mEventRule == tailEvent->mEventRule &&
             thisEvent->GetDocAccessible() == tailEvent->GetDocAccessible()) {
-          thisEvent->mEventRule = nsAccEvent::eDoNotEmit;
+          thisEvent->mEventRule = AccEvent::eDoNotEmit;
           return;
         }
       }
     } break; // case eCoalesceFromSameDocument
 
-    case nsAccEvent::eRemoveDupes:
+    case AccEvent::eRemoveDupes:
     {
       // Check for repeat events, coalesce newly appended event by more older
       // event.
       for (PRInt32 index = tail - 1; index >= 0; index--) {
-        nsAccEvent* accEvent = mEvents[index];
+        AccEvent* accEvent = mEvents[index];
         if (accEvent->mEventType == tailEvent->mEventType &&
             accEvent->mEventRule == tailEvent->mEventRule &&
             accEvent->mNode == tailEvent->mNode) {
-          tailEvent->mEventRule = nsAccEvent::eDoNotEmit;
+          tailEvent->mEventRule = AccEvent::eDoNotEmit;
           return;
         }
       }
     } break; // case eRemoveDupes
 
     default:
       break; // case eAllowDupes, eDoNotEmit
   } // switch
 }
 
 void
 nsAccEventQueue::ApplyToSiblings(PRUint32 aStart, PRUint32 aEnd,
                                  PRUint32 aEventType, nsINode* aNode,
-                                 nsAccEvent::EEventRule aEventRule)
+                                 AccEvent::EEventRule aEventRule)
 {
   for (PRUint32 index = aStart; index < aEnd; index ++) {
-    nsAccEvent* accEvent = mEvents[index];
+    AccEvent* accEvent = mEvents[index];
     if (accEvent->mEventType == aEventType &&
-        accEvent->mEventRule != nsAccEvent::eDoNotEmit &&
+        accEvent->mEventRule != AccEvent::eDoNotEmit &&
         accEvent->mNode->GetNodeParent() == aNode->GetNodeParent()) {
       accEvent->mEventRule = aEventRule;
     }
   }
 }
 
 void
-nsAccEventQueue::CoalesceReorderEventsFromSameSource(nsAccEvent *aAccEvent1,
-                                                     nsAccEvent *aAccEvent2)
+nsAccEventQueue::CoalesceReorderEventsFromSameSource(AccEvent* aAccEvent1,
+                                                     AccEvent* aAccEvent2)
 {
   // Do not emit event2 if event1 is unconditional.
-  nsAccReorderEvent *reorderEvent1 = downcast_accEvent(aAccEvent1);
+  AccReorderEvent* reorderEvent1 = downcast_accEvent(aAccEvent1);
   if (reorderEvent1->IsUnconditionalEvent()) {
-    aAccEvent2->mEventRule = nsAccEvent::eDoNotEmit;
+    aAccEvent2->mEventRule = AccEvent::eDoNotEmit;
     return;
   }
 
   // Do not emit event1 if event2 is unconditional.
-  nsAccReorderEvent *reorderEvent2 = downcast_accEvent(aAccEvent2);
+  AccReorderEvent* reorderEvent2 = downcast_accEvent(aAccEvent2);
   if (reorderEvent2->IsUnconditionalEvent()) {
-    aAccEvent1->mEventRule = nsAccEvent::eDoNotEmit;
+    aAccEvent1->mEventRule = AccEvent::eDoNotEmit;
     return;
   }
 
   // Do not emit event2 if event1 is valid, otherwise do not emit event1.
   if (reorderEvent1->HasAccessibleInReasonSubtree())
-    aAccEvent2->mEventRule = nsAccEvent::eDoNotEmit;
+    aAccEvent2->mEventRule = AccEvent::eDoNotEmit;
   else
-    aAccEvent1->mEventRule = nsAccEvent::eDoNotEmit;
+    aAccEvent1->mEventRule = AccEvent::eDoNotEmit;
 }
 
 void
-nsAccEventQueue::CoalesceReorderEventsFromSameTree(nsAccEvent *aAccEvent,
-                                                   nsAccEvent *aDescendantAccEvent)
+nsAccEventQueue::CoalesceReorderEventsFromSameTree(AccEvent* aAccEvent,
+                                                   AccEvent* aDescendantAccEvent)
 {
   // Do not emit descendant event if this event is unconditional.
-  nsAccReorderEvent *reorderEvent = downcast_accEvent(aAccEvent);
+  AccReorderEvent* reorderEvent = downcast_accEvent(aAccEvent);
   if (reorderEvent->IsUnconditionalEvent())
-    aDescendantAccEvent->mEventRule = nsAccEvent::eDoNotEmit;
+    aDescendantAccEvent->mEventRule = AccEvent::eDoNotEmit;
 }
 
 void
 nsAccEventQueue::CoalesceTextChangeEventsFor(AccHideEvent* aTailEvent,
                                              AccHideEvent* aThisEvent)
 {
   // XXX: we need a way to ignore SplitNode and JoinNode() when they do not
   // affect the text within the hypertext.
 
-  nsAccTextChangeEvent* textEvent = aThisEvent->mTextChangeEvent;
+  AccTextChangeEvent* textEvent = aThisEvent->mTextChangeEvent;
   if (!textEvent)
     return;
 
   if (aThisEvent->mNextSibling == aTailEvent->mAccessible) {
     aTailEvent->mAccessible->AppendTextTo(textEvent->mModifiedText,
                                           0, PR_UINT32_MAX);
 
   } else if (aThisEvent->mPrevSibling == aTailEvent->mAccessible) {
@@ -552,12 +547,12 @@ nsAccEventQueue::CreateTextChangeEventFo
   PRInt32 offset = textAccessible->GetChildOffset(aEvent->mAccessible);
 
   nsAutoString text;
   aEvent->mAccessible->AppendTextTo(text, 0, PR_UINT32_MAX);
   if (text.IsEmpty())
     return;
 
   aEvent->mTextChangeEvent =
-    new nsAccTextChangeEvent(textAccessible, offset, text, PR_FALSE,
-                             aEvent->mIsAsync,
-                             aEvent->mIsFromUserInput ? eFromUserInput : eNoUserInput);
+    new AccTextChangeEvent(textAccessible, offset, text, PR_FALSE,
+                           aEvent->mIsAsync,
+                           aEvent->mIsFromUserInput ? eFromUserInput : eNoUserInput);
 }
--- a/accessible/src/base/nsEventShell.h
+++ b/accessible/src/base/nsEventShell.h
@@ -34,17 +34,17 @@
  * 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 _nsEventShell_H_
 #define _nsEventShell_H_
 
-#include "nsAccEvent.h"
+#include "AccEvent.h"
 
 #include "a11yGeneric.h"
 
 #include "nsAutoPtr.h"
 
 #include "nsRefreshDriver.h"
 
 class nsIPersistentProperties;
@@ -54,17 +54,17 @@ class nsIPersistentProperties;
  */
 class nsEventShell
 {
 public:
 
   /**
    * Fire the accessible event.
    */
-  static void FireEvent(nsAccEvent *aEvent);
+  static void FireEvent(AccEvent* aEvent);
 
   /**
    * Fire accessible event of the given type for the given accessible.
    *
    * @param  aEventType   [in] the event type
    * @param  aAccessible  [in] the event target
    * @param  aIsAsync     [in, optional] specifies whether the origin change
    *                        this event is fired owing to is async.
@@ -100,17 +100,17 @@ public:
   ~nsAccEventQueue();
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(nsAccEventQueue)
 
   /**
    * Push event to queue, coalesce it if necessary. Start pending processing.
    */
-  void Push(nsAccEvent *aEvent);
+  void Push(AccEvent* aEvent);
 
   /**
    * Shutdown the queue.
    */
   void Shutdown();
 
 private:
 
@@ -137,30 +137,30 @@ private:
    * @param aEnd             end index to be scanned (not included)
    * @param aEventType       target event type
    * @param aDOMNode         target are siblings of this node
    * @param aEventRule       the event rule to be applied
    *                         (should be eDoNotEmit or eAllowDupes)
    */
   void ApplyToSiblings(PRUint32 aStart, PRUint32 aEnd,
                        PRUint32 aEventType, nsINode* aNode,
-                       nsAccEvent::EEventRule aEventRule);
+                       AccEvent::EEventRule aEventRule);
 
   /**
    * Do not emit one of two given reorder events fired for the same DOM node.
    */
-  void CoalesceReorderEventsFromSameSource(nsAccEvent *aAccEvent1,
-                                           nsAccEvent *aAccEvent2);
+  void CoalesceReorderEventsFromSameSource(AccEvent* aAccEvent1,
+                                           AccEvent* aAccEvent2);
 
   /**
    * Do not emit one of two given reorder events fired for DOM nodes in the case
    * when one DOM node is in parent chain of second one.
    */
-  void CoalesceReorderEventsFromSameTree(nsAccEvent *aAccEvent,
-                                         nsAccEvent *aDescendantAccEvent);
+  void CoalesceReorderEventsFromSameTree(AccEvent* aAccEvent,
+                                         AccEvent* aDescendantAccEvent);
 
   /**
    * Coalesce text change events caused by sibling hide events.
    */
   void CoalesceTextChangeEventsFor(AccHideEvent* aTailEvent,
                                    AccHideEvent* aThisEvent);
 
   /**
@@ -181,12 +181,12 @@ private:
    * The document accessible reference owning this queue.
    */
   nsRefPtr<nsDocAccessible> mDocument;
 
   /**
    * Pending events array.  Don't make this an nsAutoTArray; we use
    * SwapElements() on it.
    */
-  nsTArray<nsRefPtr<nsAccEvent> > mEvents;
+  nsTArray<nsRefPtr<AccEvent> > mEvents;
 };
 
 #endif
--- a/accessible/src/base/nsRootAccessible.cpp
+++ b/accessible/src/base/nsRootAccessible.cpp
@@ -398,32 +398,32 @@ nsRootAccessible::FireAccessibleFocusEve
       PRUint32 naturalRole = nsAccUtils::RoleInternal(finalFocusAccessible);
       if (role != naturalRole) { // Must be a DHTML menuitem
         nsAccessible *menuBarAccessible =
           nsAccUtils::GetAncestorWithRole(finalFocusAccessible,
                                           nsIAccessibleRole::ROLE_MENUBAR);
         if (menuBarAccessible) {
           mCurrentARIAMenubar = menuBarAccessible->GetNode();
           if (mCurrentARIAMenubar) {
-            nsRefPtr<nsAccEvent> menuStartEvent =
-              new nsAccEvent(nsIAccessibleEvent::EVENT_MENU_START,
-                             menuBarAccessible, PR_FALSE, aIsFromUserInput,
-                             nsAccEvent::eAllowDupes);
+            nsRefPtr<AccEvent> menuStartEvent =
+              new AccEvent(nsIAccessibleEvent::EVENT_MENU_START,
+                           menuBarAccessible, PR_FALSE, aIsFromUserInput,
+                           AccEvent::eAllowDupes);
             if (menuStartEvent) {
               FireDelayedAccessibleEvent(menuStartEvent);
             }
           }
         }
       }
     }
   }
   else if (mCurrentARIAMenubar) {
-    nsRefPtr<nsAccEvent> menuEndEvent =
-      new nsAccEvent(nsIAccessibleEvent::EVENT_MENU_END, mCurrentARIAMenubar,
-                     PR_FALSE, aIsFromUserInput, nsAccEvent::eAllowDupes);
+    nsRefPtr<AccEvent> menuEndEvent =
+      new AccEvent(nsIAccessibleEvent::EVENT_MENU_END, mCurrentARIAMenubar,
+                   PR_FALSE, aIsFromUserInput, AccEvent::eAllowDupes);
     if (menuEndEvent) {
       FireDelayedAccessibleEvent(menuEndEvent);
     }
     mCurrentARIAMenubar = nsnull;
   }
 
   nsCOMPtr<nsIContent> focusContent = do_QueryInterface(finalFocusNode);
   nsIFrame *focusFrame = nsnull;
@@ -441,17 +441,17 @@ nsRootAccessible::FireAccessibleFocusEve
   gLastFocusedNode = finalFocusNode;
   NS_IF_ADDREF(gLastFocusedNode);
 
   gLastFocusedFrameType = (focusFrame && focusFrame->GetStyleVisibility()->IsVisible()) ? focusFrame->GetType() : 0;
 
   // 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.
   FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_FOCUS,
-                             finalFocusNode, nsAccEvent::eCoalesceFromSameDocument,
+                             finalFocusNode, AccEvent::eCoalesceFromSameDocument,
                              aIsAsynch, aIsFromUserInput);
 
   return PR_TRUE;
 }
 
 void
 nsRootAccessible::FireCurrentFocusEvent()
 {
@@ -544,36 +544,35 @@ nsRootAccessible::HandleEvent(nsIDOMEven
 
     // radiogroup in prefWindow is exposed as a list,
     // and panebutton is exposed as XULListitem in A11y.
     // nsXULListitemAccessible::GetStateInternal uses STATE_SELECTED in this case,
     // so we need to check nsIAccessibleStates::STATE_SELECTED also.
     PRBool isEnabled = (state & (nsIAccessibleStates::STATE_CHECKED |
                         nsIAccessibleStates::STATE_SELECTED)) != 0;
 
-    nsRefPtr<nsAccEvent> accEvent =
-      new nsAccStateChangeEvent(accessible, nsIAccessibleStates::STATE_CHECKED,
-                                PR_FALSE, isEnabled);
+    nsRefPtr<AccEvent> accEvent =
+      new AccStateChangeEvent(accessible, nsIAccessibleStates::STATE_CHECKED,
+                              PR_FALSE, isEnabled);
     nsEventShell::FireEvent(accEvent);
 
     if (isEnabled)
       FireAccessibleFocusEvent(accessible, targetNode, aEvent);
 
     return NS_OK;
   }
 
   if (eventType.EqualsLiteral("CheckboxStateChange")) {
     PRUint32 state = nsAccUtils::State(accessible);
 
     PRBool isEnabled = !!(state & nsIAccessibleStates::STATE_CHECKED);
 
-    nsRefPtr<nsAccEvent> accEvent =
-      new nsAccStateChangeEvent(accessible,
-                                nsIAccessibleStates::STATE_CHECKED,
-                                PR_FALSE, isEnabled);
+    nsRefPtr<AccEvent> accEvent =
+      new AccStateChangeEvent(accessible, nsIAccessibleStates::STATE_CHECKED,
+                              PR_FALSE, isEnabled);
 
     nsEventShell::FireEvent(accEvent);
     return NS_OK;
   }
 
   nsAccessible *treeItemAccessible = nsnull;
 #ifdef MOZ_XUL
   // If it's a tree element, need the currently selected item
@@ -595,19 +594,19 @@ nsRootAccessible::HandleEvent(nsIDOMEven
   }
 #endif
 
 #ifdef MOZ_XUL
   if (treeItemAccessible && eventType.EqualsLiteral("OpenStateChange")) {
     PRUint32 state = nsAccUtils::State(accessible); // collapsed/expanded changed
     PRBool isEnabled = (state & nsIAccessibleStates::STATE_EXPANDED) != 0;
 
-    nsRefPtr<nsAccEvent> accEvent =
-      new nsAccStateChangeEvent(accessible, nsIAccessibleStates::STATE_EXPANDED,
-                                PR_FALSE, isEnabled);
+    nsRefPtr<AccEvent> accEvent =
+      new AccStateChangeEvent(accessible, nsIAccessibleStates::STATE_EXPANDED,
+                              PR_FALSE, isEnabled);
     nsEventShell::FireEvent(accEvent);
     return NS_OK;
   }
 
   if (treeItemAccessible && eventType.EqualsLiteral("select")) {
     // If multiselect tree, we should fire selectionadd or selection removed
     if (gLastFocusedNode == targetNode) {
       nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSel =
@@ -718,17 +717,18 @@ nsRootAccessible::HandleEvent(nsIDOMEven
           if (nsAccUtils::Role(containerParent) != nsIAccessibleRole::ROLE_COMBOBOX) {
             return NS_OK;
           }
         }
       }
     }
     if (!fireFocus) {
       nsCOMPtr<nsINode> realFocusedNode = GetCurrentFocus();
-      nsIContent* realFocusedContent = realFocusedNode->AsElement();
+      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;
@@ -748,17 +748,17 @@ nsRootAccessible::HandleEvent(nsIDOMEven
   }
   else if (eventType.EqualsLiteral("DOMMenuBarInactive")) {  // Always asynch, always from user input
     nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENU_END,
                             accessible, PR_TRUE, eFromUserInput);
     FireCurrentFocusEvent();
   }
   else if (eventType.EqualsLiteral("ValueChange")) {
     FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE,
-                               targetNode, nsAccEvent::eRemoveDupes);
+                               targetNode, AccEvent::eRemoveDupes);
   }
 #ifdef DEBUG
   else if (eventType.EqualsLiteral("mouseover")) {
     nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_DRAGDROP_START,
                             accessible);
   }
 #endif
   return NS_OK;
@@ -882,20 +882,20 @@ nsRootAccessible::HandlePopupShownEvent(
   }
 
   if (role == nsIAccessibleRole::ROLE_COMBOBOX_LIST) {
     // Fire expanded state change event for comboboxes and autocompeletes.
     nsAccessible *comboboxAcc = aAccessible->GetParent();
     PRUint32 comboboxRole = nsAccUtils::Role(comboboxAcc);
     if (comboboxRole == nsIAccessibleRole::ROLE_COMBOBOX ||
         comboboxRole == nsIAccessibleRole::ROLE_AUTOCOMPLETE) {
-      nsRefPtr<nsAccEvent> event =
-        new nsAccStateChangeEvent(comboboxAcc,
-                                  nsIAccessibleStates::STATE_EXPANDED,
-                                  PR_FALSE, PR_TRUE);
+      nsRefPtr<AccEvent> event =
+        new AccStateChangeEvent(comboboxAcc,
+                                nsIAccessibleStates::STATE_EXPANDED,
+                                PR_FALSE, PR_TRUE);
       NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
 
       nsEventShell::FireEvent(event);
       return NS_OK;
     }
   }
 
   return NS_OK;
@@ -924,20 +924,20 @@ nsRootAccessible::HandlePopupHidingEvent
   PRUint32 role = nsAccUtils::Role(aAccessible);
   if (role != nsIAccessibleRole::ROLE_COMBOBOX_LIST)
     return NS_OK;
 
   nsAccessible *comboboxAcc = aAccessible->GetParent();
   PRUint32 comboboxRole = nsAccUtils::Role(comboboxAcc);
   if (comboboxRole == nsIAccessibleRole::ROLE_COMBOBOX ||
       comboboxRole == nsIAccessibleRole::ROLE_AUTOCOMPLETE) {
-    nsRefPtr<nsAccEvent> event =
-      new nsAccStateChangeEvent(comboboxAcc,
-                                nsIAccessibleStates::STATE_EXPANDED,
-                                PR_FALSE, PR_FALSE);
+    nsRefPtr<AccEvent> event =
+      new AccStateChangeEvent(comboboxAcc,
+                              nsIAccessibleStates::STATE_EXPANDED,
+                              PR_FALSE, PR_FALSE);
     NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
 
     nsEventShell::FireEvent(event);
     return NS_OK;
   }
 
   return NS_OK;
 }
--- a/accessible/src/html/nsHTMLSelectAccessible.cpp
+++ b/accessible/src/html/nsHTMLSelectAccessible.cpp
@@ -758,35 +758,34 @@ nsHTMLSelectOptionAccessible::SelectionC
   if (!multiSelect)
     return;
 
   nsAccessible *option = GetAccService()->GetAccessible(aPossibleOptionNode);
   if (!option)
     return;
 
 
-  nsRefPtr<nsAccEvent> selWithinEvent =
-    new nsAccEvent(nsIAccessibleEvent::EVENT_SELECTION_WITHIN, multiSelect);
+  nsRefPtr<AccEvent> selWithinEvent =
+    new AccEvent(nsIAccessibleEvent::EVENT_SELECTION_WITHIN, multiSelect);
 
   if (!selWithinEvent)
     return;
 
   option->GetDocAccessible()->FireDelayedAccessibleEvent(selWithinEvent);
 
   PRUint32 state = nsAccUtils::State(option);
   PRUint32 eventType;
   if (state & nsIAccessibleStates::STATE_SELECTED) {
     eventType = nsIAccessibleEvent::EVENT_SELECTION_ADD;
   }
   else {
     eventType = nsIAccessibleEvent::EVENT_SELECTION_REMOVE;
   }
 
-  nsRefPtr<nsAccEvent> selAddRemoveEvent =
-    new nsAccEvent(eventType, option);
+  nsRefPtr<AccEvent> selAddRemoveEvent = new AccEvent(eventType, option);
 
   if (selAddRemoveEvent)
     option->GetDocAccessible()->FireDelayedAccessibleEvent(selAddRemoveEvent);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLSelectOptionAccessible: private methods
 
--- a/accessible/src/html/nsHyperTextAccessible.h
+++ b/accessible/src/html/nsHyperTextAccessible.h
@@ -126,17 +126,17 @@ public:
   }
 
   /**
    * Return link accessible at the given text offset.
    */
   inline PRInt32 GetLinkIndexAtOffset(PRUint32 aOffset)
   {
     nsAccessible* child = GetChildAtOffset(aOffset);
-    return GetLinkIndex(child);
+    return child ? GetLinkIndex(child) : -1;
   }
 
   /**
     * Turn a DOM Node and offset into a character offset into this hypertext.
     * Will look for closest match when the DOM node does not have an accessible
     * object associated with it. Will return an offset for the end of
     * the string if the node is not found.
     *
--- a/accessible/src/mac/nsAccessibleWrap.h
+++ b/accessible/src/mac/nsAccessibleWrap.h
@@ -73,17 +73,17 @@ class nsAccessibleWrap : public nsAccess
     virtual objc_class* GetNativeType ();
     
     // returns a pointer to the native window for this accessible tree.
     void GetNativeWindow (void **aOutNativeWindow);
     
     virtual void Shutdown ();
     virtual void InvalidateChildren();
 
-    virtual nsresult HandleAccEvent(nsAccEvent *aEvent);
+    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();
     
     PRInt32 GetUnignoredChildCount(PRBool aDeepCount);
     
     PRBool HasPopup () {
@@ -93,17 +93,17 @@ class nsAccessibleWrap : public nsAccess
     }
     
     // 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(nsAccEvent *aEvent);
+    virtual nsresult FirePlatformEvent(AccEvent* aEvent);
 
   /**
    * Return true if the parent doesn't have children to expose to AT.
    */
   PRBool AncestorIsFlat();
 
     // Wrapper around our native object.
     AccessibleWrapper *mNativeWrapper;
--- a/accessible/src/mac/nsAccessibleWrap.mm
+++ b/accessible/src/mac/nsAccessibleWrap.mm
@@ -156,30 +156,30 @@ nsAccessibleWrap::Shutdown ()
     delete mNativeWrapper;
     mNativeWrapper = nsnull;
   }
   
   nsAccessible::Shutdown();
 }
 
 nsresult
-nsAccessibleWrap::HandleAccEvent(nsAccEvent *aEvent)
+nsAccessibleWrap::HandleAccEvent(AccEvent* aEvent)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   nsresult rv = nsAccessible::HandleAccEvent(aEvent);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return FirePlatformEvent(aEvent);
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
 nsresult
-nsAccessibleWrap::FirePlatformEvent(nsAccEvent *aEvent)
+nsAccessibleWrap::FirePlatformEvent(AccEvent* aEvent)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   PRUint32 eventType = aEvent->GetEventType();
 
   // ignore everything but focus-changed and value-changed events for now.
   if (eventType != nsIAccessibleEvent::EVENT_FOCUS &&
       eventType != nsIAccessibleEvent::EVENT_VALUE_CHANGE)
--- a/accessible/src/msaa/nsAccessNodeWrap.cpp
+++ b/accessible/src/msaa/nsAccessNodeWrap.cpp
@@ -65,17 +65,17 @@ HINSTANCE nsAccessNodeWrap::gmUserLib = 
 LPFNACCESSIBLEOBJECTFROMWINDOW nsAccessNodeWrap::gmAccessibleObjectFromWindow = nsnull;
 LPFNNOTIFYWINEVENT nsAccessNodeWrap::gmNotifyWinEvent = nsnull;
 LPFNGETGUITHREADINFO nsAccessNodeWrap::gmGetGUIThreadInfo = nsnull;
 
 PRBool nsAccessNodeWrap::gIsEnumVariantSupportDisabled = 0;
 // Used to determine whether an IAccessible2 compatible screen reader is loaded.
 PRBool nsAccessNodeWrap::gIsIA2Disabled = PR_FALSE;
 
-nsAccTextChangeEvent *nsAccessNodeWrap::gTextEvent = nsnull;
+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"
 
 
 /* For documentation of the accessibility architecture, 
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
--- a/accessible/src/msaa/nsAccessNodeWrap.h
+++ b/accessible/src/msaa/nsAccessNodeWrap.h
@@ -66,17 +66,17 @@
 #endif
 #ifdef MOZ_CRASHREPORTER
 #include "nsICrashReporter.h"
 #endif
 
 typedef LRESULT (STDAPICALLTYPE *LPFNNOTIFYWINEVENT)(DWORD event,HWND hwnd,LONG idObjectType,LONG idObject);
 typedef LRESULT (STDAPICALLTYPE *LPFNGETGUITHREADINFO)(DWORD idThread, GUITHREADINFO* pgui);
 
-class nsAccTextChangeEvent;
+class AccTextChangeEvent;
 
 class nsAccessNodeWrap :  public nsAccessNode,
                           public nsIWinAccessNode,
                           public ISimpleDOMNode,
                           public IServiceProvider
 {
   public:
     NS_DECL_ISUPPORTS_INHERITED
@@ -182,17 +182,17 @@ protected:
      * loaded. Currently used for JAWS versions older than 8.0.2173.
      */
      static PRBool gIsIA2Disabled;
 
     /**
      * It is used in nsHyperTextAccessibleWrap for IA2::newText/oldText
      * implementation.
      */
-    static nsAccTextChangeEvent *gTextEvent;
+    static AccTextChangeEvent* gTextEvent;
 };
 
 /**
  * Converts nsresult to HRESULT.
  */
 HRESULT GetHRESULT(nsresult aResult);
 
 #endif
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -1577,26 +1577,26 @@ NS_IMETHODIMP nsAccessibleWrap::GetNativ
   *aOutAccessible = static_cast<IAccessible*>(this);
   NS_ADDREF_THIS();
   return NS_OK;
 }
 
 // nsAccessible
 
 nsresult
-nsAccessibleWrap::HandleAccEvent(nsAccEvent *aEvent)
+nsAccessibleWrap::HandleAccEvent(AccEvent* aEvent)
 {
   nsresult rv = nsAccessible::HandleAccEvent(aEvent);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return FirePlatformEvent(aEvent);
 }
 
 nsresult
-nsAccessibleWrap::FirePlatformEvent(nsAccEvent *aEvent)
+nsAccessibleWrap::FirePlatformEvent(AccEvent* aEvent)
 {
   PRUint32 eventType = aEvent->GetEventType();
 
   NS_ENSURE_TRUE(eventType > 0 &&
                  eventType < nsIAccessibleEvent::EVENT_LAST_ENTRY,
                  NS_ERROR_FAILURE);
 
   PRUint32 winLastEntry = gWinEventMap[nsIAccessibleEvent::EVENT_LAST_ENTRY];
--- a/accessible/src/msaa/nsAccessibleWrap.h
+++ b/accessible/src/msaa/nsAccessibleWrap.h
@@ -302,17 +302,17 @@ public: // construction, destruction
   virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid,
                                            LCID lcid, WORD wFlags,
                                            DISPPARAMS *pDispParams,
                                            VARIANT *pVarResult,
                                            EXCEPINFO *pExcepInfo,
                                            UINT *puArgErr);
 
   // nsAccessible
-  virtual nsresult HandleAccEvent(nsAccEvent *aEvent);
+  virtual nsresult HandleAccEvent(AccEvent* aEvent);
 
   // Helper methods
   static PRInt32 GetChildIDFor(nsIAccessible* aAccessible);
   static HWND GetHWNDFor(nsAccessible *aAccessible);
   static HRESULT ConvertToIA2Attributes(nsIPersistentProperties *aAttributes,
                                         BSTR *aIA2Attributes);
 
   /**
@@ -341,17 +341,17 @@ public: // construction, destruction
   /**
    * Drops the IEnumVariant current position so that navigation methods
    * Next() and Skip() doesn't work until Reset() method is called. The method
    * is used when children of the accessible are changed.
    */
   void UnattachIEnumVariant();
 
 protected:
-  virtual nsresult FirePlatformEvent(nsAccEvent *aEvent);
+  virtual nsresult FirePlatformEvent(AccEvent* aEvent);
 
   // mEnumVARIANTPosition not the current accessible's position, but a "cursor" of 
   // where we are in the current list of children, with respect to
   // nsIEnumVariant::Reset(), Skip() and Next().
   PRInt32 mEnumVARIANTPosition;
 
   /**
    * Creates ITypeInfo for LIBID_Accessibility if it's needed and returns it.
--- a/accessible/src/msaa/nsHyperTextAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsHyperTextAccessibleWrap.cpp
@@ -46,17 +46,17 @@ NS_IMPL_ISUPPORTS_INHERITED0(nsHyperText
                              nsHyperTextAccessible)
 
 IMPL_IUNKNOWN_INHERITED2(nsHyperTextAccessibleWrap,
                          nsAccessibleWrap,
                          CAccessibleHypertext,
                          CAccessibleEditableText);
 
 nsresult
-nsHyperTextAccessibleWrap::HandleAccEvent(nsAccEvent *aEvent)
+nsHyperTextAccessibleWrap::HandleAccEvent(AccEvent* aEvent)
 {
   PRUint32 eventType = aEvent->GetEventType();
 
   if (eventType == nsIAccessibleEvent::EVENT_TEXT_REMOVED ||
       eventType == nsIAccessibleEvent::EVENT_TEXT_INSERTED) {
     nsAccessible *accessible = aEvent->GetAccessible();
     if (accessible) {
       nsCOMPtr<nsIWinAccessNode> winAccessNode(do_QueryObject(accessible));
@@ -95,11 +95,13 @@ nsHyperTextAccessibleWrap::GetModifiedTe
     return NS_OK;
 
   nsAccessible *targetAcc = gTextEvent->GetAccessible();
   if (targetAcc != this)
     return NS_OK;
 
   *aStartOffset = gTextEvent->GetStartOffset();
   *aEndOffset = *aStartOffset + gTextEvent->GetLength();
-  return gTextEvent->GetModifiedText(aText);
+  gTextEvent->GetModifiedText(aText);
+
+  return NS_OK;
 }
 
--- a/accessible/src/msaa/nsHyperTextAccessibleWrap.h
+++ b/accessible/src/msaa/nsHyperTextAccessibleWrap.h
@@ -56,17 +56,17 @@ public:
 
   // IUnknown
   DECL_IUNKNOWN_INHERITED
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsAccessible
-  virtual nsresult HandleAccEvent(nsAccEvent *aEvent);
+  virtual nsresult HandleAccEvent(AccEvent* aEvent);
 
 protected:
   virtual nsresult GetModifiedText(PRBool aGetInsertedText, nsAString& aText,
                                    PRUint32 *aStartOffset,
                                    PRUint32 *aEndOffset);
 };
 
 #endif
--- a/accessible/src/other/nsAccessibleWrap.h
+++ b/accessible/src/other/nsAccessibleWrap.h
@@ -48,14 +48,15 @@
 
 class nsAccessibleWrap : public nsAccessible
 {
 public: // construction, destruction
   nsAccessibleWrap(nsIContent *aContent, nsIWeakReference *aShell);
   virtual ~nsAccessibleWrap();
 
   protected:
-    virtual nsresult FirePlatformEvent(nsAccEvent *aEvent) {
+    virtual nsresult FirePlatformEvent(AccEvent* aEvent)
+    {
       return NS_OK;
     }
 };
 
 #endif
new file mode 100644
--- /dev/null
+++ b/accessible/src/xpcom/Makefile.in
@@ -0,0 +1,61 @@
+#
+# ***** 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) 2010
+# 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 of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = accessibility
+LIBRARY_NAME = accessibility_xpcom_s
+LIBXUL_LIBRARY = 1
+
+CPPSRCS = \
+  nsAccEvent.cpp \
+  $(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
+
+LOCAL_INCLUDES = \
+  -I$(srcdir)/../base \
+  $(NULL)
new file mode 100644
--- /dev/null
+++ b/accessible/src/xpcom/nsAccEvent.cpp
@@ -0,0 +1,206 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * 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 of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsAccEvent.h"
+#include "nsDocAccessible.h"
+
+////////////////////////////////////////////////////////////////////////////////
+// nsAccEvent
+////////////////////////////////////////////////////////////////////////////////
+
+NS_IMPL_ISUPPORTS1(nsAccEvent, nsIAccessibleEvent)
+
+NS_IMETHODIMP
+nsAccEvent::GetIsFromUserInput(PRBool* aIsFromUserInput)
+{
+  *aIsFromUserInput = mEvent->IsFromUserInput();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAccEvent::GetEventType(PRUint32* aEventType)
+{
+  *aEventType = mEvent->GetEventType();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAccEvent::GetAccessible(nsIAccessible** aAccessible)
+{
+  NS_ENSURE_ARG_POINTER(aAccessible);
+  *aAccessible = nsnull;
+
+  NS_IF_ADDREF(*aAccessible = mEvent->GetAccessible());
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAccEvent::GetDOMNode(nsIDOMNode** aDOMNode)
+{
+  NS_ENSURE_ARG_POINTER(aDOMNode);
+  *aDOMNode = nsnull;
+
+  nsINode* node = mEvent->GetNode();
+  if (node)
+    CallQueryInterface(node, aDOMNode);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAccEvent::GetAccessibleDocument(nsIAccessibleDocument** aDocAccessible)
+{
+  NS_ENSURE_ARG_POINTER(aDocAccessible);
+
+  NS_IF_ADDREF(*aDocAccessible = mEvent->GetDocAccessible());
+  return NS_OK;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// nsAccStateChangeEvent
+////////////////////////////////////////////////////////////////////////////////
+
+NS_IMPL_ISUPPORTS_INHERITED1(nsAccStateChangeEvent, nsAccEvent,
+                             nsIAccessibleStateChangeEvent)
+
+NS_IMETHODIMP
+nsAccStateChangeEvent::GetState(PRUint32* aState)
+{
+  NS_ENSURE_ARG_POINTER(aState);
+  *aState = static_cast<AccStateChangeEvent*>(mEvent.get())->GetState();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAccStateChangeEvent::IsExtraState(PRBool* aIsExtraState)
+{
+  NS_ENSURE_ARG_POINTER(aIsExtraState);
+  *aIsExtraState = static_cast<AccStateChangeEvent*>(mEvent.get())->IsExtraState();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAccStateChangeEvent::IsEnabled(PRBool* aIsEnabled)
+{
+  NS_ENSURE_ARG_POINTER(aIsEnabled);
+  *aIsEnabled = static_cast<AccStateChangeEvent*>(mEvent.get())->IsStateEnabled();
+  return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsAccTextChangeEvent
+////////////////////////////////////////////////////////////////////////////////
+
+NS_IMPL_ISUPPORTS_INHERITED1(nsAccTextChangeEvent, nsAccEvent,
+                             nsIAccessibleTextChangeEvent)
+
+NS_IMETHODIMP
+nsAccTextChangeEvent::GetStart(PRInt32* aStart)
+{
+  NS_ENSURE_ARG_POINTER(aStart);
+  *aStart = static_cast<AccTextChangeEvent*>(mEvent.get())->GetStartOffset();
+  return NS_OK;
+}
+
+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)
+{
+  NS_ENSURE_ARG_POINTER(aIsInserted);
+  *aIsInserted = static_cast<AccTextChangeEvent*>(mEvent.get())->IsTextInserted();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAccTextChangeEvent::GetModifiedText(nsAString& aModifiedText)
+{
+  static_cast<AccTextChangeEvent*>(mEvent.get())->GetModifiedText(aModifiedText);
+  return NS_OK;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// nsAccCaretMoveEvent
+////////////////////////////////////////////////////////////////////////////////
+
+NS_IMPL_ISUPPORTS_INHERITED1(nsAccCaretMoveEvent, nsAccEvent,
+                             nsIAccessibleCaretMoveEvent)
+
+NS_IMETHODIMP
+nsAccCaretMoveEvent::GetCaretOffset(PRInt32 *aCaretOffset)
+{
+  NS_ENSURE_ARG_POINTER(aCaretOffset);
+
+  *aCaretOffset = static_cast<AccCaretMoveEvent*>(mEvent.get())->GetCaretOffset();
+  return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsAccTableChangeEvent
+////////////////////////////////////////////////////////////////////////////////
+
+NS_IMPL_ISUPPORTS_INHERITED1(nsAccTableChangeEvent, nsAccEvent,
+                             nsIAccessibleTableChangeEvent)
+
+NS_IMETHODIMP
+nsAccTableChangeEvent::GetRowOrColIndex(PRInt32 *aRowOrColIndex)
+{
+  NS_ENSURE_ARG_POINTER(aRowOrColIndex);
+
+  *aRowOrColIndex =
+    static_cast<AccTableChangeEvent*>(mEvent.get())->GetIndex();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsAccTableChangeEvent::GetNumRowsOrCols(PRInt32* aNumRowsOrCols)
+{
+  NS_ENSURE_ARG_POINTER(aNumRowsOrCols);
+
+  *aNumRowsOrCols = static_cast<AccTableChangeEvent*>(mEvent.get())->GetCount();
+  return NS_OK;
+}
+
new file mode 100644
--- /dev/null
+++ b/accessible/src/xpcom/nsAccEvent.h
@@ -0,0 +1,148 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * 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 of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef _nsAccEvent_H_
+#define _nsAccEvent_H_
+
+#include "nsIAccessibleEvent.h"
+
+#include "AccEvent.h"
+
+/**
+ * Generic accessible event.
+ */
+class nsAccEvent: public nsIAccessibleEvent
+{
+public:
+  nsAccEvent(AccEvent* aEvent) : mEvent(aEvent) { }
+  virtual ~nsAccEvent() { }
+
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIACCESSIBLEEVENT
+
+protected:
+  nsRefPtr<AccEvent> mEvent;
+
+private:
+  nsAccEvent();
+  nsAccEvent(const nsAccEvent&);
+  nsAccEvent& operator =(const nsAccEvent&);
+};
+
+
+/**
+ * Accessible state change event.
+ */
+class nsAccStateChangeEvent: public nsAccEvent,
+                             public nsIAccessibleStateChangeEvent
+{
+public:
+  nsAccStateChangeEvent(AccStateChangeEvent* aEvent) : nsAccEvent(aEvent) { }
+  virtual ~nsAccStateChangeEvent() { }
+
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_NSIACCESSIBLESTATECHANGEEVENT
+
+private:
+  nsAccStateChangeEvent();
+  nsAccStateChangeEvent(const nsAccStateChangeEvent&);
+  nsAccStateChangeEvent& operator =(const nsAccStateChangeEvent&);
+};
+
+
+/**
+ * Accessible text change event.
+ */
+class nsAccTextChangeEvent: public nsAccEvent,
+                            public nsIAccessibleTextChangeEvent
+{
+public:
+  nsAccTextChangeEvent(AccTextChangeEvent* aEvent) : nsAccEvent(aEvent) { }
+  virtual ~nsAccTextChangeEvent() { }
+
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_NSIACCESSIBLETEXTCHANGEEVENT
+
+private:
+  nsAccTextChangeEvent();
+  nsAccTextChangeEvent(const nsAccTextChangeEvent&);
+  nsAccTextChangeEvent& operator =(const nsAccTextChangeEvent&);
+};
+
+
+/**
+ * Accessible caret move event.
+ */
+class nsAccCaretMoveEvent: public nsAccEvent,
+                           public nsIAccessibleCaretMoveEvent
+{
+public:
+  nsAccCaretMoveEvent(AccCaretMoveEvent* aEvent) : nsAccEvent(aEvent) { }
+  virtual ~nsAccCaretMoveEvent() { }
+
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_NSIACCESSIBLECARETMOVEEVENT
+
+private:
+  nsAccCaretMoveEvent();
+  nsAccCaretMoveEvent(const nsAccCaretMoveEvent&);
+  nsAccCaretMoveEvent& operator =(const nsAccCaretMoveEvent&);
+};
+
+
+/**
+ * Accessible table change event.
+ */
+class nsAccTableChangeEvent : public nsAccEvent,
+                              public nsIAccessibleTableChangeEvent
+{
+public:
+  nsAccTableChangeEvent(AccTableChangeEvent* aEvent) : nsAccEvent(aEvent) { }
+  virtual ~nsAccTableChangeEvent() { }
+
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_NSIACCESSIBLETABLECHANGEEVENT
+
+private:
+  nsAccTableChangeEvent();
+  nsAccTableChangeEvent(const nsAccTableChangeEvent&);
+  nsAccTableChangeEvent& operator =(const nsAccTableChangeEvent&);
+};
+
+#endif
+
--- a/accessible/src/xul/nsXULTreeAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeAccessible.cpp
@@ -516,18 +516,18 @@ nsXULTreeAccessible::InvalidateCache(PRI
 
   // Fire destroy event for removed tree items and delete them from caches.
   for (PRInt32 rowIdx = aRow; rowIdx < aRow - aCount; rowIdx++) {
 
     void* key = reinterpret_cast<void*>(rowIdx);
     nsAccessible *accessible = mAccessibleCache.GetWeak(key);
 
     if (accessible) {
-      nsRefPtr<nsAccEvent> event =
-        new nsAccEvent(nsIAccessibleEvent::EVENT_HIDE, accessible, PR_FALSE);
+      nsRefPtr<AccEvent> event =
+        new AccEvent(nsIAccessibleEvent::EVENT_HIDE, accessible, PR_FALSE);
       nsEventShell::FireEvent(event);
 
       accessible->Shutdown();
 
       // Remove accessible from document cache and tree cache.
       nsDocAccessible *docAccessible = GetDocAccessible();
       if (docAccessible)
         docAccessible->RemoveAccessNodeFromCache(accessible);
@@ -617,29 +617,29 @@ void
 nsXULTreeAccessible::TreeViewChanged()
 {
   if (IsDefunct())
     return;
 
   // Fire only notification destroy/create events on accessible tree to lie to
   // AT because it should be expensive to fire destroy events for each tree item
   // in cache.
-  nsRefPtr<nsAccEvent> eventDestroy =
-    new nsAccEvent(nsIAccessibleEvent::EVENT_HIDE, this, PR_FALSE);
+  nsRefPtr<AccEvent> eventDestroy =
+    new AccEvent(nsIAccessibleEvent::EVENT_HIDE, this, PR_FALSE);
   if (!eventDestroy)
     return;
 
   FirePlatformEvent(eventDestroy);
 
   ClearCache(mAccessibleCache);
 
   mTree->GetView(getter_AddRefs(mTreeView));
 
-  nsRefPtr<nsAccEvent> eventCreate =
-    new nsAccEvent(nsIAccessibleEvent::EVENT_SHOW, this, PR_FALSE);
+  nsRefPtr<AccEvent> eventCreate =
+    new AccEvent(nsIAccessibleEvent::EVENT_SHOW, this, PR_FALSE);
   if (!eventCreate)
     return;
 
   FirePlatformEvent(eventCreate);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeAccessible: protected implementation
--- a/accessible/src/xul/nsXULTreeGridAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeGridAccessible.cpp
@@ -1233,19 +1233,19 @@ nsXULTreeGridCellAccessible::CellInvalid
   nsAutoString textEquiv;
 
   PRInt16 type;
   mColumn->GetType(&type);
   if (type == nsITreeColumn::TYPE_CHECKBOX) {
     mTreeView->GetCellValue(mRow, mColumn, textEquiv);
     if (mCachedTextEquiv != textEquiv) {
       PRBool isEnabled = textEquiv.EqualsLiteral("true");
-      nsRefPtr<nsAccEvent> accEvent =
-        new nsAccStateChangeEvent(this, nsIAccessibleStates::STATE_CHECKED,
-                                  PR_FALSE, isEnabled);
+      nsRefPtr<AccEvent> accEvent =
+        new AccStateChangeEvent(this, nsIAccessibleStates::STATE_CHECKED,
+                                PR_FALSE, isEnabled);
       nsEventShell::FireEvent(accEvent);
 
       mCachedTextEquiv = textEquiv;
     }
 
     return;
   }
 
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -54,18 +54,16 @@ PREF_JS_EXPORTS = $(srcdir)/profile/fire
 
 # hardcode en-US for the moment
 AB_CD = en-US
 
 DEFINES += -DAB_CD=$(AB_CD)
 
 APP_VERSION = $(shell cat $(srcdir)/../config/version.txt)
 DEFINES += -DAPP_VERSION="$(APP_VERSION)"
-APP_UA_NAME = $(shell echo $(MOZ_APP_DISPLAYNAME) | sed -e's/[^A-Za-z]//g')
-DEFINES += -DAPP_UA_NAME="$(APP_UA_NAME)"
 
 DIST_FILES = application.ini
 
 GRE_MILESTONE = $(shell $(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(LIBXUL_DIST)/bin/platform.ini Build Milestone)
 GRE_BUILDID = $(shell $(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(LIBXUL_DIST)/bin/platform.ini Build BuildID)
 
 DEFINES += -DGRE_MILESTONE=$(GRE_MILESTONE) -DGRE_BUILDID=$(GRE_BUILDID)
 
--- a/browser/app/macbuild/Contents/Info.plist.in
+++ b/browser/app/macbuild/Contents/Info.plist.in
@@ -131,10 +131,17 @@
 	<key>CFBundleVersion</key>
 	<string>%APP_VERSION%</string>
 	<key>NSAppleScriptEnabled</key>
 	<true/>
 	<key>CGDisableCoalescedUpdates</key>
 	<true/>
 	<key>LSMinimumSystemVersion</key>
 	<string>10.5</string>
+	<key>LSMinimumSystemVersionByArchitecture</key>
+	<dict>
+		<key>i386</key>
+		<string>10.5.0</string>
+		<key>x86_64</key>
+		<string>10.6.0</string>
+	</dict>
 </dict>
 </plist>
--- a/browser/app/profile/extensions/testpilot@labs.mozilla.com/content/all-studies-window.js
+++ b/browser/app/profile/extensions/testpilot@labs.mozilla.com/content/all-studies-window.js
@@ -211,16 +211,17 @@ var TestPilotXulWindow = {
 
     this._stringBundle = document.getElementById("testpilot-stringbundle");
     this.sizeWindow();
     this._init(false);
     Observers.add("testpilot:task:changed", this._onTaskStatusChanged, this);
   },
 
   onUnload: function() {
+    document.getElementById("settings-pane").writePreferences(true);
     Observers.remove("testpilot:task:changed", this._onTaskStatusChanged, this);
   },
 
   _onTaskStatusChanged : function() {
     this._init(true);
   },
 
   onTakeSurveyButton: function(taskId) {
--- a/browser/app/profile/extensions/testpilot@labs.mozilla.com/content/browser.js
+++ b/browser/app/profile/extensions/testpilot@labs.mozilla.com/content/browser.js
@@ -170,16 +170,25 @@ var TestPilotMenuUtils;
     setUpToolbarFeedbackButton: function() {
       /* If this is first run, and it's ffx4 beta version, and the feedback
        * button is not in the expected place, put it there!
        * (copied from MozReporterButtons extension) */
       if (!window.document.getElementById("feedback-menu-happy-button")) {
         return;
       }
       let firefoxnav = window.document.getElementById("nav-bar");
+      /* This is sometimes called for windows that don't have a navbar - in
+       * that case, do nothing. */
+      if (!firefoxnav) {
+        return;
+      }
+      // TODO if the user has removed the feedback button via customization
+      // interface, we don't want to add it back in.  Use a pref to store whether
+      // this setup was done or not.
+
       let curSet = firefoxnav.currentSet;
 
       if (-1 == curSet.indexOf("feedback-menu-button")) {
         // place the buttons after the search box.
         let newSet = curSet + ",feedback-menu-button";
 
         firefoxnav.setAttribute("currentset", newSet);
         firefoxnav.currentSet = newSet;
--- a/browser/app/profile/extensions/testpilot@labs.mozilla.com/install.rdf
+++ b/browser/app/profile/extensions/testpilot@labs.mozilla.com/install.rdf
@@ -1,24 +1,24 @@
 <?xml version="1.0"?>
 
 <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
      xmlns:em="http://www.mozilla.org/2004/em-rdf#">
   <Description about="urn:mozilla:install-manifest">
     <em:id>testpilot@labs.mozilla.com</em:id>
-    <em:version>1.0.2</em:version>
+    <em:version>1.0.3</em:version>
     <em:type>2</em:type>
 
     <!-- Target Application this extension can install into, 
          with minimum and maximum supported versions. --> 
     <em:targetApplication>
       <Description>
         <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
         <em:minVersion>3.5</em:minVersion>
-        <em:maxVersion>4.0b4</em:maxVersion>
+        <em:maxVersion>4.0b5</em:maxVersion>
       </Description>
     </em:targetApplication>
    
     <!-- Front End MetaData -->
     <em:name>Feedback</em:name>
     <em:description>Help make Firefox better by giving feedback.</em:description>
     <em:creator>Mozilla Corporation</em:creator>
     <em:homepageURL>http://testpilot.mozillalabs.com/</em:homepageURL>
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -51,18 +51,20 @@
 pref("general.startup.browser", true);
 
 pref("browser.chromeURL","chrome://browser/content/");
 pref("browser.hiddenWindowChromeURL", "chrome://browser/content/hiddenWindow.xul");
 
 // Enables some extra Extension System Logging (can reduce performance)
 pref("extensions.logging.enabled", false);
 
-// Preferences for the Get Add-ons pane
+// Preferences for the Addon Repository
+pref("extensions.getAddons.cache.enabled", true);
 pref("extensions.getAddons.maxResults", 15);
+pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/search/guid:%IDS%");
 pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/search/%TERMS%/all/%MAX_RESULTS%/%OS%/%VERSION%");
 
 // Preferences for AMO integration
 pref("extensions.webservice.discoverURL", "https://services.addons.mozilla.org/%LOCALE%/%APP%/discovery/%VERSION%/%OS%");
 
 // Blocklist preferences
 pref("extensions.blocklist.enabled", true);
 pref("extensions.blocklist.interval", 86400);
@@ -184,17 +186,16 @@ pref("lightweightThemes.update.enabled",
 
 pref("keyword.enabled", true);
 // Override the default keyword.URL. Empty value means
 // "use the search service's default engine"
 pref("keyword.URL", "");
 
 pref("general.useragent.locale", "@AB_CD@");
 pref("general.skins.selectedSkin", "classic/1.0");
-pref("general.useragent.extra.firefox", "@APP_UA_NAME@/@APP_VERSION@");
 
 pref("general.smoothScroll", false);
 #ifdef UNIX_BUT_NOT_MAC
 pref("general.autoScroll", false);
 #else
 pref("general.autoScroll", true);
 #endif
 
new file mode 100644
--- /dev/null
+++ b/browser/base/content/aboutHome.css
@@ -0,0 +1,109 @@
+%if 0
+/* ***** 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 aboutHome.xhtml.
+ *
+ * The Initial Developer of the Original Code is the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Marco Bonardo <mak77@bonardo.net> (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 ***** */
+%endif
+
+html {
+  font: message-box;
+  background: -moz-Field;
+  color: -moz-FieldText;
+}
+
+#topSection,
+#bottomSection {
+  position: relative;
+  margin: 1em auto;
+  padding: 25px;
+  width: 560px;
+}
+
+#brandStart {
+  background: -moz-linear-gradient(top, #42607C, #1E4262 30%, #1E4262 80%, #143552 98%, #244665);
+  -moz-border-radius: 1%;
+  padding-bottom: 0.2em;
+  -moz-padding-start: 0.5em;
+  font-size: 250%;
+  font-weight: bold;
+  color: #688196;
+  margin-top: 18px;
+  margin-bottom: 6px;
+}
+#brandStart > span {
+  color: white;
+}
+
+#brandLogo {
+  position: absolute;
+  top: 0;
+}
+body[dir="ltr"] #brandLogo {
+  right: 0;
+}
+body[dir="rtl"] #brandLogo {
+  left: -15px;
+}
+
+#searchContainer {
+  border: 1px solid ThreeDShadow;
+  -moz-border-radius: 1%;
+  padding: 3em;
+}
+#searchEngineLinks {
+  font-size: 80%;
+}
+#searchEngineLinks > a {
+  -moz-margin-start: 1em;
+}
+body[dir="ltr"] #searchEngineLinks {
+  float: right;
+}
+body[dir="rtl"] #searchEngineLinks {
+  float: left;
+}
+
+#searchEngineLogo {
+  margin: 5px;
+}
+
+#searchText {
+  width: 100%;
+}
+
+#aboutMozilla {
+  text-align: center;
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/aboutHome.js
@@ -0,0 +1,114 @@
+/* ***** 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 aboutHome.xhtml.
+ *
+ * The Initial Developer of the Original Code is the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Marco Bonardo <mak77@bonardo.net> (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 ***** */
+
+// If a definition requires additional params, check that the final search url
+// is handled correctly by the engine.
+const SEARCH_ENGINES = {
+  "Google": {
+    image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEYAAAAYCAMAAABwdHsxAAADAFBMVEVogZYwjM9NtOspS2u0KAfYZBb3rRTiurCMjYrUWhIaPlzDNgfVRgjaVgvoizTI9f2ta17/9Wzrs0v46M/+7VOW6vrJQAsBLochdr+nmF/++o+UDQK88vzaYQarq6scarXT+f68vLzjdRrjewp5d3WqGATkUwaTq9uk7PnUaydkICTJSBD4uCDgZAz9+LiK6PjRZFH33Xv01qbrlxznhgvwx5gCBCbOUhLjfCzhaxHztXG8RhX93UP5yTRGl9QhRGT5wigkRmXniRj70zoKWrT2yUdqjs3UhzXvl0JwU0teu+EBElGD2fH83FZo1vTPilT0vDmd0Z3dbhrWrHLhcQir8PzTTDfPrVGrajv03cf5+vkwUG6z8PrSUw571uzvpCGPTzBsPDMxMEcHagXrkg7voBHf/P8FGHHhzrbyryOQZAeDNCudnZyTJBL2zlT+xByoUCG1wspyY1nRiH7STA3yiB7Jjx/pqT/Pz8/7lhDvfBxTUkl95PY/RE0DI2SQbT7LzJjxdg1OMTzutynnm2v+5DWsNBX+/tVDqOa7tnX57OPGYSHysziEo5a3XBe3l3j+0SXCoaCsjTL++fMgQmLmxXdv0ezsv0ycQxf8p0X1hwrenDU/Tnj9//tkyNj3+fX89fDv22QXHEWQydee7/xEdKG84uRWi5bwaxyK3/L++/iU5PMWM2Q6GS7UXg81l9gmSGgXOVewsKO3x+ECK8h8x3j7/fs5bMBke6kuTmwoRV/SbArKeSrB1snY373x5aSIRz85YIvragDD5+lnorUvSWF80PCQr6o4KGKysrIeQmIgXJ1Vb4j///8+XXjs7ewaUZSutsKFkqY4T3IhXqgYSHtwiJwUNVLExcbk5eU4SGcrcLEsP1wPKV77+/vy8/NBkcBmrN+drLklNGIONHQ5WXVxyuk0VXHHz9dmxuonZahTrNqPobEcP19CVXMURIljzvE/odz29vYcP3VieZHo6OhCYHxOW29y2vNYwe79/f33+PnU2eExgcLX2Nje397NKLzjAAACjElEQVR42q2UMWvbQBTHPRgro6CDKIJOPQSeVH+CDuZ2E3BIVmNkBB5agTF0NYV00y7jdMji0XqxvNljAzmEPASrQ0Vwhk41tPZiC6l3OjmNXYeYujfo3nF3v/fe/+le5hX5HyOTzv1Of88bnXelq0q8C9NRHMcpFrHd3gPTD0qV17uisWeDqE269gyguU88pcrRDowNXrqYTt1/xkQwXi8mZ2Q/TO9vDNa2FVkJLUPocDsYDoe1lB6EURzZ4RrDThHi0RF7mRh+bFGirCEYCJnMLpzUase5XI2aZxhjKM6wS64YJlDZqWxAPEq6ztjFm01KEzGdTxGirgoNFpRfrU7IEg8IiQFoqRlmqYp0p4VGDEO8zB1sYoLyKJlFVCdxjotwntNpISJqYfjKMQKi1fDVvJlqg2G6gWmh98l8iuRoWL1O7Bc53b2TJoSFc88xquwKqig8SGyDFvxRMGyriEdDUF140+DR9HN6hGHOBJIsjinLpvHoV84EIPGCL/ClAzOiojzfKeejz9WX3H6ru98Td6GWaqOi3lbBQQsTlyzzOU1ajjimTgpUkxRDN7Uvtl1kmTGMgT5+28BcAAC/SBSJBl7mWS1kkwRVnpWvs8n1HP6nMswFQmJyp71+DK4mgZ0ssEarFsiyQe0sg9V03acnG2luClgcQx+DKaOyTwTjAUNiS5OKWFGwZbGYw5GsiqKYNI6erp8XTo7TGigAToecVSofjvrEzMuyPBIe9xvXux2MvXCZZroQhNU6a7/mJ5VsK87l+FaD2TLpTvTTbTbj7bb13PiJZ0zAT+u6PtH9nhuKxD270s0hGAfSBOCgaJLHxDrlffcQzOoXSKyYjksOwdDWOLcG2H5i8zf27La6kVLrqwAAAABJRU5ErkJggg=="
+  , params: "source=hp"
+  , links: {
+      advanced: "http://www.google.com/advanced_search"
+    , preferences: "http://www.google.com/preferences"
+    }
+  }
+
+, "Яндекс":
+  {
+    image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAArCAMAAAC5Mt3fAAABnlBMVEX/////AAD/AwP/Bgb/CQn/DAz/Dw//EhL/FRX/GBj/Gxv/Hh7/ISH/JCT/Jyf/MDD/MzP/Pz//QkL/SEj/S0v/Tk7/UVH/YGD/Zmb/aWn/bGz/cnL/dXX/eHj/e3v/fn7/hIT/jY3/k5P/lpb/mZn/nJz/n5//paX/q6v/rq7/tLT/w8P/xsb/z8//1dX/2Nj/29v/3t7/4eH/5OT/7e3/8PD/8/P/9vb/+fn//Pz8/Pz5+fn29vbz8/Pw8PDt7e3q6urn5+fk5OTh4eHe3t7b29vY2NjS0tLPz8/MzMzJycnGxsbDw8PAwMC9vb26urq0tLSurq6rq6uoqKilpaWioqKfn5+cnJyZmZmWlpaTk5ONjY2KioqHh4eEhISBgYF+fn57e3t4eHh1dXVycnJvb29sbGxpaWlmZmZjY2NgYGBdXV1aWlpXV1dUVFRRUVFOTk5LS0tISEhFRUVCQkI/Pz88PDw5OTk2NjYzMzMwMDAtLS0qKionJyckJCQhISEeHh4bGxsVFRUSEhIPDw8MDAwJCQkGBgYDAwMAAABXxKaDAAAAAXRSTlMAQObYZgAAA3pJREFUWMPt1ulbG1UUx/HfQVsUrK1a9612c6t16SZBlkpTKLIkiG26KBSLoTVUdpiUQiIJyfe/9sXcYZJJSFsfx1c9b5J57p18cu5y7pWex/OIPS6cPHrkBTOzQ/EZp9rNxcHYjPfMzOzVI50xIifN7OXPz0sn4kO+e9Hs8DkpVuQDs7azihfpajd7SzEjZ8zsdNzIcTM7Gzfyvpldiht5x8z0L5BE6s6t4f2bhzJTmSt1SDSTMvwiSXdhw28aJAj35vAmwGKPJOkeLEvSzyUYk6S+BQBWRh3yoZl9HUGAm5KUhUd+08geMuj/0ZL/tCTXb01Sd8H/VN9j1/meQ043WV1NkarnPQ6QRB7WU9O4jB1yAxiWpAXYuTGeo9gTbHgze/NpkJKfz6AkXYdSn3QfNkMksQ3zkjQO1VFJ6bG9SXnNrO3Mk5AUFGuQDXgg6RqQ3EMmoZKUpFVYiKyDL82s85snI1shMgCkJSXKkAmQxCbMyrWmmhQvO3js25bIBGyEyKTLQHn4I0DS/hBKN6H6Q8Oaftes/tBqRDLwV4jMQiUhScv++srCmjz4VZL0595bdfFpRwOSy2QymdW97lOQDZEFKEqSFmHdISkodsul93C/KvlKeDIShkPmYDpE8rDrVcIOWfDybjlLJTc30XjD7MD5ujmJIEswESKFSIcs7AK3/HoDzDQxvjCzj+snPjJcBUiGyN9QmHvoeZ7nefNuuBZxe6+3OdJ12Kz9QqvV1QvlRIjswGLtD2RhbRi4I0l9NB2uE2Z2rOU+GYdVhci2q1G1iJZhp9cN13yDcbHD7KWLLZEZf3kGyDpsNyAjwLT8PPMNyEdm9knrHe/5JT5A7gP9UUQrUO6XtALVvohx7oBZx6WWSBJWpPodf7sBGXO1fQa/2NTG22Z2vHWBvOvOogDp2YXiQBTRBlR+lIaAYn0qX7WZdX7fEukpuXkeCQ6MLFC4GkVSwJykNWBjoBZ53cxOtTxPbm9B0fM8/9AqPpB0uQSwPDfvlSdCRB5Uk9JQBagszS3mC+E+PNTVEslRFwVJGqsEj7M1SBrISRrdCVovS5KOmrV9Fp7E7ZKkKkyGF4lmiIYeAVD6vd+/SKwEBbN6VdLgll9y0k99+cm5vNytxQ2BfspMXb/Wvd9LY5nfJpLPcDPbB/lv439BspTHg+9XKv417hniH6z+4JNllI0iAAAAAElFTkSuQmCC"
+  }
+};
+
+let gSearchEngine;
+
+function onLoad(event)
+{
+  setupSearchEngine();
+  document.getElementById("searchText").focus();
+}
+
+
+function onSearchSubmit(aEvent) {
+  let searchTerms = document.getElementById("searchText").value;
+  if (gSearchEngine && searchTerms.length > 0) {
+    const SEARCH_TOKENS = {
+      "_searchTerms_": encodeURIComponent(searchTerms)
+    }
+    let url = gSearchEngine.searchUrl;
+    for (let key in SEARCH_TOKENS) {
+      url = url.replace(key, SEARCH_TOKENS[key]);
+    }
+    window.location.href = url;
+  }
+
+  aEvent.preventDefault();
+}
+
+
+function setupSearchEngine() {
+  gSearchEngine = JSON.parse(localStorage["search-engine"]);
+
+  // Look for extended information, like logo and links.
+  let searchEngineInfo = SEARCH_ENGINES[gSearchEngine.name];
+  if (searchEngineInfo) {
+    for (let prop in searchEngineInfo)
+      gSearchEngine[prop] = searchEngineInfo[prop];
+  }
+
+  // Enqueue additional params if required by the engine definition.
+  if (gSearchEngine.params)
+    gSearchEngine.searchUrl += "&" + gSearchEngine.params;
+
+  // Add search engine logo.
+  if (gSearchEngine.image)
+    document.getElementById("searchEngineLogo").src = gSearchEngine.image;
+
+  if (gSearchEngine.links) {
+    // Add search engine links.
+    if (gSearchEngine.links.advanced) {
+      let advancedLink = document.getElementById("searchEngineAdvancedLink");
+      advancedLink.setAttribute("href", gSearchEngine.links.advanced);
+      advancedLink.hidden = false;
+    }
+    if (gSearchEngine.links.preferences) {
+      let prefsLink = document.getElementById("searchEngineAdvancedPreferences");
+      prefsLink.setAttribute("href", gSearchEngine.links.preferences);
+      prefsLink.hidden = false;
+    }
+  }
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/aboutHome.xhtml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+# ***** 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 aboutHome.xhtml.
+#
+# The Initial Developer of the Original Code is the Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2010
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Marco Bonardo <mak77@bonardo.net> (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 *****
+
+<!DOCTYPE html [
+  <!ENTITY % htmlDTD
+    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "DTD/xhtml1-strict.dtd">
+  %htmlDTD;
+  <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
+  %globalDTD;
+  <!ENTITY % aboutHomeDTD SYSTEM "chrome://browser/locale/aboutHome.dtd">
+  %aboutHomeDTD;
+]>
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <title>&abouthome.pageTitle;</title>
+
+    <link rel="icon" type="image/png" id="favicon"
+          href="chrome://branding/content/icon16.png"/>
+    <link rel="stylesheet" type="text/css" media="all"
+          href="chrome://browser/content/aboutHome.css"/>
+
+    <script type="text/javascript;version=1.8"
+            src="chrome://browser/content/aboutHome.js"/>
+  </head>
+
+  <body dir="&locale.dir;" onload="onLoad(event)">
+    <div id="pageContainer">
+      <div id="topSection">
+        <img id="brandLogo" src="chrome://branding/content/icon128.png"
+             title="&abouthome.brandLogo.title;"/>
+        <div id="brandStart">
+          &abouthome.brandStart;
+        </div>
+        <div id ="searchContainer">
+          <img id="searchEngineLogo" title="&abouthome.searchEngineLogo.title;"/>
+          <form name="searchForm" onsubmit="onSearchSubmit(event)">
+            <input type="text" name="searchText" value="" id="searchText" maxLength="256"/>
+            <br/>
+            <input type="submit" value="&abouthome.searchEngineButton.label;"/>
+            <span id="searchEngineLinks">
+              <a hidden="true" id="searchEngineAdvancedLink">&abouthome.searchEngineLinks.advanced;</a>
+              <a hidden="true" id="searchEngineAdvancedPreferences">&abouthome.searchEngineLinks.preferences;</a>
+            </span>
+          </form>
+        </div>
+      </div>
+
+      <div id="bottomSection">
+        <div id="aboutMozilla">
+          <a href="http://www.mozilla.com/about/">&abouthome.aboutMozilla;</a>
+        </div>
+      </div>
+    </div>
+  </body>
+</html>
--- a/browser/base/content/baseMenuOverlay.xul
+++ b/browser/base/content/baseMenuOverlay.xul
@@ -98,16 +98,21 @@
                   label="&helpTroubleshootingInfo.label;"
                   oncommand="openTroubleshootingPage()"
                   onclick="checkForMiddleClick(this, event);"/>
         <menuitem id="releaseNotes"
                   accesskey="&helpReleaseNotes.accesskey;"
                   label="&helpReleaseNotes.label;"
                   oncommand="openReleaseNotes()"
                   onclick="checkForMiddleClick(this, event);"/>
+        <menuitem id="feedbackPage"
+                  accesskey="&helpFeedbackPage.accesskey;"
+                  label="&helpFeedbackPage.label;"
+                  oncommand="openFeedbackPage()"
+                  onclick="checkForMiddleClick(this, event);"/>
         <menuseparator id="updateSeparator"/>
 #ifdef MOZ_UPDATER
         <menuitem id="checkForUpdates"
                   label="&updateCmd.label;"
                   class="menuitem-iconic"
                   oncommand="checkForUpdates();"/>
 #endif
         <menuseparator id="aboutSeparator"/>
--- a/browser/base/content/browser-tabview.js
+++ b/browser/base/content/browser-tabview.js
@@ -191,18 +191,18 @@ let TabView = {
 
       let charCode = event.charCode;
 #ifdef XP_MACOSX
       // if a text box in a webpage has the focus, the event.altKey would
       // return false so we are depending on the charCode here.
       if (!event.ctrlKey && !event.metaKey && !event.shiftKey &&
           charCode == 160) { // alt + space
 #else
-      if (event.ctrlKey && !event.metaKey && !event.shiftKey &&
-          !event.altKey && charCode == 32) { // ctrl + space
+      if (event.ctrlKey && !event.metaKey && !event.shiftKey && !event.altKey && 
+          charCode == KeyEvent.DOM_VK_SPACE) { // ctrl + space
 #endif
 
         // Don't handle this event if it's coming from a node that might allow
         // multiple keyboard selection like selects or trees
         let node = event.target;
         switch (node.namespaceURI) {
           case "http://www.w3.org/1999/xhtml":
             // xhtml:select only allows multiple when the attr is set
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -78,19 +78,23 @@ toolbar[printpreview="true"] {
   -moz-box-ordinal-group: 100;
 }
 
 #TabsToolbar[tabsontop="true"] {
   -moz-box-ordinal-group: 10;
 }
 
 %ifdef MENUBAR_CAN_AUTOHIDE
-#main-window[inFullscreen] > #appmenu-button-container {
+#main-window[inFullscreen] > #titlebar {
   display: none;
 }
+
+#titlebar {
+  -moz-binding: url("chrome://global/content/bindings/general.xml#windowdragbox");
+}
 %endif
 
 toolbarpaletteitem[place="palette"] > toolbaritem > hbox[type="places"] {
   display: none;
 }
 
 toolbar[mode="icons"] > #reload-button:not([displaystop]) + #stop-button,
 toolbar[mode="icons"] > #reload-button[displaystop] {
@@ -130,17 +134,17 @@ toolbar[mode="icons"] > #reload-button[d
 }
 
 #urlbar html|*.autocomplete-textbox {
   direction: ltr;
 }
 
 /* For results that are actions, their description text is shown instead of
    the URL - this needs to follow the locale's direction, unlike URLs. */
-richlistitem[type="action"]:-moz-locale-dir(rtl) > .ac-url-box {
+richlistitem[type~="action"]:-moz-locale-dir(rtl) > .ac-url-box {
   direction: rtl;
 }
 
 #urlbar:not([actiontype]) > #urlbar-display {
   display: none;
 }
 
 #wrapper-urlbar-container > #urlbar-container > #urlbar {
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -500,16 +500,20 @@ const gPopupBlockerObserver = {
       item.parentNode.removeChild(item);
       item = next;
     }
 
     var foundUsablePopupURI = false;
     var pageReport = gBrowser.pageReport;
     if (pageReport) {
       for (var i = 0; i < pageReport.length; ++i) {
+        // popupWindowURI will be null if the file picker popup is blocked.
+        // xxxdz this should make the option say "Show file picker" and do it (Bug 590306) 
+        if (!pageReport[i].popupWindowURI)
+          continue;
         var popupURIspec = pageReport[i].popupWindowURI.spec;
 
         // Sometimes the popup URI that we get back from the pageReport
         // isn't useful (for instance, netscape.com's popup URI ends up
         // being "http://www.netscape.com", which isn't really the URI of
         // the popup they're trying to show).  This isn't going to be
         // useful to the user, so we won't create a menu item for it.
         if (popupURIspec == "" || popupURIspec == "about:blank" ||
@@ -673,18 +677,16 @@ const gXPInstallObserver = {
       try {
         enabled = gPrefService.getBoolPref("xpinstall.enabled");
       }
       catch (e) {
       }
 
       if (!enabled) {
         notificationID = "xpinstall-disabled"
-        if (PopupNotifications.getNotification(notificationID, browser))
-          return;
 
         if (gPrefService.prefIsLocked("xpinstall.enabled")) {
           messageString = gNavigatorBundle.getString("xpinstallDisabledMessageLocked");
           buttons = [];
         }
         else {
           messageString = gNavigatorBundle.getString("xpinstallDisabledMessage");
 
@@ -693,19 +695,16 @@ const gXPInstallObserver = {
             accessKey: gNavigatorBundle.getString("xpinstallDisabledButton.accesskey"),
             callback: function editPrefs() {
               gPrefService.setBoolPref("xpinstall.enabled", true);
             }
           };
         }
       }
       else {
-        if (PopupNotifications.getNotification(notificationID, browser))
-          return;
-
         messageString = gNavigatorBundle.getFormattedString("xpinstallPromptWarning",
                           [brandShortName, installInfo.originatingURI.host]);
 
         action = {
           label: gNavigatorBundle.getString("xpinstallPromptAllowButton"),
           accessKey: gNavigatorBundle.getString("xpinstallPromptAllowButton.accesskey"),
           callback: function() {
             installInfo.install();
@@ -740,20 +739,16 @@ const gXPInstallObserver = {
         messageString = messageString.replace("#3", brandShortName);
         messageString = messageString.replace("#4", Services.appinfo.version);
 
         PopupNotifications.show(browser, notificationID, messageString, anchorID,
                                 action, null, options);
       });
       break;
     case "addon-install-complete":
-      var notification = PopupNotifications.getNotification(notificationID, browser);
-      if (notification)
-        PopupNotifications.remove(notification);
-
       var needsRestart = installInfo.installs.some(function(i) {
         return i.addon.pendingOperations != AddonManager.PENDING_NONE;
       });
 
       if (needsRestart) {
         messageString = gNavigatorBundle.getString("addonsInstalledNeedsRestart");
         action = {
           label: gNavigatorBundle.getString("addonInstallRestartButton"),
@@ -1342,20 +1337,16 @@ function delayedStartup(isLoadingBlank, 
     let sidebarBox = document.getElementById("sidebar-box");
     sidebar.setAttribute("src", sidebarBox.getAttribute("src"));
   }
 
   UpdateUrlbarSearchSplitterState();
 
   PlacesStarButton.init();
 
-  // called when we go into full screen, even if it is
-  // initiated by a web page script
-  window.addEventListener("fullscreen", onFullScreen, true);
-
   if (isLoadingBlank && gURLBar && isElementVisible(gURLBar))
     gURLBar.focus();
   else
     gBrowser.selectedBrowser.focus();
 
   gNavToolbox.customizeDone = BrowserToolboxCustomizeDone;
   gNavToolbox.customizeChange = BrowserToolboxCustomizeChange;
 
@@ -1509,16 +1500,22 @@ function delayedStartup(isLoadingBlank, 
 
   gBrowser.mPanelContainer.addEventListener("InstallBrowserTheme", LightWeightThemeWebInstaller, false, true);
   gBrowser.mPanelContainer.addEventListener("PreviewBrowserTheme", LightWeightThemeWebInstaller, false, true);
   gBrowser.mPanelContainer.addEventListener("ResetBrowserThemePreview", LightWeightThemeWebInstaller, false, true);
 
   if (Win7Features)
     Win7Features.onOpenWindow();
 
+  // called when we go into full screen, even if it is
+  // initiated by a web page script
+  window.addEventListener("fullscreen", onFullScreen, true);
+  if (window.fullScreen)
+    onFullScreen();
+
 #ifdef MOZ_SERVICES_SYNC
   // initialize the sync UI
   gSyncUI.init();
 #endif
 
   TabView.init();
 
   Services.obs.notifyObservers(window, "browser-delayed-startup-finished", "");
@@ -2630,19 +2627,18 @@ function getMeOutOfHere() {
   content.location = url;
 }
 
 function BrowserFullScreen()
 {
   window.fullScreen = !window.fullScreen;
 }
 
-function onFullScreen()
-{
-  FullScreen.toggle();
+function onFullScreen(event) {
+  FullScreen.toggle(event);
 }
 
 function getWebNavigation()
 {
   try {
     return gBrowser.webNavigation;
   } catch (e) {
     return null;
@@ -2783,16 +2779,27 @@ function FillInHTMLTooltip(tipElement)
   var SVGTitleText = null;
 #ifdef MOZ_SVG
   var lookingForSVGTitle = true;
 #else
   var lookingForSVGTitle = false;
 #endif // MOZ_SVG
   var direction = tipElement.ownerDocument.dir;
 
+  // If the element is invalid per HTML5 Forms specifications,
+  // show the constraint validation error message instead of @tooltip.
+  if (tipElement instanceof HTMLInputElement ||
+      tipElement instanceof HTMLTextAreaElement ||
+      tipElement instanceof HTMLSelectElement ||
+      tipElement instanceof HTMLButtonElement) {
+    // If the element is barred from constraint validation or valid,
+    // the validation message will be the empty string.
+    titleText = tipElement.validationMessage;
+  }
+
   while (!titleText && !XLinkTitleText && !SVGTitleText && tipElement) {
     if (tipElement.nodeType == Node.ELEMENT_NODE) {
       titleText = tipElement.getAttribute("title");
       if ((tipElement instanceof HTMLAnchorElement && tipElement.href) ||
           (tipElement instanceof HTMLAreaElement && tipElement.href) ||
           (tipElement instanceof HTMLLinkElement && tipElement.href)
 #ifdef MOZ_SVG
           || (tipElement instanceof SVGAElement && tipElement.hasAttributeNS(XLinkNS, "href"))
@@ -3065,25 +3072,26 @@ const DOMLinkHandler = {
 
             var targetDoc = link.ownerDocument;
             var uri = makeURI(link.href, targetDoc.characterSet);
 
             if (gBrowser.isFailedIcon(uri))
               break;
 
             // Verify that the load of this icon is legal.
-            // error pages can load their favicon, to be on the safe side,
-            // only allow chrome:// favicons
-            const aboutNeterr = /^about:neterror\?/;
-            const aboutBlocked = /^about:blocked\?/;
-            const aboutCert = /^about:certerror\?/;
-            if (!(aboutNeterr.test(targetDoc.documentURI) ||
-                  aboutBlocked.test(targetDoc.documentURI) ||
-                  aboutCert.test(targetDoc.documentURI)) ||
-                !uri.schemeIs("chrome")) {
+            // Some error or special pages can load their favicon.
+            // To be on the safe side, only allow chrome:// favicons.
+            var isAllowedPage = [
+              /^about:neterror\?/,
+              /^about:blocked\?/,
+              /^about:certerror\?/,
+              /^about:home$/,
+            ].some(function (re) re.test(targetDoc.documentURI));
+
+            if (!isAllowedPage || !uri.schemeIs("chrome")) {
               var ssm = Cc["@mozilla.org/scriptsecuritymanager;1"].
                         getService(Ci.nsIScriptSecurityManager);
               try {
                 ssm.checkLoadURIWithPrincipal(targetDoc.nodePrincipal, uri,
                                               Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
               } catch(e) {
                 break;
               }
@@ -3614,27 +3622,31 @@ function updateEditUIVisibility()
     goSetCommandEnabled("cmd_paste", true);
     goSetCommandEnabled("cmd_selectAll", true);
     goSetCommandEnabled("cmd_delete", true);
     goSetCommandEnabled("cmd_switchTextDirection", true);
   }
 #endif
 }
 
-var FullScreen =
-{
+var FullScreen = {
   _XULNS: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
-  toggle: function()
-  {
+  toggle: function (event) {
+    var enterFS = window.fullScreen;
+
+    // We get the fullscreen event _before_ the window transitions into or out of FS mode.
+    if (event && event.type == "fullscreen")
+      enterFS = !enterFS;
+
     // show/hide all menubars, toolbars, and statusbars (except the full screen toolbar)
-    this.showXULChrome("toolbar", window.fullScreen);
-    this.showXULChrome("statusbar", window.fullScreen);
-    document.getElementById("View:FullScreen").setAttribute("checked", !window.fullScreen);
-
-    if (!window.fullScreen) {
+    this.showXULChrome("toolbar", !enterFS);
+    this.showXULChrome("statusbar", !enterFS);
+    document.getElementById("View:FullScreen").setAttribute("checked", enterFS);
+
+    if (enterFS) {
       // Add a tiny toolbar to receive mouseover and dragenter events, and provide affordance.
       // This will help simulate the "collapse" metaphor while also requiring less code and
       // events than raw listening of mouse coords.
       let fullScrToggler = document.getElementById("fullscr-toggler");
       if (!fullScrToggler) {
         fullScrToggler = document.createElement("hbox");
         fullScrToggler.id = "fullscr-toggler";
         fullScrToggler.collapsed = true;
@@ -4772,23 +4784,30 @@ var TabsOnTop = {
 
 #ifdef MENUBAR_CAN_AUTOHIDE
 function updateAppButtonDisplay() {
   var displayAppButton =
     !gInPrintPreviewMode &&
     window.menubar.visible &&
     document.getElementById("toolbar-menubar").getAttribute("autohide") == "true";
 
-  document.getElementById("appmenu-button-container").hidden = !displayAppButton;
+  document.getElementById("titlebar").hidden = !displayAppButton;
 
   if (displayAppButton)
     document.documentElement.setAttribute("chromemargin", "0,-1,-1,-1");
   else
     document.documentElement.removeAttribute("chromemargin");
 }
+
+function onTitlebarMaxClick() {
+  if (window.windowState == window.STATE_MAXIMIZED)
+    window.restore();
+  else
+    window.maximize();
+}
 #endif
 
 function displaySecurityInfo()
 {
   BrowserPageInfo(null, "securityTab");
 }
 
 /**
@@ -6980,18 +6999,23 @@ var gIdentityHandler = {
   /**
    * Return the eTLD+1 version of the current hostname
    */
   getEffectiveHost : function() {
     // Cache the eTLDService if this is our first time through
     if (!this._eTLDService)
       this._eTLDService = Cc["@mozilla.org/network/effective-tld-service;1"]
                          .getService(Ci.nsIEffectiveTLDService);
+    if (!this._IDNService)
+      this._IDNService = Cc["@mozilla.org/network/idn-service;1"]
+                         .getService(Ci.nsIIDNService);
     try {
-      return this._eTLDService.getBaseDomainFromHost(this._lastLocation.hostname);
+      let baseDomain =
+        this._eTLDService.getBaseDomainFromHost(this._lastLocation.hostname);
+      return this._IDNService.convertToDisplayIDN(baseDomain, {});
     } catch (e) {
       // If something goes wrong (e.g. hostname is an IP address) just fail back
       // to the full domain.
       return this._lastLocation.hostname;
     }
   },
 
   /**
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -258,20 +258,20 @@
                        label="&inspectNextButton.label;"
                        accesskey="&inspectNextButton.accesskey;"
                        class="toolbarbutton-text"
                        command="Inspector:Next"/>
         <toolbarbutton id="inspector-style-toolbutton"
                        label="&inspectStyleButton.label;"
                        accesskey="&inspectStyleButton.accesskey;"
                        class="toolbarbutton-text"
-                       oncommand="InspectorUI.toggleStylePanel();'"/>
+                       oncommand="InspectorUI.toggleStylePanel();"/>
         <toolbarbutton id="inspector-dom-toolbutton"
-                       label="&inspectDOMButton.label;"
-                       accesskey="&inspectDOMButton.accesskey;"
+                       label="&inspectObjectButton.label;"
+                       accesskey="&inspectObjectButton.accesskey;"
                        class="toolbarbutton-text"
                        oncommand="InspectorUI.toggleDOMPanel();"/>
       </toolbar>
       <tree id="inspector-tree" class="plain"
             seltype="single"
             treelines="true"
             onselect="InspectorUI.onTreeSelected()"
             flex="1">
@@ -444,17 +444,19 @@
               style="&dialog.style;"
               hidden="true"/>
     </panel>
 
     <tooltip id="tabbrowser-tab-tooltip" onpopupshowing="gBrowser.createTooltip(event);"/>
   </popupset>
 
 #ifdef MENUBAR_CAN_AUTOHIDE
-<hbox id="appmenu-button-container">
+  <vbox id="titlebar">
+  <hbox id="titlebar-content">
+  <hbox id="appmenu-button-container" align="start">
   <button id="appmenu-button"
           type="menu"
           label="&brandShortName;"
           style="-moz-user-focus: ignore;">
     <menupopup id="appmenu-popup"
                onpopupshowing="updateEditUIVisibility();">
       <hbox>
         <vbox id="appmenuPrimaryPane">
@@ -478,21 +480,20 @@
                             label="&openFileCmd.label;"
                             command="Browser:OpenFile"/>
                 </menupopup>
                </menu>
           </hbox>
           <menuitem id="appmenu_privateBrowsing"
                     class="menuitem-iconic"
                     label="&privateBrowsingCmd.start.label;"
-                    accesskey="&privateBrowsingCmd.start.accesskey;"
                     startlabel="&privateBrowsingCmd.start.label;"
                     stoplabel="&privateBrowsingCmd.stop.label;"
                     command="Tools:PrivateBrowsing"/>
-          <menuseparator class="menu-seperator"/>
+          <menuseparator/>
           <hbox class="split-menuitem">
             <menuitem id="appmenu-edit-menuitem"
                       label="&editMenu.label;"
                       disabled="true"/>
             <toolbarbutton id="appmenu-cut"
                            class="appmenu-edit-button"
                            command="cmd_cut"
                            onclick="if (!this.disabled) hidePopup();"
@@ -553,17 +554,16 @@
                         type="checkbox"
                         command="Tools:Inspect"/>
               <menuseparator/>
               <menuitem id="appmenu_pageSource"
                         label="&viewPageSourceCmd.label;"
                         command="View:PageSource"/>
               <menuseparator/>
               <menuitem label="&goOfflineCmd.label;"
-                        accesskey="&goOfflineCmd.accesskey;"
                         type="checkbox"
                         oncommand="BrowserOffline.toggleOfflineStatus();"/>
             </menupopup>
           </menu>
           <menuseparator/>
           <menuitem id="appmenu_fullScreen"
                     label="&fullScreenCmd.label;"
                     type="checkbox"
@@ -741,17 +741,25 @@
                             oncommand="openAboutDialog();"/>
                 </menupopup>
               </menu>
             </hbox>
         </vbox>
       </hbox>
     </menupopup>
   </button>
-</hbox>
+  </hbox>
+  <spacer id="titlebar-spacer" flex="1"/>
+  <hbox id="titlebar-buttonbox">
+    <toolbarbutton id="titlebar-min" oncommand="window.minimize();"/>
+    <toolbarbutton id="titlebar-max" oncommand="onTitlebarMaxClick();"/>
+    <toolbarbutton id="titlebar-close" oncommand="window.close();"/>
+  </hbox>
+  </hbox>
+  </vbox>
 #endif
 
 <deck flex="1" id="tab-view-deck">
 <vbox flex="1">
 
   <toolbox id="navigator-toolbox"
            defaultmode="icons" mode="icons"
 #ifdef WINCE
@@ -1060,17 +1068,17 @@
 
     <toolbar id="TabsToolbar"
              fullscreentoolbar="true"
              customizable="true"
              mode="icons" lockmode="true"
              iconsize="small" defaulticonsize="small" lockiconsize="true"
              aria-label="&tabsToolbar.label;"
              context="toolbar-context-menu"
-             defaultset="tabbrowser-tabs,new-tab-button,tabview-button,alltabs-button,tabs-closebutton"
+             defaultset="tabbrowser-tabs,new-tab-button,alltabs-button,tabview-button,tabs-closebutton"
              collapsed="true">
 
       <tabs id="tabbrowser-tabs"
             class="tabbrowser-tabs"
             tabbrowser="content"
             flex="1"
             setfocus="false"
             tooltip="tabbrowser-tab-tooltip">
@@ -1110,16 +1118,19 @@
                      command="cmd_close"
                      label="&closeTab.label;"
                      tooltiptext="&closeTab.label;"/>
 
     </toolbar>
 
     <toolbarpalette id="BrowserToolbarPalette">
 
+# Update primaryToolbarButtons in browser/themes/browserShared.inc when adding
+# or removing default items with the toolbarbutton-1 class.
+
       <toolbarbutton id="print-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
                      label="&printButton.label;" command="cmd_print"
                      tooltiptext="&printButton.tooltip;"/>
 
       <toolbaritem id="navigator-throbber" title="&throbberItem.title;" align="center" pack="center"
                    mousethrough="always">
         <image/>
       </toolbaritem>
@@ -1195,17 +1206,17 @@
                   flex="1" contenttooltip="aHTMLTooltip"
                   tabcontainer="tabbrowser-tabs"
                   contentcontextmenu="contentAreaContextMenu"
                   autocompletepopup="PopupAutoComplete"
                   onclick="return contentAreaClick(event, false);"/>
     </vbox>
   </hbox>
 
-  <vbox id="browser-bottombox">
+  <vbox id="browser-bottombox" layer="true">
     <statusbar class="chromeclass-status" id="status-bar"
 #ifdef WINCE
                hidden="true"
 #endif
                >
       <statusbarpanel id="statusbar-display" label="" flex="1"/>
       <statusbarpanel class="statusbarpanel-progress" collapsed="true" id="statusbar-progresspanel">
         <progressmeter class="progressmeter-statusbar" id="statusbar-icon" mode="normal" value="0"/>
--- a/browser/base/content/inspector.js
+++ b/browser/base/content/inspector.js
@@ -372,32 +372,32 @@ InspectorTreeView.prototype = {
   getCellText: function ITV_getCellText(aRow, aCol)
   {
     return this.view.getCellText(aRow, aCol);
   },
 
   /**
    * Get the index of the selected row.
    *
-   * @returns number
+   * @returns number -1 if there is no row selected.
    */
   get selectionIndex()
   {
-    return this.selection.currentIndex;
+    return this.selection ? this.selection.currentIndex : -1;
   },
 
   /**
    * Get the corresponding node for the currently-selected row in the tree.
    *
-   * @returns DOMNode
+   * @returns DOMNode|null
    */
   get selectedNode()
   {
     let rowIndex = this.selectionIndex;
-    return this.view.getNodeFromRowIndex(rowIndex);
+    return rowIndex > -1 ? this.view.getNodeFromRowIndex(rowIndex) : null;
   },
 
   /**
    * Set the selected row in the table to the specified index.
    *
    * @param anIndex
    *        The index to set the selection to.
    */
@@ -500,17 +500,17 @@ var InspectorUI = {
    * Toggle the inspector interface elements on or off.
    *
    * @param aEvent
    *        The event that requested the UI change. Toolbar button or menu.
    */
   toggleInspectorUI: function IUI_toggleInspectorUI(aEvent)
   {
     if (this.isPanelOpen) {
-      this.closeInspectorUI();
+      this.closeInspectorUI(true);
     } else {
       this.openInspectorUI();
     }
   },
 
   /**
    * Toggle the status of the inspector, starting or stopping it. Invoked
    * from the toolbar's Inspect button.
@@ -542,16 +542,17 @@ var InspectorUI = {
   /**
    * Toggle the DOM panel. Invoked from the toolbar's DOM button.
    */
   toggleDOMPanel: function IUI_toggleDOMPanel()
   {
     if (this.isDOMPanelOpen) {
       this.domPanel.hidePopup();
     } else {
+      this.clearDOMPanel();
       this.openDOMPanel();
       if (this.treeView.selectedNode) {
         this.updateDOMPanel(this.treeView.selectedNode);
       }
     }
   },
 
   /**
@@ -623,16 +624,17 @@ var InspectorUI = {
   },
 
   /**
    * Open the DOM panel if not already onscreen.
    */
   openDOMPanel: function IUI_openDOMPanel()
   {
     if (!this.isDOMPanelOpen) {
+      this.domPanel.hidden = false;
       // open at middle right of browser panel, offset by 20px from middle.
       this.domPanel.openPopup(this.browser, "end_before", 0,
         this.win.outerHeight / 2 - 20, false, false);
       // size panel to 200px wide by half browser height - 60.
       this.domPanel.sizeTo(200, this.win.outerHeight / 2 - 60);
     }
   },
 
@@ -649,28 +651,31 @@ var InspectorUI = {
       aDim.removeAttribute("dimmed");
     } else {
       aDim.setAttribute("dimmed", "true");
     }
   },
 
   /**
    * Open inspector UI. tree, style and DOM panels if enabled. Add listeners for
-   * document scrolling, resize and tabContainer.TabSelect.
+   * document scrolling, resize, tabContainer.TabSelect and others.
    */
   openInspectorUI: function IUI_openInspectorUI()
   {
     // initialization
     this.browser = gBrowser.selectedBrowser;
     this.win = this.browser.contentWindow;
+    this.winID = this.getWindowID(this.win);
 
     // DOM panel initialization and loading (via PropertyPanel.jsm)
-    let domPanelTitle = this.strings.GetStringFromName("dom.domPanelTitle");
+    let objectPanelTitle = this.strings.
+      GetStringFromName("object.objectPanelTitle");
     let parent = document.getElementById("inspector-style-panel").parentNode;
-    this.propertyPanel = new (this.PropertyPanel)(parent, document, domPanelTitle, {});
+    this.propertyPanel = new (this.PropertyPanel)(parent, document,
+      objectPanelTitle, {});
 
     // additional DOM panel setup needed for unittest identification and use
     this.domPanel = this.propertyPanel.panel;
     this.domPanel.setAttribute("id", "inspector-dom-panel");
     this.domBox = this.propertyPanel.tree;
     this.domTreeView = this.propertyPanel.treeView;
 
     // open inspector UI
@@ -682,41 +687,76 @@ var InspectorUI = {
     this.openStylePanel();
 
     // DOM panel setup and activation
     this.clearDOMPanel();
     this.openDOMPanel();
 
     // setup highlighter and start inspecting
     this.initializeHighlighter();
-    this.startInspecting();
+
+    if (!InspectorStore.hasID(this.winID) ||
+      InspectorStore.getValue(this.winID, "inspecting")) {
+      this.startInspecting();
+    }
+
     this.win.document.addEventListener("scroll", this, false);
     this.win.addEventListener("resize", this, false);
-    gBrowser.tabContainer.addEventListener("TabSelect", this, false);
     this.inspectCmd.setAttribute("checked", true);
+
+    if (InspectorStore.isEmpty()) {
+      gBrowser.tabContainer.addEventListener("TabSelect", this, false);
+    }
+
+    if (InspectorStore.hasID(this.winID)) {
+      let selectedNode = InspectorStore.getValue(this.winID, "selectedNode");
+      if (selectedNode) {
+        this.inspectNode(selectedNode);
+      }
+    } else {
+      InspectorStore.addStore(this.winID);
+      InspectorStore.setValue(this.winID, "selectedNode", null);
+      this.win.addEventListener("pagehide", this, true);
+    }
   },
 
   /**
    * Initialize highlighter.
    */
   initializeHighlighter: function IUI_initializeHighlighter()
   {
     this.highlighter = new PanelHighlighter(this.browser);
   },
 
   /**
    * Close inspector UI and associated panels. Unhighlight and stop inspecting.
-   * Remove event listeners for document scrolling, resize and
-   * tabContainer.TabSelect.
+   * Remove event listeners for document scrolling, resize,
+   * tabContainer.TabSelect and others.
+   *
+   * @param boolean aClearStore tells if you want the store associated to the
+   * current tab/window to be cleared or not.
    */
-  closeInspectorUI: function IUI_closeInspectorUI()
+  closeInspectorUI: function IUI_closeInspectorUI(aClearStore)
   {
+    if (aClearStore) {
+      InspectorStore.deleteStore(this.winID);
+      this.win.removeEventListener("pagehide", this, true);
+    } else {
+      // Update the store before closing.
+      InspectorStore.setValue(this.winID, "selectedNode",
+        this.treeView.selectedNode);
+      InspectorStore.setValue(this.winID, "inspecting", this.inspecting);
+    }
+
+    if (InspectorStore.isEmpty()) {
+      gBrowser.tabContainer.removeEventListener("TabSelect", this, false);
+    }
+
     this.win.document.removeEventListener("scroll", this, false);
     this.win.removeEventListener("resize", this, false);
-    gBrowser.tabContainer.removeEventListener("TabSelect", this, false);
     this.stopInspecting();
     if (this.highlighter && this.highlighter.isHighlighting) {
       this.highlighter.unhighlight();
     }
     if (this.isPanelOpen) {
       this.treePanel.hidePopup();
       this.treeView.destroy();
     }
@@ -726,16 +766,17 @@ var InspectorUI = {
     if (this.domPanel) {
       this.domPanel.hidePopup();
       this.domBox = null;
       this.domTreeView = null;
       this.propertyPanel.destroy();
     }
     this.inspectCmd.setAttribute("checked", false);
     this.browser = this.win = null; // null out references to browser and window
+    this.winID = null;
   },
 
   /**
    * Begin inspecting webpage, attach page event listeners, activate
    * highlighter event listeners.
    */
   startInspecting: function IUI_startInspecting()
   {
@@ -906,19 +947,51 @@ var InspectorUI = {
   /**
    * Main callback handler for events.
    *
    * @param event
    *        The event to be handled.
    */
   handleEvent: function IUI_handleEvent(event)
   {
+    let winID = null;
+    let win = null;
+
     switch (event.type) {
       case "TabSelect":
-        this.closeInspectorUI();
+        winID = this.getWindowID(gBrowser.selectedBrowser.contentWindow);
+        if (this.isPanelOpen && winID != this.winID) {
+          this.closeInspectorUI(false);
+        }
+
+        if (winID && InspectorStore.hasID(winID)) {
+          this.openInspectorUI();
+        }
+
+        if (InspectorStore.isEmpty()) {
+          gBrowser.tabContainer.removeEventListener("TabSelect", this, false);
+        }
+        break;
+      case "pagehide":
+        win = event.originalTarget.defaultView;
+        // Skip iframes/frames.
+        if (!win || win.frameElement || win.top != win) {
+          break;
+        }
+
+        win.removeEventListener(event.type, this, true);
+
+        winID = this.getWindowID(win);
+        if (winID && winID != this.winID) {
+          InspectorStore.deleteStore(winID);
+        }
+
+        if (InspectorStore.isEmpty()) {
+          gBrowser.tabContainer.removeEventListener("TabSelect", this, false);
+        }
         break;
       case "keypress":
         switch (event.keyCode) {
           case KeyEvent.DOM_VK_RETURN:
           case KeyEvent.DOM_VK_ESCAPE:
             this.stopInspecting();
             break;
         }
@@ -1027,26 +1100,171 @@ var InspectorUI = {
     }
     return node;
   },
 
   ///////////////////////////////////////////////////////////////////////////
   //// Utility functions
 
   /**
+   * Retrieve the unique ID of a window object.
+   *
+   * @param nsIDOMWindow aWindow
+   * @returns integer ID
+   */
+  getWindowID: function IUI_getWindowID(aWindow)
+  {
+    if (!aWindow) {
+      return null;
+    }
+
+    let util = {};
+
+    try {
+      util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).
+        getInterface(Ci.nsIDOMWindowUtils);
+    } catch (ex) { }
+
+    return util.currentInnerWindowID;
+  },
+
+  /**
    * debug logging facility
    * @param msg
    *        text message to send to the log
    */
   _log: function LOG(msg)
   {
     Services.console.logStringMessage(msg);
   },
 }
 
+/**
+ * The Inspector store is used for storing data specific to each tab window.
+ */
+var InspectorStore = {
+  store: {},
+  length: 0,
+
+  /**
+   * Check if there is any data recorded for any tab/window.
+   *
+   * @returns boolean True if there are no stores for any window/tab, or false
+   * otherwise.
+   */
+  isEmpty: function IS_isEmpty()
+  {
+    return this.length == 0 ? true : false;
+  },
+
+  /**
+   * Add a new store.
+   *
+   * @param string aID The Store ID you want created.
+   * @returns boolean True if the store was added successfully, or false
+   * otherwise.
+   */
+  addStore: function IS_addStore(aID)
+  {
+    let result = false;
+
+    if (!(aID in this.store)) {
+      this.store[aID] = {};
+      this.length++;
+      result = true;
+    }
+
+    return result;
+  },
+
+  /**
+   * Delete a store by ID.
+   *
+   * @param string aID The store ID you want deleted.
+   * @returns boolean True if the store was removed successfully, or false
+   * otherwise.
+   */
+  deleteStore: function IS_deleteStore(aID)
+  {
+    let result = false;
+
+    if (aID in this.store) {
+      delete this.store[aID];
+      this.length--;
+      result = true;
+    }
+
+    return result;
+  },
+
+  /**
+   * Check store existence.
+   *
+   * @param string aID The store ID you want to check.
+   * @returns boolean True if the store ID is registered, or false otherwise.
+   */
+  hasID: function IS_hasID(aID)
+  {
+    return (aID in this.store);
+  },
+
+  /**
+   * Retrieve a value from a store for a given key.
+   *
+   * @param string aID The store ID you want to read the value from.
+   * @param string aKey The key name of the value you want.
+   * @returns mixed the value associated to your store and key.
+   */
+  getValue: function IS_getValue(aID, aKey)
+  {
+    return aID in this.store ? this.store[aID][aKey] : null;
+  },
+
+  /**
+   * Set a value for a given key and store.
+   *
+   * @param string aID The store ID where you want to store the value into.
+   * @param string aKey The key name for which you want to save the value.
+   * @param mixed aValue The value you want stored.
+   * @returns boolean True if the value was stored successfully, or false
+   * otherwise.
+   */
+  setValue: function IS_setValue(aID, aKey, aValue)
+  {
+    let result = false;
+
+    if (aID in this.store) {
+      this.store[aID][aKey] = aValue;
+      result = true;
+    }
+
+    return result;
+  },
+
+  /**
+   * Delete a value for a given key and store.
+   *
+   * @param string aID The store ID where you want to store the value into.
+   * @param string aKey The key name for which you want to save the value.
+   * @returns boolean True if the value was removed successfully, or false
+   * otherwise.
+   */
+  deleteValue: function IS_deleteValue(aID, aKey)
+  {
+    let result = false;
+
+    if (aID in this.store && aKey in this.store[aID]) {
+      delete this.store[aID][aKey];
+      result = true;
+    }
+
+    return result;
+  }
+};
+
 /////////////////////////////////////////////////////////////////////////
 //// Initializors
 
 XPCOMUtils.defineLazyGetter(InspectorUI, "inspectCmd", function () {
   return document.getElementById("Tools:Inspect");
 });
 
 XPCOMUtils.defineLazyGetter(InspectorUI, "strings", function () {
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -179,30 +179,32 @@
         <parameter name="aTab"/>
         <body><![CDATA[
           if (aTab.pinned)
             return;
 
           this.moveTabTo(aTab, this._numPinnedTabs);
           aTab.setAttribute("pinned", "true");
           this.tabContainer._positionPinnedTabs();
+          this.tabContainer.adjustTabstrip();
         ]]></body>
       </method>
 
       <method name="unpinTab">
         <parameter name="aTab"/>
         <body><![CDATA[
           if (!aTab.pinned)
             return;
 
           this.moveTabTo(aTab, this._numPinnedTabs - 1);
           aTab.setAttribute("fadein", "true");
           aTab.removeAttribute("pinned");
           aTab.style.MozMarginStart = "";
           this.tabContainer._positionPinnedTabs();
+          this.tabContainer.adjustTabstrip();
         ]]></body>
       </method>
 
       <method name="previewTab">
         <parameter name="aTab"/>
         <parameter name="aCallback"/>
         <body>
           <![CDATA[
@@ -2643,19 +2645,22 @@
           switch (this.mCloseButtons) {
           case 0:
             if (this.childNodes.length == 1 && this._closeWindowWithLastTab)
               this.setAttribute("closebuttons", "noclose");
             else
               this.setAttribute("closebuttons", "activetab");
             break;
           case 1:
-            if (this.childNodes.length == 1 && this._closeWindowWithLastTab)
-              this.setAttribute("closebuttons", "noclose");
-            else {
+            if (this.childNodes.length == 1) {
+              if (this._closeWindowWithLastTab)
+                this.setAttribute("closebuttons", "noclose");
+              else
+                this.setAttribute("closebuttons", "alltabs");
+            } else {
               let tab = this.tabbrowser.visibleTabs[this.tabbrowser._numPinnedTabs];
               if (tab && tab.getBoundingClientRect().width > this.mTabClipWidth)
                 this.setAttribute("closebuttons", "alltabs");
               else
                 this.setAttribute("closebuttons", "activetab");
             }
             break;
           case 2:
@@ -2859,16 +2864,25 @@
           // XXXmano: this is a temporary workaround for bug 345399
           // We need to manually update the scroll buttons disabled state
           // if a tab was inserted to the overflow area or removed from it
           // without any scrolling and when the tabbar has already
           // overflowed.
           this.mTabstrip._updateScrollButtonsDisabledState();
         ]]></body>
       </method>
+      
+      <method name="_canAdvanceToTab">
+        <parameter name="aTab"/>
+        <body>
+        <![CDATA[
+          return this.tabbrowser._removingTabs.indexOf(aTab) == -1;
+        ]]>
+        </body>
+      </method>
 
       <!-- Deprecated stuff, implemented for backwards compatibility. -->
       <property name="mTabstripClosebutton" readonly="true"
                 onget="return document.getElementById('tabs-closebutton');"/>
       <property name="mAllTabsPopup" readonly="true"
                 onget="return document.getElementById('alltabs-popup');"/>
     </implementation>
 
--- a/browser/base/content/tabview/drag.js
+++ b/browser/base/content/tabview/drag.js
@@ -104,17 +104,17 @@ Drag.prototype = {
   //   stationaryCorner   - which corner is stationary? by default, the top left.
   //                        "topleft", "bottomleft", "topright", "bottomright"
   //   assumeConstantSize - (boolean) whether the bounds' dimensions are sacred or not.
   //   keepProportional   - (boolean) if assumeConstantSize is false, whether we should resize
   //                        proportionally or not
   //   checkItemStatus    - (boolean) make sure this is a valid item which should be snapped
   snapBounds: function Drag_snapBounds(bounds, stationaryCorner, assumeConstantSize, keepProportional, checkItemStatus) {
     if (!stationaryCorner)
-      stationaryCorner || 'topleft';
+      stationaryCorner = 'topleft';
     var update = false; // need to update
     var updateX = false;
     var updateY = false;
     var newRect;
     var snappedTrenches = {};
 
     // OH SNAP!
 
--- a/browser/base/content/tabview/groupitems.js
+++ b/browser/base/content/tabview/groupitems.js
@@ -718,29 +718,16 @@ window.GroupItem.prototype = Utils.exten
     var self = this;
     var toRemove = this._children.concat();
     toRemove.forEach(function(child) {
       self.remove(child, {dontArrange: true});
     });
   },
 
   // ----------
-  // Function: setNewTabButtonBounds
-  // Used for positioning the "new tab" button in the "new tabs" groupItem.
-  setNewTabButtonBounds: function(box, immediately) {
-    if (!immediately)
-      this.$ntb.animate(box.css(), {
-        duration: 320,
-        easing: "tabviewBounce"
-      });
-    else
-      this.$ntb.css(box.css());
-  },
-
-  // ----------
   // Function: hideExpandControl
   // Hide the control which expands a stacked groupItem into a quick-look view.
   hideExpandControl: function() {
     this.$expander.hide();
   },
 
   // ----------
   // Function: showExpandControl
@@ -1599,36 +1586,49 @@ window.GroupItems = {
   //
   // Paramaters:
   //  groupItem - the active <TabItem> or <null>
   setActiveOrphanTab: function(tabItem) {
     this._activeOrphanTab = tabItem;
   },
 
   // ----------
-  // Function: updateTabBar
+  // Function: _updateTabBar
   // Hides and shows tabs in the tab bar based on the active groupItem or
   // currently active orphan tabItem
-  updateTabBar: function() {
+  _updateTabBar: function() {
     if (!window.UI)
       return; // called too soon
 
-//    Utils.log('updateTabBar', this._activeGroupItem, this._activeOrphanTab);
-
     if (!this._activeGroupItem && !this._activeOrphanTab) {
       Utils.assert(false, "There must be something to show in the tab bar!");
       return;
     }
 
     let tabItems = this._activeGroupItem == null ?
       [this._activeOrphanTab] : this._activeGroupItem._children;
     gBrowser.showOnlyTheseTabs(tabItems.map(function(item) item.tab));
   },
 
   // ----------
+  // Function: updateActiveGroupItemAndTabBar
+  // Sets active group item and updates tab bar
+  updateActiveGroupItemAndTabBar: function(tabItem) {
+    if (tabItem.parent) {
+      let groupItem = tabItem.parent;
+      this.setActiveGroupItem(groupItem);
+      groupItem.setActiveTab(tabItem);
+    } else {
+      this.setActiveGroupItem(null);
+      this.setActiveOrphanTab(tabItem);
+    }
+    this._updateTabBar();
+  },
+
+  // ----------
   // Function: getOrphanedTabs
   // Returns an array of all tabs that aren't in a groupItem.
   getOrphanedTabs: function() {
     var tabs = TabItems.getItems();
     tabs = tabs.filter(function(tab) {
       return tab.parent == null;
     });
     return tabs;
@@ -1636,38 +1636,35 @@ window.GroupItems = {
 
   // ----------
   // Function: getNextGroupItemTab
   // Paramaters:
   //  reverse - the boolean indicates the direction to look for the next groupItem.
   // Returns the <tabItem>. If nothing is found, return null.
   getNextGroupItemTab: function(reverse) {
     var groupItems = Utils.copy(GroupItems.groupItems);
-    if (reverse)
-      groupItems = groupItems.reverse();
     var activeGroupItem = GroupItems.getActiveGroupItem();
     var activeOrphanTab = GroupItems.getActiveOrphanTab();
     var tabItem = null;
 
+    if (reverse)
+      groupItems = groupItems.reverse();
+
     if (!activeGroupItem) {
       if (groupItems.length > 0) {
-
         groupItems.some(function(groupItem) {
           var child = groupItem.getChild(0);
           if (child) {
             tabItem = child;
             return true;
           }
           return false;
         });
       }
     } else {
-      if (reverse)
-        groupItems = groupItems.reverse();
-
       var currentIndex;
       groupItems.some(function(groupItem, index) {
         if (groupItem == activeGroupItem) {
           currentIndex = index;
           return true;
         }
         return false;
       });
@@ -1744,17 +1741,17 @@ window.GroupItems = {
       let box = new Rect(pageBounds);
       box.width = 250;
       box.height = 200;
 
       new GroupItem([ tab.tabItem ], { bounds: box });
     }
 
     if (shouldUpdateTabBar)
-      this.updateTabBar();
+      this._updateTabBar();
     else if (shouldShowTabView) {
       tab.tabItem.setZoomPrep(false);
       UI.showTabView();
     }
   },
 
   // ----------
   // Function: killNewTabGroup
--- a/browser/base/content/tabview/tabitems.js
+++ b/browser/base/content/tabview/tabitems.js
@@ -518,38 +518,26 @@ window.TabItem.prototype = Utils.extend(
     if (childHitResult.shouldZoom) {
       // Zoom in!
       var orig = $tabEl.bounds();
       var scale = window.innerWidth/orig.width;
       var tab = this.tab;
 
       function onZoomDone() {
         TabItems.resumePainting();
-        // If it's not focused, the onFocus lsitener would handle it.
-        if (gBrowser.selectedTab == tab)
-          UI.tabOnFocus(tab);
-        else
-          gBrowser.selectedTab = tab;
 
         $tabEl
           .css(orig.css())
           .removeClass("front");
 
-        // If the tab is in a groupItem set then set the active
-        // groupItem to the tab's parent.
-        if (self.parent) {
-          var gID = self.parent.id;
-          var groupItem = GroupItems.groupItem(gID);
-          GroupItems.setActiveGroupItem(groupItem);
-          groupItem.setActiveTab(self);
-        } else {
-          GroupItems.setActiveGroupItem(null);
-          GroupItems.setActiveOrphanTab(self);
-        }
-        GroupItems.updateTabBar();
+        // If it's not focused, the onFocus lsitener would handle it.
+        if (gBrowser.selectedTab == tab)
+          UI.onTabSelect(tab);
+        else
+          gBrowser.selectedTab = tab;
 
         if (isNewBlankTab)
           gWindow.gURLBar.focus();
 
         if (childHitResult.callback)
           childHitResult.callback();
       }
 
@@ -597,25 +585,22 @@ window.TabItem.prototype = Utils.extend(
       left: box.left,
       top: box.top,
       width: box.width,
       height: box.height
     }, {
       duration: 300,
       easing: 'cubic-bezier', // note that this is legal easing, even without parameters
       complete: function() { // note that this will happen on the DOM thread
-        $tab.removeClass('front');
+        self.setZoomPrep(false);
 
         GroupItems.setActiveOrphanTab(null);
 
         TabItems.resumePainting();
 
-        self._zoomPrep = false;
-        self.setBounds(self.getBounds(), true, {force: true});
-
         if (typeof complete == "function")
           complete();
       }
     });
   },
 
   // ----------
   // Function: setZoomPrep
--- a/browser/base/content/tabview/ui.js
+++ b/browser/base/content/tabview/ui.js
@@ -448,80 +448,61 @@ var UIManager = {
       if (activeGroupItem)
         self.setReorderTabItemsOnShow(activeGroupItem);
     });
 
     AllTabs.register("select", function(tab) {
       if (tab.ownerDocument.defaultView != gWindow)
         return;
 
-      self.tabOnFocus(tab);
+      self.onTabSelect(tab);
     });
   },
 
   // ----------
-  // Function: tabOnFocus
+  // Function: onTabSelect
   // Called when the user switches from one tab to another outside of the TabView UI.
-  tabOnFocus: function(tab) {
-    var self = this;
-    var focusTab = tab;
-    var currentTab = this._currentTab;
+  onTabSelect: function(tab) {
+    let currentTab = this._currentTab;
+    this._currentTab = tab;
 
-    this._currentTab = focusTab;
     // if the last visible tab has just been closed, don't show the chrome UI.
     if (this._isTabViewVisible() &&
         (this._closedLastVisibleTab || this._closedSelectedTabInTabView)) {
       this._closedLastVisibleTab = false;
       this._closedSelectedTabInTabView = false;
       return;
     }
+    // reset these vars, just in case.
+    this._closedLastVisibleTab = false;
+    this._closedSelectedTabInTabView = false;
 
     // if TabView is visible but we didn't just close the last tab or
     // selected tab, show chrome.
     if (this._isTabViewVisible())
       this.hideTabView();
 
-    // reset these vars, just in case.
-    this._closedLastVisibleTab = false;
-    this._closedSelectedTabInTabView = false;
-
-    // have things have changed while we were in timeout?
-    if (focusTab != self._currentTab)
-      return;
-
+    let oldItem = null;
     let newItem = null;
-    if (focusTab && focusTab.tabItem) {
-      newItem = focusTab.tabItem;
-      if (newItem.parent)
-        GroupItems.setActiveGroupItem(newItem.parent);
-      else {
-        GroupItems.setActiveGroupItem(null);
-        GroupItems.setActiveOrphanTab(newItem);
-      }
-      GroupItems.updateTabBar();
+    
+    if (currentTab && currentTab.tabItem)
+      oldItem = currentTab.tabItem;
+    if (tab && tab.tabItem) {
+      newItem = tab.tabItem;
+      GroupItems.updateActiveGroupItemAndTabBar(newItem);
     }
 
     // ___ prepare for when we return to TabView
-    let oldItem = null;
-    if (currentTab && currentTab.tabItem)
-      oldItem = currentTab.tabItem;
-
     if (newItem != oldItem) {
       if (oldItem)
         oldItem.setZoomPrep(false);
-
-      // if the last visible tab is removed, don't set zoom prep because
-      // we should be in the TabView interface.
-      let visibleTabCount = gBrowser.visibleTabs.length;
-      if (visibleTabCount > 0 && newItem && !self._isTabViewVisible())
+      if (newItem)
         newItem.setZoomPrep(true);
-    }
-    // the tab is already focused so the new and old items are the same.
-    else if (oldItem)
-      oldItem.setZoomPrep(!self._isTabViewVisible());
+    } else if (oldItem)
+      oldItem.setZoomPrep(true);
   },
 
   // ----------
   // Function: setReorderTabsOnHide
   // Sets the groupItem which the tab items' tabs should be re-ordered when
   // switching to the main browser UI.
   // Parameters:
   //   groupItem - the groupItem which would be used for re-ordering tabs.
@@ -558,17 +539,17 @@ var UIManager = {
     });
 
     iQ(window).keydown(function(event) {
       if (event.metaKey) window.Keys.meta = true;
 
       if (!self.getActiveTab() || iQ(":focus").length > 0) {
         // prevent the default action when tab is pressed so it doesn't gives
         // us problem with content focus.
-        if (event.which == 9) {
+        if (event.keyCode == KeyEvent.DOM_VK_TAB) {
           event.stopPropagation();
           event.preventDefault();
         }
         return;
       }
 
       function getClosestTabBy(norm) {
         var centers =
@@ -580,63 +561,70 @@ var UIManager = {
             return myCenter.distance(a[0]) - myCenter.distance(b[0]);
           });
         if (matches.length > 0)
           return matches[0][1];
         return null;
       }
 
       var norm = null;
-      switch (event.which) {
-        case 39: // Right
+      switch (event.keyCode) {
+        case KeyEvent.DOM_VK_RIGHT:
           norm = function(a, me){return a.x > me.x};
           break;
-        case 37: // Left
+        case KeyEvent.DOM_VK_LEFT:
           norm = function(a, me){return a.x < me.x};
           break;
-        case 40: // Down
+        case KeyEvent.DOM_VK_DOWN:
           norm = function(a, me){return a.y > me.y};
           break;
-        case 38: // Up
+        case KeyEvent.DOM_VK_UP:
           norm = function(a, me){return a.y < me.y}
           break;
       }
 
       if (norm != null) {
         var nextTab = getClosestTabBy(norm);
         if (nextTab) {
           if (nextTab.inStack() && !nextTab.parent.expanded)
             nextTab = nextTab.parent.getChild(0);
           self.setActiveTab(nextTab);
         }
         event.stopPropagation();
         event.preventDefault();
-      } else if (event.which == 32) {
+      } else if (event.keyCode == KeyEvent.DOM_VK_SPACE) {
         // alt/control + space to zoom into the active tab.
 #ifdef XP_MACOSX
         if (event.altKey && !event.metaKey && !event.shiftKey &&
             !event.ctrlKey) {
 #else
         if (event.ctrlKey && !event.metaKey && !event.shiftKey &&
             !event.altKey) {
 #endif
           var activeTab = self.getActiveTab();
           if (activeTab)
             activeTab.zoomIn();
           event.stopPropagation();
           event.preventDefault();
         }
-      } else if (event.which == 27 || event.which == 13) {
-        // esc or return to zoom into the active tab.
-        var activeTab = self.getActiveTab();
-        if (activeTab)
-          activeTab.zoomIn();
+      } else if (event.keyCode == KeyEvent.DOM_VK_ESCAPE || 
+                 event.keyCode == KeyEvent.DOM_VK_RETURN ||
+                 event.keyCode == KeyEvent.DOM_VK_ENTER) {
+        let activeTab = self.getActiveTab();
+        let activeGroupItem = GroupItems.getActiveGroupItem();
+
+        if (activeGroupItem && activeGroupItem.expanded && 
+            event.keyCode == KeyEvent.DOM_VK_ESCAPE)
+          activeGroupItem.collapse();
+        else if (activeTab)
+            activeTab.zoomIn();
+
         event.stopPropagation();
         event.preventDefault();
-      } else if (event.which == 9) {
+      } else if (event.keyCode == KeyEvent.DOM_VK_TAB) {
         // tab/shift + tab to go to the next tab.
         var activeTab = self.getActiveTab();
         if (activeTab) {
           var tabItems = (activeTab.parent ? activeTab.parent.getChildren() :
                           [activeTab]);
           var length = tabItems.length;
           var currentIndex = tabItems.indexOf(activeTab);
 
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -137,31 +137,35 @@ endif
                  browser_bug555767.js \
                  browser_bug556061.js \
                  browser_bug561623.js \
                  browser_bug562649.js \
                  browser_bug563588.js \
                  browser_bug577121.js \
                  browser_bug580956.js \
                  browser_bug581242.js \
+                 browser_bug581947.js \
+                 browser_bug585830.js \
                  browser_contextSearchTabPosition.js \
                  browser_ctrlTab.js \
                  browser_discovery.js \
                  browser_drag.js \
                  browser_duplicateIDs.js \
                  browser_gestureSupport.js \
                  browser_getshortcutoruri.js \
                  browser_hide_removing.js \
                  browser_inspector_initialization.js \
                  browser_inspector_treeSelection.js \
                  browser_inspector_highlighter.js \
                  browser_inspector_stylePanel.js \
                  browser_inspector_domPanel.js \
                  browser_inspector_iframeTest.js \
                  browser_inspector_scrolling.js \
+                 browser_inspector_store.js \
+                 browser_inspector_tab_switch.js \
                  browser_pageInfo.js \
                  browser_page_style_menu.js \
                  browser_pinnedTabs.js \
                  browser_plainTextLinks.js \
                  browser_pluginnotification.js \
                  browser_popupUI.js \
                  browser_relatedTabs.js \
                  browser_sanitize-passwordDisabledHosts.js \
--- a/browser/base/content/test/browser_bug380960.js
+++ b/browser/base/content/test/browser_bug380960.js
@@ -8,17 +8,20 @@ function test() {
   tab = gBrowser.addTab("about:blank", { skipAnimation: true });
   gBrowser.removeTab(tab, { animate: true });
   gBrowser.removeTab(tab);
   is(tab.parentNode, null, "tab removed immediately when calling removeTab again after the animation was kicked off");
 
   waitForExplicitFinish();
 
   Services.prefs.setBoolPref("browser.tabs.animate", true);
-  preperForNextText();
+
+//  preperForNextText();
+  todo(false, "async tests disabled because of intermittent failures (bug 585361)");
+  cleanup();
 }
 
 function tabAdded() {
   info("tab added");
 }
 
 function cleanup() {
   if (Services.prefs.prefHasUserValue("browser.tabs.animate"))
--- a/browser/base/content/test/browser_bug420160.js
+++ b/browser/base/content/test/browser_bug420160.js
@@ -13,20 +13,31 @@ function test() {
   ok(gIdentityHandler, "gIdentityHandler should exist");
 
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.selectedBrowser.addEventListener("load", listener, true);
   listener.testFunction = testNormalDomain;  
   content.location = "http://test1.example.org/";
 }
 
+// Greek IDN for 'example.test'.
+var idnDomain = "\u03C0\u03B1\u03C1\u03AC\u03B4\u03B5\u03B9\u03B3\u03BC\u03B1.\u03B4\u03BF\u03BA\u03B9\u03BC\u03AE";
+
 function testNormalDomain() {
   is(gIdentityHandler._lastLocation.host, 'test1.example.org', "Identity handler is getting the full location");
   is(gIdentityHandler.getEffectiveHost(), 'example.org', "getEffectiveHost should return example.org for test1.example.org");
 
+  listener.testFunction = testIDNDomain;
+  content.location = "http://sub1." + idnDomain + "/";
+}
+
+function testIDNDomain() {
+  is(gIdentityHandler._lastLocation.host, "sub1." + idnDomain, "Identity handler is getting the full location");
+  is(gIdentityHandler.getEffectiveHost(), idnDomain, "getEffectiveHost should return the IDN base domain in UTF-8");
+
   listener.testFunction = testNormalDomainWithPort;
   content.location = "http://sub1.test1.example.org:8000/";
 }
 
 function testNormalDomainWithPort() {
   is(gIdentityHandler._lastLocation.host, 'sub1.test1.example.org:8000', "Identity handler is getting port information");
   is(gIdentityHandler.getEffectiveHost(), 'example.org', "getEffectiveHost should return example.org for sub1.test1.example.org:8000");
 
--- a/browser/base/content/test/browser_bug553455.js
+++ b/browser/base/content/test/browser_bug553455.js
@@ -54,34 +54,34 @@ function test_blocked_install() {
     "XPI": "unsigned.xpi"
   }));
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 
   // Wait for the blocked notification
   wait_for_notification(function(aPanel) {
     let notification = aPanel.childNodes[0];
-    is(notification.id, "addon-install-blocked", "Should have seen the install blocked");
+    is(notification.id, "addon-install-blocked-notification", "Should have seen the install blocked");
     is(notification.button.label, "Allow", "Should have seen the right button");
     is(notification.getAttribute("label"),
        gApp + " prevented this site (example.com) from asking you to install " +
        "software on your computer.",
        "Should have seen the right message");
 
     // Click on Allow
     EventUtils.synthesizeMouse(notification.button, 20, 10, {});
 
     // Wait for the install confirmation dialog
     wait_for_install_dialog(function(aWindow) {
       aWindow.document.documentElement.acceptDialog();
 
       // Wait for the complete notification
       wait_for_notification(function(aPanel) {
         let notification = aPanel.childNodes[0];
-        is(notification.id, "addon-install-complete", "Should have seen the install complete");
+        is(notification.id, "addon-install-complete-notification", "Should have seen the install complete");
         is(notification.button.label, "Restart Now", "Should have seen the right button");
         is(notification.getAttribute("label"), 
            "XPI Test will be installed after you restart " + gApp + ".",
            "Should have seen the right message");
 
         AddonManager.getAllInstalls(function(aInstalls) {
         is(aInstalls.length, 1, "Should be one pending install");
           aInstalls[0].cancel();
@@ -106,17 +106,17 @@ function test_whitelisted_install() {
 
   // Wait for the install confirmation dialog
   wait_for_install_dialog(function(aWindow) {
     aWindow.document.documentElement.acceptDialog();
 
     // Wait for the complete notification
     wait_for_notification(function(aPanel) {
       let notification = aPanel.childNodes[0];
-      is(notification.id, "addon-install-complete", "Should have seen the install complete");
+      is(notification.id, "addon-install-complete-notification", "Should have seen the install complete");
       is(notification.button.label, "Restart Now", "Should have seen the right button");
       is(notification.getAttribute("label"),
          "XPI Test will be installed after you restart " + gApp + ".",
          "Should have seen the right message");
 
       AddonManager.getAllInstalls(function(aInstalls) {
         is(aInstalls.length, 1, "Should be one pending install");
         aInstalls[0].cancel();
@@ -137,17 +137,17 @@ function test_failed_download() {
     "XPI": "missing.xpi"
   }));
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 
   // Wait for the failed notification
   wait_for_notification(function(aPanel) {
     let notification = aPanel.childNodes[0];
-    is(notification.id, "addon-install-failed", "Should have seen the install fail");
+    is(notification.id, "addon-install-failed-notification", "Should have seen the install fail");
     is(notification.getAttribute("label"),
        "The add-on could not be downloaded because of a connection failure " +
        "on example.com.",
        "Should have seen the right message");
 
     gBrowser.removeTab(gBrowser.selectedTab);
     Services.perms.remove("example.com", "install");
     runNextTest();
@@ -162,17 +162,17 @@ function test_corrupt_file() {
     "XPI": "corrupt.xpi"
   }));
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 
   // Wait for the failed notification
   wait_for_notification(function(aPanel) {
     let notification = aPanel.childNodes[0];
-    is(notification.id, "addon-install-failed", "Should have seen the install fail");
+    is(notification.id, "addon-install-failed-notification", "Should have seen the install fail");
     is(notification.getAttribute("label"),
        "The add-on downloaded from example.com could not be installed " +
        "because it appears to be corrupt.",
        "Should have seen the right message");
 
     gBrowser.removeTab(gBrowser.selectedTab);
     Services.perms.remove("example.com", "install");
     runNextTest();
@@ -187,17 +187,17 @@ function test_incompatible() {
     "XPI": "incompatible.xpi"
   }));
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
 
   // Wait for the failed notification
   wait_for_notification(function(aPanel) {
     let notification = aPanel.childNodes[0];
-    is(notification.id, "addon-install-failed", "Should have seen the install fail");
+    is(notification.id, "addon-install-failed-notification", "Should have seen the install fail");
     is(notification.getAttribute("label"),
        "XPI Test could not be installed because it is not compatible with " +
        gApp + " " + gVersion + ".",
        "Should have seen the right message");
 
     gBrowser.removeTab(gBrowser.selectedTab);
     Services.perms.remove("example.com", "install");
     runNextTest();
@@ -216,17 +216,17 @@ function test_restartless() {
 
   // Wait for the install confirmation dialog
   wait_for_install_dialog(function(aWindow) {
     aWindow.document.documentElement.acceptDialog();
 
     // Wait for the complete notification
     wait_for_notification(function(aPanel) {
       let notification = aPanel.childNodes[0];
-      is(notification.id, "addon-install-complete", "Should have seen the install complete");
+      is(notification.id, "addon-install-complete-notification", "Should have seen the install complete");
       is(notification.button.label, "Open Add-ons Manager", "Should have seen the right button");
       is(notification.getAttribute("label"),
          "XPI Test has been installed successfully.",
          "Should have seen the right message");
 
       AddonManager.getAllInstalls(function(aInstalls) {
         is(aInstalls.length, 0, "Should be no pending installs");
 
@@ -255,17 +255,17 @@ function test_multiple() {
 
   // Wait for the install confirmation dialog
   wait_for_install_dialog(function(aWindow) {
     aWindow.document.documentElement.acceptDialog();
 
     // Wait for the complete notification
     wait_for_notification(function(aPanel) {
       let notification = aPanel.childNodes[0];
-      is(notification.id, "addon-install-complete", "Should have seen the install complete");
+      is(notification.id, "addon-install-complete-notification", "Should have seen the install complete");
       is(notification.button.label, "Restart Now", "Should have seen the right button");
       is(notification.getAttribute("label"),
          "2 add-ons will be installed after you restart " + gApp + ".",
          "Should have seen the right message");
 
       AddonManager.getAllInstalls(function(aInstalls) {
         is(aInstalls.length, 1, "Should be one pending install");
         aInstalls[0].cancel();
@@ -288,17 +288,17 @@ function test_url() {
 
   // Wait for the install confirmation dialog
   wait_for_install_dialog(function(aWindow) {
     aWindow.document.documentElement.acceptDialog();
 
     // Wait for the complete notification
     wait_for_notification(function(aPanel) {
       let notification = aPanel.childNodes[0];
-      is(notification.id, "addon-install-complete", "Should have seen the install complete");
+      is(notification.id, "addon-install-complete-notification", "Should have seen the install complete");
       is(notification.button.label, "Restart Now", "Should have seen the right button");
       is(notification.getAttribute("label"),
          "XPI Test will be installed after you restart " + gApp + ".",
          "Should have seen the right message");
 
       AddonManager.getAllInstalls(function(aInstalls) {
         is(aInstalls.length, 1, "Should be one pending install");
         aInstalls[0].cancel();
@@ -316,17 +316,17 @@ function test_localfile() {
   var path = cr.convertChromeURL(makeURI(CHROMEROOT + "corrupt.xpi")).spec;
 
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.loadURI(path);
 
   // Wait for the complete notification
   wait_for_notification(function(aPanel) {
     let notification = aPanel.childNodes[0];
-    is(notification.id, "addon-install-failed", "Should have seen the install fail");
+    is(notification.id, "addon-install-failed-notification", "Should have seen the install fail");
     is(notification.getAttribute("label"),
        "This add-on could not be installed because it appears to be corrupt.",
        "Should have seen the right message");
 
     gBrowser.removeTab(gBrowser.selectedTab);
     runNextTest();
   });
 },
@@ -339,17 +339,17 @@ function test_wronghost() {
 
     gBrowser.removeEventListener("load", arguments.callee, true);
 
     gBrowser.loadURI(TESTROOT + "corrupt.xpi");
 
     // Wait for the complete notification
     wait_for_notification(function(aPanel) {
       let notification = aPanel.childNodes[0];
-      is(notification.id, "addon-install-failed", "Should have seen the install fail");
+      is(notification.id, "addon-install-failed-notification", "Should have seen the install fail");
       is(notification.getAttribute("label"),
          "The add-on downloaded from example.com could not be installed " +
          "because it appears to be corrupt.",
          "Should have seen the right message");
 
       gBrowser.removeTab(gBrowser.selectedTab);
       runNextTest();
     });
@@ -369,17 +369,17 @@ function test_reload() {
 
   // Wait for the install confirmation dialog
   wait_for_install_dialog(function(aWindow) {
     aWindow.document.documentElement.acceptDialog();
 
     // Wait for the complete notification
     wait_for_notification(function(aPanel) {
       let notification = aPanel.childNodes[0];
-      is(notification.id, "addon-install-complete", "Should have seen the install complete");
+      is(notification.id, "addon-install-complete-notification", "Should have seen the install complete");
       is(notification.button.label, "Restart Now", "Should have seen the right button");
       is(notification.getAttribute("label"),
          "XPI Test will be installed after you restart " + gApp + ".",
          "Should have seen the right message");
 
       function test_fail() {
         ok(false, "Reloading should not have hidden the notification");
       }
@@ -420,27 +420,126 @@ function test_theme() {
 
   // Wait for the install confirmation dialog
   wait_for_install_dialog(function(aWindow) {
     aWindow.document.documentElement.acceptDialog();
 
     // Wait for the complete notification
     wait_for_notification(function(aPanel) {
       let notification = aPanel.childNodes[0];
-      is(notification.id, "addon-install-complete", "Should have seen the install complete");
+      is(notification.id, "addon-install-complete-notification", "Should have seen the install complete");
       is(notification.button.label, "Restart Now", "Should have seen the right button");
       is(notification.getAttribute("label"),
          "Theme Test will be installed after you restart " + gApp + ".",
          "Should have seen the right message");
 
       gBrowser.removeTab(gBrowser.selectedTab);
       Services.perms.remove("example.com", "install");
       runNextTest();
     });
   });
+},
+
+function test_renotify_blocked() {
+  var triggers = encodeURIComponent(JSON.stringify({
+    "XPI": "unsigned.xpi"
+  }));
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
+
+  // Wait for the blocked notification
+  wait_for_notification(function(aPanel) {
+    let notification = aPanel.childNodes[0];
+    is(notification.id, "addon-install-blocked-notification", "Should have seen the install blocked");
+
+    aPanel.addEventListener("popuphidden", function () {
+      aPanel.removeEventListener("popuphidden", arguments.callee, false);
+      info("Timeouts after this probably mean bug 589954 regressed");
+      executeSoon(function () {
+        gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
+
+        wait_for_notification(function(aPanel) {
+          let notification = aPanel.childNodes[0];
+          is(notification.id, "addon-install-blocked-notification",
+             "Should have seen the install blocked - 2nd time");
+
+          AddonManager.getAllInstalls(function(aInstalls) {
+          is(aInstalls.length, 2, "Should be two pending installs");
+            aInstalls[0].cancel();
+            aInstalls[1].cancel();
+
+            info("Closing browser tab");
+            gBrowser.removeTab(gBrowser.selectedTab);
+            runNextTest();
+          });
+        });
+
+      });
+    }, false);
+
+    // hide the panel (this simulates the user dismissing it)
+    aPanel.hidePopup();
+  });
+},
+
+function test_renotify_installed() {
+  var pm = Services.perms;
+  pm.add(makeURI("http://example.com/"), "install", pm.ALLOW_ACTION);
+
+  var triggers = encodeURIComponent(JSON.stringify({
+    "XPI": "unsigned.xpi"
+  }));
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
+
+  // Wait for the install confirmation dialog
+  wait_for_install_dialog(function(aWindow) {
+    aWindow.document.documentElement.acceptDialog();
+
+    // Wait for the complete notification
+    wait_for_notification(function(aPanel) {
+      let notification = aPanel.childNodes[0];
+      is(notification.id, "addon-install-complete-notification", "Should have seen the install complete");
+
+      // Dismiss the notification
+      aPanel.addEventListener("popuphidden", function () {
+        aPanel.removeEventListener("popuphidden", arguments.callee, false);
+
+        // Install another
+        executeSoon(function () {
+          gBrowser.loadURI(TESTROOT + "installtrigger.html?" + triggers);
+
+          // Wait for the install confirmation dialog
+          wait_for_install_dialog(function(aWindow) {
+            aWindow.document.documentElement.acceptDialog();
+            info("Timeouts after this probably mean bug 589954 regressed");
+
+            // Wait for the complete notification
+            wait_for_notification(function(aPanel) {
+              let notification = aPanel.childNodes[0];
+              is(notification.id, "addon-install-complete-notification", "Should have seen the second install complete");
+
+              AddonManager.getAllInstalls(function(aInstalls) {
+              is(aInstalls.length, 2, "Should be two pending installs");
+                aInstalls[0].cancel();
+                aInstalls[1].cancel();
+
+                gBrowser.removeTab(gBrowser.selectedTab);
+                runNextTest();
+              });
+            });
+          });
+
+        });
+      }, false);
+  
+      // hide the panel (this simulates the user dismissing it)
+      aPanel.hidePopup();
+    });
+  });
 }
 ];
 
 function runNextTest() {
   AddonManager.getAllInstalls(function(aInstalls) {
     is(aInstalls.length, 0, "Should be no active installs");
 
     if (TESTS.length == 0) {
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_bug581947.js
@@ -0,0 +1,85 @@
+function check(aElementName, aBarred, aType) {
+  let doc = gBrowser.contentDocument;
+  let tooltip = document.getElementById("aHTMLTooltip");
+  let content = doc.getElementById('content');
+
+  let e = doc.createElement(aElementName);
+  content.appendChild(e);
+
+  if (aType) {
+    e.type = aType;
+  }
+
+  ok(!FillInHTMLTooltip(e),
+     "No tooltip should be shown when the element is valid");
+
+  e.setCustomValidity('foo');
+  if (aBarred) {
+    ok(!FillInHTMLTooltip(e),
+       "No tooltip should be shown when the element is barred from constraint validation");
+  } else {
+    ok(FillInHTMLTooltip(e),
+       "A tooltip should be shown when the element isn't valid");
+  }
+
+  content.removeChild(e);
+}
+
+function todo_check(aElementName, aBarred) {
+  let doc = gBrowser.contentDocument;
+  let tooltip = document.getElementById("aHTMLTooltip");
+  let content = doc.getElementById('content');
+
+  let e = doc.createElement(aElementName);
+  content.appendChild(e);
+
+  let cought = false;
+  try {
+    e.setCustomValidity('foo');
+  } catch (e) {
+    cought = true;
+  }
+
+  todo(!cought, "setCustomValidity should exist for " + aElementName);
+
+  content.removeChild(e);
+}
+
+function test () {
+  waitForExplicitFinish();
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.selectedBrowser.addEventListener("load", function () {
+    gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
+
+    let testData = [
+    /* element name, barred, type */
+      [ 'input',    false, null],
+      [ 'textarea', false, null],
+      [ 'button',   true,  'button'],
+      [ 'button',   false, 'submit' ],
+      [ 'select',   false, null],
+      [ 'output',   true,  null],
+      [ 'fieldset', true,  null],
+      [ 'object', 'false' ],
+    ];
+
+    for each (let data in testData) {
+      check(data[0], data[1], data[2]);
+    }
+
+    let todo_testData = [
+      [ 'keygen', 'false' ],
+    ];
+
+    for each(let data in todo_testData) {
+      todo_check(data[0], data[1]);
+    }
+
+    gBrowser.removeCurrentTab();
+    finish();
+  }, true);
+
+  content.location = 
+    "data:text/html,<!DOCTYPE html><html><body><div id='content'></div></body></html>";
+}
+
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_bug585830.js
@@ -0,0 +1,57 @@
+/* ***** 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 bug 585830 test.
+ *
+ * The Initial Developer of the Original Code is
+ * Sindre Dammann <sindrebugzilla@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 ***** */
+
+function test() {
+  let tab1 = gBrowser.selectedTab;
+  let tab2 = gBrowser.addTab("about:blank", {skipAnimation: true});
+  let tab3 = gBrowser.addTab();
+  gBrowser.selectedTab = tab2;
+  
+  gBrowser.removeCurrentTab({animate: true});
+  gBrowser.tabContainer.advanceSelectedTab(-1, true);
+  is(gBrowser.selectedTab, tab1, "First tab should be selected");
+  gBrowser.removeTab(tab2);
+  
+  // test for "null has no properties" fix. See Bug 585830 Comment 13
+  gBrowser.removeCurrentTab({animate: true});
+  try {
+    gBrowser.tabContainer.advanceSelectedTab(-1, false);
+  } catch(err) {
+    ok(false, "Shouldn't throw");
+  }
+  
+  gBrowser.removeTab(tab1);
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_inspector_store.js
@@ -0,0 +1,106 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* ***** 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 Inspector Store Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Mihai Șucan <mihai.sucan@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+function test()
+{
+  ok(InspectorUI, "InspectorUI variable exists");
+  ok(!InspectorUI.inspecting, "Inspector is not highlighting");
+  is(InspectorStore.length, 0, "InspectorStore is empty");
+  ok(InspectorStore.isEmpty(), "InspectorStore is empty (confirmed)");
+  is(typeof InspectorStore.store, "object",
+    "InspectorStore.store is an object");
+
+  ok(InspectorStore.addStore("foo"), "addStore('foo') returns true");
+
+  is(InspectorStore.length, 1, "InspectorStore.length = 1");
+  ok(!InspectorStore.isEmpty(), "InspectorStore is not empty");
+  is(typeof InspectorStore.store.foo, "object", "store.foo is an object");
+
+  ok(InspectorStore.addStore("fooBar"), "addStore('fooBar') returns true");
+
+  is(InspectorStore.length, 2, "InspectorStore.length = 2");
+  is(typeof InspectorStore.store.fooBar, "object", "store.fooBar is an object");
+
+  ok(!InspectorStore.addStore("fooBar"), "addStore('fooBar') returns false");
+
+  ok(InspectorStore.deleteStore("fooBar"),
+    "deleteStore('fooBar') returns true");
+
+  is(InspectorStore.length, 1, "InspectorStore.length = 1");
+  ok(!InspectorStore.store.fooBar, "store.fooBar is deleted");
+
+  ok(!InspectorStore.deleteStore("fooBar"),
+    "deleteStore('fooBar') returns false");
+
+  ok(!InspectorStore.hasID("fooBar"), "hasID('fooBar') returns false");
+
+  ok(InspectorStore.hasID("foo"), "hasID('foo') returns true");
+
+  ok(InspectorStore.setValue("foo", "key1", "val1"), "setValue() returns true");
+
+  ok(!InspectorStore.setValue("fooBar", "key1", "val1"),
+    "setValue() returns false");
+
+  is(InspectorStore.getValue("foo", "key1"), "val1",
+    "getValue() returns the correct value");
+
+  is(InspectorStore.store.foo.key1, "val1", "store.foo.key1 = 'val1'");
+
+  ok(!InspectorStore.getValue("fooBar", "key1"),
+    "getValue() returns null for unknown store");
+
+  ok(!InspectorStore.getValue("fooBar", "key1"),
+    "getValue() returns null for unknown store");
+
+  ok(InspectorStore.deleteValue("foo", "key1"),
+    "deleteValue() returns true for known value");
+
+  ok(!InspectorStore.store.foo.key1, "deleteValue() removed the value.");
+
+  ok(!InspectorStore.deleteValue("fooBar", "key1"),
+    "deleteValue() returns false for unknown store.");
+
+  ok(!InspectorStore.deleteValue("foo", "key1"),
+    "deleteValue() returns false for unknown value.");
+
+  ok(InspectorStore.deleteStore("foo"), "deleteStore('foo') returns true");
+
+  ok(InspectorStore.isEmpty(), "InspectorStore is empty");
+}
+
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_inspector_tab_switch.js
@@ -0,0 +1,198 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* ***** 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 Inspector Tab Switch Tests.
+ *
+ * The Initial Developer of the Original Code is
+ * The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Rob Campbell <rcampbell@mozilla.com>
+ *   Mihai Șucan <mihai.sucan@gmail.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+let div;
+let tab1;
+let tab2;
+let tab1window;
+
+function inspectorTabOpen1()
+{
+  ok(InspectorUI, "InspectorUI variable exists");
+  ok(!InspectorUI.inspecting, "Inspector is not highlighting");
+  ok(InspectorStore.isEmpty(), "InspectorStore is empty");
+
+  document.addEventListener("popupshown", inspectorUIOpen1, false);
+  InspectorUI.toggleInspectorUI();
+}
+
+function inspectorUIOpen1(evt)
+{
+  if (evt.target.id != "inspector-style-panel") {
+    return true;
+  }
+
+  document.removeEventListener(evt.type, arguments.callee, false);
+
+  // Make sure the inspector is open.
+  ok(InspectorUI.inspecting, "Inspector is highlighting");
+  ok(InspectorUI.isPanelOpen, "Inspector Tree Panel is open");
+  ok(InspectorUI.isStylePanelOpen, "Inspector Style Panel is open");
+  ok(!InspectorStore.isEmpty(), "InspectorStore is not empty");
+  is(InspectorStore.length, 1, "InspectorStore.length = 1");
+
+  // Highlight a node.
+  div = content.document.getElementsByTagName("div")[0];
+  InspectorUI.inspectNode(div);
+  is(InspectorUI.treeView.selectedNode, div,
+    "selection matches the div element");
+
+  // Open the second tab.
+  tab2 = gBrowser.addTab();
+  gBrowser.selectedTab = tab2;
+  gBrowser.selectedBrowser.addEventListener("load", function(evt) {
+    gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee,
+      true);
+    waitForFocus(inspectorTabOpen2, content);
+  }, true);
+
+  content.location = "data:text/html,<p>tab 2: the inspector should close now";
+}
+
+function inspectorTabOpen2()
+{
+  // Make sure the inspector is closed.
+  ok(!InspectorUI.inspecting, "Inspector is not highlighting");
+  ok(!InspectorUI.isPanelOpen, "Inspector Tree Panel is closed");
+  ok(!InspectorUI.isStylePanelOpen, "Inspector Style Panel is closed");
+  is(InspectorStore.length, 1, "InspectorStore.length = 1");
+
+  // Activate the inspector again.
+  document.addEventListener("popupshown", inspectorUIOpen2, false);
+  InspectorUI.toggleInspectorUI();
+}
+
+function inspectorUIOpen2(evt)
+{
+  if (evt.target.id != "inspector-style-panel") {
+    return true;
+  }
+
+  document.removeEventListener(evt.type, arguments.callee, false);
+
+  // Make sure the inspector is open.
+  ok(InspectorUI.inspecting, "Inspector is highlighting");
+  ok(InspectorUI.isPanelOpen, "Inspector Tree Panel is open");
+  ok(InspectorUI.isStylePanelOpen, "Inspector Style Panel is open");
+  is(InspectorStore.length, 2, "InspectorStore.length = 2");
+
+  // Disable highlighting.
+  InspectorUI.toggleInspection();
+  ok(!InspectorUI.inspecting, "Inspector is not highlighting");
+
+  // Switch back to tab 1.
+  document.addEventListener("popupshown", inspectorFocusTab1, false);
+  gBrowser.selectedTab = tab1;
+}
+
+function inspectorFocusTab1(evt)
+{
+  if (evt.target.id != "inspector-style-panel") {
+    return true;
+  }
+
+  document.removeEventListener(evt.type, arguments.callee, false);
+
+  // Make sure the inspector is still open.
+  ok(InspectorUI.inspecting, "Inspector is highlighting");
+  ok(InspectorUI.isPanelOpen, "Inspector Tree Panel is open");
+  ok(InspectorUI.isStylePanelOpen, "Inspector Style Panel is open");
+  is(InspectorStore.length, 2, "InspectorStore.length = 2");
+  is(InspectorUI.treeView.selectedNode, div,
+    "selection matches the div element");
+
+  // Switch back to tab 2.
+  document.addEventListener("popupshown", inspectorFocusTab2, false);
+  gBrowser.selectedTab = tab2;
+}
+
+function inspectorFocusTab2(evt)
+{
+  if (evt.target.id != "inspector-style-panel") {
+    return true;
+  }
+
+  document.removeEventListener(evt.type, arguments.callee, false);
+
+  // Make sure the inspector is still open.
+  ok(!InspectorUI.inspecting, "Inspector is not highlighting");
+  ok(InspectorUI.isPanelOpen, "Inspector Tree Panel is open");
+  ok(InspectorUI.isStylePanelOpen, "Inspector Style Panel is open");
+  is(InspectorStore.length, 2, "InspectorStore.length = 2");
+  isnot(InspectorUI.treeView.selectedNode, div,
+    "selection does not match the div element");
+
+  // Remove tab 1.
+  tab1window = gBrowser.getBrowserForTab(tab1).contentWindow;
+  tab1window.addEventListener("unload", inspectorTabUnload1, false);
+  gBrowser.removeTab(tab1);
+}
+
+function inspectorTabUnload1(evt)
+{
+  tab1window.removeEventListener(evt.type, arguments.callee, false);
+  tab1window = tab1 = tab2 = div = null;
+
+  // Make sure the Inspector is still open and that the state is correct.
+  ok(!InspectorUI.inspecting, "Inspector is not highlighting");
+  ok(InspectorUI.isPanelOpen, "Inspector Tree Panel is open");
+  ok(InspectorUI.isStylePanelOpen, "Inspector Style Panel is open");
+  is(InspectorStore.length, 1, "InspectorStore.length = 1");
+
+  gBrowser.removeCurrentTab();
+  finish();
+}
+
+function test()
+{
+  waitForExplicitFinish();
+
+  tab1 = gBrowser.addTab();
+  gBrowser.selectedTab = tab1;
+  gBrowser.selectedBrowser.addEventListener("load", function(evt) {
+    gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee,
+      true);
+    waitForFocus(inspectorTabOpen1, content);
+  }, true);
+
+  content.location = "data:text/html,<p>tab switching tests for inspector" +
+    "<div>tab 1</div>";
+}
+
--- a/browser/base/content/test/browser_popupNotification.js
+++ b/browser/base/content/test/browser_popupNotification.js
@@ -322,20 +322,21 @@ var tests = [
     onShown: function (popup) {
       checkPopup(popup, this.notifyObj);
       dismissNotification(popup);
     },
     onHidden: function (popup) {
       this.notification.remove();
     }
   },
-  // Test that anchor icon appears
+  // Test that icons appear
   { // Test #11
     run: function () {
       this.notifyObj = new basicNotification();
+      this.notifyObj.id = "geolocation";
       this.notifyObj.anchorID = "geo-notification-icon";
       this.notification = showNotification(this.notifyObj);
     },
     onShown: function (popup) {
       checkPopup(popup, this.notifyObj);
       isnot(document.getElementById("geo-notification-icon").boxObject.width, 0,
             "geo anchor should be visible");
       dismissNotification(popup);
@@ -472,18 +473,21 @@ function showNotification(notifyObj) {
 }
 
 function checkPopup(popup, notificationObj) {
   info("[Test #" + gTestIndex + "] checking popup");
   let notifications = popup.childNodes;
 
   is(notifications.length, 1, "only one notification displayed");
   let notification = notifications[0];
+  let icon = document.getAnonymousElementByAttribute(notification, "class", "popup-notification-icon");
+  if (notificationObj.id == "geolocation")
+    isnot(icon.boxObject.width, 0, "icon for geo displayed");
   is(notification.getAttribute("label"), notificationObj.message, "message matches");
-  is(notification.id, notificationObj.id, "id matches");
+  is(notification.id, notificationObj.id + "-notification", "id matches");
   if (notificationObj.mainAction) {
     is(notification.getAttribute("buttonlabel"), notificationObj.mainAction.label, "main action label matches");
     is(notification.getAttribute("buttonaccesskey"), notificationObj.mainAction.accessKey, "main action accesskey matches");
   }
   let actualSecondaryActions = notification.childNodes;
   let secondaryActions = notificationObj.secondaryActions || [];
   is(actualSecondaryActions.length, secondaryActions.length, actualSecondaryActions.length + " secondary actions");
   secondaryActions.forEach(function (a, i) {
--- a/browser/base/content/test/tabview/Makefile.in
+++ b/browser/base/content/test/tabview/Makefile.in
@@ -42,14 +42,14 @@ relativesrcdir  = browser/base/content/t
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 $(warning All TabView tests are disabled for now while we iterate on the UI)
 
 _BROWSER_FILES = \
                  browser_tabview_launch.js \
-    $(NULL)
-#                 browser_tabview_dragdrop.js \
-#                 browser_tabview_group.js \
+                 browser_tabview_dragdrop.js \
+                 browser_tabview_group.js \
+                 $(NULL)
 
 libs::	$(_BROWSER_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
--- a/browser/base/content/test/tabview/browser_tabview_dragdrop.js
+++ b/browser/base/content/test/tabview/browser_tabview_dragdrop.js
@@ -34,25 +34,26 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 function test() {
   waitForExplicitFinish();
 
   window.addEventListener("tabviewshown", onTabViewWindowLoaded, false);
-  setTimeout(function() { TabView.toggle(); }, 0);
+  TabView.toggle();
 }
 
 function onTabViewWindowLoaded() {
   window.removeEventListener("tabviewshown", onTabViewWindowLoaded, false);
 
   ok(TabView.isVisible(), "Tab View is visible");
 
   let contentWindow = document.getElementById("tab-view").contentWindow;
+  let [originalTab] = gBrowser.visibleTabs;
 
   // create group one and two
   let padding = 10;
   let pageBounds = contentWindow.Items.getPageBounds();
   pageBounds.inset(padding, padding);
 
   let box = new contentWindow.Rect(pageBounds);
   box.width = 300;
@@ -60,39 +61,39 @@ function onTabViewWindowLoaded() {
 
   let groupOne = new contentWindow.GroupItem([], { bounds: box });
   ok(groupOne.isEmpty(), "This group is empty");
 
   let groupTwo = new contentWindow.GroupItem([], { bounds: box });
 
   groupOne.addSubscriber(groupOne, "tabAdded", function() {
     groupOne.removeSubscriber(groupOne, "tabAdded");
-    groupTwo.newTab("");
-  });
-  groupTwo.addSubscriber(groupTwo, "tabAdded", function() {
-    groupTwo.removeSubscriber(groupTwo, "tabAdded");
-    // carry on testing
-    addTest(contentWindow, groupOne.id, groupTwo.id);
+    groupTwo.newTab();
   });
 
   let count = 0;
-  let onTabViewHidden = function() {
-    // show the tab view.
-    TabView.toggle();
-    if (++count == 2) {
-      window.removeEventListener("tabviewhidden", onTabViewHidden, false);
+  let onTabViewShown = function() {
+    if (count == 2) {
+      window.removeEventListener("tabviewshown", onTabViewShown, false);
+      addTest(contentWindow, groupOne.id, groupTwo.id, originalTab);
     }
   };
+  let onTabViewHidden = function() {
+    TabView.toggle();
+    if (++count == 2)
+      window.removeEventListener("tabviewhidden", onTabViewHidden, false);
+  };
+  window.addEventListener("tabviewshown", onTabViewShown, false);
   window.addEventListener("tabviewhidden", onTabViewHidden, false);
 
   // open tab in group
-  groupOne.newTab("");
+  groupOne.newTab();
 }
 
-function addTest(contentWindow, groupOneId, groupTwoId) {
+function addTest(contentWindow, groupOneId, groupTwoId, originalTab) {
   let groupOne = contentWindow.GroupItems.groupItem(groupOneId);
   let groupTwo = contentWindow.GroupItems.groupItem(groupTwoId);
   let groupOneTabItemCount = groupOne.getChildren().length;
   let groupTwoTabItemCount = groupTwo.getChildren().length;
   is(groupOneTabItemCount, 1, "GroupItem one has a tab");
   is(groupTwoTabItemCount, 1, "GroupItem two has two tabs");
 
   let srcElement = groupOne.getChild(0).container;
@@ -110,25 +111,24 @@ function addTest(contentWindow, groupOne
 
   is(groupOne.getChildren().length, --groupOneTabItemCount,
      "The number of children in group one is decreased by 1");
   is(groupTwo.getChildren().length, ++groupTwoTabItemCount,
      "The number of children in group two is increased by 1");
 
   let onTabViewHidden = function() {
     window.removeEventListener("tabviewhidden", onTabViewHidden, false);
-    finish();
+     groupTwo.closeAll();
   };
-  window.addEventListener("tabviewhidden", onTabViewHidden, false);
-
   groupTwo.addSubscriber(groupTwo, "close", function() {
     groupTwo.removeSubscriber(groupTwo, "close");
-    contentWindow.UI.hideTabView();
+    finish();  
   });
-  groupTwo.closeAll();
+  window.addEventListener("tabviewhidden", onTabViewHidden, false);
+  gBrowser.selectedTab = originalTab;
 }
 
 function simulateDragDrop(srcElement, offsetX, offsetY, contentWindow) {
   // enter drag mode
   let dataTransfer;
 
   EventUtils.synthesizeMouse(
     srcElement, 1, 1, { type: "mousedown" }, contentWindow);
--- a/browser/base/content/test/tabview/browser_tabview_group.js
+++ b/browser/base/content/test/tabview/browser_tabview_group.js
@@ -90,29 +90,29 @@ function testGroupItemWithTabItem(conten
     window.removeEventListener("tabviewhidden", onTabViewHidden, false);
 
     is(groupItem.getChildren().length, ++tabItemCount,
        "The number of children in new tab group is increased by 1");
 
     let tabItem = groupItem.getChild(groupItem.getChildren().length - 1);
     ok(tabItem, "Tab item exists");
 
-    let tabRemoved = false;
+    let tabItemClosed = false;
     tabItem.addSubscriber(tabItem, "close", function() {
       tabItem.removeSubscriber(tabItem, "close");
-
-      ok(tabRemoved, "Tab is removed");
-      // tabItem would get destroyed after the close event is sent so we have a 0 delay here.
-      is(groupItem.getChildren().length, --tabItemCount,
-        "The number of children in new tab group is decreased by 1");
-      finish();
+      tabItemClosed = true;
     });
     tabItem.addSubscriber(tabItem, "tabRemoved", function() {
       tabItem.removeSubscriber(tabItem, "tabRemoved");
-      tabRemoved = true;
+
+      ok(tabItemClosed, "The tab item is closed");
+      is(groupItem.getChildren().length, --tabItemCount,
+        "The number of children in new tab group is decreased by 1");
+
+      finish();
     });
 
     // remove the tab item.  The code detects mousedown and mouseup so we stimulate here
     let closeButton = tabItem.container.getElementsByClassName("close");
     ok(closeButton, "Tab item close button exists");
 
     EventUtils.sendMouseEvent({ type: "mousedown" }, closeButton[0], contentWindow);
     EventUtils.sendMouseEvent({ type: "mouseup" }, closeButton[0], contentWindow);
--- a/browser/base/content/utilityOverlay.js
+++ b/browser/base/content/utilityOverlay.js
@@ -447,16 +447,25 @@ function openReleaseNotes()
  * Opens the troubleshooting information (about:support) page for this version
  * of the application.
  */
 function openTroubleshootingPage()
 {
   openUILinkIn("about:support", "tab");
 }
 
+/**
+ * Opens the feedback page for this version of the application.
+ */
+function openFeedbackPage()
+{
+  openUILinkIn("http://input.mozilla.com/sad", "tab");
+}
+
+
 #ifdef MOZ_UPDATER
 /**
  * Opens the update manager and checks for updates to the application.
  */
 function checkForUpdates()
 {
   var um = 
       Components.classes["@mozilla.org/updates/update-manager;1"].
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -12,16 +12,19 @@ browser.jar:
 %  overlay chrome://global/content/viewSource.xul chrome://browser/content/viewSourceOverlay.xul
 %  overlay chrome://global/content/viewPartialSource.xul chrome://browser/content/viewSourceOverlay.xul
 %  style chrome://global/content/customizeToolbar.xul chrome://browser/content/browser.css
 %  style chrome://global/content/customizeToolbar.xul chrome://browser/skin/
 *       content/browser/aboutDialog.xul               (content/aboutDialog.xul)
 *       content/browser/aboutDialog.js                (content/aboutDialog.js)
         content/browser/aboutDialog.css               (content/aboutDialog.css)
 *       content/browser/aboutRobots.xhtml             (content/aboutRobots.xhtml)
+*       content/browser/aboutHome.xhtml               (content/aboutHome.xhtml)
+*       content/browser/aboutHome.js                  (content/aboutHome.js)
+*       content/browser/aboutHome.css                 (content/aboutHome.css)
         content/browser/aboutRobots-icon.png          (content/aboutRobots-icon.png)
         content/browser/aboutRobots-icon-rtl.png      (content/aboutRobots-icon-rtl.png)
         content/browser/aboutRobots-widget-left.png   (content/aboutRobots-widget-left.png)
         content/browser/aboutRobots-widget-right.png  (content/aboutRobots-widget-right.png)
 *       content/browser/browser.css                   (content/browser.css)
 *       content/browser/browser.js                    (content/browser.js)
 *       content/browser/browser.xul                   (content/browser.xul)
 *       content/browser/browser-tabPreviews.xml       (content/browser-tabPreviews.xml)
--- a/browser/branding/nightly/content/jar.mn
+++ b/browser/branding/nightly/content/jar.mn
@@ -1,7 +1,9 @@
 browser.jar:
-% content branding %content/branding/
+% content branding %content/branding/ contentaccessible=yes
   content/branding/about.png                     (about.png)
   content/branding/aboutCredits.png              (aboutCredits.png)
   content/branding/aboutFooter.png               (aboutFooter.png)
   content/branding/icon48.png                    (icon48.png)
   content/branding/icon64.png                    (icon64.png)
+  content/branding/icon128.png                   (../mozicon128.png)
+  content/branding/icon16.png                    (../default16.png)
--- a/browser/branding/unofficial/configure.sh
+++ b/browser/branding/unofficial/configure.sh
@@ -1,1 +1,1 @@
-MOZ_APP_DISPLAYNAME="MozillaDeveloperPreview"
+MOZ_APP_DISPLAYNAME=MozillaDeveloperPreview
--- a/browser/branding/unofficial/content/jar.mn
+++ b/browser/branding/unofficial/content/jar.mn
@@ -1,7 +1,9 @@
 browser.jar:
-% content branding %content/branding/
+% content branding %content/branding/ contentaccessible=yes
   content/branding/about.png                     (about.png)
   content/branding/aboutCredits.png              (aboutCredits.png)
   content/branding/aboutFooter.png               (aboutFooter.png)
   content/branding/icon48.png                    (icon48.png)
   content/branding/icon64.png                    (icon64.png)
+  content/branding/icon128.png                   (../mozicon128.png)
+  content/branding/icon16.png                    (../default16.png)
--- a/browser/components/about/AboutRedirector.cpp
+++ b/browser/components/about/AboutRedirector.cpp
@@ -95,16 +95,19 @@ static RedirEntry kRedirMap[] = {
     nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
     nsIAboutModule::ALLOW_SCRIPT },
   { "sessionrestore", "chrome://browser/content/aboutSessionRestore.xhtml",
     nsIAboutModule::ALLOW_SCRIPT },
 #ifdef MOZ_SERVICES_SYNC
   { "sync-tabs", "chrome://browser/content/aboutSyncTabs.xul",
     nsIAboutModule::ALLOW_SCRIPT },
 #endif
+  { "home", "chrome://browser/content/aboutHome.xhtml",
+    nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
+    nsIAboutModule::ALLOW_SCRIPT },
 };
 static const int kRedirTotal = NS_ARRAY_LENGTH(kRedirMap);
 
 static nsCAutoString
 GetAboutModuleName(nsIURI *aURI)
 {
   nsCAutoString path;
   aURI->GetPath(path);
--- a/browser/components/build/nsModule.cpp
+++ b/browser/components/build/nsModule.cpp
@@ -200,16 +200,17 @@ static const mozilla::Module::ContractID
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "feeds", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "privatebrowsing", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "rights", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "robots", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "sessionrestore", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
 #ifdef MOZ_SERVICES_SYNC
     { NS_ABOUT_MODULE_CONTRACTID_PREFIX "sync-tabs", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
 #endif
+    { NS_ABOUT_MODULE_CONTRACTID_PREFIX "home", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
 #ifndef WINCE
     { NS_PROFILEMIGRATOR_CONTRACTID, &kNS_FIREFOX_PROFILEMIGRATOR_CID },
 #if defined(XP_WIN) && !defined(__MINGW32__)
     { NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "ie", &kNS_WINIEPROFILEMIGRATOR_CID },
 #elif defined(XP_MACOSX)
     { NS_SHELLSERVICE_CONTRACTID, &kNS_SHELLSERVICE_CID },
     { NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "safari", &kNS_SAFARIPROFILEMIGRATOR_CID },
     { NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "macie", &kNS_MACIEPROFILEMIGRATOR_CID },
--- a/browser/components/certerror/content/aboutCertError.css
+++ b/browser/components/certerror/content/aboutCertError.css
@@ -18,16 +18,17 @@
  * Portions created by the Initial Developer are Copyright (C) 2008
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   William Price <bugzilla@mob.rice.edu>
  *   Steven Garrity <steven@silverorange.com>
  *   Henrik Skupin  <mozilla@hskupin.info>
  *   Johnathan Nightingale <johnath@mozilla.com>
+ *   Ehsan Akhgari <ehsan.akhgari@gmail.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -43,17 +44,23 @@
 
 #technicalContentText {
   overflow: auto;
   white-space: pre-wrap;
 }
 
 #technicalContent > h2, #expertContent > h2 {
   cursor: pointer;
-  padding-left: 20px;
+  -moz-padding-start: 20px;
   position: relative;
   left: -20px;
 }
 
+body[dir="rtl"] #technicalContent > h2,
+body[dir="rtl"] #expertContent > h2 {
+  left: auto;
+  right: -20px;
+}
+
 div[collapsed] > p,
 div[collapsed] > div {
   display: none;
 }
--- a/browser/components/certerror/content/aboutCertError.xhtml
+++ b/browser/components/certerror/content/aboutCertError.xhtml
@@ -117,16 +117,23 @@
               replaceWithHost(node.childNodes[i]);
         };
         replaceWithHost(intro);
         
         if (getCSSClass() == "expertBadCert") {
           toggle('technicalContent');
           toggle('expertContent');
         }
+
+        // if this is a Strict-Transport-Security host and the cert
+        // is bad, don't allow overrides (STS Spec section 7.3).
+        if (getCSSClass() == "badStsCert") {
+          var ec = document.getElementById('expertContent');
+          document.getElementById('errorLongContent').removeChild(ec);
+        }
         
         var tech = document.getElementById("technicalContentText");
         if (tech)
           tech.textContent = getDescription();
         
         addDomainErrorLink();
       }
       
--- a/browser/components/nsBrowserContentHandler.js
+++ b/browser/components/nsBrowserContentHandler.js
@@ -32,16 +32,17 @@
 # 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 *****
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource://gre/modules/Services.jsm");
 
 const nsISupports            = Components.interfaces.nsISupports;
 
 const nsIBrowserDOMWindow    = Components.interfaces.nsIBrowserDOMWindow;
 const nsIBrowserHandler      = Components.interfaces.nsIBrowserHandler;
 const nsIBrowserHistory      = Components.interfaces.nsIBrowserHistory;
 const nsIChannel             = Components.interfaces.nsIChannel;
 const nsICommandLine         = Components.interfaces.nsICommandLine;
@@ -60,16 +61,17 @@ const nsISupportsString      = Component
 const nsIURIFixup            = Components.interfaces.nsIURIFixup;
 const nsIWebNavigation       = Components.interfaces.nsIWebNavigation;
 const nsIWindowMediator      = Components.interfaces.nsIWindowMediator;
 const nsIWindowWatcher       = Components.interfaces.nsIWindowWatcher;
 const nsICategoryManager     = Components.interfaces.nsICategoryManager;
 const nsIWebNavigationInfo   = Components.interfaces.nsIWebNavigationInfo;
 const nsIBrowserSearchService = Components.interfaces.nsIBrowserSearchService;
 const nsICommandLineValidator = Components.interfaces.nsICommandLineValidator;
+const nsIXULAppInfo          = Components.interfaces.nsIXULAppInfo;
 
 const NS_BINDING_ABORTED = Components.results.NS_BINDING_ABORTED;
 const NS_ERROR_WONT_HANDLE_CONTENT = 0x805d0001;
 const NS_ERROR_ABORT = Components.results.NS_ERROR_ABORT;
 
 const URI_INHERITS_SECURITY_CONTEXT = nsIHttpProtocolHandler
                                         .URI_INHERITS_SECURITY_CONTEXT;
 
@@ -111,48 +113,65 @@ function resolveURIInternal(aCmdLine, aA
   }
 
   return uri;
 }
 
 const OVERRIDE_NONE        = 0;
 const OVERRIDE_NEW_PROFILE = 1;
 const OVERRIDE_NEW_MSTONE  = 2;
+const OVERRIDE_NEW_BUILD_ID = 3;
 /**
  * Determines whether a home page override is needed.
  * Returns:
  *  OVERRIDE_NEW_PROFILE if this is the first run with a new profile.
  *  OVERRIDE_NEW_MSTONE if this is the first run with a build with a different
  *                      Gecko milestone (i.e. right after an upgrade).
+ *  OVERRIDE_NEW_BUILD_ID if this is the first run with a new build ID of the
+ *                        same Gecko milestone (i.e. after a nightly upgrade).
  *  OVERRIDE_NONE otherwise.
  */
 function needHomepageOverride(prefb) {
   var savedmstone = null;
   try {
     savedmstone = prefb.getCharPref("browser.startup.homepage_override.mstone");
   } catch (e) {}
 
   if (savedmstone == "ignore")
     return OVERRIDE_NONE;
 
   var mstone = Components.classes["@mozilla.org/network/protocol;1?name=http"]
                          .getService(nsIHttpProtocolHandler).misc;
 
+  var savedBuildID = null;
+  try {
+    savedBuildID = prefb.getCharPref("browser.startup.homepage_override.buildID");
+  } catch (e) {}
+
+  var buildID =  Components.classes["@mozilla.org/xre/app-info;1"]
+                           .getService(nsIXULAppInfo).platformBuildID;
+
   if (mstone != savedmstone) {
     // Bug 462254. Previous releases had a default pref to suppress the EULA
     // agreement if the platform's installer had already shown one. Now with
     // about:rights we've removed the EULA stuff and default pref, but we need
     // a way to make existing profiles retain the default that we removed.
     if (savedmstone)
       prefb.setBoolPref("browser.rights.3.shown", true);
     
     prefb.setCharPref("browser.startup.homepage_override.mstone", mstone);
+    prefb.setCharPref("browser.startup.homepage_override.buildID", buildID);
     return (savedmstone ? OVERRIDE_NEW_MSTONE : OVERRIDE_NEW_PROFILE);
   }
 
+  if (buildID != savedBuildID) {
+    prefb.setCharPref("browser.startup.homepage_override.buildID", buildID);
+    return OVERRIDE_NEW_BUILD_ID;
+  }
+
   return OVERRIDE_NONE;
 }
 
 /**
  * Gets the override page for the first run after the application has been
  * updated.
  * @param  defaultOverridePage
  *         The default override page.
@@ -557,34 +576,40 @@ nsBrowserContentHandler.prototype = {
     var prefb = Components.classes["@mozilla.org/preferences-service;1"]
                           .getService(nsIPrefBranch);
     var formatter = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
                               .getService(Components.interfaces.nsIURLFormatter);
 
     var overridePage = "";
     var haveUpdateSession = false;
     try {
-      switch (needHomepageOverride(prefb)) {
-        case OVERRIDE_NEW_PROFILE:
-          // New profile
-          overridePage = formatter.formatURLPref("startup.homepage_welcome_url");
-          break;
-        case OVERRIDE_NEW_MSTONE:
-          // Existing profile, new build
-          copyPrefOverride();
+      let override = needHomepageOverride(prefb);
+      if (override != OVERRIDE_NONE) {
+        // Setup the default search engine to about:home page.
+        AboutHomeUtils.loadDefaultSearchEngine();
 
-          // Check whether we have a session to restore. If we do, we assume
-          // that this is an "update" session.
-          var ss = Components.classes["@mozilla.org/browser/sessionstartup;1"]
-                             .getService(Components.interfaces.nsISessionStartup);
-          haveUpdateSession = ss.doRestore();
-          overridePage = formatter.formatURLPref("startup.homepage_override_url");
-          if (prefb.prefHasUserValue("app.update.postupdate"))
-            overridePage = getPostUpdateOverridePage(overridePage);
-          break;
+        switch (override) {
+          case OVERRIDE_NEW_PROFILE:
+            // New profile.
+            overridePage = formatter.formatURLPref("startup.homepage_welcome_url");
+            break;
+          case OVERRIDE_NEW_MSTONE:
+            // Existing profile, new milestone build.
+            copyPrefOverride();
+
+            // Check whether we have a session to restore. If we do, we assume
+            // that this is an "update" session.
+            var ss = Components.classes["@mozilla.org/browser/sessionstartup;1"]
+                               .getService(Components.interfaces.nsISessionStartup);
+            haveUpdateSession = ss.doRestore();
+            overridePage = formatter.formatURLPref("startup.homepage_override_url");
+            if (prefb.prefHasUserValue("app.update.postupdate"))
+              overridePage = getPostUpdateOverridePage(overridePage);
+            break;
+        }
       }
     } catch (ex) {}
 
     // formatURLPref might return "about:blank" if getting the pref fails
     if (overridePage == "about:blank")
       overridePage = "";
 
     var startPage = "";
@@ -851,10 +876,35 @@ nsDefaultCommandLineHandler.prototype = 
                  "chrome,dialog=no,all" + gBrowserContentHandler.getFeatures(cmdLine),
                  gBrowserContentHandler.defaultArgs, NO_EXTERNAL_URIS);
     }
   },
 
   helpInfo : "",
 };
 
+let AboutHomeUtils = {
+  get _storage() {
+    let aboutHomeURI = Services.io.newURI("moz-safe-about:home", null, null);
+    let principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"].
+                    getService(Components.interfaces.nsIScriptSecurityManager).
+                    getCodebasePrincipal(aboutHomeURI);
+    let dsm = Components.classes["@mozilla.org/dom/storagemanager;1"].
+              getService(Components.interfaces.nsIDOMStorageManager);
+    return dsm.getLocalStorageForPrincipal(principal, "");
+  },
+
+  loadDefaultSearchEngine: function AHU_loadDefaultSearchEngine()
+  {
+    let defaultEngine = Services.search.originalDefaultEngine;
+    let submission = defaultEngine.getSubmission("_searchTerms_");
+    if (submission.postData)
+      throw new Error("Home page does not support POST search engines.");
+    let engine = {
+      name: defaultEngine.name
+    , searchUrl: submission.uri.spec
+    }
+    this._storage.setItem("search-engine", JSON.stringify(engine));
+  }
+};
+
 var components = [nsBrowserContentHandler, nsDefaultCommandLineHandler];
 var NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -220,18 +220,17 @@ BrowserGlue.prototype = {
         Services.obs.removeObserver(this, "places-database-locked");
         this._isPlacesLockedObserver = false;
         break;
       case "places-shutdown":
         if (this._isPlacesShutdownObserver) {
           Services.obs.removeObserver(this, "places-shutdown");
           this._isPlacesShutdownObserver = false;
         }
-        // places-shutdown is fired on profile-before-change, but before
-        // Places executes the last flush and closes connection.
+        // places-shutdown is fired when the profile is about to disappear.
         this._onProfileShutdown();
         break;
       case "idle":
         if (this._idleService.idleTime > BOOKMARKS_BACKUP_IDLE_TIME * 1000)
           this._backupBookmarks();
         break;
       case "distribution-customization-complete":
         Services.obs.removeObserver(this, "distribution-customization-complete");
--- a/browser/components/places/content/bookmarkProperties.js
+++ b/browser/components/places/content/bookmarkProperties.js
@@ -541,17 +541,17 @@ var BookmarkPropertiesPanel = {
    *        the ID of the textbox element whose contents we'll test
    *
    * @returns true if the textbox contains a valid URI string, false otherwise
    */
   _containsValidURI: function BPP__containsValidURI(aTextboxID) {
     try {
       var value = this._element(aTextboxID).value;
       if (value) {
-        var uri = PlacesUIUtils.createFixedURI(value);
+        PlacesUIUtils.createFixedURI(value);
         return true;
       }
     } catch (e) { }
     return false;
   },
 
   /**
    * [New Item Mode] Get the insertion point details for the new item, given
--- a/browser/components/places/content/organizer.css
+++ b/browser/components/places/content/organizer.css
@@ -1,7 +1,3 @@
-#contentTitle {
-  width: 0px;
-}
-
 #searchFilter {
   width: 23em;
 }
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -386,18 +386,17 @@ var PlacesOrganizer = {
              createInstance(Ci.nsIFilePicker);
     fp.init(window, PlacesUIUtils.getString("SelectImport"),
             Ci.nsIFilePicker.modeOpen);
     fp.appendFilters(Ci.nsIFilePicker.filterHTML);
     if (fp.show() != Ci.nsIFilePicker.returnCancel) {
       if (fp.file) {
         var importer = Cc["@mozilla.org/browser/places/import-export-service;1"].
                        getService(Ci.nsIPlacesImportExportService);
-        var file = fp.file.QueryInterface(Ci.nsILocalFile);
-        importer.importHTMLFromFile(file, false);
+        importer.importHTMLFromFile(fp.file, false);
       }
     }
   },
 
   /**
    * Allows simple exporting of bookmarks.
    */
   exportBookmarks: function PO_exportBookmarks() {
--- a/browser/components/places/tests/Makefile.in
+++ b/browser/components/places/tests/Makefile.in
@@ -35,16 +35,17 @@
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 DEPTH		= ../../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
+relativesrcdir = browser/components/places/tests
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= test_browser_places
 
 XPCSHELL_TESTS = unit
 
 DIRS = browser chrome perf
--- a/browser/components/places/tests/unit/bookmarks.glue.json
+++ b/browser/components/places/tests/unit/bookmarks.glue.json
@@ -1,1 +1,1 @@
-{"title":"","id":1,"dateAdded":1233157910552624,"lastModified":1233157955206833,"type":"text/x-moz-place-container","root":"placesRoot","children":[{"title":"Bookmarks Menu","id":2,"parent":1,"dateAdded":1233157910552624,"lastModified":1233157993171424,"type":"text/x-moz-place-container","root":"bookmarksMenuFolder","children":[{"title":"examplejson","id":27,"parent":2,"dateAdded":1233157972101126,"lastModified":1233157984999673,"type":"text/x-moz-place","uri":"http://example.com/"}]},{"index":1,"title":"Bookmarks Toolbar","id":3,"parent":1,"dateAdded":1233157910552624,"lastModified":1233157972101126,"annos":[{"name":"bookmarkProperties/description","flags":0,"expires":4,"mimeType":null,"type":3,"value":"Add bookmarks to this folder to see them displayed on the Bookmarks Toolbar"}],"type":"text/x-moz-place-container","root":"toolbarFolder","children":[{"title":"examplejson","id":26,"parent":3,"dateAdded":1233157972101126,"lastModified":1233157984999673,"type":"text/x-moz-place","uri":"http://example.com/"}]},{"index":2,"title":"Tags","id":4,"parent":1,"dateAdded":1233157910552624,"lastModified":1233157910582667,"type":"text/x-moz-place-container","root":"tagsFolder","children":[]},{"index":3,"title":"Unsorted Bookmarks","id":5,"parent":1,"dateAdded":1233157910552624,"lastModified":1233157911033315,"type":"text/x-moz-place-container","root":"unfiledBookmarksFolder","children":[]}]}
\ No newline at end of file
+{"title":"","id":1,"dateAdded":1233157910552624,"lastModified":1233157955206833,"type":"text/x-moz-place-container","root":"placesRoot","children":[{"title":"Bookmarks Menu","id":2,"parent":1,"dateAdded":1233157910552624,"lastModified":1233157993171424,"type":"text/x-moz-place-container","root":"bookmarksMenuFolder","children":[{"title":"examplejson","id":27,"parent":2,"dateAdded":1233157972101126,"lastModified":1233157984999673,"type":"text/x-moz-place","uri":"http://example.com/"}]},{"index":1,"title":"Bookmarks Toolbar","id":3,"parent":1,"dateAdded":1233157910552624,"lastModified":1233157972101126,"annos":[{"name":"bookmarkProperties/description","flags":0,"expires":4,"mimeType":null,"type":3,"value":"Add bookmarks to this folder to see them displayed on the Bookmarks Toolbar"}],"type":"text/x-moz-place-container","root":"toolbarFolder","children":[{"title":"examplejson","id":26,"parent":3,"dateAdded":1233157972101126,"lastModified":1233157984999673,"type":"text/x-moz-place","uri":"http://example.com/"}]},{"index":2,"title":"Tags","id":4,"parent":1,"dateAdded":1233157910552624,"lastModified":1233157910582667,"type":"text/x-moz-place-container","root":"tagsFolder","children":[]},{"index":3,"title":"Unsorted Bookmarks","id":5,"parent":1,"dateAdded":1233157910552624,"lastModified":1233157911033315,"type":"text/x-moz-place-container","root":"unfiledBookmarksFolder","children":[]},]}
--- a/browser/components/places/tests/unit/head_bookmarks.js
+++ b/browser/components/places/tests/unit/head_bookmarks.js
@@ -40,17 +40,17 @@
 const Ci = Components.interfaces;
 const Cc = Components.classes;
 const Cr = Components.results;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/Services.jsm");
 
 // Import common head.
-let (commonFile = do_get_file("../../test_places/head_common.js", false)) {
+let (commonFile = do_get_file("../../../../../toolkit/components/places/tests/head_common.js", false)) {
   let uri = Services.io.newFileURI(commonFile);
   Services.scriptloader.loadSubScript(uri.spec, this);
 }
 
 // Put any other stuff relative to this test folder below.
 
 
 XPCOMUtils.defineLazyGetter(this, "PlacesUIUtils", function() {
--- a/browser/components/places/tests/unit/test_clearHistory_shutdown.js
+++ b/browser/components/places/tests/unit/test_clearHistory_shutdown.js
@@ -42,42 +42,72 @@
 
 const URIS = [
   "http://a.example1.com/"
 , "http://b.example1.com/"
 , "http://b.example2.com/"
 , "http://c.example3.com/"
 ];
 
-let expirationObserver = {
+const TOPIC_CONNECTION_CLOSED = "places-connection-closed";
+
+let EXPECTED_NOTIFICATIONS = [
+  "places-shutdown"
+, "places-will-close-connection"
+, "places-connection-closing"
+, "places-sync-finished"
+, "places-expiration-finished"
+, "places-sync-finished"
+, "places-connection-closed"
+];
+
+const UNEXPECTED_NOTIFICATIONS = [
+  "xpcom-shutdown"
+];
+
+const URL = "ftp://localhost/clearHistoryOnShutdown/";
+
+let notificationIndex = 0;
+
+let notificationsObserver = {
   observe: function observe(aSubject, aTopic, aData) {
-    print("Finished expiration.");
-    Services.obs.removeObserver(expirationObserver,
-                                PlacesUtils.TOPIC_EXPIRATION_FINISHED);
-  
-    let db = PlacesUtils.history
-                        .QueryInterface(Ci.nsPIPlacesDatabase)
-                        .DBConnection;
+    print("Received notification: " + aTopic);
+
+    // Note that some of these notifications could arrive multiple times, for
+    // example in case of sync, we allow that.
+    if (EXPECTED_NOTIFICATIONS[notificationIndex] != aTopic)
+      notificationIndex++;
+    do_check_eq(EXPECTED_NOTIFICATIONS[notificationIndex], aTopic);
 
-    let stmt = db.createStatement(
-      "SELECT id FROM moz_places_temp WHERE url = :page_url "
-    + "UNION ALL "
-    + "SELECT id FROM moz_places WHERE url = :page_url "
+    if (aTopic != TOPIC_CONNECTION_CLOSED)
+      return;
+
+    getDistinctNotifications().forEach(
+      function (topic) Services.obs.removeObserver(notificationsObserver, topic)
+    );
+
+    print("Looking for uncleared stuff.");
+
+    let stmt = DBConn().createStatement(
+      "SELECT id FROM moz_places WHERE url = :page_url "
     );
 
     try {
       URIS.forEach(function(aUrl) {
         stmt.params.page_url = aUrl;
         do_check_false(stmt.executeStep());
         stmt.reset();
       });
     } finally {
       stmt.finalize();
     }
 
+    // Check cache.
+    do_check_false(cacheExists(URL));
+
     do_test_finished();
   }
 }
 
 let timeInMicroseconds = Date.now() * 1000;
 
 function run_test() {
   do_test_pending();
@@ -99,16 +129,65 @@ function run_test() {
   Services.prefs.setBoolPref("privacy.sanitize.sanitizeOnShutdown", true);
 
   print("Add visits.");
   URIS.forEach(function(aUrl) {
     PlacesUtils.history.addVisit(uri(aUrl), timeInMicroseconds++, null,
                                  PlacesUtils.history.TRANSITION_TYPED,
                                  false, 0);
   });
+  print("Add cache.");
+  storeCache(URL, "testData");
 
-  print("Wait expiration.");
-  Services.obs.addObserver(expirationObserver,
-                           PlacesUtils.TOPIC_EXPIRATION_FINISHED, false);
-  print("Simulate shutdown.");
-  PlacesUtils.history.QueryInterface(Ci.nsIObserver)
-                     .observe(null, TOPIC_GLOBAL_SHUTDOWN, null);
+  print("Simulate and wait shutdown.");
+  getDistinctNotifications().forEach(
+    function (topic)
+      Services.obs.addObserver(notificationsObserver, topic, false)
+  );
+
+  shutdownPlaces();
+}
+
+function getDistinctNotifications() {
+  let ar = EXPECTED_NOTIFICATIONS.concat(UNEXPECTED_NOTIFICATIONS);
+  return [ar[i] for (i in ar) if (ar.slice(0, i).indexOf(ar[i]) == -1)];
 }
+
+function storeCache(aURL, aContent) {
+  let cache = Cc["@mozilla.org/network/cache-service;1"].
+              getService(Ci.nsICacheService);
+  let session = cache.createSession("FTP", Ci.nsICache.STORE_ANYWHERE,
+                                    Ci.nsICache.STREAM_BASED);
+  let cacheEntry =
+    session.openCacheEntry(aURL, Ci.nsICache.ACCESS_READ_WRITE, false);
+
+  cacheEntry.setMetaDataElement("servertype", "0");
+  var oStream = cacheEntry.openOutputStream(0);
+
+  var written = oStream.write(aContent, aContent.length);
+  if (written != aContent.length) {
+    do_throw("oStream.write has not written all data!\n" +
+             "  Expected: " + written  + "\n" +
+             "  Actual: " + aContent.length + "\n");
+  }
+  oStream.close();
+  cacheEntry.close();
+}
+
+function cacheExists(aURL) {
+  let cache = Cc["@mozilla.org/network/cache-service;1"].
+              getService(Ci.nsICacheService);
+  let session = cache.createSession("FTP", Ci.nsICache.STORE_ANYWHERE,
+                                    Ci.nsICache.STREAM_BASED);
+  try {
+    let cacheEntry =
+      session.openCacheEntry(aURL, Ci.nsICache.ACCESS_READ, true);
+  } catch (e) {
+    if (e.result == Cr.NS_ERROR_CACHE_KEY_NOT_FOUND ||
+        e.result == Cr.NS_ERROR_FAILURE)
+      return false;
+ 
+    // Throw the textual error description.
+    do_throw(e);
+  }
+  cacheEntry.close();
+  return true;
+}
--- a/browser/components/preferences/advanced.xul
+++ b/browser/components/preferences/advanced.xul
@@ -63,16 +63,19 @@
 
       <!-- General tab -->
       <preference id="accessibility.browsewithcaret"   name="accessibility.browsewithcaret"   type="bool"/>
       <preference id="accessibility.typeaheadfind"     name="accessibility.typeaheadfind"     type="bool"/>
       <preference id="accessibility.blockautorefresh"  name="accessibility.blockautorefresh"  type="bool"/>
 
       <preference id="general.autoScroll"              name="general.autoScroll"              type="bool"/>
       <preference id="general.smoothScroll"            name="general.smoothScroll"            type="bool"/>
+#ifdef XP_WIN
+      <preference id="gfx.direct2d.disabled"           name="gfx.direct2d.disabled"           type="bool"   inverted="true"/>
+#endif
       <preference id="layout.spellcheckDefault"        name="layout.spellcheckDefault"        type="int"/>
 
 #ifdef HAVE_SHELL_SERVICE
       <preference id="browser.shell.checkDefaultBrowser"
                   name="browser.shell.checkDefaultBrowser"
                   type="bool"/>
 
       <preference id="pref.general.disable_button.default_browser"
@@ -169,16 +172,22 @@
             <checkbox id="useAutoScroll"
                       label="&useAutoScroll.label;"
                       accesskey="&useAutoScroll.accesskey;"
                       preference="general.autoScroll"/>
             <checkbox id="useSmoothScrolling"
                       label="&useSmoothScrolling.label;"
                       accesskey="&useSmoothScrolling.accesskey;"
                       preference="general.smoothScroll"/>
+#ifdef XP_WIN
+            <checkbox id="allowHWAccel"
+                      label="&allowHWAccel.label;"
+                      accesskey="&allowHWAccel.accesskey;"
+                      preference="gfx.direct2d.disabled"/>
+#endif
             <checkbox id="checkSpelling"
                       label="&checkSpelling.label;"
                       accesskey="&checkSpelling.accesskey;"
                       onsyncfrompreference="return gAdvancedPane.readCheckSpelling();"
                       onsynctopreference="return gAdvancedPane.writeCheckSpelling();"
                       preference="layout.spellcheckDefault"/>
           </groupbox>
 
--- a/browser/components/sessionstore/content/aboutSessionRestore.js
+++ b/browser/components/sessionstore/content/aboutSessionRestore.js
@@ -138,16 +138,24 @@ function restoreSession() {
     ss.setWindowState(newWindow, stateString, true);
     
     var tabbrowser = top.gBrowser;
     var tabIndex = tabbrowser.getBrowserIndexForDocument(document);
     tabbrowser.removeTab(tabbrowser.tabs[tabIndex]);
   }, true);
 }
 
+function startNewSession() {
+  var prefBranch = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
+  if (prefBranch.getIntPref("browser.startup.page") == 0)
+    getBrowserWindow().gBrowser.loadURI("about:blank");
+  else
+    getBrowserWindow().BrowserHome();
+}
+
 function onListClick(aEvent) {
   // don't react to right-clicks
   if (aEvent.button == 2)
     return;
   
   var row = {}, col = {};
   treeView.treeBox.getCellAt(aEvent.clientX, aEvent.clientY, row, col, {});
   if (col.value) {
--- a/browser/components/sessionstore/content/aboutSessionRestore.xhtml
+++ b/browser/components/sessionstore/content/aboutSessionRestore.xhtml
@@ -98,18 +98,30 @@
             </treecols>
             <treechildren flex="1"/>
           </tree>
         </div>
       </div>
 
       <!-- Buttons -->
       <hbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" id="buttons">
+#ifdef XP_UNIX
+        <button id="errorCancel" label="&restorepage.cancelButton;"
+                accesskey="&restorepage.cancel.access;"
+                oncommand="startNewSession();"/>
         <button id="errorTryAgain" label="&restorepage.tryagainButton;"
                 accesskey="&restorepage.restore.access;"
                 oncommand="restoreSession();"/>
+#else
+        <button id="errorTryAgain" label="&restorepage.tryagainButton;"
+                accesskey="&restorepage.restore.access;"
+                oncommand="restoreSession();"/>
+        <button id="errorCancel" label="&restorepage.cancelButton;"
+                accesskey="&restorepage.cancel.access;"
+                oncommand="startNewSession();"/>
+#endif
       </hbox>
       <!-- holds the session data for when the tab is closed -->
       <input type="text" id="sessionData" style="display: none;"/>
     </div>
 
   </body>
 </html>
--- a/browser/components/sessionstore/jar.mn
+++ b/browser/components/sessionstore/jar.mn
@@ -1,3 +1,3 @@
 browser.jar:
-    content/browser/aboutSessionRestore.xhtml             (content/aboutSessionRestore.xhtml) 
+*   content/browser/aboutSessionRestore.xhtml             (content/aboutSessionRestore.xhtml) 
 *   content/browser/aboutSessionRestore.js                (content/aboutSessionRestore.js)
--- a/browser/components/sessionstore/src/nsSessionStore.js
+++ b/browser/components/sessionstore/src/nsSessionStore.js
@@ -2073,29 +2073,43 @@ SessionStoreService.prototype = {
       browser.userTypedValue = activePageData ? activePageData.url || null : null;
       
       // keep the data around to prevent dataloss in case
       // a tab gets closed before it's been properly restored
       browser.__SS_data = tabData;
     }
     
     if (aTabs.length > 0) {
+      // Load hidden tabs last, by pushing them to the end of the list
+      let unhiddenTabs = aTabs.length;
+      for (let t = 0; t < unhiddenTabs; ) {
+        if (aTabs[t].hidden) {
+          aTabs = aTabs.concat(aTabs.splice(t, 1));
+          aTabData = aTabData.concat(aTabData.splice(t, 1));
+          if (aSelectTab > t)
+            --aSelectTab;
+          --unhiddenTabs;
+          continue;
+        }
+        ++t;
+      }
+
       // Determine if we can optimize & load visible tabs first
       let maxVisibleTabs = Math.ceil(tabbrowser.tabContainer.mTabstrip.scrollClientSize /
-                                     aTabs[aTabs.length - 1].clientWidth);
+                                     aTabs[unhiddenTabs - 1].clientWidth);
 
       // make sure we restore visible tabs first, if there are enough
-      if (maxVisibleTabs < aTabs.length && aSelectTab > 1) {
+      if (maxVisibleTabs < unhiddenTabs && aSelectTab > 1) {
         let firstVisibleTab = 0;
-        if (aTabs.length - maxVisibleTabs > aSelectTab) {
+        if (unhiddenTabs - maxVisibleTabs > aSelectTab) {
           // aSelectTab is leftmost since we scroll to it when possible
           firstVisibleTab = aSelectTab - 1;
         } else {
           // aSelectTab is rightmost or no more room to scroll right
-          firstVisibleTab = aTabs.length - maxVisibleTabs;
+          firstVisibleTab = unhiddenTabs - maxVisibleTabs;
         }
         aTabs = aTabs.splice(firstVisibleTab, maxVisibleTabs).concat(aTabs);
         aTabData = aTabData.splice(firstVisibleTab, maxVisibleTabs).concat(aTabData);
         aSelectTab -= firstVisibleTab;
       }
 
       // make sure to restore the selected tab first (if any)
       if (aSelectTab-- && aTabs[aSelectTab]) {
--- a/browser/components/sessionstore/test/browser/Makefile.in
+++ b/browser/components/sessionstore/test/browser/Makefile.in
@@ -94,16 +94,17 @@ include $(topsrcdir)/config/rules.mk
 	browser_465215.js \
 	browser_465223.js \
 	browser_466937.js \
 	browser_466937_sample.html \
 	browser_476161.js \
 	browser_476161_sample.html \
 	browser_477657.js \
 	browser_480148.js \
+	browser_480893.js \
 	browser_483330.js \
 	browser_485482.js \
 	browser_485482_sample.html \
 	browser_485563.js \
 	browser_490040.js \
 	browser_491168.js \
 	browser_491577.js \
 	browser_493467.js \
--- a/browser/components/sessionstore/test/browser/browser_480148.js
+++ b/browser/components/sessionstore/test/browser/browser_480148.js
@@ -47,20 +47,26 @@ function browserWindowsCount() {
 function test() {
   /** Test for Bug 484108 **/
   is(browserWindowsCount(), 1, "Only one browser window should be open initially");
 
   let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
   waitForExplicitFinish();
 
   // builds the tests state based on a few parameters
-  function buildTestState(num, selected) {
+  function buildTestState(num, selected, hidden) {
     let state = { windows: [ { "tabs": [], "selected": selected } ] };
-    while (num--)
+    while (num--) {
       state.windows[0].tabs.push({entries: [{url: "http://example.com/"}]});
+      let i = state.windows[0].tabs.length - 1;
+      if (hidden.length > 0 && i == hidden[0]) {
+        state.windows[0].tabs[i].hidden = true;
+        hidden.splice(0, 1);
+      }
+    }
     return state;
   }
 
   // builds an array of the indexs we expect to see in the order they get loaded
   function buildExpectedOrder(num, selected, shown) {
     // assume selected is 1-based index
     selected--;
     let expected = [selected];
@@ -75,27 +81,27 @@ function test() {
       if (expected.indexOf(i) == -1) {
         expected.push(i);
       }
     }
     return expected;
   }
 
   // the number of tests we're running
-  let numTests = 4;
+  let numTests = 6;
   let completedTests = 0;
 
   let tabMinWidth = parseInt(getComputedStyle(gBrowser.selectedTab, null).minWidth);
 
-  function runTest(testNum, totalTabs, selectedTab, shownTabs, order) {
+  function runTest(testNum, totalTabs, selectedTab, shownTabs, hiddenTabs, order) {
     let test = {
       QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMEventListener,
                                              Ci.nsISupportsWeakReference]),
 
-      state: buildTestState(totalTabs, selectedTab),
+      state: buildTestState(totalTabs, selectedTab, hiddenTabs),
       numTabsToShow: shownTabs,
       expectedOrder: order,
       actualOrder: [],
       windowWidth: null,
       callback: null,
       window: null,
 
       handleSSTabRestoring: function (aEvent) {
@@ -152,15 +158,17 @@ function test() {
         this.window.addEventListener("SSTabRestoring", this, false);
         this.window.addEventListener("load", this, false);
       }
     };
     test.run();
   }
 
   // actually create & run the tests
-  runTest(1, 13, 1, 6,  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
-  runTest(2, 13, 13, 6, [12, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6]);
-  runTest(3, 13, 4, 6,  [3, 4, 5, 6, 7, 8, 0, 1, 2, 9, 10, 11, 12]);
-  runTest(4, 13, 11, 6, [10, 7, 8, 9, 11, 12, 0, 1, 2, 3, 4, 5, 6]);
+  runTest(1, 13, 1,  6, [],         [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
+  runTest(2, 13, 13, 6, [],         [12, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6]);
+  runTest(3, 13, 4,  6, [],         [3, 4, 5, 6, 7, 8, 0, 1, 2, 9, 10, 11, 12]);
+  runTest(4, 13, 11, 6, [],         [10, 7, 8, 9, 11, 12, 0, 1, 2, 3, 4, 5, 6]);
+  runTest(5, 13, 13, 6, [0, 4, 9],  [12, 6, 7, 8, 10, 11, 1, 2, 3, 5, 0, 4, 9]);
+  runTest(6, 13, 4,  6, [1, 7, 12], [3, 4, 5, 6, 8, 9, 0, 2, 10, 11, 1, 7, 12]);
 
   // finish() is run by the last test to finish, so no cleanup down here
 }
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser/browser_480893.js
@@ -0,0 +1,90 @@
+/* ***** 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 sessionstore test code.
+ *
+ * The Initial Developer of the Original Code is
+ * Michael Kohler <michaelkohler@live.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 ***** */
+
+function test() {
+  /** Test for Bug 480893 **/
+
+  waitForExplicitFinish();
+
+  // Test that starting a new session loads a blank page if Firefox is
+  // configured to display a blank page at startup (browser.startup.page = 0)
+  gPrefService.setIntPref("browser.startup.page", 0);
+  let tab = gBrowser.addTab("about:sessionrestore");
+  gBrowser.selectedTab = tab;
+  let browser = tab.linkedBrowser;
+  browser.addEventListener("load", function(aEvent) {
+    browser.removeEventListener("load", arguments.callee, true);
+    let doc = browser.contentDocument;
+
+    // click on the "Start New Session" button after about:sessionrestore is loaded
+    doc.getElementById("errorCancel").click();
+    browser.addEventListener("load", function(aEvent) {
+      browser.removeEventListener("load", arguments.callee, true);
+      let doc = browser.contentDocument;
+
+      is(doc.URL, "about:blank", "loaded page is about:blank");
+
+      // Test that starting a new session loads the homepage (set to http://mochi.test:8888)
+      // if Firefox is configured to display a homepage at startup (browser.startup.page = 1)
+      let homepage = "http://mochi.test:8888/";
+      gPrefService.setCharPref("browser.startup.homepage", homepage);
+      gPrefService.setIntPref("browser.startup.page", 1);
+      gBrowser.loadURI("about:sessionrestore");
+      browser.addEventListener("load", function(aEvent) {
+        browser.removeEventListener("load", arguments.callee, true);
+        let doc = browser.contentDocument;
+
+        // click on the "Start New Session" button after about:sessionrestore is loaded
+        doc.getElementById("errorCancel").click();
+        browser.addEventListener("load", function(aEvent) {
+          browser.removeEventListener("load", arguments.callee, true);
+          let doc = browser.contentDocument;
+
+          is(doc.URL, homepage, "loaded page is the homepage");
+
+          // close tab, restore default values and finish the test
+          gBrowser.removeTab(tab);
+          // we need this if-statement because if there is no user set value, 
+          // clearUserPref throws a uncatched exception and finish is not called
+          if (gPrefService.prefHasUserValue("browser.startup.page"))
+            gPrefService.clearUserPref("browser.startup.page");
+          gPrefService.clearUserPref("browser.startup.homepage");
+          finish();
+        }, true);
+      }, true);
+    }, true);
+  }, true);
+}
--- a/browser/confvars.sh
+++ b/browser/confvars.sh
@@ -43,12 +43,12 @@ MOZ_PHOENIX=1
 MOZ_ENABLE_LIBXUL=1
 MOZ_CHROME_FILE_FORMAT=omni
 MOZ_STATIC_BUILD_UNSUPPORTED=1
 # always enabled for form history
 MOZ_MORKREADER=1
 MOZ_SAFE_BROWSING=1
 MOZ_SERVICES_SYNC=1
 MOZ_APP_VERSION=$FIREFOX_VERSION
-MOZ_EXTENSIONS_DEFAULT=" gnomevfs reporter"
+MOZ_EXTENSIONS_DEFAULT=" gnomevfs"
 # MOZ_APP_DISPLAYNAME will be set by branding/configure.sh
 MOZ_BRANDING_DIRECTORY=browser/branding/nightly
 MOZ_OFFICIAL_BRANDING_DIRECTORY=other-licenses/branding/firefox
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -407,17 +407,16 @@
 @BINPATH@/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
 @BINPATH@/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/icon.png
 @BINPATH@/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/preview.png
 #if MOZ_UPDATE_CHANNEL == beta
 @BINPATH@/extensions/testpilot@labs.mozilla.com/*
 #endif
 @BINPATH@/chrome/toolkit@JAREXT@
 @BINPATH@/chrome/toolkit.manifest
-@BINPATH@/@PREF_DIR@/reporter.js
 #ifdef XP_UNIX
 #ifndef XP_MACOSX
 @BINPATH@/chrome/icons/default/default16.png
 @BINPATH@/chrome/icons/default/default32.png
 @BINPATH@/chrome/icons/default/default48.png
 #endif
 #endif
 
--- a/browser/installer/removed-files.in
+++ b/browser/installer/removed-files.in
@@ -69,16 +69,17 @@ components/pluginGlue.js
 components/sidebar.xpt
 components/xmlextras.xpt
 components/xpcom.xpt
 components/xpti.dat
 components/xptitemp.dat
 defaults/pref/all.js
 defaults/pref/bug259708.js
 defaults/pref/bug307259.js
+defaults/pref/reporter.js
 defaults/pref/security-prefs.js
 defaults/pref/winpref.js
 defaults/pref/xpinstall.js
 defaults/profile/US/
 defaults/profile/extensions/
 defaults/profile/extensions/Extensions.rdf
 defaults/profile/extensions/installed-extensions.txt
 defaults/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/
@@ -624,17 +625,16 @@ xpicleanup@BIN_SUFFIX@
   components/Weave.js
   components/WebContentConverter.js
   defaults/autoconfig/platform.js
   defaults/autoconfig/prefcalls.js
   defaults/pref/channel-prefs.js
   defaults/pref/firefox-branding.js
   defaults/pref/firefox.js
   defaults/pref/firefox-l10n.js
-  defaults/pref/reporter.js
   defaults/pref/services-sync.js
   defaults/profile/bookmarks.html
   defaults/profile/chrome/userChrome-example.css
   defaults/profile/chrome/userContent-example.css
   defaults/profile/localstore.rdf
   defaults/profile/mimeTypes.rdf
   defaults/profile/prefs.js
   greprefs.js
@@ -667,16 +667,17 @@ xpicleanup@BIN_SUFFIX@
   modules/openLocationLastURL.jsm
   modules/PerfMeasurement.jsm
   modules/PlacesDBUtils.jsm
   modules/PlacesUIUtils.jsm
   modules/PlacesUtils.jsm
   modules/PluginProvider.jsm
   modules/PluralForm.jsm
   modules/PopupNotifications.jsm
+  modules/PropertyPanel.jsm
   modules/Services.jsm
   modules/services-sync/auth.js
   modules/services-sync/base_records/collection.js
   modules/services-sync/base_records/crypto.js
   modules/services-sync/base_records/keys.js
   modules/services-sync/base_records/wbo.js
   modules/services-sync/constants.js
   modules/services-sync/engines/bookmarks.js
@@ -731,16 +732,19 @@ xpicleanup@BIN_SUFFIX@
   res/entityTables/htmlEntityVersions.properties
   res/entityTables/mathml20.properties
   res/entityTables/transliterate.properties
   res/fonts/mathfont.properties
   res/fonts/mathfontStandardSymbolsL.properties
   res/fonts/mathfontSTIXNonUnicode.properties
   res/fonts/mathfontSTIXSize1.properties
   res/fonts/mathfontSTIXSizeOneSym.properties
+  #ifdef XP_WIN
+    res/fonts/mathfontSymbol.properties
+  #endif
   res/fonts/mathfontUnicode.properties
   res/grabber.gif
   res/html/folder.png
   res/langGroups.properties
   res/language.properties
   res/svg.css
   res/table-add-column-after-active.gif
   res/table-add-column-after.gif
--- a/browser/installer/windows/nsis/defines.nsi.in
+++ b/browser/installer/windows/nsis/defines.nsi.in
@@ -11,17 +11,16 @@
 !define AppUserModelID        "${AppVendor}.${AppName}.${AppVersion}"
 !define GREVersion            @MOZILLA_VERSION@
 !define AB_CD                 "@AB_CD@"
 
 !define FileMainEXE           "@MOZ_APP_NAME@.exe"
 !define WindowClass           "FirefoxMessageWindow"
 !define DDEApplication        "Firefox"
 !define AppRegName            "Firefox"
-!define MinSupportedVer       "Microsoft Windows 2000"
 
 !define BrandShortName        "@MOZ_APP_DISPLAYNAME@"
 !define PreReleaseSuffix      "@PRE_RELEASE_SUFFIX@"
 !define BrandFullName         "${BrandFullNameInternal}${PreReleaseSuffix}"
 
 # LSP_CATEGORIES is the permitted LSP categories for the application. Each LSP
 # category value is ANDed together to set multiple permitted categories.
 # See http://msdn.microsoft.com/en-us/library/ms742253%28VS.85%29.aspx
@@ -33,8 +32,19 @@
 # NO_INSTDIR_FROM_REG is defined for pre-releases which have a PreReleaseSuffix
 # (e.g. Alpha X, Beta X, etc.) to prevent finding a non-default installation
 # directory in the registry and using that as the default. This prevents
 # Beta releases built with official branding from finding an existing install
 # of an official release and defaulting to its installation directory.
 !if "@PRE_RELEASE_SUFFIX@" != ""
 !define NO_INSTDIR_FROM_REG
 !endif
+
+# ARCH is used when it is necessary to differentiate the x64 registry keys from
+# the x86 registry keys (e.g. the uninstall registry key).
+#ifdef HAVE_64BIT_OS
+!define HAVE_64BIT_OS
+!define ARCH "x64"
+!define MinSupportedVer "Microsoft Windows Vista x64"
+#else
+!define ARCH "x86"
+!define MinSupportedVer "Microsoft Windows 2000"
+#endif
--- a/browser/installer/windows/nsis/installer.nsi
+++ b/browser/installer/windows/nsis/installer.nsi
@@ -129,18 +129,21 @@ VIAddVersionKey "OriginalFilename" "setu
 !insertmacro InstallStartCleanupCommon
 !insertmacro LeaveDirectoryCommon
 !insertmacro LeaveOptionsCommon
 !insertmacro OnEndCommon
 !insertmacro PreDirectoryCommon
 
 Name "${BrandFullName}"
 OutFile "setup.exe"
-InstallDirRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${BrandFullNameInternal} (${AppVersion})" "InstallLocation"
-InstallDir "$PROGRAMFILES\${BrandFullName}\"
+!ifdef HAVE_64BIT_OS
+  InstallDir "$PROGRAMFILES64\${BrandFullName}\"
+!else
+  InstallDir "$PROGRAMFILES32\${BrandFullName}\"
+!endif
 ShowInstDetails nevershow
 
 ################################################################################
 # Modern User Interface - MUI
 
 !define MOZ_MUI_CUSTOM_ABORT
 !define MUI_CUSTOMFUNCTION_ABORT "CustomAbort"
 !define MUI_ICON setup.ico
@@ -243,17 +246,17 @@ Section "-Application" APP_IDX
 
   ; Register DLLs
   ; XXXrstrong - AccessibleMarshal.dll can be used by multiple applications but
   ; is only registered for the last application installed. When the last
   ; application installed is uninstalled AccessibleMarshal.dll will no longer be
   ; registered. bug 338878
   ${LogHeader} "DLL Registration"
   ClearErrors
-  RegDLL "$INSTDIR\AccessibleMarshal.dll"
+  ${RegisterDLL} "$INSTDIR\AccessibleMarshal.dll"
   ${If} ${Errors}
     ${LogMsg} "** ERROR Registering: $INSTDIR\AccessibleMarshal.dll **"
   ${Else}
     ${LogUninstall} "DLLReg: \AccessibleMarshal.dll"
     ${LogMsg} "Registered: $INSTDIR\AccessibleMarshal.dll"
   ${EndIf}
 
   ; Write extra files created by the application to the uninstall log so they
@@ -546,17 +549,17 @@ Function CustomAbort
       ClearErrors
       ${GetParameters} $1
       ${GetOptions} "$1" "/UAC:" $2
       ${If} ${Errors}
         Call $0
       ${Else}
         UAC::ExecCodeSegment $0
       ${EndIf}
-      
+
       CustomAbort_finish:
       Return
     ${EndUnless}
   ${EndIf}
 
   MessageBox MB_YESNO|MB_ICONEXCLAMATION "$(MOZ_MUI_TEXT_ABORTWARNING)" \
              IDYES +1 IDNO +2
   Return
@@ -997,18 +1000,17 @@ Function .onInit
   WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" Left   "15"
   WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" Right  "-1"
   WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" Top    "60"
   WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" Bottom "70"
   WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" State  "1"
 
   ; There must always be a core directory.
   ${GetSize} "$EXEDIR\core\" "/S=0K" $R5 $R7 $R8
-  IntOp $R8 $R5 + $R6
-  SectionSetSize ${APP_IDX} $R8
+  SectionSetSize ${APP_IDX} $R5
 
   ; Initialize $hHeaderBitmap to prevent redundant changing of the bitmap if
   ; the user clicks the back button
   StrCpy $hHeaderBitmap ""
 FunctionEnd
 
 Function .onGUIEnd
   ${OnEndCommon}
--- a/browser/installer/windows/nsis/shared.nsh
+++ b/browser/installer/windows/nsis/shared.nsh
@@ -284,17 +284,17 @@
   WriteRegStr HKLM "$0\shell\safemode" "" "$(CONTEXT_SAFE_MODE)"
   WriteRegStr HKLM "$0\shell\safemode\command" "" "$\"$8$\" -safe-mode"
 
   ; Vista Capabilities registry keys
   WriteRegStr HKLM "$0\Capabilities" "ApplicationDescription" "$(REG_APP_DESC)"
   WriteRegStr HKLM "$0\Capabilities" "ApplicationIcon" "$8,0"
   WriteRegStr HKLM "$0\Capabilities" "ApplicationName" "${BrandShortName}"
 
-  WriteRegStr HKLM "$0\Capabilities\FileAssociations" ".htm"   "FirefoxHTML" 
+  WriteRegStr HKLM "$0\Capabilities\FileAssociations" ".htm"   "FirefoxHTML"
   WriteRegStr HKLM "$0\Capabilities\FileAssociations" ".html"  "FirefoxHTML"
   WriteRegStr HKLM "$0\Capabilities\FileAssociations" ".shtml" "FirefoxHTML"
   WriteRegStr HKLM "$0\Capabilities\FileAssociations" ".xht"   "FirefoxHTML"
   WriteRegStr HKLM "$0\Capabilities\FileAssociations" ".xhtml" "FirefoxHTML"
 
   WriteRegStr HKLM "$0\Capabilities\StartMenu" "StartMenuInternet" "$R9"
 
   WriteRegStr HKLM "$0\Capabilities\URLAssociations" "ftp"    "FirefoxURL"
@@ -326,17 +326,17 @@
 ; Add Software\Mozilla\ registry entries (uses SHCTX).
 !macro SetAppKeys
   ${GetLongPath} "$INSTDIR" $8
   StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})\Main"
   ${WriteRegStr2} $TmpVal "$0" "Install Directory" "$8" 0
   ${WriteRegStr2} $TmpVal "$0" "PathToExe" "$8\${FileMainEXE}" 0
 
   StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})\Uninstall"
-  ${WriteRegStr2} $TmpVal "$0" "Description" "${BrandFullNameInternal} (${AppVersion})" 0
+  ${WriteRegStr2} $TmpVal "$0" "Description" "${BrandFullNameInternal} ${AppVersion} (${ARCH} ${AB_CD})" 0
 
   StrCpy $0 "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})"
   ${WriteRegStr2} $TmpVal  "$0" "" "${AppVersion} (${AB_CD})" 0
 
   StrCpy $0 "Software\Mozilla\${BrandFullNameInternal} ${AppVersion}\bin"
   ${WriteRegStr2} $TmpVal "$0" "PathToExe" "$8\${FileMainEXE}" 0
 
   StrCpy $0 "Software\Mozilla\${BrandFullNameInternal} ${AppVersion}\extensions"
@@ -350,43 +350,46 @@
   ${WriteRegStr2} $TmpVal "$0" "" "${GREVersion}" 0
   ${WriteRegStr2} $TmpVal "$0" "CurrentVersion" "${AppVersion} (${AB_CD})" 0
 !macroend
 !define SetAppKeys "!insertmacro SetAppKeys"
 
 ; Add uninstall registry entries. This macro tests for write access to determine
 ; if the uninstall keys should be added to HKLM or HKCU.
 !macro SetUninstallKeys
-  StrCpy $0 "Software\Microsoft\Windows\CurrentVersion\Uninstall\${BrandFullNameInternal} (${AppVersion})"
+  StrCpy $0 "Software\Microsoft\Windows\CurrentVersion\Uninstall\${BrandFullNameInternal} ${AppVersion} (${ARCH} ${AB_CD})"
 
   WriteRegStr HKLM "$0" "${BrandShortName}InstallerTest" "Write Test"
   ${If} ${Errors}
     StrCpy $1 "HKCU"
     SetShellVarContext current  ; Set SHCTX to the current user (e.g. HKCU)
   ${Else}
     StrCpy $1 "HKLM"
     SetShellVarContext all     ; Set SHCTX to all users (e.g. HKLM)
     DeleteRegValue HKLM "$0" "${BrandShortName}InstallerTest"
   ${EndIf}
 
   ${GetLongPath} "$INSTDIR" $8
 
   ; Write the uninstall registry keys
-  ${WriteRegStr2} $1 "$0" "Comments" "${BrandFullNameInternal}" 0
+  ${WriteRegStr2} $1 "$0" "Comments" "${BrandFullNameInternal} ${AppVersion} (${ARCH} ${AB_CD})" 0
   ${WriteRegStr2} $1 "$0" "DisplayIcon" "$8\${FileMainEXE},0" 0
-  ${WriteRegStr2} $1 "$0" "DisplayName" "${BrandFullNameInternal} (${AppVersion})" 0
-  ${WriteRegStr2} $1 "$0" "DisplayVersion" "${AppVersion} (${AB_CD})" 0
+  ${WriteRegStr2} $1 "$0" "DisplayName" "${BrandFullNameInternal} ${AppVersion} (${ARCH} ${AB_CD})" 0
+  ${WriteRegStr2} $1 "$0" "DisplayVersion" "${AppVersion}" 0
   ${WriteRegStr2} $1 "$0" "InstallLocation" "$8" 0
   ${WriteRegStr2} $1 "$0" "Publisher" "Mozilla" 0
   ${WriteRegStr2} $1 "$0" "UninstallString" "$8\uninstall\helper.exe" 0
   ${WriteRegStr2} $1 "$0" "URLInfoAbout" "${URLInfoAbout}" 0
   ${WriteRegStr2} $1 "$0" "URLUpdateInfo" "${URLUpdateInfo}" 0
   ${WriteRegDWORD2} $1 "$0" "NoModify" 1 0
   ${WriteRegDWORD2} $1 "$0" "NoRepair" 1 0
 
+  ${GetSize} "$8" "/S=0K" $R2 $R3 $R4
+  ${WriteRegDWORD2} $1 "$0" "EstimatedSize" $R2 0
+
   ${If} "$TmpVal" == "HKLM"
     SetShellVarContext all     ; Set SHCTX to all users (e.g. HKLM)
   ${Else}
     SetShellVarContext current  ; Set SHCTX to the current user (e.g. HKCU)
   ${EndIf}
 !macroend
 !define SetUninstallKeys "!insertmacro SetUninstallKeys"
 
--- a/browser/installer/windows/nsis/uninstaller.nsi
+++ b/browser/installer/windows/nsis/uninstaller.nsi
@@ -65,16 +65,17 @@ Var TmpVal
 ; The following includes are provided by NSIS.
 !include FileFunc.nsh
 !include LogicLib.nsh
 !include MUI.nsh
 !include WinMessages.nsh
 !include WinVer.nsh
 !include WordFunc.nsh
 
+!insertmacro GetSize
 !insertmacro StrFilter
 !insertmacro WordReplace
 
 !insertmacro un.GetParent
 
 ; The following includes are custom.
 !include branding.nsi
 !include defines.nsi
@@ -128,21 +129,25 @@ VIAddVersionKey "OriginalFilename" "help
 
 !include shared.nsh
 
 ; Helper macros for ui callbacks. Insert these after shared.nsh
 !insertmacro OnEndCommon
 !insertmacro UninstallOnInitCommon
 
 !insertmacro un.OnEndCommon
+!insertmacro un.UninstallUnOnInitCommon
 
 Name "${BrandFullName}"
 OutFile "helper.exe"
-InstallDirRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${BrandFullNameInternal} (${AppVersion})" "InstallLocation"
-InstallDir "$PROGRAMFILES\${BrandFullName}"
+!ifdef HAVE_64BIT_OS
+  InstallDir "$PROGRAMFILES64\${BrandFullName}\"
+!else
+  InstallDir "$PROGRAMFILES32\${BrandFullName}\"
+!endif
 ShowUnInstDetails nevershow
 
 ################################################################################
 # Modern User Interface - MUI
 
 !define MUI_ABORTWARNING
 !define MUI_ICON setup.ico
 !define MUI_UNICON setup.ico
@@ -204,17 +209,17 @@ Section "Uninstall"
   SetDetailsPrint none
 
   ; Delete the app exe to prevent launching the app while we are uninstalling.
   ClearErrors
   ${DeleteFile} "$INSTDIR\${FileMainEXE}"
   ${If} ${Errors}
     ; If the user closed the application it can take several seconds for it to
     ; shut down completely. If the application is being used by another user we
-    ; can still delete the files when the system is restarted. 
+    ; can still delete the files when the system is restarted.
     Sleep 5000
     ${DeleteFile} "$INSTDIR\${FileMainEXE}"
     ClearErrors
   ${EndIf}
 
   ${MUI_INSTALLOPTIONS_READ} $0 "unconfirm.ini" "Field 3" "State"
   ${If} "$0" == "1"
     ${un.DeleteRelativeProfiles} "Mozilla\Firefox"
@@ -566,28 +571,19 @@ FunctionEnd
 ################################################################################
 # Initialization Functions
 
 Function .onInit
   ${UninstallOnInitCommon}
 FunctionEnd
 
 Function un.onInit
-  ${un.GetParent} "$INSTDIR" $INSTDIR
-  ${un.GetLongPath} "$INSTDIR" $INSTDIR
-  ${Unless} ${FileExists} "$INSTDIR\${FileMainEXE}"
-    Abort
-  ${EndUnless}
+  StrCpy $LANGUAGE 0
 
-  StrCpy $LANGUAGE 0
-  ${un.SetBrandNameVars} "$INSTDIR\distribution\setup.ini"
-
-  ; Initialize $hHeaderBitmap to prevent redundant changing of the bitmap if
-  ; the user clicks the back button
-  StrCpy $hHeaderBitmap ""
+  ${un.UninstallUnOnInitCommon}
 
   !insertmacro InitInstallOptionsFile "unconfirm.ini"
 FunctionEnd
 
 Function .onGUIEnd
   ${OnEndCommon}
 FunctionEnd
 
--- a/browser/locales/Makefile.in
+++ b/browser/locales/Makefile.in
@@ -182,17 +182,16 @@ libs:: $(addsuffix .xml,$(SEARCH_PLUGINS
 install:: $(addsuffix .xml,$(SEARCH_PLUGINS))
 	$(SYSINSTALL) $(IFLAGS1) $^ $(DESTDIR)$(mozappdir)/searchplugins
 
 
 libs-%:
 	$(NSINSTALL) -D $(DIST)/install
 	@$(MAKE) -C ../../toolkit/locales libs-$* BOTH_MANIFESTS=1
 	@$(MAKE) -C ../../services/sync/locales AB_CD=$* XPI_NAME=locale-$* BOTH_MANIFESTS=1
-	@$(MAKE) -C ../../extensions/reporter/locales libs AB_CD=$* XPI_NAME=locale-$* BOTH_MANIFESTS=1
 	@$(MAKE) -C ../../extensions/spellcheck/locales AB_CD=$* XPI_NAME=locale-$* BOTH_MANIFESTS=1
 	@$(MAKE) libs AB_CD=$* XPI_NAME=locale-$* PREF_DIR=defaults/pref BOTH_MANIFESTS=1
 	@$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales AB_CD=$* XPI_NAME=locale-$* BOTH_MANIFESTS=1
 
 
 repackage-win32-installer: WIN32_INSTALLER_OUT="$(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe"
 repackage-win32-installer: $(WIN32_INSTALLER_IN) $(SUBMAKEFILES)
 	@echo "Repackaging $(WIN32_INSTALLER_IN) into $(WIN32_INSTALLER_OUT)."
new file mode 100644
--- /dev/null
+++ b/browser/locales/en-US/chrome/browser/aboutHome.dtd
@@ -0,0 +1,20 @@
+<!ENTITY % brandDTD
+    SYSTEM "chrome://branding/locale/brand.dtd">
+  %brandDTD;
+
+<!-- These strings are used in the about:home page -->
+
+<!ENTITY abouthome.pageTitle "&brandFullName; Start Page">
+<!ENTITY abouthome.brandLogo.title "&brandFullName; logo">
+
+<!-- LOCALIZATION NOTE (brandStart): brandShortName must be in a <span/> -->
+<!ENTITY abouthome.brandStart "<span>&brandShortName;</span> Start">
+
+<!ENTITY abouthome.searchEngineLogo.title "Search engine logo">
+
+<!ENTITY abouthome.searchEngineButton.label "Search">
+
+<!ENTITY abouthome.searchEngineLinks.advanced "Advanced Search">
+<!ENTITY abouthome.searchEngineLinks.preferences "Preferences">
+
+<!ENTITY abouthome.aboutMozilla "About Mozilla">
--- a/browser/locales/en-US/chrome/browser/aboutSessionRestore.dtd
+++ b/browser/locales/en-US/chrome/browser/aboutSessionRestore.dtd
@@ -5,13 +5,15 @@
 <!ENTITY restorepage.errorTitle     "Well, this is embarrassing.">
 <!ENTITY restorepage.problemDesc    "&brandShortName; is having trouble recovering your windows and tabs. This is usually caused by a recently opened web page.">
 <!ENTITY restorepage.tryThis        "You can try:">
 <!ENTITY restorepage.restoreSome    "Removing one or more tabs that you think may be causing the problem">
 <!ENTITY restorepage.startNew       "Starting an entirely new browsing session">
 
 <!ENTITY restorepage.tryagainButton "Restore">
 <!ENTITY restorepage.restore.access "R">
+<!ENTITY restorepage.cancelButton   "Start New Session">
+<!ENTITY restorepage.cancel.access  "S">
 
 <!ENTITY restorepage.restoreHeader  "Restore">
 <!ENTITY restorepage.listHeader     "Windows and Tabs">
 <!-- LOCALIZATION NOTE: &#37;S will be replaced with a number. -->
 <!ENTITY restorepage.windowLabel    "Window &#37;S">
--- a/browser/locales/en-US/chrome/browser/baseMenuOverlay.dtd
+++ b/browser/locales/en-US/chrome/browser/baseMenuOverlay.dtd
@@ -19,16 +19,19 @@
 <!ENTITY helpMac.commandkey       "?">
 
 <!ENTITY helpReleaseNotes.label         "Release Notes">
 <!ENTITY helpReleaseNotes.accesskey     "N">
 
 <!ENTITY helpTroubleshootingInfo.label      "Troubleshooting Information">
 <!ENTITY helpTroubleshootingInfo.accesskey  "T">
 
+<!ENTITY helpFeedbackPage.label      "Submit Feedback…">
+<!ENTITY helpFeedbackPage.accesskey  "S">
+
 <!ENTITY updateCmd.label                "Check for Updates…">
 
 <!ENTITY preferencesCmdMac.label        "Preferences…">
 <!ENTITY preferencesCmdMac.commandkey   ",">
 
 <!ENTITY servicesMenuMac.label          "Services">
 
 <!ENTITY hideThisAppCmdMac.label        "Hide &brandShortName;">
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -186,22 +186,22 @@
 <!ENTITY inspectButton.accesskey      "I">
 <!ENTITY inspectNextButton.label      "Next">
 <!ENTITY inspectNextButton.accesskey  "N">
 <!ENTITY inspectPreviousButton.label  "Previous">
 <!ENTITY inspectPreviousButton.accesskey "P">
 <!ENTITY inspectStyleButton.label     "Style">
 <!ENTITY inspectStyleButton.accesskey "S">
 <!ENTITY inspectStylePanelTitle.label  "Style">
-<!-- LOCALIZATION NOTE (inspectDOMButton.label): This button label
-  -  stands for Document Object Model and appears on the inspector's toolbar.
-  -  It is used to open and closed the DOM panel. There is also a DOM label in
-  -  inspector.properties for the panel titlebar. -->
-<!ENTITY inspectDOMButton.label       "DOM">
-<!ENTITY inspectDOMButton.accesskey       "D">
+<!-- LOCALIZATION NOTE (inspectObjectButton.label): This button label
+  -  appears on the Inspector's toolbar. It is used to open and close the Object
+  -  panel. There is also a label in inspector.properties for the panel
+  -  titlebar: object.objectPanelTitle. -->
+<!ENTITY inspectObjectButton.label       "Object">
+<!ENTITY inspectObjectButton.accesskey   "O">
 
 <!ENTITY fileMenu.label         "File"> 
 <!ENTITY fileMenu.accesskey       "F">
 <!ENTITY newNavigatorCmd.label        "New Window">
 <!ENTITY newNavigatorCmd.key        "N">
 <!ENTITY newNavigatorCmd.accesskey      "N">
 
 <!ENTITY editMenu.label         "Edit"> 
--- a/browser/locales/en-US/chrome/browser/inspector.properties
+++ b/browser/locales/en-US/chrome/browser/inspector.properties
@@ -5,13 +5,12 @@ style.selectorLabel=Selector
 # LOCALIZATION NOTE  (style.inheritedFrom): used in Style panel in
 #  inspector. Describes which tagname[#id] the properties are inherited from.
 style.inheritedFrom=Inherited from: #1
 
 # LOCALIZATION NOTE (style.styleItemLabel): used in Style panel in inspector.
 #  Used for construction of list items, #1 = label, #2 = content.
 style.styleItemLabel=#1: #2
 
-# LOCALIZATION NOTE (dom.domPanelTitle): used in DOM Panel in inspector.
-#  Stands for "Document Object Model". Also referenced in in browser.dtd
-#  and used as a button title.
-#  Unsure if this localizes well, but including just in case
-dom.domPanelTitle=DOM
+# LOCALIZATION NOTE (object.objectPanelTitle): used in the Object Panel in the
+#  Inspector tool. There's also inspectObjectButton in browser.dtd for the
+#  toolbar button which allows users to open/close the Object panel.
+object.objectPanelTitle=Object
--- a/browser/locales/en-US/chrome/browser/preferences/advanced.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/advanced.dtd
@@ -12,16 +12,18 @@
 <!ENTITY blockAutoRefresh.accesskey      "b">
 
 <!ENTITY browsing.label                  "Browsing">
 
 <!ENTITY useAutoScroll.label             "Use autoscrolling">
 <!ENTITY useAutoScroll.accesskey         "a">
 <!ENTITY useSmoothScrolling.label        "Use smooth scrolling">
 <!ENTITY useSmoothScrolling.accesskey    "m">
+<!ENTITY allowHWAccel.label              "Use hardware acceleration when available">
+<!ENTITY allowHWAccel.accesskey          "h">
 <!ENTITY checkSpelling.label             "Check my spelling as I type">
 <!ENTITY checkSpelling.accesskey         "t">
 
 <!ENTITY systemDefaults.label            "System Defaults">
 <!ENTITY alwaysCheckDefault.label        "Always check to see if &brandShortName; is the default browser on startup"><!--XXX-->
 <!ENTITY alwaysCheckDefault.accesskey    "w">
 <!ENTITY checkNow.label                  "Check Now">
 <!ENTITY checkNow.accesskey              "N">
--- a/browser/locales/jar.mn
+++ b/browser/locales/jar.mn
@@ -1,16 +1,17 @@
 #filter substitution
 
 @AB_CD@.jar:
 % locale browser @AB_CD@ %locale/browser/
     locale/browser/aboutCertError.dtd              (%chrome/browser/aboutCertError.dtd)
     locale/browser/aboutDialog.dtd                 (%chrome/browser/aboutDialog.dtd)
     locale/browser/aboutPrivateBrowsing.dtd        (%chrome/browser/aboutPrivateBrowsing.dtd)
     locale/browser/aboutRobots.dtd                 (%chrome/browser/aboutRobots.dtd)
+    locale/browser/aboutHome.dtd                   (%chrome/browser/aboutHome.dtd)
     locale/browser/aboutSessionRestore.dtd         (%chrome/browser/aboutSessionRestore.dtd)
 #ifdef MOZ_SERVICES_SYNC
     locale/browser/aboutSyncTabs.dtd               (%chrome/browser/aboutSyncTabs.dtd)
 #endif
     locale/browser/credits.dtd                     (%chrome/browser/credits.dtd)
 *   locale/browser/browser.dtd                     (%chrome/browser/browser.dtd)
     locale/browser/baseMenuOverlay.dtd             (%chrome/browser/baseMenuOverlay.dtd)
     locale/browser/browser.properties              (%chrome/browser/browser.properties)
new file mode 100644
--- /dev/null
+++ b/browser/themes/browserShared.inc
@@ -0,0 +1,3 @@
+%filter substitution
+
+%define primaryToolbarButtons #back-button, #forward-button, #reload-button, #stop-button, #home-button, #print-button, #downloads-button, #history-button, #bookmarks-button, #bookmarks-menu-button, #new-tab-button, #new-window-button, #cut-button, #copy-button, #paste-button, #fullscreen-button
--- a/browser/themes/gnomestripe/browser/aboutCertError.css
+++ b/browser/themes/gnomestripe/browser/aboutCertError.css
@@ -18,16 +18,17 @@
  * Portions created by the Initial Developer are Copyright (C) 2008
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   William Price <bugzilla@mob.rice.edu>
  *   Steven Garrity <steven@silverorange.com>
  *   Henrik Skupin  <mozilla@hskupin.info>
  *   Johnathan Nightingale <johnath@mozilla.com>
+ *   Ehsan Akhgari <ehsan.akhgari@gmail.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -84,12 +85,22 @@ body[dir="rtl"] #errorPageContainer {
 #errorLongContent {
   -moz-margin-start: 80px;
 }
 
 #technicalContent > h2, #expertContent > h2 {
   background : url("chrome://browser/skin/section_expanded.png") left 0 no-repeat;
 }
 
+body[dir="rtl"] #technicalContent > h2,
+body[dir="rtl"] #expertContent > h2 {
+  background-position: right 0;
+}
+
 #technicalContent[collapsed] > h2,
 #expertContent[collapsed] > h2{
   background-image: url("chrome://browser/skin/section_collapsed.png");
 }
+
+body[dir="rtl"] #technicalContent[collapsed] > h2,
+body[dir="rtl"] #expertContent[collapsed] > h2 {
+  background-image: url("chrome://browser/skin/section_collapsed-rtl.png");
+}
--- a/browser/themes/gnomestripe/browser/browser.css
+++ b/browser/themes/gnomestripe/browser/browser.css
@@ -43,16 +43,18 @@
  * ***** END LICENSE BLOCK ***** */
 %endif
 
 @import url("chrome://global/skin/");
 
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 @namespace html url("http://www.w3.org/1999/xhtml");
 
+%include ../../browserShared.inc
+
 #menubar-items {
   -moz-box-orient: vertical; /* for flex hack */
 }
 
 #main-menubar {
   -moz-box-flex: 1; /* make menu items expand to fill toolbar height */
 }
 
@@ -61,16 +63,21 @@
 }
 
 #navigator-toolbox[inFullscreen="true"],
 #navigator-toolbox[inFullscreen="true"] > #nav-bar {
   border-top: none;
   padding-top: 0;
 }
 
+#browser-bottombox:not([lwthemefooter="true"]) {
+  /* opaque for layers optimization */
+  background-color: -moz-Dialog;
+}
+
 #urlbar:-moz-lwtheme:not([focused="true"]),
 .searchbar-textbox:-moz-lwtheme:not([focused="true"]),
 .tabbrowser-tab:-moz-lwtheme:not([selected="true"]) {
   opacity: .85;
 }
 
 .tabbrowser-tab:-moz-lwtheme {
   text-shadow: none;
@@ -476,32 +483,33 @@ menuitem:not([type]) {
   list-style-image: url("moz-icon://stock/gtk-about?size=menu");
 }
 
 #javascriptConsole {
   list-style-image: url("chrome://global/skin/console/console.png");
 }
 
 /* Primary toolbar buttons */
-.toolbarbutton-1 {
+.toolbarbutton-1:not([type="menu-button"]) {
   -moz-box-orient: vertical;
   min-width: 0;
   list-style-image: url("chrome://browser/skin/Toolbar.png");
 }
 
 .toolbarbutton-1 > .toolbarbutton-icon {
-  -moz-margin-end: 0px;
+  -moz-margin-end: 0;
 }
 
-toolbar[mode="full"] .toolbarbutton-1,
-toolbar[mode="full"] .toolbarbutton-menubutton-button {
+toolbar[mode="full"] .toolbarbutton-1:not([type="menu-button"]),
+toolbar[mode="full"] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
   min-width: 57px;
 }
 
-.toolbarbutton-1, .toolbarbutton-menubutton-button {
+.toolbarbutton-1:not([type="menu-button"]),
+.toolbarbutton-1 > .toolbarbutton-menubutton-button {
   padding: 5px;
 }
 
 .toolbarbutton-1[checked="true"] {
   padding: 5px !important;
 }
 
 /* Put the unified dropdown button on a diet */
@@ -624,17 +632,17 @@ toolbar[mode="full"] .toolbarbutton-menu
   list-style-image: url("moz-icon://stock/gtk-paste?size=toolbar&state=disabled");
 }
 
 #fullscreen-button {
   list-style-image: url("moz-icon://stock/gtk-fullscreen?size=toolbar");
 }
 
 /* 16px primary toolbar buttons */
-toolbar[iconsize="small"] .toolbarbutton-1 {
+toolbar[iconsize="small"] .toolbarbutton-1:not([type="menu-button"]) {
   -moz-box-orient: vertical;
   min-width: 0;
   list-style-image: url("chrome://browser/skin/Toolbar-small.png");
 }
 
 toolbar[iconsize="small"] .toolbarbutton-1[type="menu-button"] {
   border: 0 !important;
 }
@@ -1072,17 +1080,17 @@ toolbar[iconsize="small"] #fullscreen-bu
 .ac-extra > .ac-comment {
   font-size: inherit;
 }
 
 .ac-url-text {
   color: -moz-nativehyperlinktext;
 }
 
-richlistitem[type="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
+richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
   list-style-image: url("chrome://browser/skin/actionicon-tab.png");
 }
 
 .autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
   color: GrayText;
 }
 
 .ac-comment[selected="true"], .ac-url-text[selected="true"] {
@@ -1223,17 +1231,17 @@ statusbarpanel#statusbar-display {
   height: 16px;
   -moz-margin-start: 1px;
   -moz-margin-end: 4px;
   list-style-image: url("chrome://global/skin/icons/folder-item.png");
   -moz-image-region: rect(0px, 16px, 16px, 0px);
 }
 
 .tabbrowser-tab[pinned] > .tab-icon-image {
-  margin: 2px 0 0;
+  margin: 2px 2px 0;
 }
 
 .tabbrowser-tab[busy] > .tab-icon-image {
   list-style-image: url("chrome://browser/skin/tabbrowser/progress.png") !important;
   -moz-image-region: rect(0, 16px, 16px, 0);
 }
 .tabbrowser-tab[busy][stalled] > .tab-icon-image {
   list-style-image: url("chrome://browser/skin/tabbrowser/progress-pulsing.png") !important;
--- a/browser/themes/gnomestripe/browser/jar.mn
+++ b/browser/themes/gnomestripe/browser/jar.mn
@@ -23,16 +23,17 @@ browser.jar:
   skin/classic/browser/monitor_16-10.png
 * skin/classic/browser/pageInfo.css
   skin/classic/browser/pageInfo.png
   skin/classic/browser/page-livemarks.png
   skin/classic/browser/Privacy-16.png
   skin/classic/browser/Privacy-48.png
   skin/classic/browser/searchbar.css                  (searchbar.css)
   skin/classic/browser/section_collapsed.png
+  skin/classic/browser/section_collapsed-rtl.png
   skin/classic/browser/section_expanded.png
   skin/classic/browser/Secure.png
   skin/classic/browser/Security-broken.png
   skin/classic/browser/setDesktopBackground.css
   skin/classic/browser/Toolbar.png
   skin/classic/browser/Toolbar-small.png
   skin/classic/browser/urlbar-favicon-glow.png
   skin/classic/browser/feeds/feedIcon.png             (feeds/feedIcon.png)
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..84ba18c0a388d48a4aa3e8782f151cb69e20936e
GIT binary patch
literal 791
zc$@(j1L*vTP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0006eX+uL$Nkc;*
zP;zf(X>4Tx0C?K1(mQBVQ5eAS|4ooaln^i#?36*OLX?;U+C@m4hfNw|NK*2cOzusS
zXmWGC_a;7Ys30y*f{&pH4l0d^f`b(-Se#r0rJzANIO|yGA|(#jlMGT_{NTXve0-e8
zcMjOUl{Kwt16r!7XHL(03dNFVtj}I-I5>o>EF0QPI-O+K*#3+JuyMSsY0byCmv6q^
z>?LlUdwS#UhW90Z52s!zmO%0X?waKg;I3HC0q#qtW`a})+;Y9FfOHM;>bXo9q!qwf
zv-}!xRxG~<oL#wQg473ms?t!w<^ZOZsv(0d1k@EnZh>tD_}*%@6|mm{j>?*Df_)7*
zTqu@2){&Qgz?lh<f}>pE1w6>W_{CA~$SD}_!P@mvZmW+3NCzFpV!#i8v~Lym+#3wG
z@-TJ`cD@V-KUW8XohM-b3hUc)NALdbmn40Ff6c8sTXXni3hidAF97(Uw*<Km1ef6X
zI!xY&18*Q5f?Nn&ARva-L+c$Q(PYve^iAbs>A5ifH(Je(*vAFzS1YNrzy$Eo=w_qB
zi;Y-ZSSd&5g|F7bsbP&C%Ltz@C(^=Ibs;OPnX|*1su9hO*2(3C^-g9%_(FSrSg%wg
z!}F-kR8qKM#&g0%h>|3UpCCS_$P**Y9AU8jAAsu_Je)k4$YkF=di6(7%<5$mAl%lj
z=#5(4^vq~lv+DK4Rr!S1<M;Wd`2}L;u1b6y1;hXV00v@9M??Vs0RI60puMM)00009
za7bBm000XU000XU0RWnu7ytkO2XskIMF-gh6Ac+RSj-Os0001TNkl<ZILl*T7zOkJ
zzdv36|M_zA|91yu|D(&X5YqVL;RJ@y=e%&LVIfx|P6NK(@B2@TMi^j17vNGXV&vAI
z&A`l~O_Tvxy}&N&!N|bC!0_|+j{iR%PGI=^<tk;d@bmSK{~ynIV2uTm4H|~26ae(l
VH*@=`>P`Rv002ovPDHLkV1i>OZ)*Sm
--- a/browser/themes/pinstripe/browser/aboutCertError.css
+++ b/browser/themes/pinstripe/browser/aboutCertError.css
@@ -18,16 +18,17 @@
  * Portions created by the Initial Developer are Copyright (C) 2008
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   William Price <bugzilla@mob.rice.edu>
  *   Steven Garrity <steven@silverorange.com>
  *   Henrik Skupin  <mozilla@hskupin.info>
  *   Johnathan Nightingale <johnath@mozilla.com>
+ *   Ehsan Akhgari <ehsan.akhgari@gmail.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -84,12 +85,22 @@ body[dir="rtl"] #errorPageContainer {
 #errorLongContent {
   -moz-margin-start: 80px;
 }
 
 #technicalContent > h2, #expertContent > h2 {
   background : url("chrome://browser/skin/section_expanded.png") left 0 no-repeat;
 }
 
+body[dir="rtl"] #technicalContent > h2,
+body[dir="rtl"] #expertContent > h2 {
+  background-position: right 0;
+}
+
 #technicalContent[collapsed] > h2,
 #expertContent[collapsed] > h2{
   background-image: url("chrome://browser/skin/section_collapsed.png");
 }
+
+body[dir="rtl"] #technicalContent[collapsed] > h2,
+body[dir="rtl"] #expertContent[collapsed] > h2 {
+  background-image: url("chrome://browser/skin/section_collapsed-rtl.png");
+}
--- a/browser/themes/pinstripe/browser/browser.css
+++ b/browser/themes/pinstripe/browser/browser.css
@@ -285,147 +285,145 @@ toolbarbutton.bookmark-item > menupopup 
 }
 
 #BMB_unsortedBookmarksFolderMenu {
   list-style-image: url("chrome://browser/skin/places/unfiledBookmarks.png");
 }
 
 /* ----- PRIMARY TOOLBAR BUTTONS ----- */
 
-.toolbarbutton-1,
-#restore-button,
-toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-button,
-toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-dropmarker {
-  margin: 0;
+.toolbarbutton-1:not([type="menu-button"]),
+.toolbarbutton-1 > .toolbarbutton-menubutton-button,
+.toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker,
+#restore-button {
   -moz-box-orient: vertical;
   padding: 0 3px;
   height: 22px;
   border: 1px solid @toolbarbuttonBorderColor@;
   -moz-border-radius: @toolbarbuttonCornerRadius@;
   -moz-box-shadow: 0 1px rgba(255, 255, 255, 0.2);
   background: @toolbarbuttonBackground@;
   background-origin: border-box;
 }
 
+.toolbarbutton-1 > .toolbarbutton-menubutton-button,
+.toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
+  margin: 0;
+}
+
+.toolbarbutton-1,
+#restore-button {
+  margin: 0 4px;
+  list-style-image: url("chrome://browser/skin/Toolbar.png");
+}
+
 toolbar:not([mode="icons"]) .toolbarbutton-1:not([type="menu-button"]),
-toolbar:not([mode="icons"]) #restore-button,
-toolbar:not([mode="icons"]) toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-button,
-toolbar:not([mode="icons"]) toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-dropmarker {
+toolbar:not([mode="icons"]) .toolbarbutton-1 > .toolbarbutton-menubutton-button,
+toolbar:not([mode="icons"]) .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker,
+toolbar:not([mode="icons"]) #restore-button {
   padding: 0;
   height: auto;
   border: none;
   -moz-box-shadow: none;
   background: none;
 }
 
 .toolbarbutton-1:not([type="menu-button"]),
-#restore-button,
-toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-button {
+.toolbarbutton-1 > .toolbarbutton-menubutton-button,
+#restore-button {
   min-width: 28px;
 }
 
 toolbar:not([mode="icons"]) .toolbarbutton-1:not([type="menu-button"]),
-toolbar:not([mode="icons"]) #restore-button,
-toolbar:not([mode="icons"]) toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-button {
+toolbar:not([mode="icons"]) .toolbarbutton-1 > .toolbarbutton-menubutton-button,
+toolbar:not([mode="icons"]) #restore-button {
   min-width: 0;
 }
 
 .toolbarbutton-1 > .toolbarbutton-icon,
-#restore-button > .toolbarbutton-icon,
-toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-button > .toolbarbutton-icon {
+.toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
+#restore-button > .toolbarbutton-icon {
   padding: 0;
   height: 20px;
   width: 20px;
 }
 
 .toolbarbutton-1[disabled="true"] > .toolbarbutton-icon,
-#restore-button[disabled="true"] > .toolbarbutton-icon,
-toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-button[disabled="true"] > .toolbarbutton-icon {
+.toolbarbutton-1[type="menu-button"] > .toolbarbutton-menubutton-button[disabled="true"] > .toolbarbutton-icon,
+#restore-button[disabled="true"] > .toolbarbutton-icon {
   opacity: .4;
 }
 
-.toolbarbutton-1,
-#restore-button,
-toolbarbutton[type="menu-button"] {
-  margin: 0 4px;
-}
-
-.toolbarbutton-1,
-#restore-button {
-  list-style-image: url("chrome://browser/skin/Toolbar.png");
-}
-
-toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-dropmarker {
+.toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
   list-style-image: url(chrome://browser/skin/toolbarbutton-dropmarker.png);
   width: 14px;
   padding-top: 2px;
   -moz-border-start: none !important;
 }
 
-toolbar:not([mode="icons"]) toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-dropmarker {
+toolbar:not([mode="icons"]) .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
   width: auto;
   padding-top: 0;
 }
 
-toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-button:-moz-locale-dir(rtl),
-toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-dropmarker:-moz-locale-dir(ltr) {
+.toolbarbutton-1 > .toolbarbutton-menubutton-button:-moz-locale-dir(rtl),
+.toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:-moz-locale-dir(ltr) {
   -moz-border-radius-topleft: 0;
   -moz-border-radius-bottomleft: 0;
 }
 
-toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-button:-moz-locale-dir(ltr),
-toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-dropmarker:-moz-locale-dir(rtl) {
+.toolbarbutton-1 > .toolbarbutton-menubutton-button:-moz-locale-dir(ltr),
+.toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:-moz-locale-dir(rtl) {
   -moz-border-radius-topright: 0;
   -moz-border-radius-bottomright: 0;
 }
 
-toolbar:not([mode="icons"]) toolbarbutton[type="menu-button"]:not([open="true"]) > .toolbarbutton-menubutton-dropmarker {
+toolbar:not([mode="icons"]) .toolbarbutton-1:not([open="true"]) > .toolbarbutton-menubutton-dropmarker {
   opacity: .7;
 }
 
 .toolbarbutton-1 > .toolbarbutton-text,
-toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-button > .toolbarbutton-text {
+.toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-text {
   margin: 2px 0 0;
 }
 
 toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]):not([disabled="true"]):active:hover,
-toolbar[mode="icons"] #restore-button:not([disabled="true"]):active:hover,
 toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"])[open="true"],
-toolbar[mode="icons"] toolbarbutton[type="menu-button"]:not([disabled="true"]) > .toolbarbutton-menubutton-button:active:hover,
-toolbar[mode="icons"] toolbarbutton[type="menu-button"][open="true"] > .toolbarbutton-menubutton-dropmarker {
+toolbar[mode="icons"] .toolbarbutton-1:not([disabled="true"]) > .toolbarbutton-menubutton-button:active:hover,
+toolbar[mode="icons"] .toolbarbutton-1[open="true"] > .toolbarbutton-menubutton-dropmarker,
+toolbar[mode="icons"] #restore-button:not([disabled="true"]):active:hover {
   background: @toolbarbuttonPressedBackgroundColor@;
   text-shadow: @loweredShadow@;
   -moz-box-shadow: @toolbarbuttonPressedInnerShadow@, @loweredShadow@;
 }
 
 toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]):not(#fullscreen-button)[checked="true"] {
   background: #606060;
   -moz-box-shadow: inset #2A2A2A 0 3px 5px, @loweredShadow@;
 }
 
 toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]):not(#fullscreen-button)[checked="true"]:not([disabled="true"]):active:hover {
   background: #4E4E4E;
   -moz-box-shadow: inset #1c1c1c 0 3px 5px;
 }
 
 toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]):-moz-window-inactive,
-toolbar[mode="icons"] #restore-button:-moz-window-inactive,
-toolbar[mode="icons"] toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-button:-moz-window-inactive,
-toolbar[mode="icons"] toolbarbutton[type="menu-button"] > .toolbarbutton-menubutton-dropmarker:-moz-window-inactive {
+toolbar[mode="icons"] .toolbarbutton-1 > .toolbarbutton-menubutton-button:-moz-window-inactive,
+toolbar[mode="icons"] .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:-moz-window-inactive,
+toolbar[mode="icons"] #restore-button:-moz-window-inactive {
   border-color: @toolbarbuttonInactiveBorderColor@;
   background-image: @toolbarbuttonInactiveBackgroundImage@;
 }
 
 toolbar[mode="icons"] .toolbarbutton-1:not([type="menu-button"]):not(#fullscreen-button)[checked="true"]:-moz-window-inactive {
   background: #8E8E8E;
   -moz-box-shadow: inset rgba(0, 0, 0, 0.5) 0 3px 5px, @loweredShadow@;
 }
 
-toolbar[mode="icons"] .toolbarbutton-1 > menupopup,
-toolbar[mode="icons"] toolbarbutton[type="menu-button"] > menupopup {
+toolbar[mode="icons"] .toolbarbutton-1 > menupopup {
   margin-top: 1px;
 }
 
 /* unified back/forward button */
 
 #unified-back-forward-button {
   -moz-box-align: center;
 }
@@ -869,17 +867,17 @@ richlistitem[selected="true"][current="t
   font-size: inherit;
 }
 
 .ac-url-text {
   color: -moz-nativehyperlinktext;
   font-size: 0.95em;
 }
 
-richlistitem[type="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
+richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
   list-style-image: url("chrome://browser/skin/actionicon-tab.png");
 }
 
 .autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
   color: GrayText;
 }
 
 .ac-comment[selected="true"], .ac-url-text[selected="true"] {
--- a/browser/themes/pinstripe/browser/jar.mn
+++ b/browser/themes/pinstripe/browser/jar.mn
@@ -41,16 +41,17 @@ browser.jar:
   skin/classic/browser/Popup-blocked.png
   skin/classic/browser/Privacy-16.png
   skin/classic/browser/Privacy-48.png
   skin/classic/browser/searchbar-dropmarker.png
   skin/classic/browser/searchbar.css
   skin/classic/browser/Search.png
   skin/classic/browser/Search-addengines.png
   skin/classic/browser/section_collapsed.png
+  skin/classic/browser/section_collapsed-rtl.png
   skin/classic/browser/section_expanded.png
   skin/classic/browser/Secure-Glyph-White.png
   skin/classic/browser/Secure-statusbar.png
   skin/classic/browser/Secure-statusbar-broken.png
   skin/classic/browser/Secure-background.gif
   skin/classic/browser/Toolbar.png
   skin/classic/browser/toolbarbutton-dropmarker.png
   skin/classic/browser/urlbar-favicon-glow.png
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..84ba18c0a388d48a4aa3e8782f151cb69e20936e
GIT binary patch
literal 791
zc$@(j1L*vTP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0006eX+uL$Nkc;*
zP;zf(X>4Tx0C?K1(mQBVQ5eAS|4ooaln^i#?36*OLX?;U+C@m4hfNw|NK*2cOzusS
zXmWGC_a;7Ys30y*f{&pH4l0d^f`b(-Se#r0rJzANIO|yGA|(#jlMGT_{NTXve0-e8
zcMjOUl{Kwt16r!7XHL(03dNFVtj}I-I5>o>EF0QPI-O+K*#3+JuyMSsY0byCmv6q^
z>?LlUdwS#UhW90Z52s!zmO%0X?waKg;I3HC0q#qtW`a})+;Y9FfOHM;>bXo9q!qwf
zv-}!xRxG~<oL#wQg473ms?t!w<^ZOZsv(0d1k@EnZh>tD_}*%@6|mm{j>?*Df_)7*
zTqu@2){&Qgz?lh<f}>pE1w6>W_{CA~$SD}_!P@mvZmW+3NCzFpV!#i8v~Lym+#3wG
z@-TJ`cD@V-KUW8XohM-b3hUc)NALdbmn40Ff6c8sTXXni3hidAF97(Uw*<Km1ef6X
zI!xY&18*Q5f?Nn&ARva-L+c$Q(PYve^iAbs>A5ifH(Je(*vAFzS1YNrzy$Eo=w_qB
zi;Y-ZSSd&5g|F7bsbP&C%Ltz@C(^=Ibs;OPnX|*1su9hO*2(3C^-g9%_(FSrSg%wg
z!}F-kR8qKM#&g0%h>|3UpCCS_$P**Y9AU8jAAsu_Je)k4$YkF=di6(7%<5$mAl%lj
z=#5(4^vq~lv+DK4Rr!S1<M;Wd`2}L;u1b6y1;hXV00v@9M??Vs0RI60puMM)00009
za7bBm000XU000XU0RWnu7ytkO2XskIMF-gh6Ac+RSj-Os0001TNkl<ZILl*T7zOkJ
zzdv36|M_zA|91yu|D(&X5YqVL;RJ@y=e%&LVIfx|P6NK(@B2@TMi^j17vNGXV&vAI
z&A`l~O_Tvxy}&N&!N|bC!0_|+j{iR%PGI=^<tk;d@bmSK{~ynIV2uTm4H|~26ae(l
VH*@=`>P`Rv002ovPDHLkV1i>OZ)*Sm
--- a/browser/themes/pinstripe/browser/shared.inc
+++ b/browser/themes/pinstripe/browser/shared.inc
@@ -1,3 +1,4 @@
 %include ../../../../toolkit/themes/pinstripe/global/shared.inc
+%include ../../browserShared.inc
 
 %define hudButton -moz-appearance: none; background: url("chrome://browser/skin/hud-style-button-middle-background.png") repeat-x #464646 center center; border: 3px solid; -moz-border-top-colors: rgba(0,0,0,0.35) rgba(26,26,26,0.5) rgba(255,255,255,0.4); -moz-border-right-colors: rgba(53,53,53,1) rgba(53,53,53,1) rgba(162,162,162,1); -moz-border-bottom-colors: rgba(128,128,128,0.35) rgba(0,0,0,0.5) rgba(255,255,255,0.15); -moz-border-left-colors: rgba(0,0,0,0.35) rgba(26,26,26,0.5) rgba(255,255,255,0.4); -moz-border-radius: 20px; color: #fff;
--- a/browser/themes/winstripe/browser/aboutCertError.css
+++ b/browser/themes/winstripe/browser/aboutCertError.css
@@ -18,16 +18,17 @@
  * Portions created by the Initial Developer are Copyright (C) 2008
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   William Price <bugzilla@mob.rice.edu>
  *   Steven Garrity <steven@silverorange.com>
  *   Henrik Skupin  <mozilla@hskupin.info>
  *   Johnathan Nightingale <johnath@mozilla.com>
+ *   Ehsan Akhgari <ehsan.akhgari@gmail.com>
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -84,12 +85,22 @@ body[dir="rtl"] #errorPageContainer {
 #errorLongContent {
   -moz-margin-start: 80px;
 }
 
 #technicalContent > h2, #expertContent > h2 {
   background : url("chrome://browser/skin/section_expanded.png") left center no-repeat;
 }
 
+body[dir="rtl"] #technicalContent > h2,
+body[dir="rtl"] #expertContent > h2 {
+  background-position: right center;
+}
+
 #technicalContent[collapsed] > h2,
 #expertContent[collapsed] > h2{
   background-image: url("chrome://browser/skin/section_collapsed.png");
 }
+
+body[dir="rtl"] #technicalContent[collapsed] > h2,
+body[dir="rtl"] #expertContent[collapsed] > h2 {
+  background-image: url("chrome://browser/skin/section_collapsed-rtl.png");
+}
--- a/browser/themes/winstripe/browser/browser-aero.css
+++ b/browser/themes/winstripe/browser/browser-aero.css
@@ -11,45 +11,41 @@
 
   .tabbrowser-tab[selected="true"]:not(:-moz-lwtheme) {
     background-image: -moz-linear-gradient(rgba(255,255,255,.7), @toolbarHighlight@ 30%),
                       -moz-linear-gradient(@customToolbarColor@, @customToolbarColor@);
   }
 }
 
 @media all and (-moz-windows-compositor) {
-  #main-window:not(:-moz-lwtheme) {
-    -moz-appearance: -moz-win-borderless-glass;
-    background: transparent;
+  /* these should be hidden w/glass enabled. windows draws it's own buttons. */
+  #titlebar-buttonbox {
+    display: none;
   }
 
-  /* the new titlebar requires this, or content will be clipped at the top of the screen. */
-  #main-window[sizemode="maximized"][chromemargin^="0,"] {
-    margin-top: 8px;
-  }
-
-  #main-window[sizemode="normal"][chromemargin^="0,"] {
-    margin-top: 2px;
+  #main-window {
+    -moz-appearance: -moz-win-borderless-glass;
+    background: transparent;
   }
 
   #main-window:not(:-moz-lwtheme)[inFullscreen="true"] {
     -moz-appearance: none;
     background-color: #556;
   }
 
   #toolbar-menubar:not(:-moz-lwtheme),
   #TabsToolbar[tabsontop="true"]:not(:-moz-lwtheme),
   #navigator-toolbox[tabsontop="false"] > #nav-bar:not(:-moz-lwtheme),
   #nav-bar + #customToolbars + #PersonalToolbar[collapsed="true"] + #TabsToolbar[tabsontop="false"]:last-child:not(:-moz-lwtheme) {
     background: transparent !important;
     color: black;
     text-shadow: 0 0 .7em white, 0 0 .7em white, 0 1px 0 rgba(255,255,255,.4);
   }
 
-  #navigator-toolbox[tabsontop="true"] > toolbar:not(#toolbar-menubar):not(#TabsToolbar) {
+  #main-window[sizemode="normal"] #navigator-toolbox[tabsontop="true"] > toolbar:not(#toolbar-menubar):not(#TabsToolbar) {
     border-left: 1px solid ThreeDShadow;
     border-right: 1px solid ThreeDShadow;
   }
 
   /* Make the window draggable by glassed toolbars (bug 555081) */
   #toolbar-menubar:not([autohide="true"]),
   #TabsToolbar[tabsontop="true"],
   #navigator-toolbox[tabsontop="false"] > #nav-bar,
@@ -58,16 +54,21 @@
     -moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbar-drag");
   }
 
   #browser:not(:-moz-lwtheme),
   #browser-bottombox:not(:-moz-lwtheme) {
     background-color: -moz-dialog;
   }
 
+  #main-menubar:not(:-moz-lwtheme):not(:-moz-window-inactive) {
+    background-color: rgba(255,255,255,.5);
+    -moz-border-radius: 4px;
+  }
+
   #urlbar,
   .searchbar-textbox {
     background-color: rgba(255,255,255,.725);
     @navbarTextboxCustomBorder@
     color: black;
   }
 
   /*XXX :-moz-placeholder isn't implemented yet (bug 457801)
--- a/browser/themes/winstripe/browser/browser.css
+++ b/browser/themes/winstripe/browser/browser.css
@@ -21,16 +21,17 @@
  * Contributor(s):
  *   Joe Hewitt (hewitt@netscape.com)
  *   Jason Kersey (kerz@netscape.com)
  *   Pierre Chanial (chanial@noos.fr)
  *   Dean Tessman (dean_tessman@hotmail.com)
  *   Blake Ross (blake@cs.stanford.edu)
  *   Pamela Greene (pamg.bugs@gmail.com)
  *   Dão Gottwald (dao@mozilla.com)
+ *   Jim Mathies (jmathies@mozilla.com)
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -41,16 +42,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 @import url("chrome://global/skin/");
 
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 @namespace html url("http://www.w3.org/1999/xhtml");
 
+%include ../../browserShared.inc
 %filter substitution
 %define toolbarHighlight rgba(255,255,255,.5)
 %define navbarTextboxCustomBorder border-color: rgba(0,0,0,.25) rgba(0,0,0,.32) rgba(0,0,0,.37);
 
 #menubar-items {
   -moz-box-orient: vertical; /* for flex hack */
 }
 
@@ -85,43 +87,35 @@
 #navigator-toolbox[tabsontop="true"]:not([customizing]) > #nav-bar[collapsed="true"] + #customToolbars + #PersonalToolbar {
   background-image: -moz-linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
 }
 
 #navigator-toolbox[tabsontop="false"] > #toolbar-menubar:not(:-moz-lwtheme) {
   background-image: -moz-linear-gradient(@toolbarHighlight@, @toolbarHighlight@);
 }
 
+#navigator-toolbox[tabsontop="true"] > #nav-bar:not(:-moz-lwtheme),
+#navigator-toolbox[tabsontop="true"]:not([customizing]) > #nav-bar[collapsed="true"] + toolbar:not(:-moz-lwtheme),
+#navigator-toolbox[tabsontop="true"]:not([customizing]) > #nav-bar[collapsed="true"] + #customToolbars + #PersonalToolbar:not(:-moz-lwtheme) {
+  border-top: 1px solid ThreeDShadow;
+}
+
 #personal-bookmarks {
   min-height: 24px;
 }
 
 #print-preview-toolbar:not(:-moz-lwtheme) {
   -moz-appearance: toolbox;
 }
 
 statusbarpanel#statusbar-display {
   -moz-padding-start: 0;
 }
 
-/* App menu button */
-
-%ifndef WINSTRIPE_AERO
-#appmenu-button-container {
-  background: ActiveCaption;
-}
-
-#appmenu-button-container:-moz-window-inactive {
-  background: InactiveCaption;
-}
-%endif
-
-#appmenu-button-container {
-  -moz-binding: url("chrome://global/content/bindings/general.xml#windowdragbox");
-}
+/* ::::: app menu button ::::: */
 
 #appmenu-button {
   -moz-appearance: none;
   background-color: rgb(228,120,14);
   background-image: -moz-linear-gradient(rgba(255,255,255,.7),
                                          rgba(255,255,255,.4) 10%,
                                          rgba(255,255,255,0) 50%);
   background-clip: padding-box;
@@ -274,34 +268,85 @@ statusbarpanel#statusbar-display {
   -moz-image-region: rect(0px 16px 16px 0px);
 }
 
 #appmenu_bookmarkThisPage {
   list-style-image: url("chrome://browser/skin/places/bookmark.png");
   -moz-image-region: rect(0 16px 16px 0);
 }
 
-/* XXX: stop-gap until the button can be drawn in the title bar */
-%ifdef WINSTRIPE_AERO
-@media not all and (-moz-windows-compositor) {
+/* ::::: titlebar ::::: */
+
+#titlebar {
+  -moz-appearance: -moz-window-titlebar;
+  /* we only need to the middle section, hide the edges of the
+  theme background beyond the window frame. */
+  margin-left: -15px;
+  margin-right: -15px;
+}
+
+#main-window[sizemode="maximized"] > #titlebar {
+  -moz-appearance: -moz-window-titlebar-maximized;
+}
+
+#titlebar-content {
+  margin-left: 15px;
+  margin-right: 15px;
+}
+
+/* aesthetic - push the fx button off the top window border */
+@media not all and (-moz-windows-classic) {
+  #main-window[sizemode="normal"] > #titlebar > #titlebar-content > #appmenu-button-container {
+%ifndef WINSTRIPE_AERO
+    margin-top: 1px;
+%else
+    margin-top: 2px;
 %endif
-  #main-window[tabsontop="true"] > #appmenu-button-container > #appmenu-button {
-    position: relative !important;
-    margin-bottom: -1.6em !important;
   }
-  #navigator-toolbox[tabsontop="true"] > #toolbar-menubar[autohide="true"] {
-    position: relative !important;
-    background-color: -moz-dialog !important;
+}
+
+#titlebar-buttonbox {
+  -moz-appearance: -moz-window-button-box;
+  -moz-box-align: start;
+}
+
+#main-window[sizemode="maximized"] > #titlebar > #titlebar-content > #titlebar-buttonbox {
+  -moz-appearance: -moz-window-button-box-maximized;
+}
+
+/* titlebar command buttons */
+
+#titlebar-min {
+  -moz-appearance: -moz-window-button-minimize;
+}
+
+#titlebar-max {
+  -moz-appearance: -moz-window-button-maximize;
+}
+
+#main-window[sizemode="maximized"] > #titlebar > #titlebar-content > #titlebar-buttonbox > #titlebar-max {
+  -moz-appearance: -moz-window-button-restore;
+}
+
+#titlebar-close {
+  -moz-appearance: -moz-window-button-close;
+}
+
+@media not all and (-moz-windows-classic) {
+  #titlebar-min,
+  #titlebar-max {
+    -moz-margin-end: 2px;
   }
-  #navigator-toolbox[tabsontop="true"] > #toolbar-menubar[autohide="true"] ~ #TabsToolbar:not([inFullscreen]) {
-    -moz-padding-start: 10em !important;
+}
+
+@media all and (-moz-windows-classic) {
+  #titlebar-close {
+    -moz-margin-start: 2px;
   }
-%ifdef WINSTRIPE_AERO
 }
-%endif
 
 /* ::::: bookmark buttons ::::: */
 
 toolbarbutton.bookmark-item {
   margin: 0;
   padding: 2px 3px;
 }
 
@@ -402,18 +447,18 @@ menuitem.bookmark-item {
 
 .bookmark-item[query][hostContainer][open] {
   list-style-image: url("chrome://global/skin/icons/folder-item.png");
   -moz-image-region: rect(16px, 32px, 32px, 16px);
 }
 
 /* ::::: primary toolbar buttons ::::: */
 
-.toolbarbutton-menubutton-button,
-.toolbarbutton-menubutton-dropmarker,
+.toolbarbutton-1 > .toolbarbutton-menubutton-button,
+.toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker,
 .toolbarbutton-1 {
   -moz-appearance: none;
   padding: 1px 5px;
   background: rgba(151,152,153,.05)
               -moz-linear-gradient(rgba(251,252,253,.95), rgba(246,247,248,.47) 49%, 
                                    rgba(231,232,233,.45) 51%, rgba(225,226,229,.3));
   background-clip: padding-box;
   -moz-border-radius: 4.5px;
@@ -421,153 +466,165 @@ menuitem.bookmark-item {
   border-color: rgba(0,0,0,.12) rgba(0,0,0,.19) rgba(0,0,0,.38);
   -moz-box-shadow: 0 0 0 1px rgba(255,255,255,.3) inset,
                    0 0 0 2px rgba(255,255,255,.1) inset,
                    0 1px 0 rgba(0,0,0,.15);
   color: black;
   text-shadow: 0 0 3px white;
 }
 
-.toolbarbutton-menubutton-dropmarker,
-toolbar[iconsize="small"][mode="icons"] .toolbarbutton-menubutton-button,
+.toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker,
+toolbar[iconsize="small"][mode="icons"] .toolbarbutton-1 > .toolbarbutton-menubutton-button,
 toolbar[iconsize="small"][mode="icons"] .toolbarbutton-1 {
   padding-left: 3px;
   padding-right: 3px;
 }
 
-.toolbarbutton-1 {
+.toolbarbutton-1:not([type="menu-button"]) {
   -moz-box-orient: vertical;
   list-style-image: url("chrome://browser/skin/Toolbar.png");
 }
 
-toolbarbutton[type="menu-button"] {
+.toolbarbutton-1[type="menu-button"] {
   -moz-appearance: none;
   padding: 0;
   background: none !important;
   border: none !important;
   -moz-box-shadow: none !important;
 }
 
-.toolbarbutton-1,
-toolbarbutton[type="menu-button"] {
+.toolbarbutton-1 {
   margin: 1px 3px;
 }
 
-toolbar[iconsize="small"][mode="icons"] .toolbarbutton-1,
-toolbar[iconsize="small"][mode="icons"] toolbarbutton[type="menu-button"] {
+toolbar[iconsize="small"][mode="icons"] .toolbarbutton-1 {
   margin-left: 2px;
   margin-right: 2px;
 }
 
-.toolbarbutton-menubutton-dropmarker {
+.toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
   -moz-border-start-style: none;
 }
 
-.toolbarbutton-menubutton-button:-moz-locale-dir(ltr),
-.toolbarbutton-menubutton-dropmarker:-moz-locale-dir(rtl) {
+.toolbarbutton-1 > .toolbarbutton-menubutton-button:-moz-locale-dir(ltr),
+.toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:-moz-locale-dir(rtl) {
   -moz-border-radius-topright: 0;
   -moz-border-radius-bottomright: 0;
 }
 
-.toolbarbutton-menubutton-button:-moz-locale-dir(rtl),
-.toolbarbutton-menubutton-dropmarker:-moz-locale-dir(ltr) {
+.toolbarbutton-1 > .toolbarbutton-menubutton-button:-moz-locale-dir(rtl),
+.toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker:-moz-locale-dir(ltr) {
   -moz-border-radius-topleft: 0;
   -moz-border-radius-bottomleft: 0;
 }
 
-.toolbarbutton-menubutton-button[disabled="true"],
-.toolbarbutton-menubutton-dropmarker[disabled="true"],
 .toolbarbutton-1[disabled="true"] {
   opacity: .8;
 }
 
-.toolbarbutton-menubutton-button[disabled="true"] > .toolbarbutton-icon,
+.toolbarbutton-1[disabled="true"] > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
 .toolbarbutton-1[disabled="true"] > .toolbarbutton-icon {
   opacity: .5;
 }
 
-.toolbarbutton-menubutton-button:not([disabled="true"]):not(:active):hover,
-toolbarbutton[type="menu-button"]:not([open="true"]):not(:active):hover > .toolbarbutton-menubutton-dropmarker:not([disabled="true"]),
-.toolbarbutton-1:not([disabled="true"]):not([checked="true"]):not([open="true"]):not(:active):hover {
+.toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled="true"]):not(:active):hover,
+.toolbarbutton-1:not([open="true"]):not(:active):hover > .toolbarbutton-menubutton-dropmarker:not([disabled="true"]),
+.toolbarbutton-1:not([type="menu-button"]):not([disabled="true"]):not([checked="true"]):not([open="true"]):not(:active):hover {
   background-color: hsla(190,60%,70%,.5);
   border-color: hsla(190,50%,65%,.8) hsla(190,50%,50%,.8) hsla(190,50%,40%,.8);
   -moz-box-shadow: 0 0 0 1px rgba(255,255,255,.3) inset,
                    0 0 0 2px rgba(255,255,255,.1) inset,
                    0 1px 0 rgba(0,0,0,.1),
                    0 0 5px hsl(190,90%,80%);
   -moz-transition: background-color .4s ease-in,
                    border-color .3s ease-in,
                    -moz-box-shadow .3s ease-in;
 }
 
-.toolbarbutton-menubutton-button:not([disabled="true"]):hover:active,
-toolbarbutton[type="menu-button"]:hover:active > .toolbarbutton-menubutton-dropmarker:not([disabled="true"]),
-toolbarbutton[type="menu-button"][open="true"] > .toolbarbutton-menubutton-dropmarker,
-.toolbarbutton-1:not([disabled="true"]):hover:active,
-.toolbarbutton-1[checked="true"],
+.toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled="true"]):hover:active,
+.toolbarbutton-1:hover:active > .toolbarbutton-menubutton-dropmarker:not([disabled="true"]),
+.toolbarbutton-1[open="true"] > .toolbarbutton-menubutton-dropmarker,
+.toolbarbutton-1:not([type="menu-button"]):not([disabled="true"]):hover:active,
+.toolbarbutton-1:not([type="menu-button"])[checked="true"],
 .toolbarbutton-1[open="true"] {
   background-color: transparent;
   border-color: rgba(0,0,0,.65) rgba(0,0,0,.55) rgba(0,0,0,.5);
   -moz-box-shadow: 0 0 9px rgba(0,0,0,.4) inset,
                    0 0 3px rgba(0,0,0,.4) inset,
                    0 1px 0 rgba(255,255,255,.4);
   text-shadow: none;
 }
 
 .toolbarbutton-1[checked="true"]:not(:active):hover {
   background-color: rgba(90%,90%,90%,.4);
   -moz-transition: background-color .4s;
 }
 
-.toolbarbutton-menubutton-button > .toolbarbutton-icon,
+.toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
 .toolbarbutton-1 > .toolbarbutton-icon {
   -moz-margin-end: 0;
   width: 18px;
   height: 18px;
 }
 
-toolbar[iconsize="small"] .toolbarbutton-menubutton-button > .toolbarbutton-icon,
+toolbar[iconsize="small"] .toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
 toolbar[iconsize="small"] .toolbarbutton-1 > .toolbarbutton-icon {
   margin: 1px;
   width: 16px;
   height: 16px;
 }
 
 /* Default icons have a built-in glow, so they are 18*18px even in small mode,
    except for the large back icon, which is why the code below uses 'auto' rather
    than 18px. This will pick the correct size based on the image region. */
-:-moz-any(
-    #back-button, #forward-button, #reload-button, #stop-button,
-    #home-button, #print-button, #downloads-button, #history-button,
-    #bookmarks-button, #bookmarks-menu-button, #new-tab-button,
-    #new-window-button, #cut-button, #copy-button, #paste-button,
-    #fullscreen-button) > .toolbarbutton-icon {
+:-moz-any(@primaryToolbarButtons@) > .toolbarbutton-icon {
   margin: 0 !important;
   width: auto !important;
   height: auto !important;
 }
 
 toolbar[mode="full"] .toolbarbutton-1,
-toolbar[mode="full"] .toolbarbutton-menubutton-button {
+toolbar[mode="full"] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
   min-width: 57px;
 }
 
 #TabsToolbar > .toolbarbutton-1,
+#TabsToolbar > .toolbarbutton-1 > .toolbarbutton-menubutton-button,
+#TabsToolbar > .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker,
 #TabsToolbar > toolbarpaletteitem > .toolbarbutton-1,
+#TabsToolbar > toolbarpaletteitem > .toolbarbutton-1 > .toolbarbutton-menubutton-button,
+#TabsToolbar > toolbarpaletteitem > .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker,
 #TabsToolbar > #bookmarks-menu-button-container > #bookmarks-menu-button {
   -moz-appearance: toolbarbutton;
+%ifdef WINSTRIPE_AERO
+  margin: -1px 0;
+%else
   margin: 0;
+%endif
   padding: 0 3px;
   border: none !important;
   color: inherit !important;
   background: transparent !important;
   text-shadow: inherit !important;
   -moz-box-shadow: none !important;
 }
 
+%ifdef WINSTRIPE_AERO
+/* resetting the margin from the above rule */
+.toolbarbutton-1 > .toolbarbutton-menubutton-button,
+.toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
+  margin: 0 !important;
+}
+%endif
+
+#TabsToolbar > .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker,
+#TabsToolbar > toolbarpaletteitem > .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
+  -moz-appearance: none;
+}
+
 /* unified back/forward button */
 
 #back-button {
   -moz-image-region: rect(0, 18px, 18px, 0);
   -moz-margin-end: 0;
 }
 
 #forward-button {
@@ -1079,17 +1136,17 @@ toolbar:not([iconsize="small"])[mode="ic
 }
 
 %ifndef WINSTRIPE_AERO
 .ac-url-text:-moz-system-metric(windows-default-theme) {
   color: #006600;
 }
 %endif
 
-richlistitem[type="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
+richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
   list-style-image: url("chrome://browser/skin/actionicon-tab.png");
 }
 
 .autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
   color: GrayText;
 }
 
 .ac-comment[selected="true"], .ac-url-text[selected="true"] {
@@ -1221,18 +1278,25 @@ richlistitem[type="action"][actiontype="
 }
 
 #TabsToolbar:not(:-moz-lwtheme),
 #TabsToolbar[tabsontop="false"] {
   background-image: -moz-linear-gradient(transparent, transparent 50%,
                                          rgba(0,0,0,.05) 90%, rgba(0,0,0,.1));
 }
 
-#TabsToolbar[tabsontop="true"]:not(:-moz-lwtheme) {
-  -moz-box-shadow: 0 -1px ThreeDShadow inset;
+#tabbrowser-tabs[tabsontop="true"] > .tabbrowser-arrowscrollbox > scrollbox:not(:-moz-lwtheme) {
+  padding-bottom: 1px;
+  margin-bottom: -1px;
+  position: relative;
+}
+
+#tabbrowser-tabs[tabsontop="true"] > .tabbrowser-tab[selected="true"]:not(:-moz-lwtheme) {
+  margin-bottom: -1px;
+  padding-bottom: 1px;
 }
 
 .tabbrowser-tabs:-moz-system-metric(touch-enabled) {
   min-height: 7.3mozmm;
 }
 
 .tabbrowser-tabs:not([overflow="true"]) {
   -moz-margin-start: 3px;
@@ -1322,20 +1386,22 @@ richlistitem[type="action"][actiontype="
   -moz-image-region: rect(0, 144px, 16px, 128px);
 }
 
 .tab-icon-image {
   width: 16px;
   height: 16px;
   list-style-image: url("chrome://global/skin/icons/folder-item.png");
   -moz-image-region: rect(0px, 16px, 16px, 0px);
+  -moz-margin-end: 3px;
 }
 
-.tabbrowser-tab:not([pinned]) > .tab-icon-image {
-  -moz-margin-end: 3px;
+.tabbrowser-tab[pinned] > .tab-icon-image {
+  -moz-margin-start: 2px;
+  -moz-margin-end: 2px;
 }
 
 /* tabbrowser-tab focus ring */
 .tabbrowser-tab > .tab-text {
   border: 1px dotted transparent;
 }
 
 .tabbrowser-tab:focus > .tab-text {
@@ -1396,17 +1462,21 @@ richlistitem[type="action"][actiontype="
     min-width: 10mozmm;
   }
 }
 
 .tabbrowser-arrowscrollbox > .scrollbutton-up,
 .tabbrowser-arrowscrollbox > .scrollbutton-down {
   list-style-image: url("chrome://browser/skin/tabbrowser/tab-arrow-left.png");
   -moz-image-region: rect(0, 15px, 17px, 0);
+%ifdef WINSTRIPE_AERO
+  margin: -1px 0;
+%else
   margin: 0;
+%endif
   padding-top: 0;
   padding-bottom: 0;
 }
 
 .tabbrowser-arrowscrollbox > .scrollbutton-up[disabled="true"],
 .tabbrowser-arrowscrollbox > .scrollbutton-down[disabled="true"] {
   opacity: .4;
 }
--- a/browser/themes/winstripe/browser/jar.mn
+++ b/browser/themes/winstripe/browser/jar.mn
@@ -35,16 +35,17 @@ browser.jar:
         skin/classic/browser/Secure.png                              (Secure.png)
         skin/classic/browser/Secure24.png                            (Secure24.png)
         skin/classic/browser/Security-broken.png                     (Security-broken.png)
         skin/classic/browser/Toolbar.png                             (Toolbar.png)
         skin/classic/browser/Go-arrow.png                            (Go-arrow.png)
 *       skin/classic/browser/searchbar.css                           (searchbar.css)
         skin/classic/browser/Search-addengines.png
         skin/classic/browser/section_collapsed.png
+        skin/classic/browser/section_collapsed-rtl.png
         skin/classic/browser/section_expanded.png
         skin/classic/browser/setDesktopBackground.css
         skin/classic/browser/menu-back.png                           (menu-back.png)
         skin/classic/browser/menu-forward.png                        (menu-forward.png)
         skin/classic/browser/monitor.png
         skin/classic/browser/monitor_16-10.png
         skin/classic/browser/urlbar-favicon-glow.png
         skin/classic/browser/feeds/feed-icons-16.png                 (feeds/feed-icons-16.png)
@@ -149,16 +150,17 @@ browser.jar:
         skin/classic/aero/browser/Secure.png                         (Secure-aero.png)
         skin/classic/aero/browser/Secure24.png                       (Secure24-aero.png)
         skin/classic/aero/browser/Security-broken.png                (Security-broken-aero.png)
         skin/classic/aero/browser/Toolbar.png
         skin/classic/aero/browser/Go-arrow.png                       (Go-arrow-aero.png)
 *       skin/classic/aero/browser/searchbar.css                      (searchbar.css)
         skin/classic/aero/browser/Search-addengines.png
         skin/classic/aero/browser/section_collapsed.png
+        skin/classic/aero/browser/section_collapsed-rtl.png
         skin/classic/aero/browser/section_expanded.png
         skin/classic/aero/browser/setDesktopBackground.css
         skin/classic/aero/browser/menu-back.png                      (menu-back-aero.png)
         skin/classic/aero/browser/menu-forward.png                   (menu-forward-aero.png)
         skin/classic/aero/browser/monitor.png
         skin/classic/aero/browser/monitor_16-10.png
         skin/classic/aero/browser/urlbar-favicon-glow.png
         skin/classic/aero/browser/feeds/feed-icons-16.png            (feeds/feed-icons-16-aero.png)
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..84ba18c0a388d48a4aa3e8782f151cb69e20936e
GIT binary patch
literal 791
zc$@(j1L*vTP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0006eX+uL$Nkc;*
zP;zf(X>4Tx0C?K1(mQBVQ5eAS|4ooaln^i#?36*OLX?;U+C@m4hfNw|NK*2cOzusS
zXmWGC_a;7Ys30y*f{&pH4l0d^f`b(-Se#r0rJzANIO|yGA|(#jlMGT_{NTXve0-e8
zcMjOUl{Kwt16r!7XHL(03dNFVtj}I-I5>o>EF0QPI-O+K*#3+JuyMSsY0byCmv6q^
z>?LlUdwS#UhW90Z52s!zmO%0X?waKg;I3HC0q#qtW`a})+;Y9FfOHM;>bXo9q!qwf
zv-}!xRxG~<oL#wQg473ms?t!w<^ZOZsv(0d1k@EnZh>tD_}*%@6|mm{j>?*Df_)7*
zTqu@2){&Qgz?lh<f}>pE1w6>W_{CA~$SD}_!P@mvZmW+3NCzFpV!#i8v~Lym+#3wG
z@-TJ`cD@V-KUW8XohM-b3hUc)NALdbmn40Ff6c8sTXXni3hidAF97(Uw*<Km1ef6X
zI!xY&18*Q5f?Nn&ARva-L+c$Q(PYve^iAbs>A5ifH(Je(*vAFzS1YNrzy$Eo=w_qB
zi;Y-ZSSd&5g|F7bsbP&C%Ltz@C(^=Ibs;OPnX|*1su9hO*2(3C^-g9%_(FSrSg%wg
z!}F-kR8qKM#&g0%h>|3UpCCS_$P**Y9AU8jAAsu_Je)k4$YkF=di6(7%<5$mAl%lj
z=#5(4^vq~lv+DK4Rr!S1<M;Wd`2}L;u1b6y1;hXV00v@9M??Vs0RI60puMM)00009
za7bBm000XU000XU0RWnu7ytkO2XskIMF-gh6Ac+RSj-Os0001TNkl<ZILl*T7zOkJ
zzdv36|M_zA|91yu|D(&X5YqVL;RJ@y=e%&LVIfx|P6NK(@B2@TMi^j17vNGXV&vAI
z&A`l~O_Tvxy}&N&!N|bC!0_|+j{iR%PGI=^<tk;d@bmSK{~ynIV2uTm4H|~26ae(l
VH*@=`>P`Rv002ovPDHLkV1i>OZ)*Sm
--- a/build/mobile/sutagent/android/DoCommand.java
+++ b/build/mobile/sutagent/android/DoCommand.java
@@ -110,16 +110,18 @@ public class DoCommand {
 	InputStream	sutErr;
 	InputStream	sutOut;
 	AlertLooperThread alrt = null;
 	ContextWrapper	contextWrapper = null;
 	
 	String	currentDir = "/";
 	String	sErrorPrefix = "##AGENT-ERROR## ";
 	
+	private final String prgVersion = "SUTAgentAndroid Version 0.80";
+	
 	public enum Command
 		{
 		RUN ("run"),
 		EXEC ("exec"),
 		ARUN ("arun"),
 		KILL ("kill"),
 		PS ("ps"),
 		DEVINFO ("info"),
@@ -158,18 +160,20 @@ public class DoCommand {
 		CLOK ("clok"),
 		STAT ("stat"),
 		QUIT ("quit"),
 		EXIT ("exit"),
 		HELP ("help"),
 		FTPG ("ftpg"),
 		FTPP ("ftpp"),
 		INST ("inst"),
+		UPDT ("updt"),
 		UNINST ("uninst"),
 		TEST ("test"),
+		VER ("ver"),
 		UNKNOWN ("unknown");
 		
 		private final String theCmd;
 		
 		Command(String theCmd) { this.theCmd = theCmd; }
 
 		public String theCmd() {return theCmd;}
 		
@@ -202,16 +206,24 @@ public class DoCommand {
 		String [] Argv = parseCmdLine(theCmdLine);
 		
 		int Argc = Argv.length;
 		
 		cCmd = Command.getCmd(Argv[0]);
 		
 		switch(cCmd)
 			{
+			case VER:
+				strReturn = prgVersion;
+				break;
+				
+			case UPDT:
+				strReturn = StartUpdateOMatic(Argv[1], Argv[2]);
+				break;
+			
 			case CWD:
 				try {
 					strReturn = new java.io.File(currentDir).getCanonicalPath();
 					} 
 				catch (IOException e)
 					{
 					e.printStackTrace();
 					}
@@ -2289,16 +2301,68 @@ public class DoCommand {
 			{
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 			}
 
 		return (sRet);
 		}
 
+	public String StartUpdateOMatic(String sPkgName, String sPkgFileName)
+		{
+		String sRet = "";
+	
+//		Context ctx = SUTAgentAndroid.me.getApplicationContext();
+		Context ctx = contextWrapper.getApplicationContext();
+		PackageManager pm = ctx.getPackageManager();
+
+		Intent prgIntent = new Intent();
+		prgIntent.setPackage("com.mozilla.UpdateOMatic");
+		prgIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+		try {
+			PackageInfo pi = pm.getPackageInfo("com.mozilla.UpdateOMatic", PackageManager.GET_ACTIVITIES | PackageManager.GET_INTENT_FILTERS);
+			ActivityInfo [] ai = pi.activities;
+			for (int i = 0; i < ai.length; i++)
+				{
+				ActivityInfo a = ai[i];
+				if (a.name.length() > 0)
+					{
+					prgIntent.setClassName(a.packageName, a.name);
+					break;
+					}
+				}
+			}
+		catch (NameNotFoundException e)
+			{
+			e.printStackTrace();
+			}
+		
+		prgIntent.putExtra("pkgName", sPkgName);
+		prgIntent.putExtra("pkgFileName", sPkgFileName);
+
+		try 
+			{
+			contextWrapper.startActivity(prgIntent);
+//			Thread.sleep(5000);
+			sRet = "exit";
+			}
+		catch(ActivityNotFoundException anf)