Merge mozilla-central into electrolysis
authorBenjamin Smedberg <benjamin@smedbergs.us>
Tue, 09 Feb 2010 11:39:28 -0500
changeset 46642 a77f5a6cce34dece7c0b90275001fa35b80465de
parent 46641 240e383440c40844d335ce2229f18125b1f961f3 (current diff)
parent 38005 83eef73d2ff715746b48f2dabbbc49afe13bb385 (diff)
child 46643 1666292c7610900bc6d21624d66a4f5f95cf7ce1
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
milestone1.9.3a2pre
Merge mozilla-central into electrolysis
accessible/tests/mochitest/test_actions.html
accessible/tests/mochitest/test_actions.xul
accessible/tests/mochitest/test_actions_anchors.html
accessible/tests/mochitest/test_actions_aria.html
accessible/tests/mochitest/test_actions_inputs.html
accessible/tests/mochitest/test_actions_tree.xul
accessible/tests/mochitest/test_actions_treegrid.xul
accessible/tests/mochitest/test_role_table_cells.html
accessible/tests/mochitest/test_states.html
accessible/tests/mochitest/test_states_doc.html
accessible/tests/mochitest/test_states_docarticle.html
accessible/tests/mochitest/test_states_editablebody.html
accessible/tests/mochitest/test_states_frames.html
accessible/tests/mochitest/test_states_popup.xul
accessible/tests/mochitest/test_states_tree.xul
accessible/tests/mochitest/z_states_frame.html
accessible/tests/mochitest/z_states_framearticle.html
accessible/tests/mochitest/z_states_framecheckbox.html
accessible/tests/mochitest/z_states_frametextbox.html
browser/app/profile/firefox.js
content/base/src/nsGkAtomList.h
content/canvas/src/nsCanvasRenderingContext2D.cpp
dom/plugins/PluginInstanceChild.cpp
dom/plugins/PluginInstanceParent.cpp
dom/plugins/PluginMessageUtils.h
dom/plugins/PluginModuleChild.cpp
ipc/glue/AsyncChannel.cpp
ipc/glue/MozillaChildThread.cpp
ipc/glue/MozillaChildThread.h
ipc/glue/RPCChannel.cpp
layout/generic/nsFrameFrame.cpp
modules/plugin/base/src/nsPluginHost.cpp
nsprpub/lib/ds/MANIFEST
nsprpub/lib/libc/include/MANIFEST
nsprpub/lib/libc/include/plresolv.h
nsprpub/lib/msgc/include/MANIFEST
nsprpub/pr/include/MANIFEST
security/nss/cmd/zlib/Makefile
security/nss/cmd/zlib/README
security/nss/cmd/zlib/adler32.c
security/nss/cmd/zlib/compress.c
security/nss/cmd/zlib/config.mk
security/nss/cmd/zlib/crc32.c
security/nss/cmd/zlib/crc32.h
security/nss/cmd/zlib/deflate.c
security/nss/cmd/zlib/deflate.h
security/nss/cmd/zlib/example.c
security/nss/cmd/zlib/gzio.c
security/nss/cmd/zlib/infback.c
security/nss/cmd/zlib/inffast.c
security/nss/cmd/zlib/inffast.h
security/nss/cmd/zlib/inffixed.h
security/nss/cmd/zlib/inflate.c
security/nss/cmd/zlib/inflate.h
security/nss/cmd/zlib/inftrees.c
security/nss/cmd/zlib/inftrees.h
security/nss/cmd/zlib/manifest.mn
security/nss/cmd/zlib/minigzip.c
security/nss/cmd/zlib/trees.c
security/nss/cmd/zlib/trees.h
security/nss/cmd/zlib/uncompr.c
security/nss/cmd/zlib/zconf.h
security/nss/cmd/zlib/zlib.h
security/nss/cmd/zlib/zutil.c
security/nss/cmd/zlib/zutil.h
toolkit/mozapps/update/public/Makefile.in
toolkit/mozapps/update/public/nsIUpdateService.idl
toolkit/mozapps/update/public/nsIUpdateTimerManager.idl
toolkit/mozapps/update/src/Makefile.in
toolkit/mozapps/update/src/nsUpdateService.js.in
toolkit/mozapps/update/src/nsUpdateServiceStub.js
toolkit/mozapps/update/src/nsUpdateTimerManager.js
toolkit/mozapps/update/src/updater/Makefile.in
toolkit/mozapps/update/src/updater/archivereader.cpp
toolkit/mozapps/update/src/updater/archivereader.h
toolkit/mozapps/update/src/updater/bspatch.cpp
toolkit/mozapps/update/src/updater/bspatch.h
toolkit/mozapps/update/src/updater/launchchild_osx.mm
toolkit/mozapps/update/src/updater/macbuild/Contents/Info.plist
toolkit/mozapps/update/src/updater/macbuild/Contents/PkgInfo
toolkit/mozapps/update/src/updater/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in
toolkit/mozapps/update/src/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/classes.nib
toolkit/mozapps/update/src/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/info.nib
toolkit/mozapps/update/src/updater/macbuild/Contents/Resources/English.lproj/MainMenu.nib/keyedobjects.nib
toolkit/mozapps/update/src/updater/macbuild/Contents/Resources/updater.icns
toolkit/mozapps/update/src/updater/module.ver
toolkit/mozapps/update/src/updater/progressui.h
toolkit/mozapps/update/src/updater/progressui_gtk.cpp
toolkit/mozapps/update/src/updater/progressui_null.cpp
toolkit/mozapps/update/src/updater/progressui_osx.mm
toolkit/mozapps/update/src/updater/progressui_win.cpp
toolkit/mozapps/update/src/updater/resource.h
toolkit/mozapps/update/src/updater/updater.cpp
toolkit/mozapps/update/src/updater/updater.exe.manifest
toolkit/mozapps/update/src/updater/updater.ico
toolkit/mozapps/update/src/updater/updater.png
toolkit/mozapps/update/src/updater/updater.rc
toolkit/mozapps/update/src/updater/updater_wince.cpp
toolkit/mozapps/update/src/updater/updater_wince.h
toolkit/mozapps/update/src/updater/updater_wince.rc
toolkit/mozapps/update/src/updater/updater_winmo.rc
toolkit/themes/pinstripe/global/menu/menu-arrow-dis-rtl.gif
toolkit/themes/pinstripe/global/menu/menu-arrow-dis.gif
toolkit/themes/pinstripe/global/menu/menu-arrow-hov.gif
toolkit/themes/pinstripe/global/menu/menu-arrow.gif
toolkit/themes/pinstripe/global/menu/menu-check-dis.png
toolkit/themes/pinstripe/global/menu/menu-check-hov.png
toolkit/themes/pinstripe/global/scrollbox/autorepeat-arrow-dn-dis.gif
toolkit/themes/pinstripe/global/scrollbox/autorepeat-arrow-dn.gif
toolkit/themes/pinstripe/global/scrollbox/autorepeat-arrow-up-dis.gif
toolkit/themes/pinstripe/global/scrollbox/autorepeat-arrow-up.gif
toolkit/xre/nsEmbedFunctions.cpp
widget/src/windows/nsWindow.cpp
--- a/accessible/src/base/nsAccessibilityAtomList.h
+++ b/accessible/src/base/nsAccessibilityAtomList.h
@@ -257,16 +257,18 @@ ACCESSIBILITY_ATOM(aria_valuenow, "aria-
 ACCESSIBILITY_ATOM(aria_valuemin, "aria-valuemin")
 ACCESSIBILITY_ATOM(aria_valuemax, "aria-valuemax")
 ACCESSIBILITY_ATOM(aria_valuetext, "aria-valuetext")
 
   // misc atoms
 // a form property used to obtain the default label
 // of an HTML button from the button frame
 ACCESSIBILITY_ATOM(defaultLabel, "defaultLabel")
+// the attribute specifying the editor's bogus br node
+ACCESSIBILITY_ATOM(mozeditorbogusnode, "_moz_editor_bogus_node")
 
 // Object attributes
 ACCESSIBILITY_ATOM(tableCellIndex, "table-cell-index")
 ACCESSIBILITY_ATOM(containerAtomic, "container-atomic")
 ACCESSIBILITY_ATOM(containerBusy, "container-busy")
 ACCESSIBILITY_ATOM(containerLive, "container-live")
 ACCESSIBILITY_ATOM(containerLiveRole, "container-live-role")
 ACCESSIBILITY_ATOM(containerRelevant, "container-relevant")
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -1608,17 +1608,17 @@ nsAccessibilityService::GetAccessible(ns
   }
 
   // If no accessible, see if we need to create a generic accessible because
   // of some property that makes this object interesting
   // We don't do this for <body>, <html>, <window>, <dialog> etc. which 
   // correspond to the doc accessible and will be created in any case
   if (!newAcc && content->Tag() != nsAccessibilityAtoms::body && content->GetParent() && 
       ((weakFrame.GetFrame() && weakFrame.GetFrame()->IsFocusable()) ||
-       (isHTML && nsCoreUtils::HasListener(content, NS_LITERAL_STRING("click"))) ||
+       (isHTML && nsCoreUtils::HasClickListener(content)) ||
        HasUniversalAriaProperty(content, aWeakShell) || roleMapEntry ||
        HasRelatedContent(content) || nsCoreUtils::IsXLink(content))) {
     // This content is focusable or has an interesting dynamic content accessibility property.
     // If it's interesting we need it in the accessibility hierarchy so that events or
     // other accessibles can point to it, or so that it can hold a state, etc.
     if (isHTML) {
       // Interesting HTML container which may have selectable text and/or embedded objects
       CreateHyperTextAccessible(weakFrame.GetFrame(), getter_AddRefs(newAcc));
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -3007,30 +3007,31 @@ nsAccessible::CacheChildren()
 
     walker.GetNextSibling();
   }
 }
 
 void
 nsAccessible::TestChildCache(nsAccessible *aCachedChild)
 {
-#ifdef DEBUG_A11Y
+#ifdef DEBUG
   // All cached accessible nodes should be in the parent
   // It will assert if not all the children were created
   // when they were first cached, and no invalidation
   // ever corrected parent accessible's child cache.
   PRUint32 childCount = mChildren.Length();
   if (childCount == 0) {
     NS_ASSERTION(mAreChildrenInitialized,
-                 "Children are stored but not initailzied!");
+                 "Children are stored but not initialized!");
     return;
   }
 
+  nsAccessible *child;
   for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
-    nsAccessible *child = GetChildAt(childIdx);
+    child = GetChildAt(childIdx);
     if (child == aCachedChild)
       break;
   }
 
   NS_ASSERTION(child == aCachedChild,
                "[TestChildCache] cached accessible wasn't found. Wrong accessible tree!");  
 #endif
 }
@@ -3209,18 +3210,17 @@ nsAccessible::GetActionRule(PRUint32 aSt
     return eJumpAction;
 
   // Return "click" action on elements that have an attached popup menu.
   if (content->IsXUL())
     if (content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::popup))
       return eClickAction;
 
   // Has registered 'click' event handler.
-  PRBool isOnclick = nsCoreUtils::HasListener(content,
-                                              NS_LITERAL_STRING("click"));
+  PRBool isOnclick = nsCoreUtils::HasClickListener(content);
 
   if (isOnclick)
     return eClickAction;
   
   // Get an action based on ARIA role.
   if (mRoleMapEntry &&
       mRoleMapEntry->actionRule != eNoAction)
     return mRoleMapEntry->actionRule;
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -296,32 +296,32 @@ public:
    *
    * @param aText         returned text of the accessible
    * @param aStartOffset  start offset inside of the accesible
    * @param aLength       required lenght of text
    */
   virtual nsresult AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
                                 PRUint32 aLength);
 
+  /**
+   * Assert if child not in parent's cache.
+   */
+  void TestChildCache(nsAccessible *aCachedChild);
+
 protected:
 
   //////////////////////////////////////////////////////////////////////////////
   // Initializing, cache and tree traverse methods
 
   /**
    * Cache accessible children.
    */
   virtual void CacheChildren();
 
   /**
-   * Assert if child not in parent's cache.
-   */
-  void TestChildCache(nsAccessible *aCachedChild);
-
-  /**
    * Cache children if necessary. Return true if the accessible is defunct.
    */
   PRBool EnsureChildren();
 
   /**
    * Return sibling accessible at the given offset.
    */
   virtual nsIAccessible* GetSiblingAtOffset(PRInt32 aOffset,
--- a/accessible/src/base/nsBaseWidgetAccessible.cpp
+++ b/accessible/src/base/nsBaseWidgetAccessible.cpp
@@ -246,28 +246,26 @@ nsLinkableAccessible::Shutdown()
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsLinkableAccessible
 
 void
 nsLinkableAccessible::CacheActionContent()
 {
   nsCOMPtr<nsIContent> walkUpContent(do_QueryInterface(mDOMNode));
-  PRBool isOnclick = nsCoreUtils::HasListener(walkUpContent,
-                                              NS_LITERAL_STRING("click"));
+  PRBool isOnclick = nsCoreUtils::HasClickListener(walkUpContent);
 
   if (isOnclick) {
     mActionContent = walkUpContent;
     mIsOnclick = PR_TRUE;
     return;
   }
 
   while ((walkUpContent = walkUpContent->GetParent())) {
-    isOnclick = nsCoreUtils::HasListener(walkUpContent,
-                                         NS_LITERAL_STRING("click"));
+    isOnclick = nsCoreUtils::HasClickListener(walkUpContent);
   
     nsCOMPtr<nsIDOMNode> walkUpNode(do_QueryInterface(walkUpContent));
 
     nsCOMPtr<nsIAccessible> walkUpAcc;
     GetAccService()->GetAccessibleInWeakShell(walkUpNode, mWeakShell,
                                               getter_AddRefs(walkUpAcc));
 
     if (nsAccUtils::Role(walkUpAcc) == nsIAccessibleRole::ROLE_LINK &&
--- a/accessible/src/base/nsCoreUtils.cpp
+++ b/accessible/src/base/nsCoreUtils.cpp
@@ -70,23 +70,26 @@
 
 #include "nsContentCID.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIInterfaceRequestorUtils.h"
 
 static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID);
 
 PRBool
-nsCoreUtils::HasListener(nsIContent *aContent, const nsAString& aEventType)
+nsCoreUtils::HasClickListener(nsIContent *aContent)
 {
   NS_ENSURE_TRUE(aContent, PR_FALSE);
   nsIEventListenerManager* listenerManager =
     aContent->GetListenerManager(PR_FALSE);
 
-  return listenerManager && listenerManager->HasListenersFor(aEventType);  
+  return listenerManager &&
+    (listenerManager->HasListenersFor(NS_LITERAL_STRING("click")) ||
+     listenerManager->HasListenersFor(NS_LITERAL_STRING("mousedown")) ||
+     listenerManager->HasListenersFor(NS_LITERAL_STRING("mouseup")));
 }
 
 void
 nsCoreUtils::DispatchClickEvent(nsITreeBoxObject *aTreeBoxObj,
                                 PRInt32 aRowIndex, nsITreeColumn *aColumn,
                                 const nsCString& aPseudoElt)
 {
   nsCOMPtr<nsIDOMElement> tcElm;
--- a/accessible/src/base/nsCoreUtils.h
+++ b/accessible/src/base/nsCoreUtils.h
@@ -52,20 +52,20 @@
 #include "nsIArray.h"
 #include "nsIMutableArray.h"
 #include "nsPoint.h"
 
 class nsCoreUtils
 {
 public:
   /**
-   * Return true if the given node has registered event listener of the given
-   * type.
+   * Return true if the given node has registered click, mousedown or mouseup
+   * event listeners.
    */
-  static PRBool HasListener(nsIContent *aContent, const nsAString& aEventType);
+  static PRBool HasClickListener(nsIContent *aContent);
 
   /**
    * Dispatch click event to XUL tree cell.
    *
    * @param  aTreeBoxObj  [in] tree box object
    * @param  aRowIndex    [in] row index
    * @param  aColumn      [in] column object
    * @param  aPseudoElm   [in] pseudo elemenet inside the cell, see
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -161,17 +161,16 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_IN
   tmp->ClearCache(tmp->mAccessNodeCache);
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDocAccessible)
   NS_INTERFACE_MAP_STATIC_AMBIGUOUS(nsDocAccessible)
   NS_INTERFACE_MAP_ENTRY(nsIAccessibleDocument)
   NS_INTERFACE_MAP_ENTRY(nsIDocumentObserver)
   NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
-  NS_INTERFACE_MAP_ENTRY(nsIScrollPositionListener)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAccessibleDocument)
 NS_INTERFACE_MAP_END_INHERITING(nsHyperTextAccessible)
 
 NS_IMPL_ADDREF_INHERITED(nsDocAccessible, nsHyperTextAccessible)
 NS_IMPL_RELEASE_INHERITED(nsDocAccessible, nsHyperTextAccessible)
 
@@ -538,17 +537,17 @@ NS_IMETHODIMP nsDocAccessible::GetAssoci
     NS_ADDREF(*aEditor = editor);
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP nsDocAccessible::GetCachedAccessNode(void *aUniqueID, nsIAccessNode **aAccessNode)
 {
   GetCacheEntry(mAccessNodeCache, aUniqueID, aAccessNode); // Addrefs for us
-#ifdef DEBUG_A11Y
+#ifdef DEBUG
   // All cached accessible nodes should be in the parent
   // It will assert if not all the children were created
   // when they were first cached, and no invalidation
   // ever corrected parent accessible's child cache.
   nsRefPtr<nsAccessible> acc =
     nsAccUtils::QueryObject<nsAccessible>(*aAccessNode);
 
   if (acc) {
@@ -950,22 +949,17 @@ void nsDocAccessible::RemoveScrollListen
   if (sf) {
     sf->RemoveScrollPositionListener(this);
   }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIScrollPositionListener
 
-NS_IMETHODIMP nsDocAccessible::ScrollPositionWillChange(nscoord aX, nscoord aY)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsDocAccessible::ScrollPositionDidChange(nscoord aX, nscoord aY)
+void nsDocAccessible::ScrollPositionDidChange(nscoord aX, nscoord aY)
 {
   // Start new timer, if the timer cycles at least 1 full cycle without more scroll position changes,
   // then the ::Notify() method will fire the accessibility event for scroll position changes
   const PRUint32 kScrollPosCheckWait = 50;
   if (mScrollWatchTimer) {
     mScrollWatchTimer->SetDelay(kScrollPosCheckWait);  // Create new timer, to avoid leaks
   }
   else {
@@ -973,17 +967,16 @@ NS_IMETHODIMP nsDocAccessible::ScrollPos
     if (mScrollWatchTimer) {
       NS_ADDREF_THIS(); // Kung fu death grip
       mScrollWatchTimer->InitWithFuncCallback(ScrollTimerCallback, this,
                                               kScrollPosCheckWait,
                                               nsITimer::TYPE_REPEATING_SLACK);
     }
   }
   mScrollPositionChangedTicks = 1;
-  return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIObserver
 
 NS_IMETHODIMP nsDocAccessible::Observe(nsISupports *aSubject, const char *aTopic,
                                        const PRUnichar *aData)
 {
@@ -1958,21 +1951,21 @@ nsDocAccessible::InvalidateCacheSubtree(
   childNode->GetLocalName(localName);
   const char *hasAccessible = childAccessible ? " (acc)" : "";
   if (aChangeType == nsIAccessibilityService::FRAME_HIDE)
     printf("[Hide %s %s]\n", NS_ConvertUTF16toUTF8(localName).get(), hasAccessible);
   else if (aChangeType == nsIAccessibilityService::FRAME_SHOW)
     printf("[Show %s %s]\n", NS_ConvertUTF16toUTF8(localName).get(), hasAccessible);
   else if (aChangeType == nsIAccessibilityService::FRAME_SIGNIFICANT_CHANGE)
     printf("[Layout change %s %s]\n", NS_ConvertUTF16toUTF8(localName).get(), hasAccessible);
-  else if (aChangeType == nsIAccessibleEvent::NODE_APPEND)
+  else if (aChangeType == nsIAccessibilityService::NODE_APPEND)
     printf("[Create %s %s]\n", NS_ConvertUTF16toUTF8(localName).get(), hasAccessible);
   else if (aChangeType == nsIAccessibilityService::NODE_REMOVE)
     printf("[Destroy  %s %s]\n", NS_ConvertUTF16toUTF8(localName).get(), hasAccessible);
-  else if (aChangeEventType == nsIAccessibilityService::NODE_SIGNIFICANT_CHANGE)
+  else if (aChangeType == nsIAccessibilityService::NODE_SIGNIFICANT_CHANGE)
     printf("[Type change %s %s]\n", NS_ConvertUTF16toUTF8(localName).get(), hasAccessible);
 #endif
 
   nsCOMPtr<nsIAccessible> containerAccessible;
   GetAccessibleInParentChain(childNode, PR_TRUE, getter_AddRefs(containerAccessible));
   if (!containerAccessible) {
     containerAccessible = this;
   }
--- a/accessible/src/base/nsDocAccessible.h
+++ b/accessible/src/base/nsDocAccessible.h
@@ -85,19 +85,18 @@ public:
   // nsIAccessible
   NS_IMETHOD GetName(nsAString& aName);
   NS_IMETHOD GetDescription(nsAString& aDescription);
   NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
   NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
   NS_IMETHOD TakeFocus(void);
 
   // nsIScrollPositionListener
-  NS_IMETHOD ScrollPositionWillChange(nscoord aX, nscoord aY);
-  virtual void ViewPositionDidChange(nsTArray<nsIWidget::Configuration>* aConfigurations) {}
-  NS_IMETHOD ScrollPositionDidChange(nscoord aX, nscoord aY);
+  virtual void ScrollPositionWillChange(nscoord aX, nscoord aY) {}
+  virtual void ScrollPositionDidChange(nscoord aX, nscoord aY);
 
   // nsIDocumentObserver
   NS_DECL_NSIDOCUMENTOBSERVER
 
   // nsAccessNode
   virtual nsresult Init();
   virtual nsresult Shutdown();
   virtual nsIFrame* GetFrame();
--- a/accessible/src/html/nsHTMLLinkAccessible.cpp
+++ b/accessible/src/html/nsHTMLLinkAccessible.cpp
@@ -82,18 +82,17 @@ nsHTMLLinkAccessible::GetStateInternal(P
     *aState |= nsIAccessibleStates::STATE_SELECTABLE;
   }
 
   nsLinkState linkState = content->GetLinkState();
   if (linkState == eLinkState_NotLink || linkState == eLinkState_Unknown) {
     // This is a either named anchor (a link with also a name attribute) or
     // it doesn't have any attributes. Check if 'click' event handler is
     // registered, otherwise bail out.
-    PRBool isOnclick = nsCoreUtils::HasListener(content,
-                                                NS_LITERAL_STRING("click"));
+    PRBool isOnclick = nsCoreUtils::HasClickListener(content);
     if (!isOnclick)
       return NS_OK;
   }
 
   *aState |= nsIAccessibleStates::STATE_LINKED;
 
   if (linkState == eLinkState_Visited)
     *aState |= nsIAccessibleStates::STATE_TRAVERSED;
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -581,26 +581,24 @@ nsresult nsHyperTextAccessible::DOMPoint
   }
 
   // Get accessible for this findNode, or if that node isn't accessible, use the
   // accessible for the next DOM node which has one (based on forward depth first search)
   nsCOMPtr<nsIAccessible> descendantAccessible;
   if (findNode) {
     nsCOMPtr<nsIContent> findContent = do_QueryInterface(findNode);
     if (findContent->IsHTML() && 
-        findContent->NodeInfo()->Equals(nsAccessibilityAtoms::br)) {
-      nsIContent *parent = findContent->GetParent();
-      if (parent &&
-          parent->IsRootOfNativeAnonymousSubtree() &&
-          parent->GetChildCount() == 1) {
-        // This <br> is the only node in a text control, therefore it is the hacky
-        // "bogus node" used when there is no text in a control
-        *aHyperTextOffset = 0;
-        return NS_OK;
-      }
+        findContent->NodeInfo()->Equals(nsAccessibilityAtoms::br) &&
+        findContent->AttrValueIs(kNameSpaceID_None,
+                                 nsAccessibilityAtoms::mozeditorbogusnode,
+                                 nsAccessibilityAtoms::_true,
+                                 eIgnoreCase)) {
+      // This <br> is the hacky "bogus node" used when there is no text in a control
+      *aHyperTextOffset = 0;
+      return NS_OK;
     }
     descendantAccessible = GetFirstAvailableAccessible(findNode);
   }
   // From the descendant, go up and get the immediate child of this hypertext
   nsCOMPtr<nsIAccessible> childAccessible;
   while (descendantAccessible) {
     nsCOMPtr<nsIAccessible> parentAccessible;
     descendantAccessible->GetParent(getter_AddRefs(parentAccessible));
--- a/accessible/src/xul/nsXULMenuAccessible.cpp
+++ b/accessible/src/xul/nsXULMenuAccessible.cpp
@@ -174,26 +174,21 @@ NS_IMETHODIMP nsXULSelectableAccessible:
   nsCOMPtr<nsIDOMXULMultiSelectControlElement> xulMultiSelect =
     do_QueryInterface(mSelectControl);
   if (xulMultiSelect)
     xulMultiSelect->GetSelectedItem(aIndex, getter_AddRefs(selectedItem));
 
   if (aIndex == 0)
     mSelectControl->GetSelectedItem(getter_AddRefs(selectedItem));
 
-  if (selectedItem) {
+  if (selectedItem)
     GetAccService()->GetAccessibleInWeakShell(selectedItem, mWeakShell,
                                               aAccessible);
-    if (*aAccessible) {
-      NS_ADDREF(*aAccessible);
-      return NS_OK;
-    }
-  }
 
-  return NS_ERROR_FAILURE;
+  return (*aAccessible) ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP nsXULSelectableAccessible::GetSelectionCount(PRInt32 *aSelectionCount)
 {
   *aSelectionCount = 0;
   if (!mSelectControl) {
     return NS_ERROR_FAILURE;
   }
--- a/accessible/tests/mochitest/Makefile.in
+++ b/accessible/tests/mochitest/Makefile.in
@@ -37,17 +37,17 @@
 # ***** END LICENSE BLOCK *****
 
 DEPTH		= ../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = accessible
 
-DIRS	= attributes events selectable tree
+DIRS	= actions attributes events selectable states tree
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES =\
 		letters.gif \
 		moz.png \
 		$(topsrcdir)/content/media/test/bug461281.ogg \
@@ -66,23 +66,16 @@ include $(topsrcdir)/config/rules.mk
 		namerules.xml \
  		nsIAccessible_selects.js \
 		nsIAccessibleEditableText.js \
 		relations.js \
 		role.js \
 		states.js \
 		table.js \
 		value.js \
-		test_actions.html \
-		test_actions.xul \
-		test_actions_anchors.html \
-		test_actions_aria.html \
-		test_actions_inputs.html \
-		test_actions_tree.xul \
-		test_actions_treegrid.xul \
 		test_aria_activedescendant.html \
 		test_aria_role_article.html \
 		test_aria_role_equation.html \
 		test_aria_roles.html \
 		test_aria_roles.xul \
 		test_aria_token_attrs.html \
 		test_bug420863.html \
 	$(warning   test_childAtPoint.html temporarily disabled) \
@@ -109,24 +102,16 @@ include $(topsrcdir)/config/rules.mk
 		test_nsIAccessibleHyperText.html \
 		test_nsIAccessibleImage.html \
 		test_nsIAccessNode_utils.html \
 		test_nsOuterDocAccessible.html \
 		test_relations.html \
 		test_relations.xul \
 		test_relations_tree.xul \
 		test_role_nsHyperTextAcc.html \
-		test_role_table_cells.html \
-		test_states.html \
-		test_states_doc.html \
-		test_states_docarticle.html \
-		test_states_editablebody.html \
-		test_states_frames.html \
-		test_states_popup.xul \
-		test_states_tree.xul \
 		test_table_1.html \
 		test_table_4.html \
 		test_table_headers.html \
 		test_table_headers_ariagrid.html \
 		test_table_headers_listbox.xul \
 		test_table_headers_tree.xul \
 		test_table_indexes.html \
 		test_table_indexes_ariagrid.html \
@@ -144,16 +129,12 @@ include $(topsrcdir)/config/rules.mk
 		test_table_struct_tree.xul \
 		test_textboxes.html \
 		test_textboxes.xul \
 		test_value.html \
 		test_value.xul \
 		testTextboxes.js \
 		treeview.css \
 		treeview.js \
-		z_states_frame.html \
-		z_states_framearticle.html \
-		z_states_framecheckbox.html \
-		z_states_frametextbox.html \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/a11y/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/actions/Makefile.in
@@ -0,0 +1,59 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Mozilla Corporation.
+# Portions created by the Initial Developer are Copyright (C) 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@
+relativesrcdir  = accessible/actions
+
+include $(DEPTH)/config/autoconf.mk
+include $(topsrcdir)/config/rules.mk
+
+_TEST_FILES =\
+		test_anchors.html \
+		test_aria.html \
+		test_general.html \
+		test_general.xul \
+		test_inputs.html \
+		test_tree.xul \
+		test_treegrid.xul \
+		$(NULL)
+
+libs:: $(_TEST_FILES)
+	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/a11y/$(relativesrcdir)
rename from accessible/tests/mochitest/test_actions_anchors.html
rename to accessible/tests/mochitest/actions/test_anchors.html
--- a/accessible/tests/mochitest/test_actions_anchors.html
+++ b/accessible/tests/mochitest/actions/test_anchors.html
@@ -1,12 +1,13 @@
 <html>
 
 <head>
-  <title>nsIAccessible actions testing for anchors</title>
+  <title>nsIAccessible actions testing for HTML links that
+   scroll the page to named anchors</title>
 
   <link rel="stylesheet" type="text/css"
         href="chrome://mochikit/content/tests/SimpleTest/test.css" />
 
   <script type="application/javascript"
           src="chrome://mochikit/content/MochiKit/packed.js"></script>
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
rename from accessible/tests/mochitest/test_actions_aria.html
rename to accessible/tests/mochitest/actions/test_aria.html
rename from accessible/tests/mochitest/test_actions.html
rename to accessible/tests/mochitest/actions/test_general.html
--- a/accessible/tests/mochitest/test_actions.html
+++ b/accessible/tests/mochitest/actions/test_general.html
@@ -18,17 +18,27 @@
   <script type="application/javascript"
           src="chrome://mochikit/content/a11y/accessible/actions.js"></script>
 
   <script type="application/javascript">
     function doTest()
     {
       var actionsArray = [
         {
-          ID: "li_clickable",
+          ID: "li_clickable1",
+          actionName: "click",
+          events: CLICK_EVENTS
+        },
+        {
+          ID: "li_clickable2",
+          actionName: "click",
+          events: CLICK_EVENTS
+        },
+        {
+          ID: "li_clickable3",
           actionName: "click",
           events: CLICK_EVENTS
         }
       ];
       testActions(actionsArray);
     }
 
     SimpleTest.waitForExplicitFinish();
@@ -37,19 +47,26 @@
 </head>
 
 <body>
 
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=523789"
      title="nsHTMLLiAccessible shouldn't be inherited from linkable accessible">
     Mozilla Bug 523789
+  </a><br>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=423409"
+     title="Expose click action if mouseup and mousedown are registered">
+    Mozilla Bug 423409
   </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <ul>
-    <li id="li_clickable" onclick="">Clickable list item</li>
+    <li id="li_clickable1" onclick="">Clickable list item</li>
+    <li id="li_clickable2" onmousedown="">Clickable list item</li>
+    <li id="li_clickable3" onmouseup="">Clickable list item</li>
   </ul>
 </body>
 </html>
rename from accessible/tests/mochitest/test_actions.xul
rename to accessible/tests/mochitest/actions/test_general.xul
rename from accessible/tests/mochitest/test_actions_inputs.html
rename to accessible/tests/mochitest/actions/test_inputs.html
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/actions/test_link.html
@@ -0,0 +1,99 @@
+<html>
+
+<head>
+  <title>nsIAccessible actions testing on HTML links (HTML:a)</title>
+
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/common.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/events.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/actions.js"></script>
+
+  <script type="application/javascript">
+    function doTest()
+    {
+      var actionsArray = [
+        {
+          ID: "link1",
+          actionName: "jump",
+          events: CLICK_EVENTS
+        },
+        {
+          ID: "img1",
+          actionName: "click",
+          events: CLICK_EVENTS
+        },
+        {
+          ID: "link2",
+          actionName: "click",
+          events: CLICK_EVENTS
+        },
+        {
+          ID: "img2",
+          actionName: "click",
+          events: CLICK_EVENTS
+        },
+        {
+          ID: "link3",
+          actionName: "click",
+          events: CLICK_EVENTS
+        },
+        {
+          ID: "img3",
+          actionName: "click",
+          events: CLICK_EVENTS
+        },
+        {
+          ID: "link4",
+          actionName: "click",
+          events: CLICK_EVENTS
+        },
+        {
+          ID: "img4",
+          actionName: "click",
+          events: CLICK_EVENTS
+        }
+      ];
+      testActions(actionsArray);
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  </script>
+</head>
+
+<body>
+
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=423409"
+     title="Expose click action if mouseup and mousedown are registered">
+    Mozilla Bug 423409
+  </a>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+
+  <a href="http://mozilla.org" id="link1">
+    <img src="chrome://mochikit/content/a11y/accessible/moz.png" id="img1">
+  </a>
+  <a id="link2" onmousedown="">
+    <img src="chrome://mochikit/content/a11y/accessible/moz.png" id="img2">
+  </a>
+  <a id="link3" onclick="">
+    <img src="chrome://mochikit/content/a11y/accessible/moz.png" id="img3">
+  </a>
+  <a id="link4" onmouseup="">
+    <img src="chrome://mochikit/content/a11y/accessible/moz.png" id="img4">
+  </a>
+</body>
+</html>
rename from accessible/tests/mochitest/test_actions_tree.xul
rename to accessible/tests/mochitest/actions/test_tree.xul
rename from accessible/tests/mochitest/test_actions_treegrid.xul
rename to accessible/tests/mochitest/actions/test_treegrid.xul
--- a/accessible/tests/mochitest/events.js
+++ b/accessible/tests/mochitest/events.js
@@ -68,31 +68,27 @@ function waitForEvent(aEventType, aTarge
  * @param aEventHandler  event listener object, when accessible event of the
  *                       given type is handled then 'handleEvent' method of
  *                       this object is invoked with nsIAccessibleEvent object
  *                       as the first argument.
  */
 function registerA11yEventListener(aEventType, aEventHandler)
 {
   listenA11yEvents(true);
-
-  gA11yEventApplicantsCount++;
   addA11yEventListener(aEventType, aEventHandler);
 }
 
 /**
  * Unregister accessibility event listener. Must be called for every registered
  * event listener (see registerA11yEventListener() function) when the listener
  * is not needed.
  */
 function unregisterA11yEventListener(aEventType, aEventHandler)
 {
   removeA11yEventListener(aEventType, aEventHandler);
-
-  gA11yEventApplicantsCount--;
   listenA11yEvents(false);
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // Event queue
 
 /**
@@ -168,17 +164,16 @@ function eventQueue(aEventType)
   }
 
   /**
    * Start the queue processing.
    */
   this.invoke = function eventQueue_invoke()
   {
     listenA11yEvents(true);
-    gA11yEventApplicantsCount++;
 
     // XXX: Intermittent test_events_caretmove.html fails withouth timeout,
     // see bug 474952.
     this.processNextInvokerInTimeout(true);
   }
 
   /**
    * This function is called when all events in the queue were handled.
@@ -190,17 +185,17 @@ function eventQueue(aEventType)
 
   // private
 
   /**
    * Process next invoker.
    */
   this.processNextInvoker = function eventQueue_processNextInvoker()
   {
-    // Finish rocessing of the current invoker.
+    // Finish processing of the current invoker.
     var testFailed = false;
 
     var invoker = this.getInvoker();
     if (invoker) {
       if ("finalCheck" in invoker)
         invoker.finalCheck();
 
       if (invoker.wasCaught) {
@@ -239,17 +234,16 @@ function eventQueue(aEventType)
         }
       }
     }
 
     this.clearEventHandler();
 
     // Check if need to stop the test.
     if (testFailed || this.mIndex == this.mInvokers.length - 1) {
-      gA11yEventApplicantsCount--;
       listenA11yEvents(false);
 
       var res = this.onFinish();
       if (res != DO_NOT_FINISH_TEST)
         SimpleTest.finish();
 
       return;
     }
@@ -762,29 +756,42 @@ function invokerChecker(aEventType, aTar
 ////////////////////////////////////////////////////////////////////////////////
 // Private implementation details.
 ////////////////////////////////////////////////////////////////////////////////
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // General
 
-var gObserverService = null;
-
 var gA11yEventListeners = {};
 var gA11yEventApplicantsCount = 0;
 
 var gA11yEventObserver =
 {
+  // The service reference needs to live in the observer, instead of as a global var,
+  //   to be available in observe() catch case too.
+  observerService :
+    Components.classes["@mozilla.org/observer-service;1"]
+              .getService(nsIObserverService),
+
   observe: function observe(aSubject, aTopic, aData)
   {
     if (aTopic != "accessible-event")
       return;
 
-    var event = aSubject.QueryInterface(nsIAccessibleEvent);
+    var event;
+    try {
+      event = aSubject.QueryInterface(nsIAccessibleEvent);
+    } catch (ex) {
+      // After a test is aborted (i.e. timed out by the harness), this exception is soon triggered.
+      // Remove the leftover observer, otherwise it "leaks" to all the following tests.
+      this.observerService.removeObserver(this, "accessible-event");
+      // Forward the exception, with added explanation.
+      throw "[accessible/events.js, gA11yEventObserver.observe] This is expected if a previous test has been aborted... Initial exception was: [ " + ex + " ]";
+    }
     var listenersArray = gA11yEventListeners[event.eventType];
 
     if (gA11yEventDumpID) { // debug stuff
       var target = event.DOMNode;
       var dumpElm = document.getElementById(gA11yEventDumpID);
 
       var parent = target;
       while (parent && parent != dumpElm)
@@ -807,26 +814,27 @@ var gA11yEventObserver =
 
     for (var index = 0; index < listenersArray.length; index++)
       listenersArray[index].handleEvent(event);
   }
 };
 
 function listenA11yEvents(aStartToListen)
 {
-  if (aStartToListen && !gObserverService) {
-    gObserverService = Components.classes["@mozilla.org/observer-service;1"].
-      getService(nsIObserverService);
-    
-    gObserverService.addObserver(gA11yEventObserver, "accessible-event",
-                                 false);
-  } else if (!gA11yEventApplicantsCount) {
-    gObserverService.removeObserver(gA11yEventObserver,
-                                    "accessible-event");
-    gObserverService = null;
+  if (aStartToListen) {
+    // Add observer when adding the first applicant only.
+    if (!(gA11yEventApplicantsCount++))
+      gA11yEventObserver.observerService
+                        .addObserver(gA11yEventObserver, "accessible-event", false);
+  } else {
+    // Remove observer when there are no more applicants only.
+    // '< 0' case should not happen, but just in case: removeObserver() will throw.
+    if (--gA11yEventApplicantsCount <= 0)
+      gA11yEventObserver.observerService
+                        .removeObserver(gA11yEventObserver, "accessible-event");
   }
 }
 
 function addA11yEventListener(aEventType, aEventHandler)
 {
   if (!(aEventType in gA11yEventListeners))
     gA11yEventListeners[aEventType] = new Array();
   
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/states/Makefile.in
@@ -0,0 +1,64 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Mozilla Corporation.
+# Portions created by the Initial Developer are Copyright (C) 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@
+relativesrcdir  = accessible/states
+
+include $(DEPTH)/config/autoconf.mk
+include $(topsrcdir)/config/rules.mk
+
+_TEST_FILES =\
+		test_aria.html \
+		test_doc.html \
+		test_docarticle.html \
+		test_editablebody.html \
+		test_frames.html \
+		test_link.html \
+		test_popup.xul \
+		test_tree.xul \
+		z_frames.html \
+		z_frames_article.html \
+		z_frames_checkbox.html \
+		z_frames_textbox.html \
+		$(NULL)
+
+libs:: $(_TEST_FILES)
+	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/a11y/$(relativesrcdir)
rename from accessible/tests/mochitest/test_states.html
rename to accessible/tests/mochitest/states/test_aria.html
--- a/accessible/tests/mochitest/test_states.html
+++ b/accessible/tests/mochitest/states/test_aria.html
@@ -1,12 +1,12 @@
 <html>
 
 <head>
-  <title>nsIAccessible states testing</title>
+  <title>ARIA based nsIAccessible states testing</title>
 
   <link rel="stylesheet" type="text/css"
         href="chrome://mochikit/content/tests/SimpleTest/test.css" />
 
   <style type="text/css">
     .offscreen {
       position: absolute;
       left: -5000px;
rename from accessible/tests/mochitest/test_states_doc.html
rename to accessible/tests/mochitest/states/test_doc.html
rename from accessible/tests/mochitest/test_states_docarticle.html
rename to accessible/tests/mochitest/states/test_docarticle.html
rename from accessible/tests/mochitest/test_states_editablebody.html
rename to accessible/tests/mochitest/states/test_editablebody.html
rename from accessible/tests/mochitest/test_states_frames.html
rename to accessible/tests/mochitest/states/test_frames.html
--- a/accessible/tests/mochitest/test_states_frames.html
+++ b/accessible/tests/mochitest/states/test_frames.html
@@ -56,14 +56,14 @@
     title="Expose non-editable documents as readonly, regardless of role">
      Mozilla Bug 467387
   </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
   
-  <iframe id="frame_doc" src="z_states_frame.html"></iframe>
-  <iframe id="frame_doc_article" src="z_states_framearticle.html"></iframe>
-  <iframe id="frame_doc_checkbox" src="z_states_framecheckbox.html"></iframe>
-  <iframe id="frame_doc_textbox" src="z_states_frametextbox.html"></iframe>
+  <iframe id="frame_doc" src="z_frames.html"></iframe>
+  <iframe id="frame_doc_article" src="z_frames_article.html"></iframe>
+  <iframe id="frame_doc_checkbox" src="z_frames_checkbox.html"></iframe>
+  <iframe id="frame_doc_textbox" src="z_frames_textbox.html"></iframe>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_link.html
@@ -0,0 +1,57 @@
+<html>
+
+<head>
+  <title>HTML link states testing</title>
+
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/common.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/role.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/a11y/accessible/states.js"></script>
+
+  <script type="application/javascript">
+    function doTest()
+    {
+      // strong roles
+      testStates("link1", STATE_LINKED);
+      testStates("link2", STATE_LINKED);
+      testStates("link3", STATE_LINKED);
+      testStates("link4", STATE_LINKED);
+
+      SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  </script>
+
+</head>
+
+<body>
+
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=423409"
+     title="Expose click action if mouseup and mousedown are registered">
+    Mozilla Bug 423409
+  </a>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+
+  <a id="link1" href="http://mozilla.org">link</a>
+  <a id="link2" onclick="">link</a>
+  <a id="link3" onmousedown="">link</a>
+  <a id="link4" onmouseup="">link</a>
+
+</body>
+</html>
rename from accessible/tests/mochitest/test_states_popup.xul
rename to accessible/tests/mochitest/states/test_popup.xul
rename from accessible/tests/mochitest/test_states_tree.xul
rename to accessible/tests/mochitest/states/test_tree.xul
rename from accessible/tests/mochitest/z_states_frame.html
rename to accessible/tests/mochitest/states/z_frames.html
rename from accessible/tests/mochitest/z_states_framearticle.html
rename to accessible/tests/mochitest/states/z_frames_article.html
rename from accessible/tests/mochitest/z_states_framecheckbox.html
rename to accessible/tests/mochitest/states/z_frames_checkbox.html
rename from accessible/tests/mochitest/z_states_frametextbox.html
rename to accessible/tests/mochitest/states/z_frames_textbox.html
--- a/accessible/tests/mochitest/test_role_nsHyperTextAcc.html
+++ b/accessible/tests/mochitest/test_role_nsHyperTextAcc.html
@@ -1,15 +1,12 @@
 <!DOCTYPE html>
 <html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=472326
--->
 <head>
-  <title>test nsHyperTextAccessible roles</title>
+  <title>test nsHyperTextAccessible accesible objects creation and their roles</title>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
 
   <script type="application/javascript"
           src="chrome://mochikit/content/MochiKit/packed.js"></script>
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
 
   <script type="application/javascript"
@@ -46,31 +43,42 @@ https://bugzilla.mozilla.org/show_bug.cg
       // get broken.
       testRole("p", ROLE_PARAGRAPH);
 
       // Test dl, dt, dd
       testRole("definitionlist", ROLE_LIST);
       testRole("definitionterm", ROLE_LISTITEM);
       testRole("definitiondescription", ROLE_PARAGRAPH);
 
+      // Has click, mousedown or mouseup listeners.
+      testRole("span1", ROLE_TEXT_CONTAINER);
+      testRole("span2", ROLE_TEXT_CONTAINER);
+      testRole("span3", ROLE_TEXT_CONTAINER);
+
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTests);
   </script>
 </head>
 <body>
 
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=472326"
      title="html:input of type "file" no longer rendered to screen readers">
-     Mozilla Bug 472326</a>
+    Mozilla Bug 472326
+  </a><br>
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=474261"
       title="Test remaining implementations in nsHypertextAccessible::GetRole">
-      bug 474261</a>
+    bug 474261
+  </a><br>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=423409"
+     title="Expose click action if mouseup and mousedown are registered">
+    Mozilla Bug 423409
   </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
   <form id="frm" action="submit.php" method="post">
     <label for="data">File</label>:
     <input type="file" id="data" name="data" size="50"/>
@@ -84,10 +92,14 @@ https://bugzilla.mozilla.org/show_bug.cg
   <h4 id="head4">A heading level 4</h4>
   <h5 id="head5">A heading level 5</h5>
   <h6 id="head6">A heading level 6</h6>
 
   <dl id="definitionlist">
   <dt id="definitionterm">gecko</dt>
   <dd id="definitiondescription">geckos have sticky toes</dd>
   </dl>
+
+  <span id="span1" onclick="">clickable span</span>
+  <span id="span2" onmousedown="">clickable span</span>
+  <span id="span3" onmouseup="">clickable span</span>
 </body>
 </html>
deleted file mode 100644
--- a/accessible/tests/mochitest/test_role_table_cells.html
+++ /dev/null
@@ -1,71 +0,0 @@
-<!DOCTYPE html>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=474281
--->
-<head>
-  <title>Name calculation for table and grid cells</title>
-  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
-
-  <script type="application/javascript"
-          src="chrome://mochikit/content/MochiKit/packed.js"></script>
-  <script type="application/javascript"
-          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-
-  <script type="application/javascript"
-          src="chrome://mochikit/content/a11y/accessible/common.js"></script>
-  <script type="application/javascript"
-          src="chrome://mochikit/content/a11y/accessible/nsIAccessible_name.js"></script>
-  <script type="application/javascript"
-          src="chrome://mochikit/content/a11y/accessible/role.js"></script>
-
-  <script type="application/javascript">
-    function doTests()
-    {
-      // Test table cell name and role
-      testRole("tc", ROLE_CELL);
-
-      // Test grid cell.
-      testRole("gc", ROLE_GRID_CELL);
-
-      SimpleTest.finish();
-    }
-
-    SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTests);
-  </script>
-</head>
-<body>
-
-  <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=474281"
-      title="accessible name of html table cells is incorrectly including descendants">
-      Mozilla bug 474281</a>
-  </a>
-  <p id="display"></p>
-  <div id="content" style="display: none"></div>
-  <pre id="test">
-  </pre>
-  <table>
-    <tr>
-      <td id="tc">
-        <p>This is a paragraph</p>
-        <a href="#">This is a link</a>
-        <ul>
-          <li>This is a list</li>
-        </ul>
-      </td>
-    </tr>
-  </table>
-  <table>
-    <tr>
-      <td id="gc" role="gridcell">
-        <p>This is a paragraph</p>
-        <a href="#">This is a link</a>
-        <ul>
-          <li>This is a list</li>
-        </ul>
-      </td>
-    </tr>
-  </table>
-</body>
-</html>
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -206,17 +206,17 @@ ifdef BUILD_STATIC_LIBS
 OS_LIBS += -ltracker -lgame
 endif
 endif
 
 ifeq ($(OS_ARCH),OS2)
 RESFILE=splashos2.res
 RCFLAGS += -DMOZ_PHOENIX
 ifdef BUILD_STATIC_LIBS
-RCFLAGS += -DMOZ_STATIC_BUILD -i $(DIST)/include/widget
+RCFLAGS += -DMOZ_STATIC_BUILD -i $(DIST)/include
 endif
 ifdef DEBUG
 RCFLAGS += -DDEBUG
 endif
 RCFLAGS += -DFIREFOX_ICO=\"$(DIST)/branding/firefox-os2.ico\" -DDOCUMENT_ICO=\"$(DIST)/branding/document-os2.ico\"
 endif
 
 include $(topsrcdir)/config/rules.mk
--- a/browser/base/content/browser-fullZoom.js
+++ b/browser/base/content/browser-fullZoom.js
@@ -203,19 +203,19 @@ var FullZoom = {
     // the event before the event state manager has a chance to apply the zoom
     // during nsEventStateManager::PostHandleEvent.
     window.setTimeout(function (self) { self._applySettingToPref() }, 0, this);
   },
 
   // nsIObserver
 
   observe: function (aSubject, aTopic, aData) {
-    switch(aTopic) {
+    switch (aTopic) {
       case "nsPref:changed":
-        switch(aData) {
+        switch (aData) {
           case "browser.zoom.siteSpecific":
             this._siteSpecificPref =
               this._prefBranch.getBoolPref("browser.zoom.siteSpecific");
             break;
           case "browser.zoom.updateBackgroundTabs":
             this.updateBackgroundTabs =
               this._prefBranch.getBoolPref("browser.zoom.updateBackgroundTabs");
             break;
--- a/browser/base/content/browser-tabPreviews.js
+++ b/browser/base/content/browser-tabPreviews.js
@@ -571,17 +571,17 @@ var allTabs = {
   },
   get previews () this.container.getElementsByClassName("allTabs-preview"),
   get isOpen () this.panel.state == "open" || this.panel.state == "showing",
 
   init: function allTabs_init() {
     if (this._initiated)
       return;
     this._initiated = true;
-	
+
     Array.forEach(gBrowser.mTabs, function (tab) {
       this._addPreview(tab);
     }, this);
 
     gBrowser.tabContainer.addEventListener("TabOpen", this, false);
     gBrowser.tabContainer.addEventListener("TabAttrModified", this, false);
     gBrowser.tabContainer.addEventListener("TabMove", this, false);
     gBrowser.tabContainer.addEventListener("TabClose", this, false);
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2631,37 +2631,48 @@ function FillInHTMLTooltip(tipElement)
   if (tipElement.namespaceURI == "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul")
     return retVal;
 
   const XLinkNS = "http://www.w3.org/1999/xlink";
 
 
   var titleText = null;
   var XLinkTitleText = null;
+  var SVGTitleText = null;
   var direction = tipElement.ownerDocument.dir;
 
-  while (!titleText && !XLinkTitleText && tipElement) {
+  while (!titleText && !XLinkTitleText && !SVGTitleText && tipElement) {
     if (tipElement.nodeType == Node.ELEMENT_NODE) {
       titleText = tipElement.getAttribute("title");
       XLinkTitleText = tipElement.getAttributeNS(XLinkNS, "title");
+      if (tipElement instanceof SVGElement) {
+        let length = tipElement.childNodes.length;
+        for (let i = 0; i < length; i++) {
+          let childNode = tipElement.childNodes[i];
+          if (childNode instanceof SVGTitleElement) {
+            SVGTitleText = childNode.textContent;
+            break;
+          }
+        }
+      }
       var defView = tipElement.ownerDocument.defaultView;
       // XXX Work around bug 350679:
       // "Tooltips can be fired in documents with no view".
       if (!defView)
         return retVal;
       direction = defView.getComputedStyle(tipElement, "")
         .getPropertyValue("direction");
     }
     tipElement = tipElement.parentNode;
   }
 
   var tipNode = document.getElementById("aHTMLTooltip");
   tipNode.style.direction = direction;
   
-  [titleText, XLinkTitleText].forEach(function (t) {
+  [titleText, XLinkTitleText, SVGTitleText].forEach(function (t) {
     if (t && /\S/.test(t)) {
 
       // Per HTML 4.01 6.2 (CDATA section), literal CRs and tabs should be
       // replaced with spaces, and LFs should be removed entirely.
       // XXX Bug 322270: We don't preserve the result of entities like &#13;,
       // which should result in a line break in the tooltip, because we can't
       // distinguish that from a literal character in the source by this point.
       t = t.replace(/[\r\t]/g, ' ');
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -2171,18 +2171,17 @@
                 this.moveTabTo(newTab, newIndex);
                 if (draggedTab.parentNode != this.mTabContainer || aEvent.shiftKey)
                   this.selectedTab = newTab;
               }
               else {
                 // move the dropped tab
                 if (newIndex > draggedTab._tPos)
                   newIndex--;
-                if (newIndex != draggedTab._tPos)
-                  this.moveTabTo(draggedTab, newIndex);
+                this.moveTabTo(draggedTab, newIndex);
               }
             }
             else if (draggedTab) {
               // swap the dropped tab with a new one we create and then close
               // it in the other window (making it seem to have moved between
               // windows)
               newIndex = this.getNewIndex(aEvent);
               newTab = this.addTab("about:blank");
@@ -2335,44 +2334,43 @@
         </body>
       </method>
 
       <method name="moveTabTo">
         <parameter name="aTab"/>
         <parameter name="aIndex"/>
         <body>
         <![CDATA[
+          var oldPosition = aTab._tPos;
+          if (oldPosition == aIndex)
+            return;
+
           this._lastRelatedTab = null;
           this._browsers = null; // invalidate cache
           this.mTabFilters.splice(aIndex, 0, this.mTabFilters.splice(aTab._tPos, 1)[0]);
           this.mTabListeners.splice(aIndex, 0, this.mTabListeners.splice(aTab._tPos, 1)[0]);
 
-          var oldPosition = aTab._tPos;
-
           aIndex = aIndex < aTab._tPos ? aIndex: aIndex+1;
           this.mCurrentTab._selected = false;
           // use .item() instead of [] because dragging to the end of the strip goes out of
           // bounds: .item() returns null (so it acts like appendChild), but [] throws
-          this.mTabContainer.insertBefore(aTab, this.mTabContainer.childNodes.item(aIndex));
+          this.mTabContainer.insertBefore(aTab, this.mTabs.item(aIndex));
           // invalidate cache, because mTabContainer is about to change
           this._browsers = null;
 
-          var i;
-          for (i = 0; i < this.mTabContainer.childNodes.length; i++) {
-            this.mTabContainer.childNodes[i]._tPos = i;
-            this.mTabContainer.childNodes[i]._selected = false;
+          for (let i = 0; i < this.mTabs.length; i++) {
+            this.mTabs[i]._tPos = i;
+            this.mTabs[i]._selected = false;
           }
           this.mCurrentTab._selected = true;
           this.mTabContainer.mTabstrip.ensureElementIsVisible(this.mCurrentTab, false);
 
           var evt = document.createEvent("UIEvents");
           evt.initUIEvent("TabMove", true, false, window, oldPosition);
           aTab.dispatchEvent(evt);
-
-          return aTab;
         ]]>
         </body>
       </method>
 
       <method name="getNewIndex">
         <parameter name="aEvent"/>
         <body>
           <![CDATA[
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -76,81 +76,84 @@ include $(topsrcdir)/config/rules.mk
 #   browser_bug423833.js is bug 428712
 #   browser_sanitize-download-history.js is bug 432425
 #
 # browser_sanitizeDialog_treeView.js is disabled until the tree view is added
 # back to the clear recent history dialog (santize.xul), if it ever is (bug
 # 480169)
 
 _BROWSER_FILES = \
+                 browser_NetworkPrioritizer.js \
+                 browser_allTabsPanel.js \
+                 browser_alltabslistener.js \
+                 browser_bug304198.js \
                  browser_bug321000.js \
-                 browser_sanitize-timespans.js \
+                 title_test.svg \
+                 browser_bug329212.js \
+                 browser_bug356571.js \
+                 browser_bug386835.js \
                  browser_bug405137.js \
                  browser_bug409481.js \
                  browser_bug413915.js \
+                 browser_bug416661.js \
                  browser_bug417483.js \
                  browser_bug419612.js \
                  browser_bug420160.js \
+                 browser_bug422590.js \
                  browser_bug424101.js \
                  browser_bug427559.js \
                  browser_bug432599.js \
                  browser_bug435035.js \
                  browser_bug441778.js \
                  browser_bug455852.js \
                  browser_bug462673.js \
+                 browser_bug477014.js \
+                 browser_bug479408.js \
+                 browser_bug479408_sample.html \
                  browser_bug481560.js \
                  browser_bug484315.js \
-                 browser_bug477014.js \
+                 browser_bug491431.js \
                  browser_bug495058.js \
                  browser_bug517902.js \
                  browser_bug520538.js \
                  browser_bug521216.js \
                  browser_bug537474.js \
+                 browser_contextSearchTabPosition.js \
+                 browser_ctrlTab.js \
                  browser_discovery.js \
+                 browser_drag.js \
+                 browser_gestureSupport.js \
+                 browser_getshortcutoruri.js \
+                 browser_overflowScroll.js \
+                 browser_pageInfo.js \
+                 browser_page_style_menu.js \
+                 browser_plainTextLinks.js \
+                 browser_pluginnotification.js \
+                 browser_relatedTabs.js \
+                 browser_sanitize-passwordDisabledHosts.js \
+                 browser_sanitize-sitepermissions.js \
+                 browser_sanitize-timespans.js \
+                 browser_sanitizeDialog.js \
+                 browser_scope.js \
+                 browser_selectTabAtIndex.js \
                  browser_tabfocus.js \
+                 browser_tabs_owner.js \
                  discovery.html \
                  moz.png \
                  test_bug435035.html \
                  test_bug462673.html \
-                 browser_getshortcutoruri.js \
-                 browser_page_style_menu.js \
                  page_style_sample.html \
-                 browser_ctrlTab.js \
-                 browser_selectTabAtIndex.js \
-                 browser_gestureSupport.js \
-                 browser_pageInfo.js \
                  feed_tab.html \
-                 browser_pluginnotification.js \
                  plugin_unknown.html \
                  plugin_test.html \
                  plugin_both.html \
                  plugin_both2.html \
-                 browser_alltabslistener.js \
                  alltabslistener.html \
                  zoom_test.html \
-                 browser_bug416661.js \
-                 browser_bug386835.js \
                  dummy_page.html \
-                 browser_bug422590.js \
-                 browser_sanitize-sitepermissions.js \
-                 browser_bug356571.js \
-                 browser_sanitize-passwordDisabledHosts.js \
-                 browser_bug479408.js \
-                 browser_bug479408_sample.html \
-                 browser_scope.js \
-                 browser_overflowScroll.js \
-                 browser_sanitizeDialog.js \
-                 browser_tabs_owner.js \
-                 browser_bug491431.js \
-                 browser_bug304198.js \
-                 browser_drag.js \
-                 browser_relatedTabs.js \
-                 browser_plainTextLinks.js \
-                 browser_contextSearchTabPosition.js \
-                 browser_NetworkPrioritizer.js \
     $(NULL)
 
 ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 _BROWSER_FILES += browser_bug462289.js
 else
 _BROWSER_FILES += browser_customize.js
 endif
 
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_allTabsPanel.js
@@ -0,0 +1,154 @@
+function test() {
+  waitForExplicitFinish();
+  allTabs.init();
+  nextSequence();
+}
+
+var sequences = 3;
+var chars = "ABCDEFGHI";
+var closedTabs;
+var history;
+var steps;
+var whenOpen = [
+  startSearch,
+  clearSearch, clearSearch,
+  closeTab,
+  moveTab,
+  closePanel,
+];
+var whenClosed = [
+  openPanel, openPanel, openPanel, openPanel, openPanel, openPanel,
+  closeTab, closeTab, closeTab,
+  moveTab, moveTab, moveTab,
+  selectTab, selectTab,
+  undoCloseTab,
+  openTab,
+];
+
+function rand(min, max) {
+  return min + Math.floor(Math.random() * (max - min + 1));
+}
+function pickOne(array) {
+  return array[rand(0, array.length - 1)];
+}
+function pickOneTab() {
+  var tab = pickOne(gBrowser.tabContainer.childNodes);
+  return [tab, Array.indexOf(gBrowser.tabContainer.childNodes, tab)];
+}
+function nextSequence() {
+  while (gBrowser.browsers.length > 1)
+    gBrowser.removeCurrentTab();
+  if (sequences-- <= 0) {
+    allTabs.close();
+    gBrowser.addTab();
+    gBrowser.removeCurrentTab();
+    finish();
+    return;
+  }
+  closedTabs = 0;
+  steps = rand(10, 20);
+  var initialTabs = "";
+  while (gBrowser.browsers.length < rand(3, 20)) {
+    let tabChar = pickOne(chars);
+    initialTabs += tabChar;
+    gBrowser.addTab("data:text/plain," + tabChar);
+  }
+  history = [initialTabs];
+  gBrowser.removeCurrentTab();
+  next();
+}
+function next() {
+  executeSoon(function () {
+    is(allTabs.previews.length, gBrowser.browsers.length,
+       history.join(", "));
+    if (steps-- <= 0) {
+      nextSequence();
+      return;
+    }
+    var step;
+    var rv;
+    do {
+      step = pickOne(allTabs.isOpen ? whenOpen : whenClosed);
+      rv = step();
+    } while (rv === false);
+    history.push(step.name + (rv !== true && rv !== undefined ? " " + rv : ""));
+  });
+}
+
+function openPanel() {
+  if (allTabs.isOpen)
+    return false;
+  allTabs.panel.addEventListener("popupshown", function () {
+    allTabs.panel.removeEventListener("popupshown", arguments.callee, false);
+    next();
+  }, false);
+  allTabs.open();
+  return true;
+}
+
+function closePanel() {
+  allTabs.panel.addEventListener("popuphidden", function () {
+    allTabs.panel.removeEventListener("popuphidden", arguments.callee, false);
+    next();
+  }, false);
+  allTabs.close();
+}
+
+function closeTab() {
+  if (gBrowser.browsers.length == 1)
+    return false;
+  var [tab, index] = pickOneTab();
+  gBrowser.removeTab(tab);
+  closedTabs++;
+  next();
+  return index;
+}
+
+function startSearch() {
+  allTabs.filterField.value = pickOne(chars);
+  allTabs.filter();
+  next();
+  return allTabs.filterField.value;
+}
+
+function clearSearch() {
+  if (!allTabs.filterField.value)
+    return false;
+  allTabs.filterField.value = "";
+  allTabs.filter();
+  next();
+  return true;
+}
+
+function undoCloseTab() {
+  if (!closedTabs)
+    return false;
+  window.undoCloseTab(0);
+  closedTabs--;
+  next();
+  return true;
+}
+
+function selectTab() {
+  var [tab, index] = pickOneTab();
+  gBrowser.selectedTab = tab;
+  next();
+  return index;
+}
+
+function openTab() {
+  BrowserOpenTab();
+  next();
+}
+
+function moveTab() {
+  if (gBrowser.browsers.length == 1)
+    return false;
+  var [tab, currentIndex] = pickOneTab();
+  do {
+    var [, newIndex] = pickOneTab();
+  } while (newIndex == currentIndex);
+  gBrowser.moveTabTo(tab, newIndex);
+  next();
+  return currentIndex + "->" + newIndex;
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_bug329212.js
@@ -0,0 +1,36 @@
+function test () {
+  waitForExplicitFinish();
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.selectedBrowser.addEventListener("load", function () {
+    gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
+
+    let doc = gBrowser.contentDocument;
+    let tooltip = document.getElementById("aHTMLTooltip");
+    ok(FillInHTMLTooltip(doc.getElementById("text1"), "should get title"));
+    is(tooltip.getAttribute("label"), "    This            is a title    ");
+
+    ok(!FillInHTMLTooltip(doc.getElementById("text2"), "should not get title"));
+
+    ok(!FillInHTMLTooltip(doc.getElementById("text3"), "should not get title"));
+
+    ok(FillInHTMLTooltip(doc.getElementById("link1"), "should get title"));
+    is(tooltip.getAttribute("label"), "      This is a title    ");
+    ok(FillInHTMLTooltip(doc.getElementById("text4"), "should get title"));
+    is(tooltip.getAttribute("label"), "      This is a title    ");
+
+    ok(!FillInHTMLTooltip(doc.getElementById("link2"), "should not get title"));
+
+    ok(FillInHTMLTooltip(doc.getElementById("link3"), "should get title"));
+    ok(tooltip.getAttribute("label") != "");
+
+    ok(FillInHTMLTooltip(doc.getElementById("link4"), "should get title"));
+    is(tooltip.getAttribute("label"), "This is an xlink:title attribute");
+
+    gBrowser.removeCurrentTab();
+    finish();
+  }, true);
+
+  content.location = 
+    "http://localhost:8888/browser/browser/base/content/test/title_test.svg";
+}
+
--- a/browser/base/content/test/browser_drag.js
+++ b/browser/base/content/test/browser_drag.js
@@ -1,23 +1,24 @@
 function test()
 {
   // ---- Test dragging the proxy icon ---
-
   var value = content.location.href;
   var urlString = value + "\n" + content.document.title;
   var htmlString = "<a href=\"" + value + "\">" + value + "</a>";
-
   var expected = [ [
-    "text/x-moz-url: " + urlString,
-    "text/uri-list: " + value,
-    "text/plain: " + value,
-    "text/html: " + htmlString
+    { type  : "text/x-moz-url",
+      data  : urlString },
+    { type  : "text/uri-list",
+      data  : value },
+    { type  : "text/plain",
+      data  : value },
+    { type  : "text/html",
+      data  : htmlString }
   ] ];
-
   // set the valid attribute so dropping is allowed
   var proxyicon = document.getElementById("page-proxy-favicon")
   var oldstate = proxyicon.getAttribute("pageproxystate");
   proxyicon.setAttribute("pageproxystate", "valid");
   var dt = EventUtils.synthesizeDragStart(proxyicon, expected);
   is(dt, null, "drag on proxy icon");
   proxyicon.setAttribute("pageproxystate", oldstate);
   // Now, the identity information panel is opened by the proxy icon click.
--- a/browser/base/content/test/browser_pageInfo.js
+++ b/browser/base/content/test/browser_pageInfo.js
@@ -8,37 +8,35 @@ function test() {
   gBrowser.selectedBrowser.addEventListener("load", function () {
     gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
     pageInfo = BrowserPageInfo();
     obs.addObserver(observer, "page-info-dialog-loaded", false);
   }, true);
   content.location =
     "https://example.com/browser/browser/base/content/test/feed_tab.html";
 
-  var observer = {
-    observe: function(win, topic, data) {
-      if (topic != "page-info-dialog-loaded")
-        return;
+  function observer(win, topic, data) {
+    if (topic != "page-info-dialog-loaded")
+      return;
 
-      switch (atTest) {
-        case 0:
-          atTest++;
-          handlePageInfo();
-          break;
-        case 1:
-          atTest++;
-          pageInfo = win;
-          testLockClick();
-          break;
-        case 2:
-          atTest++;
-          obs.removeObserver(observer, "page-info-dialog-loaded");
-          testLockDoubleClick();
-          break;
-      }
+    switch (atTest) {
+      case 0:
+        atTest++;
+        handlePageInfo();
+        break;
+      case 1:
+        atTest++;
+        pageInfo = win;
+        testLockClick();
+        break;
+      case 2:
+        atTest++;
+        obs.removeObserver(observer, "page-info-dialog-loaded");
+        testLockDoubleClick();
+        break;
     }
   }
 
   function $(aId) { return pageInfo.document.getElementById(aId) };
 
   function handlePageInfo() {
     var feedTab = $("feedTab");
     var feedListbox = $("feedListbox");
--- a/browser/base/content/test/browser_sanitize-download-history.js
+++ b/browser/base/content/test/browser_sanitize-download-history.js
@@ -140,25 +140,24 @@ function test()
 
   // Empty any old downloads
   db.executeSimpleSQL("DELETE FROM moz_downloads");
 
   // Close the UI if necessary
   let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
            getService(Ci.nsIWindowWatcher);
   let win = ww.getWindowByName("Sanatize", null);
-  if (win && (win instanceof Ci.nsIDOMWindowInternal)) win.close();
+  if (win && (win instanceof Ci.nsIDOMWindowInternal))
+    win.close();
 
   // Start the test when the sanitize window loads
-  ww.registerNotification({
-    observe: function(aSubject, aTopic, aData) {
-      ww.unregisterNotification(this);
-      aSubject.QueryInterface(Ci.nsIDOMEventTarget).
-      addEventListener("DOMContentLoaded", doTest, false);
-    }
+  ww.registerNotification(function (aSubject, aTopic, aData) {
+    ww.unregisterNotification(arguments.callee);
+    aSubject.QueryInterface(Ci.nsIDOMEventTarget)
+            .addEventListener("DOMContentLoaded", doTest, false);
   });
 
   // Let the methods that run onload finish before we test
   let doTest = function() setTimeout(function() {
     let win = ww.getWindowByName("Sanitize", null)
                 .QueryInterface(Ci.nsIDOMWindowInternal);
 
     for (let i = 0; i < tests.length; i++)
--- a/browser/base/content/test/browser_sanitizeDialog.js
+++ b/browser/base/content/test/browser_sanitizeDialog.js
@@ -531,79 +531,77 @@ WindowHelper.prototype = {
    * Opens the clear recent history dialog.  Before calling this, set
    * this.onload to a function to execute onload.  It should close the dialog
    * when done so that the tests may continue.  Set this.onunload to a function
    * to execute onunload.  this.onunload is optional.
    */
   open: function () {
     let wh = this;
 
-    let windowObserver = {
-      observe: function(aSubject, aTopic, aData) {
-        if (aTopic !== "domwindowopened")
+    function windowObserver(aSubject, aTopic, aData) {
+      if (aTopic != "domwindowopened")
+        return;
+
+      winWatch.unregisterNotification(windowObserver);
+
+      var loaded = false;
+      let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
+
+      win.addEventListener("load", function onload(event) {
+        win.removeEventListener("load", onload, false);
+
+        if (win.name !== "SanitizeDialog")
           return;
 
-        winWatch.unregisterNotification(this);
-
-        var loaded = false;
-        let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
-
-        win.addEventListener("load", function onload(event) {
-          win.removeEventListener("load", onload, false);
-
-          if (win.name !== "SanitizeDialog")
-            return;
-
-          wh.win = win;
-          loaded = true;
+        wh.win = win;
+        loaded = true;
 
-          executeSoon(function () {
-            // Some exceptions that reach here don't reach the test harness, but
-            // ok()/is() do...
-            try {
-              wh.onload();
-            }
-            catch (exc) {
-              win.close();
-              ok(false, "Unexpected exception: " + exc + "\n" + exc.stack);
-              finish();
-            }
-          });
-        }, false);
+        executeSoon(function () {
+          // Some exceptions that reach here don't reach the test harness, but
+          // ok()/is() do...
+          try {
+            wh.onload();
+          }
+          catch (exc) {
+            win.close();
+            ok(false, "Unexpected exception: " + exc + "\n" + exc.stack);
+            finish();
+          }
+        });
+      }, false);
+
+      win.addEventListener("unload", function onunload(event) {
+        if (win.name !== "SanitizeDialog") {
+          win.removeEventListener("unload", onunload, false);
+          return;
+        }
 
-        win.addEventListener("unload", function onunload(event) {
-          if (win.name !== "SanitizeDialog") {
-            win.removeEventListener("unload", onunload, false);
-            return;
-          }
+        // Why is unload fired before load?
+        if (!loaded)
+          return;
 
-          // Why is unload fired before load?
-          if (!loaded)
-            return;
-
-          win.removeEventListener("unload", onunload, false);
-          wh.win = win;
+        win.removeEventListener("unload", onunload, false);
+        wh.win = win;
 
-          executeSoon(function () {
-            // Some exceptions that reach here don't reach the test harness, but
-            // ok()/is() do...
-            try {
-              if (wh.onunload)
-                wh.onunload();
-              doNextTest();
-            }
-            catch (exc) {
-              win.close();
-              ok(false, "Unexpected exception: " + exc + "\n" + exc.stack);
-              finish();
-            }
-          });
-        }, false);
-      }
-    };
+        executeSoon(function () {
+          // Some exceptions that reach here don't reach the test harness, but
+          // ok()/is() do...
+          try {
+            if (wh.onunload)
+              wh.onunload();
+            doNextTest();
+          }
+          catch (exc) {
+            win.close();
+            ok(false, "Unexpected exception: " + exc + "\n" + exc.stack);
+            finish();
+          }
+        });
+      }, false);
+    }
     winWatch.registerNotification(windowObserver);
     winWatch.openWindow(null,
                         "chrome://browser/content/sanitize.xul",
                         "SanitizeDialog",
                         "chrome,titlebar,dialog,centerscreen,modal",
                         null);
   },
 
--- a/browser/base/content/test/browser_sanitizeDialog_treeView.js
+++ b/browser/base/content/test/browser_sanitizeDialog_treeView.js
@@ -613,40 +613,39 @@ function ensureHistoryClearedState(aURIs
 
 /**
  * Opens the sanitize dialog and runs a callback once it's finished loading.
  * 
  * @param aOnloadCallback
  *        A function that will be called once the dialog has loaded
  */
 function openWindow(aOnloadCallback) {
-  let windowObserver = {
-    observe: function(aSubject, aTopic, aData) {
-      if (aTopic === "domwindowopened") {
-        winWatch.unregisterNotification(this);
-        let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
-        win.addEventListener("load", function onload(event) {
-          win.removeEventListener("load", onload, false);
-          executeSoon(function () {
-            // Some exceptions that reach here don't reach the test harness, but
-            // ok()/is() do...
-            try {
-              aOnloadCallback(win);
-              doNextTest();
-            }
-            catch (exc) {
-              win.close();
-              ok(false, "Unexpected exception: " + exc + "\n" + exc.stack);
-              finish();
-            }
-          });
-        }, false);
-      }
-    }
-  };
+  function windowObserver(aSubject, aTopic, aData) {
+    if (aTopic != "domwindowopened")
+      return;
+
+    winWatch.unregisterNotification(windowObserver);
+    let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
+    win.addEventListener("load", function onload(event) {
+      win.removeEventListener("load", onload, false);
+      executeSoon(function () {
+        // Some exceptions that reach here don't reach the test harness, but
+        // ok()/is() do...
+        try {
+          aOnloadCallback(win);
+          doNextTest();
+        }
+        catch (exc) {
+          win.close();
+          ok(false, "Unexpected exception: " + exc + "\n" + exc.stack);
+          finish();
+        }
+      });
+    }, false);
+  }
   winWatch.registerNotification(windowObserver);
   winWatch.openWindow(null,
                       "chrome://browser/content/sanitize.xul",
                       "Sanitize",
                       "chrome,titlebar,dialog,centerscreen,modal",
                       null);
 }
 
--- a/browser/base/content/test/test_contextmenu.html
+++ b/browser/base/content/test/test_contextmenu.html
@@ -134,17 +134,17 @@ function checkMenu(menu, expectedItems) 
  * (thus kicking off another cycle).
  *
  */
 function runTest(testNum) {
   // Seems we need to enable this again, or sendKeyEvent() complaints.
   netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
   ok(true, "Starting test #" + testNum);
 
-  switch(testNum) {
+  switch (testNum) {
     case 1:
         // Invoke context menu for next test.
         openContextMenuFor(text);
         break;
 
     case 2:
         // Context menu for plain text
         checkContextMenu(["context-back",         false,
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/title_test.svg
@@ -0,0 +1,45 @@
+<svg width="640px" height="480px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.0">
+  <text id="text1" x="10px" y="32px" font-size="24px">
+    This contains only &lt;title&gt;
+    <title>
+
+
+    This            is a title
+
+    </title>
+  </text>
+  <text id="text2" x="10px" y="96px" font-size="24px">
+    This contains only &lt;desc&gt;
+    <desc>This is a desc</desc>
+  </text>
+  <text id="text3" x="10px" y="128px" font-size="24px">
+    This contains nothing.
+  </text>
+  <a id="link1" xlink:href="#">
+    This link contains &lt;title&gt;
+    <title>
+      This is a title
+    </title>
+    <text id="text4" x="10px" y="192px" font-size="24px">
+    </text>
+  </a>
+  <a id="link2" xlink:href="#">
+    <text x="10px" y="192px" font-size="24px">
+      This text contains &lt;title&gt;
+      <title>
+      This is a title
+      </title>
+    </text>
+  </a>
+  <a id="link3" xlink:href="#" xlink:title="This is an xlink:title attribute">
+    <text x="10px" y="224px" font-size="24px">
+      This link contains &lt;title&gt; &amp; xlink:title attr.
+      <title>This is a title</title>
+    </text>
+  </a>
+  <a id="link4" xlink:href="#" xlink:title="This is an xlink:title attribute">
+    <text x="10px" y="256px" font-size="24px">
+      This link contains xlink:title attr.
+    </text>
+  </a>
+</svg>
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -346,17 +346,17 @@
       ]]></field>
 
       <method name="observe">
         <parameter name="aSubject"/>
         <parameter name="aTopic"/>
         <parameter name="aData"/>
         <body><![CDATA[
           if (aTopic == "nsPref:changed") {
-            switch(aData) {
+            switch (aData) {
               case "clickSelectsAll":
               case "doubleClickSelectsAll":
                 this[aData] = this._prefs.getBoolPref(aData);
                 break;
               case "autoFill":
                 this.completeDefaultIndex = this._prefs.getBoolPref(aData);
                 break;
               case "delay":
--- a/browser/branding/unofficial/branding.nsi
+++ b/browser/branding/unofficial/branding.nsi
@@ -35,13 +35,13 @@
 # ***** END LICENSE BLOCK *****
 
 # NSIS branding defines for unofficial builds.
 # The official release build branding.nsi is located in other-license/branding/firefox/
 # The nightly build branding.nsi is located in browser/installer/windows/nsis/
 
 # BrandFullNameInternal is used for some registry and file system values
 # instead of BrandFullName and typically should not be modified.
-!define BrandFullNameInternal "Namoroka"
+!define BrandFullNameInternal "Mozilla Developer Preview"
 !define CompanyName           "mozilla.org"
 !define URLInfoAbout          "http://www.mozilla.org"
 !define URLUpdateInfo         "http://www.mozilla.org/projects/firefox"
 !define SurveyURL             "https://survey.mozilla.com/1/Mozilla%20Firefox/${AppVersion}/${AB_CD}/exit.html"
--- a/browser/branding/unofficial/configure.sh
+++ b/browser/branding/unofficial/configure.sh
@@ -1,1 +1,1 @@
-MOZ_APP_DISPLAYNAME="Namoroka"
+MOZ_APP_DISPLAYNAME="MozillaDeveloperPreview"
--- a/browser/branding/unofficial/locales/browserconfig.properties
+++ b/browser/branding/unofficial/locales/browserconfig.properties
@@ -1,3 +1,3 @@
 # Do NOT localize or otherwise change these values
-browser.startup.homepage=http://www.mozilla.org/projects/namoroka/
+browser.startup.homepage=http://www.mozilla.org/projects/devpreview/
 
--- a/browser/branding/unofficial/locales/en-US/brand.dtd
+++ b/browser/branding/unofficial/locales/en-US/brand.dtd
@@ -1,7 +1,7 @@
-<!ENTITY  brandShortName        "Namoroka">
-<!ENTITY  brandFullName         "Namoroka">
+<!ENTITY  brandShortName        "Mozilla Developer Preview">
+<!ENTITY  brandFullName         "Mozilla Developer Preview">
 <!ENTITY  vendorShortName       "mozilla.org">
 <!ENTITY  logoTrademark         " ">
 
 <!-- LOCALIZATION NOTE (releaseBaseURL): The about: page appends __MOZ_APP_VERSION__.html, e.g. 2.0.html -->
-<!ENTITY  releaseBaseURL        "http://www.mozilla.org/projects/namoroka/releases/">
+<!ENTITY  releaseBaseURL        "http://www.mozilla.org/projects/devpreview/releases/">
--- a/browser/branding/unofficial/locales/en-US/brand.properties
+++ b/browser/branding/unofficial/locales/en-US/brand.properties
@@ -1,3 +1,3 @@
-brandShortName=Namoroka
-brandFullName=Namoroka
+brandShortName=Mozilla Developer Preview
+brandFullName=Mozilla Developer Preview
 vendorShortName=mozilla.org
--- a/browser/components/distribution.js
+++ b/browser/components/distribution.js
@@ -133,16 +133,17 @@ DistributionCustomizer.prototype = {
     let items = {};
     let defaultItemId = -1;
     let maxItemId = -1;
 
     for (let i = 0; i < keys.length; i++) {
       let m = /^item\.(\d+)\.(\w+)\.?(\w*)/.exec(keys[i]);
       if (m) {
         let [foo, iid, iprop, ilocale] = m;
+        iid = parseInt(iid);
 
         if (ilocale)
           continue;
 
         if (!items[iid])
           items[iid] = {};
         if (keys.indexOf(keys[i] + "." + this._locale) >= 0) {
           items[iid][iprop] = this._ini.getString(section, keys[i] + "." +
--- a/browser/components/microsummaries/src/nsMicrosummaryService.js
+++ b/browser/components/microsummaries/src/nsMicrosummaryService.js
@@ -1719,17 +1719,17 @@ MicrosummaryResource.prototype = {
 
   QueryInterface: function MSR_QueryInterface(iid) {
     if (!this.interfaces.some( function(v) { return iid.equals(v) } ))
       throw Cr.NS_ERROR_NO_INTERFACE;
 
     // nsIAuthPrompt and nsIPrompt need separate implementations because
     // their method signatures conflict.  The other interfaces we implement
     // within MicrosummaryResource itself.
-    switch(iid) {
+    switch (iid) {
     case Ci.nsIAuthPrompt:
       return this.authPrompt;
     case Ci.nsIPrompt:
       return this.prompt;
     default:
       return this;
     }
   },
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -132,17 +132,17 @@ BrowserGlue.prototype = {
     // This method can be called via [NSApplication terminate:] on Mac, which
     // ends up causing prefs not to be flushed to disk, so we need to do that
     // explicitly here. See bug 497652.
     this._prefs.QueryInterface(Ci.nsIPrefService).savePrefFile(null);
   },
 
   // nsIObserver implementation 
   observe: function BG_observe(subject, topic, data) {
-    switch(topic) {
+    switch (topic) {
       case "xpcom-shutdown":
         this._dispose();
         break;
       case "prefservice:after-app-defaults":
         this._onAppDefaults();
         break;
       case "final-ui-startup":
         this._onProfileStartup();
--- a/browser/components/places/content/bookmarkProperties.js
+++ b/browser/components/places/content/bookmarkProperties.js
@@ -191,17 +191,17 @@ var BookmarkPropertiesPanel = {
         this._defaultInsertionPoint = dialogInfo.defaultInsertionPoint;
       }
       else
         this._defaultInsertionPoint =
           new InsertionPoint(PlacesUtils.bookmarksMenuFolderId,
                              PlacesUtils.bookmarks.DEFAULT_INDEX,
                              Ci.nsITreeView.DROP_ON);
 
-      switch(dialogInfo.type) {
+      switch (dialogInfo.type) {
         case "bookmark":
           this._itemType = BOOKMARK_ITEM;
           if ("uri" in dialogInfo) {
             NS_ASSERT(dialogInfo.uri instanceof Ci.nsIURI,
                       "uri property should be a uri object");
             this._uri = dialogInfo.uri;
             if (typeof(this._title) != "string") {
               this._title = this._getURITitleFromHistory(this._uri) ||
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -454,17 +454,17 @@ PlacesController.prototype = {
     for (var i=0; i < nodes.length; i++) {
       var nodeData = {};
       var node = nodes[i];
       var nodeType = node.type;
       var uri = null;
 
       // We don't use the nodeIs* methods here to avoid going through the type
       // property way too often
-      switch(nodeType) {
+      switch (nodeType) {
         case Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY:
           nodeData["query"] = true;
           if (node.parent) {
             switch (asQuery(node.parent).queryOptions.resultType) {
               case Ci.nsINavHistoryQueryOptions.RESULTS_AS_SITE_QUERY:
                 nodeData["host"] = true;
                 break;
               case Ci.nsINavHistoryQueryOptions.RESULTS_AS_DATE_SITE_QUERY:
--- a/browser/components/places/tests/browser/browser_0_library_left_pane_migration.js
+++ b/browser/components/places/tests/browser/browser_0_library_left_pane_migration.js
@@ -42,57 +42,55 @@
  *        of next tests could be unexpected due to PlacesUIUtils getters.
  */
 
 const TEST_URI = "http://www.mozilla.org/";
 
 var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
          getService(Ci.nsIWindowWatcher);
 
-var windowObserver = {
-  observe: function(aSubject, aTopic, aData) {
-    if (aTopic === "domwindowopened") {
-      ww.unregisterNotification(this);
-      var organizer = aSubject.QueryInterface(Ci.nsIDOMWindow);
-      organizer.addEventListener("load", function onLoad(event) {
-        organizer.removeEventListener("load", onLoad, false);
-        executeSoon(function () {
-          // Check left pane.
-          ok(PlacesUIUtils.leftPaneFolderId > 0,
-             "Left pane folder correctly created");
-          var leftPaneItems =
-            PlacesUtils.annotations
-                       .getItemsWithAnnotation(ORGANIZER_FOLDER_ANNO);
-          is(leftPaneItems.length, 1,
-             "We correctly have only 1 left pane folder");
-          var leftPaneRoot = leftPaneItems[0];
-          is(leftPaneRoot, PlacesUIUtils.leftPaneFolderId,
-             "leftPaneFolderId getter has correct value");
-          // Check version has been upgraded.
-          var version =
-            PlacesUtils.annotations.getItemAnnotation(leftPaneRoot,
-                                                      ORGANIZER_FOLDER_ANNO);
-          is(version, ORGANIZER_LEFTPANE_VERSION,
-             "Left pane version has been correctly upgraded");
+function windowObserver(aSubject, aTopic, aData) {
+  if (aTopic != "domwindowopened")
+    return;
+  ww.unregisterNotification(windowObserver);
+  var organizer = aSubject.QueryInterface(Ci.nsIDOMWindow);
+  organizer.addEventListener("load", function onLoad(event) {
+    organizer.removeEventListener("load", onLoad, false);
+    executeSoon(function () {
+      // Check left pane.
+      ok(PlacesUIUtils.leftPaneFolderId > 0,
+         "Left pane folder correctly created");
+      var leftPaneItems =
+        PlacesUtils.annotations
+                   .getItemsWithAnnotation(ORGANIZER_FOLDER_ANNO);
+      is(leftPaneItems.length, 1,
+         "We correctly have only 1 left pane folder");
+      var leftPaneRoot = leftPaneItems[0];
+      is(leftPaneRoot, PlacesUIUtils.leftPaneFolderId,
+         "leftPaneFolderId getter has correct value");
+      // Check version has been upgraded.
+      var version =
+        PlacesUtils.annotations.getItemAnnotation(leftPaneRoot,
+                                                  ORGANIZER_FOLDER_ANNO);
+      is(version, ORGANIZER_LEFTPANE_VERSION,
+         "Left pane version has been correctly upgraded");
 
-          // Check left pane is populated.
-          organizer.PlacesOrganizer.selectLeftPaneQuery('History');
-          is(organizer.PlacesOrganizer._places.selectedNode.itemId,
-             PlacesUIUtils.leftPaneQueries["History"],
-             "Library left pane is populated and working");
+      // Check left pane is populated.
+      organizer.PlacesOrganizer.selectLeftPaneQuery('History');
+      is(organizer.PlacesOrganizer._places.selectedNode.itemId,
+         PlacesUIUtils.leftPaneQueries["History"],
+         "Library left pane is populated and working");
 
-          // Close Library window.
-          organizer.close();
-          // No need to cleanup anything, we have a correct left pane now.
-          finish();
-        });
-      }, false);
-    }
-  }
-};
+      // Close Library window.
+      organizer.close();
+      // No need to cleanup anything, we have a correct left pane now.
+      finish();
+    });
+  }, false);
+}
 
 function test() {
   waitForExplicitFinish();
   // Sanity checks.
   ok(PlacesUtils, "PlacesUtils is running in chrome context");
   ok(PlacesUIUtils, "PlacesUIUtils is running in chrome context");
   ok(ORGANIZER_LEFTPANE_VERSION > 0,
      "Left pane version in chrome context, current version is: " + ORGANIZER_LEFTPANE_VERSION );
--- a/browser/components/places/tests/browser/browser_bookmarksProperties.js
+++ b/browser/components/places/tests/browser/browser_bookmarksProperties.js
@@ -220,27 +220,25 @@ gTests.push({
     is(tree.selectedNode.itemId, this._itemId, "Bookmark has been selected");
   },
 
   run: function() {
     // open tags autocomplete and press enter
     var tagsField = this.window.document.getElementById("editBMPanel_tagsField");
     var self = this;
 
-    var windowObserver = {
-      observe: function(aSubject, aTopic, aData) {
-        if (aTopic === "domwindowclosed" &&
-            aSubject.QueryInterface(Ci.nsIDOMWindow).location == DIALOG_URL) {
-          ww.unregisterNotification(this);
-          tagsField.popup.removeEventListener("popuphidden", popupListener, true);
-          ok(false, "Dialog window should not be closed by pressing Enter on the autocomplete popup");
-          self.finish();
-        }
+    function windowObserver(aSubject, aTopic, aData) {
+      if (aTopic == "domwindowclosed" &&
+          aSubject.QueryInterface(Ci.nsIDOMWindow).location == DIALOG_URL) {
+        ww.unregisterNotification(windowObserver);
+        tagsField.popup.removeEventListener("popuphidden", popupListener, true);
+        ok(false, "Dialog window should not be closed by pressing Enter on the autocomplete popup");
+        self.finish();
       }
-    };
+    }
 
     var popupListener = {
       handleEvent: function(aEvent) {
         switch (aEvent.type) {
           case "popuphidden":
             // Everything worked fine, we can stop observing the window.
             ww.unregisterNotification(windowObserver);
             tagsField.popup.removeEventListener("popuphidden", this, true);
@@ -379,27 +377,25 @@ gTests.push({
     is(tree.selectedNode.itemId, this._itemId, "Bookmark has been selected");
   },
 
   run: function() {
     // open tags autocomplete and press enter
     var tagsField = this.window.document.getElementById("editBMPanel_tagsField");
     var self = this;
 
-    var windowObserver = {
-      observe: function(aSubject, aTopic, aData) {
-        if (aTopic === "domwindowclosed" &&
-            aSubject.QueryInterface(Ci.nsIDOMWindow).location == DIALOG_URL) {
-          ww.unregisterNotification(this);
-          tagsField.popup.removeEventListener("popuphidden", popupListener, true);
-          ok(false, "Dialog window should not be closed by pressing Escape on the autocomplete popup");
-          self.finish();
-        }
+    function windowObserver(aSubject, aTopic, aData) {
+      if (aTopic == "domwindowclosed" &&
+          aSubject.QueryInterface(Ci.nsIDOMWindow).location == DIALOG_URL) {
+        ww.unregisterNotification(windowObserver);
+        tagsField.popup.removeEventListener("popuphidden", popupListener, true);
+        ok(false, "Dialog window should not be closed by pressing Escape on the autocomplete popup");
+        self.finish();
       }
-    };
+    }
 
     var popupListener = {
       handleEvent: function(aEvent) {
         switch (aEvent.type) {
           case "popuphidden":
             // Everything worked fine, we can stop observing the window.
             ww.unregisterNotification(windowObserver);
             tagsField.popup.removeEventListener("popuphidden", this, true);
@@ -481,27 +477,25 @@ gTests.push({
   },
 
   run: function() {
     // Open folder selector.
     var foldersExpander = this.window.document.getElementById("editBMPanel_foldersExpander");
     var folderTree = this.window.document.getElementById("editBMPanel_folderTree");
     var self = this;
 
-    var windowObserver = {
-      observe: function(aSubject, aTopic, aData) {
-        if (aTopic === "domwindowclosed" &&
-            aSubject.QueryInterface(Ci.nsIDOMWindow).location == DIALOG_URL_MINIMAL_UI) {
-          ww.unregisterNotification(this);
-          ok(self._cleanShutdown,
-             "Dialog window should not be closed by pressing ESC in folder name textbox");
-          self.finish();
-        }
+    function windowObserver(aSubject, aTopic, aData) {
+      if (aTopic == "domwindowclosed" &&
+          aSubject.QueryInterface(Ci.nsIDOMWindow).location == DIALOG_URL_MINIMAL_UI) {
+        ww.unregisterNotification(windowObserver);
+        ok(self._cleanShutdown,
+           "Dialog window should not be closed by pressing ESC in folder name textbox");
+        self.finish();
       }
-    };
+    }
     ww.registerNotification(windowObserver);
 
     folderTree.addEventListener("DOMAttrModified", function onDOMAttrModified(event) {
       if (event.attrName != "place")
         return;
       folderTree.removeEventListener("DOMAttrModified", arguments.callee, false);
       executeSoon(function () {
         // Create a new folder.
@@ -596,42 +590,40 @@ function open_properties_dialog() {
     ok(tree, "Sidebar tree has been loaded");
 
     // Ask current test to select the node to edit.
     gCurrentTest.selectNode(tree);
     ok(tree.selectedNode,
        "We have a places node selected: " + tree.selectedNode.title);
 
     // Wait for the Properties dialog.
-    var windowObserver = {
-      observe: function(aSubject, aTopic, aData) {
-        if (aTopic === "domwindowopened") {
-          ww.unregisterNotification(this);
-          var win = aSubject.QueryInterface(Ci.nsIDOMWindow);
-          win.addEventListener("focus", function(event) {
-            win.removeEventListener("focus", arguments.callee, false);
-            // Windows has been loaded, execute our test now.
-            executeSoon(function () {
-              // Ensure overlay is loaded
-              ok(win.gEditItemOverlay._initialized, "EditItemOverlay is initialized");
-              gCurrentTest.window = win;
-              try {
-                gCurrentTest.run();
-              } catch (ex) {
-                ok(false, "An error occured during test run: " + ex.message);
-              }
-            });
-          }, false);
-        }
-      }
-    };
+    function windowObserver(aSubject, aTopic, aData) {
+      if (aTopic != "domwindowopened")
+        return;
+      ww.unregisterNotification(windowObserver);
+      var win = aSubject.QueryInterface(Ci.nsIDOMWindow);
+      win.addEventListener("focus", function (event) {
+        win.removeEventListener("focus", arguments.callee, false);
+        // Windows has been loaded, execute our test now.
+        executeSoon(function () {
+          // Ensure overlay is loaded
+          ok(win.gEditItemOverlay._initialized, "EditItemOverlay is initialized");
+          gCurrentTest.window = win;
+          try {
+            gCurrentTest.run();
+          } catch (ex) {
+            ok(false, "An error occured during test run: " + ex.message);
+          }
+        });
+      }, false);
+    }
     ww.registerNotification(windowObserver);
 
     var command = null;
-    switch(gCurrentTest.action) {
+    switch (gCurrentTest.action) {
       case ACTION_EDIT:
         command = "placesCmd_show:info";
         break;
       case ACTION_ADD:
         if (gCurrentTest.sidebar == SIDEBAR_BOOKMARKS_ID) {
           if (gCurrentTest.itemType == TYPE_FOLDER)
             command = "placesCmd_new:folder";
           else if (gCurrentTest.itemType == TYPE_BOOKMARK)
--- a/browser/components/places/tests/browser/browser_forgetthissite_single.js
+++ b/browser/components/places/tests/browser/browser_forgetthissite_single.js
@@ -50,64 +50,62 @@ function test() {
   let history = PlacesUtils.history;
   TEST_URIs.forEach(function(TEST_URI) {
     let visitId = history.addVisit(PlacesUtils._uri(TEST_URI), Date.now() * 1000,
                                    null, PlacesUtils.history.TRANSITION_TYPED, false, 0);
     ok(visitId > 0, TEST_URI + " successfully marked visited");
   });
 
   function testForgetThisSiteVisibility(selectionCount, funcNext) {
-    let observer = {
-      observe: function(aSubject, aTopic, aData) {
-        if (aTopic === "domwindowopened") {
-          ww.unregisterNotification(this);
-          let organizer = aSubject.QueryInterface(Ci.nsIDOMWindow);
-          organizer.addEventListener("load", function onLoad(event) {
-            organizer.removeEventListener("load", onLoad, false);
-            executeSoon(function () {
-              // Select History in the left pane.
-              organizer.PlacesOrganizer.selectLeftPaneQuery('History');
-              let PO = organizer.PlacesOrganizer;
-              let histContainer = PO._places.selectedNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
-              histContainer.containerOpen = true;
-              PO._places.selectNode(histContainer.getChild(0));
-              // Select the first history entry.
-              let doc = organizer.document;
-              let tree = PO._content;
-              let selection = tree.view.selection;
-              selection.clearSelection();
-              selection.rangedSelect(0, selectionCount - 1, true);
-              is(selection.count, selectionCount,
-                "The selected range is as big as expected");
-              // Open the context menu
-              let contextmenu = doc.getElementById("placesContext");
-              contextmenu.addEventListener("popupshown", function() {
-                contextmenu.removeEventListener("popupshown", arguments.callee, false);
-                let forgetThisSite = doc.getElementById("placesContext_deleteHost");
-                let hideForgetThisSite = (selectionCount != 1);
-                is(forgetThisSite.hidden, hideForgetThisSite,
-                  "The Forget this site menu item should " + (hideForgetThisSite ? "" : "not ") +
-                  "be hidden with " + selectionCount + " items selected");
-                // Close the context menu
-                contextmenu.hidePopup();
-                // Close Library window.
-                organizer.close();
-                // Proceed
-                funcNext();
-              }, false);
-              let event = document.createEvent("MouseEvents");
-              event.initMouseEvent("contextmenu", true, true, organizer, 0,
-                                   0, 0, 0, 0, false, false, false, false,
-                                   0, null);
-              tree.dispatchEvent(event);
-            });
+    function observer(aSubject, aTopic, aData) {
+      if (aTopic != "domwindowopened")
+        return;
+      ww.unregisterNotification(observer);
+      let organizer = aSubject.QueryInterface(Ci.nsIDOMWindow);
+      organizer.addEventListener("load", function onLoad(event) {
+        organizer.removeEventListener("load", onLoad, false);
+        executeSoon(function () {
+          // Select History in the left pane.
+          organizer.PlacesOrganizer.selectLeftPaneQuery('History');
+          let PO = organizer.PlacesOrganizer;
+          let histContainer = PO._places.selectedNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
+          histContainer.containerOpen = true;
+          PO._places.selectNode(histContainer.getChild(0));
+          // Select the first history entry.
+          let doc = organizer.document;
+          let tree = PO._content;
+          let selection = tree.view.selection;
+          selection.clearSelection();
+          selection.rangedSelect(0, selectionCount - 1, true);
+          is(selection.count, selectionCount,
+            "The selected range is as big as expected");
+          // Open the context menu
+          let contextmenu = doc.getElementById("placesContext");
+          contextmenu.addEventListener("popupshown", function() {
+            contextmenu.removeEventListener("popupshown", arguments.callee, false);
+            let forgetThisSite = doc.getElementById("placesContext_deleteHost");
+            let hideForgetThisSite = (selectionCount != 1);
+            is(forgetThisSite.hidden, hideForgetThisSite,
+              "The Forget this site menu item should " + (hideForgetThisSite ? "" : "not ") +
+              "be hidden with " + selectionCount + " items selected");
+            // Close the context menu
+            contextmenu.hidePopup();
+            // Close Library window.
+            organizer.close();
+            // Proceed
+            funcNext();
           }, false);
-        }
-      }
-    };
+          let event = document.createEvent("MouseEvents");
+          event.initMouseEvent("contextmenu", true, true, organizer, 0,
+                               0, 0, 0, 0, false, false, false, false,
+                               0, null);
+          tree.dispatchEvent(event);
+        });
+      }, false);
+    }
 
     ww.registerNotification(observer);
     ww.openWindow(null,
                   "chrome://browser/content/places/places.xul",
                   "",
                   "chrome,toolbar=yes,dialog=no,resizable",
                   null);
   }
--- a/browser/components/places/tests/browser/browser_library_infoBox.js
+++ b/browser/components/places/tests/browser/browser_library_infoBox.js
@@ -214,31 +214,26 @@ function nextTest() {
     // No need to cleanup anything, we have a correct left pane now.
     finish();
   }
 }
 
 var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
          getService(Ci.nsIWindowWatcher);
 
-var windowObserver = {
-  observe: function(aSubject, aTopic, aData) {
-    if (aTopic === "domwindowopened") {
-      ww.unregisterNotification(this);
-      gLibrary = aSubject.QueryInterface(Ci.nsIDOMWindow);
-      gLibrary.addEventListener("load", function onLoad(event) {
-        gLibrary.removeEventListener("load", onLoad, false);
-        executeSoon(function () {
-          // Execute tests.
-          nextTest();
-        });
-      }, false);
-    }
-  }
-};
+function windowObserver(aSubject, aTopic, aData) {
+  if (aTopic != "domwindowopened")
+    return;
+  ww.unregisterNotification(windowObserver);
+  gLibrary = aSubject.QueryInterface(Ci.nsIDOMWindow);
+  gLibrary.addEventListener("load", function onLoad(event) {
+    gLibrary.removeEventListener("load", onLoad, false);
+    executeSoon(nextTest);
+  }, false);
+}
 
 function test() {
   dump("Starting test browser_library_infoBox.js\n");
   waitForExplicitFinish();
   // Sanity checks.
   ok(PlacesUtils, "PlacesUtils is running in chrome context");
   ok(PlacesUIUtils, "PlacesUIUtils is running in chrome context");
 
--- a/browser/components/places/tests/browser/browser_library_left_pane_commands.js
+++ b/browser/components/places/tests/browser/browser_library_left_pane_commands.js
@@ -171,31 +171,26 @@ function nextTest() {
     // No need to cleanup anything, we have a correct left pane now.
     finish();
   }
 }
 
 var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
          getService(Ci.nsIWindowWatcher);
 
-var windowObserver = {
-  observe: function(aSubject, aTopic, aData) {
-    if (aTopic === "domwindowopened") {
-      ww.unregisterNotification(this);
-      gLibrary = aSubject.QueryInterface(Ci.nsIDOMWindow);
-      gLibrary.addEventListener("load", function onLoad(event) {
-        gLibrary.removeEventListener("load", onLoad, false);
-        executeSoon(function () {
-          // Execute tests.
-          nextTest();
-        });
-      }, false);
-    }
-  }
-};
+function windowObserver(aSubject, aTopic, aData) {
+  if (aTopic != "domwindowopened")
+    return;
+  ww.unregisterNotification(windowObserver);
+  gLibrary = aSubject.QueryInterface(Ci.nsIDOMWindow);
+  gLibrary.addEventListener("load", function onLoad(event) {
+    gLibrary.removeEventListener("load", onLoad, false);
+    executeSoon(nextTest);
+  }, false);
+}
 
 function test() {
   waitForExplicitFinish();
   // Sanity checks.
   ok(PlacesUtils, "PlacesUtils is running in chrome context");
   ok(PlacesUIUtils, "PlacesUIUtils is running in chrome context");
 
   // Open Library.
--- a/browser/components/places/tests/browser/browser_library_left_pane_fixnames.js
+++ b/browser/components/places/tests/browser/browser_library_left_pane_fixnames.js
@@ -44,44 +44,42 @@ var ww = Cc["@mozilla.org/embedcomp/wind
          getService(Ci.nsIWindowWatcher);
 
 // Array of left pane queries objects, each one has the following properties:
 // name: query's identifier got from annotations,
 // itemId: query's itemId,
 // correctTitle: original and correct query's title.
 var leftPaneQueries = [];
 
-var windowObserver = {
-  observe: function(aSubject, aTopic, aData) {
-    if (aTopic === "domwindowopened") {
-      ww.unregisterNotification(this);
-      var organizer = aSubject.QueryInterface(Ci.nsIDOMWindow);
-      organizer.addEventListener("load", function onLoad(event) {
-        organizer.removeEventListener("load", onLoad, false);
-        executeSoon(function () {
-          // Check titles have been fixed.
-          for (var i = 0; i < leftPaneQueries.length; i++) {
-            var query = leftPaneQueries[i];
-            is(PlacesUtils.bookmarks.getItemTitle(query.itemId),
-               query.correctTitle, "Title is correct for query " + query.name);
-            if ("concreteId" in query) {
-              is(PlacesUtils.bookmarks.getItemTitle(query.concreteId),
-               query.concreteTitle, "Concrete title is correct for query " + query.name);
-            }
-          }
+function windowObserver(aSubject, aTopic, aData) {
+  if (aTopic != "domwindowopened")
+    return;
+  ww.unregisterNotification(windowObserver);
+  var organizer = aSubject.QueryInterface(Ci.nsIDOMWindow);
+  organizer.addEventListener("load", function onLoad(event) {
+    organizer.removeEventListener("load", onLoad, false);
+    executeSoon(function () {
+      // Check titles have been fixed.
+      for (var i = 0; i < leftPaneQueries.length; i++) {
+        var query = leftPaneQueries[i];
+        is(PlacesUtils.bookmarks.getItemTitle(query.itemId),
+           query.correctTitle, "Title is correct for query " + query.name);
+        if ("concreteId" in query) {
+          is(PlacesUtils.bookmarks.getItemTitle(query.concreteId),
+           query.concreteTitle, "Concrete title is correct for query " + query.name);
+        }
+      }
 
-          // Close Library window.
-          organizer.close();
-          // No need to cleanup anything, we have a correct left pane now.
-          finish();
-        });
-      }, false);
-    }
-  }
-};
+      // Close Library window.
+      organizer.close();
+      // No need to cleanup anything, we have a correct left pane now.
+      finish();
+    });
+  }, false);
+}
 
 function test() {
   waitForExplicitFinish();
   // Sanity checks.
   ok(PlacesUtils, "PlacesUtils is running in chrome context");
   ok(PlacesUIUtils, "PlacesUIUtils is running in chrome context");
   ok(ORGANIZER_LEFTPANE_VERSION > 0,
      "Left pane version in chrome context, current version is: " + ORGANIZER_LEFTPANE_VERSION );
--- a/browser/components/places/tests/browser/browser_library_middleclick.js
+++ b/browser/components/places/tests/browser/browser_library_middleclick.js
@@ -262,29 +262,27 @@ function test() {
   gBrowser.addTabsProgressListener(gTabsListener);
 
   // Temporary disable history, so we won't record pages navigation.
   gPrefService.setBoolPref(ENABLE_HISTORY_PREF, false);
 
   // Window watcher for Library window.
   var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
            getService(Ci.nsIWindowWatcher);
-  var windowObserver = {
-    observe: function(aSubject, aTopic, aData) {
-      if (aTopic === "domwindowopened") {
-        ww.unregisterNotification(this);
-        gLibrary = aSubject.QueryInterface(Ci.nsIDOMWindow);
-        gLibrary.addEventListener("load", function onLoad(event) {
-          gLibrary.removeEventListener("load", onLoad, false);
-          // Kick off tests.
-          setTimeout(runNextTest, 0);
-        }, false);
-      }
-    }
-  };
+  function windowObserver(aSubject, aTopic, aData) {
+    if (aTopic != "domwindowopened")
+      return;
+    ww.unregisterNotification(windowObserver);
+    gLibrary = aSubject.QueryInterface(Ci.nsIDOMWindow);
+    gLibrary.addEventListener("load", function onLoad(event) {
+      gLibrary.removeEventListener("load", onLoad, false);
+      // Kick off tests.
+      setTimeout(runNextTest, 0);
+    }, false);
+  }
 
   // Open Library window.
   ww.registerNotification(windowObserver);
   ww.openWindow(null,
                 "chrome://browser/content/places/places.xul",
                 "",
                 "chrome,toolbar=yes,dialog=no,resizable",
                 null); 
--- a/browser/components/places/tests/browser/browser_library_open_leak.js
+++ b/browser/components/places/tests/browser/browser_library_open_leak.js
@@ -43,32 +43,30 @@
  * Tests for leaks caused by simply opening and closing the Places Library
  * window.  Opens the Places Library window, waits for it to load, closes it,
  * and finishes.
  */
 
 let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
          getService(Ci.nsIWindowWatcher);
 
-let windowObserver = {
-  observe: function(aSubject, aTopic, aData) {
-    if (aTopic === "domwindowopened") {
-      ww.unregisterNotification(this);
-      let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
-      win.addEventListener("load", function onLoad(event) {
-        win.removeEventListener("load", onLoad, false);
-        executeSoon(function () {
-          ok(true, "Library has been correctly opened");
-          win.close();
-          finish();
-        });
-      }, false);
-    }
-  }
-};
+function windowObserver(aSubject, aTopic, aData) {
+  if (aTopic != "domwindowopened")
+    return;
+  ww.unregisterNotification(windowObserver);
+  let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
+  win.addEventListener("load", function onLoad(event) {
+    win.removeEventListener("load", onLoad, false);
+    executeSoon(function () {
+      ok(true, "Library has been correctly opened");
+      win.close();
+      finish();
+    });
+  }, false);
+}
 
 function test() {
   waitForExplicitFinish();
   ww.registerNotification(windowObserver);
   ww.openWindow(null,
                 "chrome://browser/content/places/places.xul",
                 "",
                 "chrome,toolbar=yes,dialog=no,resizable",
--- a/browser/components/places/tests/browser/browser_library_panel_leak.js
+++ b/browser/components/places/tests/browser/browser_library_panel_leak.js
@@ -48,47 +48,45 @@
  *        never removed.
  */
 
 const TEST_URI = "http://www.mozilla.org/";
 
 let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
          getService(Ci.nsIWindowWatcher);
 
-let windowObserver = {
-  observe: function(aSubject, aTopic, aData) {
-    if (aTopic === "domwindowopened") {
-      ww.unregisterNotification(this);
-      let organizer = aSubject.QueryInterface(Ci.nsIDOMWindow);
-      organizer.addEventListener("load", function onLoad(event) {
-        organizer.removeEventListener("load", onLoad, false);
-        executeSoon(function () {
-          let contentTree = organizer.document.getElementById("placeContent");
-          isnot(contentTree, null, "Sanity check: placeContent tree should exist");
-          isnot(organizer.PlacesOrganizer, null, "Sanity check: PlacesOrganizer should exist");
-          isnot(organizer.gEditItemOverlay, null, "Sanity check: gEditItemOverlay should exist");
-          isnot(organizer.gEditItemOverlay.itemId, -1, "Editing a bookmark");
-          // Select History in the left pane.
-          organizer.PlacesOrganizer.selectLeftPaneQuery('History');
-          // Select the first history entry.
-          let selection = contentTree.view.selection;
-          selection.clearSelection();
-          selection.rangedSelect(0, 0, true);
-          // Check the panel is editing the history entry.
-          is(organizer.gEditItemOverlay.itemId, -1, "Editing an history entry");
-          // Close Library window.
-          organizer.close();
-          // Clean up history.
-          PlacesUtils.history.QueryInterface(Ci.nsIBrowserHistory).removeAllPages();
-          finish();
-        });
-      }, false);
-    }
-  }
-};
+function windowObserver(aSubject, aTopic, aData) {
+  if (aTopic != "domwindowopened")
+    return;
+  ww.unregisterNotification(windowObserver);
+  let organizer = aSubject.QueryInterface(Ci.nsIDOMWindow);
+  organizer.addEventListener("load", function onLoad(event) {
+    organizer.removeEventListener("load", onLoad, false);
+    executeSoon(function () {
+      let contentTree = organizer.document.getElementById("placeContent");
+      isnot(contentTree, null, "Sanity check: placeContent tree should exist");
+      isnot(organizer.PlacesOrganizer, null, "Sanity check: PlacesOrganizer should exist");
+      isnot(organizer.gEditItemOverlay, null, "Sanity check: gEditItemOverlay should exist");
+      isnot(organizer.gEditItemOverlay.itemId, -1, "Editing a bookmark");
+      // Select History in the left pane.
+      organizer.PlacesOrganizer.selectLeftPaneQuery('History');
+      // Select the first history entry.
+      let selection = contentTree.view.selection;
+      selection.clearSelection();
+      selection.rangedSelect(0, 0, true);
+      // Check the panel is editing the history entry.
+      is(organizer.gEditItemOverlay.itemId, -1, "Editing an history entry");
+      // Close Library window.
+      organizer.close();
+      // Clean up history.
+      PlacesUtils.history.QueryInterface(Ci.nsIBrowserHistory).removeAllPages();
+      finish();
+    });
+  }, false);
+}
 
 function test() {
   waitForExplicitFinish();
   // Add an history entry.
   ok(PlacesUtils, "checking PlacesUtils, running in chrome context?");
   PlacesUtils.history.addVisit(PlacesUtils._uri(TEST_URI), Date.now() * 1000,
                                null, PlacesUtils.history.TRANSITION_TYPED,
                                false, 0);
--- a/browser/components/places/tests/browser/browser_library_search.js
+++ b/browser/components/places/tests/browser/browser_library_search.js
@@ -295,28 +295,26 @@ function test() {
                                        PlacesUtils._uri(TEST_URL),
                                        PlacesUtils.bookmarks.DEFAULT_INDEX,
                                        "dummy");
   PlacesUtils.tagging.tagURI(PlacesUtils._uri(TEST_URL), ["dummyTag"]);
 
   var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
            getService(Ci.nsIWindowWatcher);
 
-  var windowObserver = {
-    observe: function(aSubject, aTopic, aData) {
-      if (aTopic === "domwindowopened") {
-        ww.unregisterNotification(this);
-        var win = aSubject.QueryInterface(Ci.nsIDOMWindow);
-        win.addEventListener("load", function onLoad(event) {
-          win.removeEventListener("load", onLoad, false);
-          executeSoon(function () testHelper(win));
-        }, false);
-      }
-    }
-  };
+  function windowObserver(aSubject, aTopic, aData) {
+    if (aTopic != "domwindowopened")
+      return;
+    ww.unregisterNotification(windowObserver);
+    var win = aSubject.QueryInterface(Ci.nsIDOMWindow);
+    win.addEventListener("load", function onLoad(event) {
+      win.removeEventListener("load", onLoad, false);
+      executeSoon(function () testHelper(win));
+    }, false);
+  }
 
   ww.registerNotification(windowObserver);
   ww.openWindow(null,
                 "chrome://browser/content/places/places.xul",
                 "",
                 "chrome,toolbar=yes,dialog=no,resizable",
                 null);
 }
--- a/browser/components/places/tests/browser/browser_library_views_liveupdate.js
+++ b/browser/components/places/tests/browser/browser_library_views_liveupdate.js
@@ -53,28 +53,26 @@ function test() {
 
   // Sanity checks.
   ok(PlacesUtils, "PlacesUtils in context");
   ok(PlacesUIUtils, "PlacesUIUtils in context");
 
   // Open Library, we will check the left pane.
   var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
            getService(Ci.nsIWindowWatcher);
-  var windowObserver = {
-    observe: function(aSubject, aTopic, aData) {
-      if (aTopic === "domwindowopened") {
-        ww.unregisterNotification(this);
-        gLibrary = aSubject.QueryInterface(Ci.nsIDOMWindow);
-        gLibrary.addEventListener("load", function onLoad(event) {
-          gLibrary.removeEventListener("load", onLoad, false);
-          executeSoon(startTest);
-        }, false);
-      }
-    }
-  };
+  function windowObserver(aSubject, aTopic, aData) {
+    if (aTopic != "domwindowopened")
+      return;
+    ww.unregisterNotification(windowObserver);
+    gLibrary = aSubject.QueryInterface(Ci.nsIDOMWindow);
+    gLibrary.addEventListener("load", function onLoad(event) {
+      gLibrary.removeEventListener("load", onLoad, false);
+      executeSoon(startTest);
+    }, false);
+  }
   ww.registerNotification(windowObserver);
   ww.openWindow(null,
                 "chrome://browser/content/places/places.xul",
                 "",
                 "chrome,toolbar=yes,dialog=no,resizable",
                 null);
 }
 
--- a/browser/components/places/tests/browser/browser_sidebarpanels_click.js
+++ b/browser/components/places/tests/browser/browser_sidebarpanels_click.js
@@ -119,34 +119,32 @@ function test() {
       let tree = doc.getElementById(currentTest.treeName);
       let tbo = tree.treeBoxObject;
 
       executeSoon(function() {
         currentTest.prepare();
         if (preFunc)
           preFunc();
 
-        let observer = {
-          observe: function(aSubject, aTopic, aData) {
-            if (aTopic === "domwindowopened") {
-              ww.unregisterNotification(this);
-              let alertDialog = aSubject.QueryInterface(Ci.nsIDOMWindow);
-              alertDialog.addEventListener("load", function() {
-                alertDialog.removeEventListener("load", arguments.callee, false);
-                info("alert dialog observed as expected");
-                executeSoon(function() {
-                  alertDialog.close();
-                  toggleSidebar(currentTest.sidebarName);
-                  currentTest.cleanup();
-                  postFunc();
-                });
-              }, false);
-            }
-          }
-        };
+        function observer(aSubject, aTopic, aData) {
+          if (aTopic != "domwindowopened")
+            return;
+          ww.unregisterNotification(observer);
+          let alertDialog = aSubject.QueryInterface(Ci.nsIDOMWindow);
+          alertDialog.addEventListener("load", function () {
+            alertDialog.removeEventListener("load", arguments.callee, false);
+            info("alert dialog observed as expected");
+            executeSoon(function () {
+              alertDialog.close();
+              toggleSidebar(currentTest.sidebarName);
+              currentTest.cleanup();
+              postFunc();
+            });
+          }, false);
+        }
         ww.registerNotification(observer);
 
         // Select the inserted places item.
         currentTest.selectNode(tree);
         is(tbo.view.selection.count, 1,
            "The test node should be successfully selected");
         // Get its row ID.
         let min = {}, max = {};
--- a/browser/components/places/tests/browser/browser_sort_in_library.js
+++ b/browser/components/places/tests/browser/browser_sort_in_library.js
@@ -266,42 +266,40 @@ function testSortByDir(aOrganizerWin, aP
 ///////////////////////////////////////////////////////////////////////////////
 
 function test() {
   waitForExplicitFinish();
 
   let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
            getService(Ci.nsIWindowWatcher);
 
-  let windowObserver = {
-    observe: function(aSubject, aTopic, aData) {
-      if (aTopic === "domwindowopened") {
-        ww.unregisterNotification(this);
-        let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
-        win.addEventListener("load", function onLoad(event) {
-          win.removeEventListener("load", onLoad, false);
-          executeSoon(function () {
-            let tree = win.document.getElementById("placeContent");
-            isnot(tree, null, "sanity check: placeContent tree should exist");
-            // Run the tests.
-            testSortByColAndDir(win, tree, true);
-            testSortByColAndDir(win, tree, false);
-            testSortByDir(win, tree, true);
-            testSortByDir(win, tree, false);
-            testInvalid(win, tree);
-            // Reset the sort to SORT_BY_NONE.
-            setSort(win, tree, false, false);
-            // Close the window and finish.
-            win.close();
-            finish();
-          });
-        }, false);
-      }
-    }
-  };
+  function windowObserver(aSubject, aTopic, aData) {
+    if (aTopic != "domwindowopened")
+      return;
+    ww.unregisterNotification(windowObserver);
+    let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
+    win.addEventListener("load", function onLoad(event) {
+      win.removeEventListener("load", onLoad, false);
+      executeSoon(function () {
+        let tree = win.document.getElementById("placeContent");
+        isnot(tree, null, "sanity check: placeContent tree should exist");
+        // Run the tests.
+        testSortByColAndDir(win, tree, true);
+        testSortByColAndDir(win, tree, false);
+        testSortByDir(win, tree, true);
+        testSortByDir(win, tree, false);
+        testInvalid(win, tree);
+        // Reset the sort to SORT_BY_NONE.
+        setSort(win, tree, false, false);
+        // Close the window and finish.
+        win.close();
+        finish();
+      });
+    }, false);
+  }
 
   ww.registerNotification(windowObserver);
   ww.openWindow(null,
                 "chrome://browser/content/places/places.xul",
                 "",
                 "chrome,toolbar=yes,dialog=no,resizable",
                 null);
 }
--- a/browser/components/places/tests/unit/test_browserGlue_corrupt.js
+++ b/browser/components/places/tests/unit/test_browserGlue_corrupt.js
@@ -10,17 +10,17 @@
  *
  * 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 Places Unit Test code.
  *
- * The Initial Developer of the Original Code is Mozilla Corp.
+ * The Initial Developer of the Original Code is Mozilla Foundation.
  * Portions created by the Initial Developer are Copyright (C) 2009
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *  Marco Bonardo <mak77@bonardo.net>
  *
  * 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
@@ -37,22 +37,23 @@
  * ***** END LICENSE BLOCK ***** */
 
 /**
  * Tests that nsBrowserGlue correctly restores bookmarks from a JSON backup if
  * database is corrupt and one backup is available.
  */
 
 function run_test() {
+  do_test_pending();
+
   // Create our bookmarks.html copying bookmarks.glue.html to the profile
-  // folder.  It will be ignored.
+  // folder.  It should be ignored.
   create_bookmarks_html("bookmarks.glue.html");
 
-  // Create our JSON backup copying bookmarks.glue.json to the profile
-  // folder.  It will be ignored.
+  // Create our JSON backup copying bookmarks.glue.json to the profile folder.
   create_JSON_backup("bookmarks.glue.json");
 
   // Remove current database file.
   let db = gProfD.clone();
   db.append("places.sqlite");
   if (db.exists()) {
     db.remove(false);
     do_check_false(db.exists());
@@ -68,30 +69,39 @@ function run_test() {
 
   // Initialize Places through the History Service.
   let hs = Cc["@mozilla.org/browser/nav-history-service;1"].
            getService(Ci.nsINavHistoryService);
   // Check the database was corrupt.
   // nsBrowserGlue uses databaseStatus to manage initialization.
   do_check_eq(hs.databaseStatus, hs.DATABASE_STATUS_CORRUPT);
 
-  // Restore could take some time, usually less than 1s.
-  // We will poll later in continue_test to be sure restore has finished.
-  do_test_pending();
-  do_timeout(1000, continue_test);
+  // Wait for restore to finish.
+  let os = Cc["@mozilla.org/observer-service;1"].
+           getService(Ci.nsIObserverService);
+  let observer = {
+    observe: function(aSubject, aTopic, aData) {
+      os.removeObserver(observer, "bookmarks-restore-success");
+      os.removeObserver(observer, "bookmarks-restore-failed");
+      do_check_eq(aTopic, "bookmarks-restore-success");
+      do_check_eq(aData, "json");
+      continue_test();
+    }
+  }
+  os.addObserver(observer, "bookmarks-restore-success", false);
+  os.addObserver(observer, "bookmarks-restore-failed", false);
 }
 
 function continue_test() {
   let bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
            getService(Ci.nsINavBookmarksService);
 
-  if (bs.getIdForItemAt(bs.toolbarFolder, 0) == -1) {
-    // Not enough time to complete restore, poll again later.
-    do_timeout(1000, continue_test);
-    return;
-  }
+  // Check that JSON backup has been restored.
+  // Notice restore from JSON notification is fired before smart bookmarks creation.
+  let itemId = bs.getIdForItemAt(bs.toolbarFolder, 0);
+  do_check_neq(itemId, -1);
+  do_check_eq(bs.getItemTitle(itemId), "examplejson");
 
-  // Check that JSON backup has been restored.
-  let itemId = bs.getIdForItemAt(bs.toolbarFolder, SMART_BOOKMARKS_ON_TOOLBAR);
-  do_check_eq(bs.getItemTitle(itemId), "examplejson");
+  remove_bookmarks_html();
+  remove_all_JSON_backups();
 
   do_test_finished();
 }
--- a/browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup.js
+++ b/browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup.js
@@ -10,17 +10,17 @@
  *
  * 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 Places Unit Test code.
  *
- * The Initial Developer of the Original Code is Mozilla Corp.
+ * The Initial Developer of the Original Code is Mozilla Foundation.
  * Portions created by the Initial Developer are Copyright (C) 2009
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *  Marco Bonardo <mak77@bonardo.net>
  *
  * 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
@@ -36,76 +36,69 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 /**
  * Tests that nsBrowserGlue correctly imports from bookmarks.html if database
  * is corrupt but a JSON backup is not available.
  */
 
-const NS_PLACES_INIT_COMPLETE_TOPIC = "places-init-complete";
-
-// Create an observer for the Places notifications
-var os = Cc["@mozilla.org/observer-service;1"].
-         getService(Ci.nsIObserverService);
-var observer = {
-  observe: function thn_observe(aSubject, aTopic, aData) {
-    if (aTopic == NS_PLACES_INIT_COMPLETE_TOPIC) {
-        os.removeObserver(this, NS_PLACES_INIT_COMPLETE_TOPIC);
-        var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
-                 getService(Ci.nsINavHistoryService);
-      // Check the database was corrupt.
-      // nsBrowserGlue uses databaseStatus to manage initialization.
-      do_check_eq(hs.databaseStatus, hs.DATABASE_STATUS_CORRUPT);
+function run_test() {
+  do_test_pending();
 
-      // Enqueue next part of the test.
-      var tm = Cc["@mozilla.org/thread-manager;1"].
-               getService(Ci.nsIThreadManager);
-      tm.mainThread.dispatch({
-        run: function() {
-          continue_test();
-        }
-      }, Ci.nsIThread.DISPATCH_NORMAL);
-    }
-  }
-};
-os.addObserver(observer, NS_PLACES_INIT_COMPLETE_TOPIC, false);
-
-function run_test() {
   // Create bookmarks.html in the profile.
   create_bookmarks_html("bookmarks.glue.html");
   // Remove JSON backup from profile.
   remove_all_JSON_backups();
 
   // Remove current database file.
-  var db = gProfD.clone();
+  let db = gProfD.clone();
   db.append("places.sqlite");
   if (db.exists()) {
     db.remove(false);
     do_check_false(db.exists());
   }
   // Create a corrupt database.
-  var corruptDB = gTestDir.clone();
+  let corruptDB = gTestDir.clone();
   corruptDB.append("corruptDB.sqlite");
   corruptDB.copyTo(gProfD, "places.sqlite");
   do_check_true(db.exists());
 
   // Initialize nsBrowserGlue before Places.
   Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsIBrowserGlue);
 
   // Initialize Places through the History Service.
-  var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
+  let hs = Cc["@mozilla.org/browser/nav-history-service;1"].
            getService(Ci.nsINavHistoryService);
+  // Check the database was corrupt.
+  // nsBrowserGlue uses databaseStatus to manage initialization.
+  do_check_eq(hs.databaseStatus, hs.DATABASE_STATUS_CORRUPT);
 
-  // Wait for init-complete notification before going on.
-  do_test_pending();
+  // Wait for restore to finish.
+  let os = Cc["@mozilla.org/observer-service;1"].
+           getService(Ci.nsIObserverService);
+  let observer = {
+    observe: function(aSubject, aTopic, aData) {
+      os.removeObserver(observer, "bookmarks-restore-success");
+      os.removeObserver(observer, "bookmarks-restore-failed");
+      do_check_eq(aTopic, "bookmarks-restore-success");
+      do_check_eq(aData, "html-initial");
+      continue_test();
+    }
+  }
+  os.addObserver(observer, "bookmarks-restore-success", false);
+  os.addObserver(observer, "bookmarks-restore-failed", false);
 }
 
 function continue_test() {
-  var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
+  let bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
            getService(Ci.nsINavBookmarksService);
 
-  var itemId = bs.getIdForItemAt(bs.toolbarFolder, SMART_BOOKMARKS_ON_TOOLBAR);
+  // Check that bookmarks html has been restored.
+  // Notice restore from HTML notification is fired after smart bookmarks creation.
+  let itemId = bs.getIdForItemAt(bs.toolbarFolder, SMART_BOOKMARKS_ON_TOOLBAR);
   do_check_neq(itemId, -1);
   do_check_eq(bs.getItemTitle(itemId), "example");
 
+  remove_bookmarks_html();
+
   do_test_finished();
 }
--- a/browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup_default.js
+++ b/browser/components/places/tests/unit/test_browserGlue_corrupt_nobackup_default.js
@@ -10,17 +10,17 @@
  *
  * 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 Places Unit Test code.
  *
- * The Initial Developer of the Original Code is Mozilla Corp.
+ * The Initial Developer of the Original Code is Mozilla Foundation.
  * Portions created by the Initial Developer are Copyright (C) 2009
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *  Marco Bonardo <mak77@bonardo.net>
  *
  * 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
@@ -36,76 +36,66 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 /**
  * Tests that nsBrowserGlue correctly restores default bookmarks if database is
  * corrupt, nor a JSON backup nor bookmarks.html are available.
  */
 
-const NS_PLACES_INIT_COMPLETE_TOPIC = "places-init-complete";
-
-// Create an observer for the Places notifications
-var os = Cc["@mozilla.org/observer-service;1"].
-         getService(Ci.nsIObserverService);
-var observer = {
-  observe: function thn_observe(aSubject, aTopic, aData) {
-    if (aTopic == NS_PLACES_INIT_COMPLETE_TOPIC) {
-        os.removeObserver(this, NS_PLACES_INIT_COMPLETE_TOPIC);
-        var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
-                 getService(Ci.nsINavHistoryService);
-      // Check the database was corrupt.
-      // nsBrowserGlue uses databaseStatus to manage initialization.
-      do_check_eq(hs.databaseStatus, hs.DATABASE_STATUS_CORRUPT);
+function run_test() {
+  do_test_pending();
 
-      // Enqueue next part of the test.
-      var tm = Cc["@mozilla.org/thread-manager;1"].
-               getService(Ci.nsIThreadManager);
-      tm.mainThread.dispatch({
-        run: function() {
-          continue_test();
-        }
-      }, Ci.nsIThread.DISPATCH_NORMAL);
-    }
-  }
-};
-os.addObserver(observer, NS_PLACES_INIT_COMPLETE_TOPIC, false);
-
-function run_test() {
   // Remove bookmarks.html from profile.
   remove_bookmarks_html();
   // Remove JSON backup from profile.
   remove_all_JSON_backups();
 
   // Remove current database file.
-  var db = gProfD.clone();
+  let db = gProfD.clone();
   db.append("places.sqlite");
   if (db.exists()) {
     db.remove(false);
     do_check_false(db.exists());
   }
   // Create a corrupt database.
-  var corruptDB = gTestDir.clone();
+  let corruptDB = gTestDir.clone();
   corruptDB.append("corruptDB.sqlite");
   corruptDB.copyTo(gProfD, "places.sqlite");
   do_check_true(db.exists());
 
   // Initialize nsBrowserGlue before Places.
   Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsIBrowserGlue);
 
   // Initialize Places through the History Service.
-  var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
+  let hs = Cc["@mozilla.org/browser/nav-history-service;1"].
            getService(Ci.nsINavHistoryService);
+  // Check the database was corrupt.
+  // nsBrowserGlue uses databaseStatus to manage initialization.
+  do_check_eq(hs.databaseStatus, hs.DATABASE_STATUS_CORRUPT);
 
-  // Wait for init-complete notification before going on.
-  do_test_pending();
+  // Wait for restore to finish.
+  let os = Cc["@mozilla.org/observer-service;1"].
+           getService(Ci.nsIObserverService);
+  let observer = {
+    observe: function(aSubject, aTopic, aData) {
+      os.removeObserver(observer, "bookmarks-restore-success");
+      os.removeObserver(observer, "bookmarks-restore-failed");
+      do_check_eq(aTopic, "bookmarks-restore-success");
+      do_check_eq(aData, "html-initial");
+      continue_test();
+    }
+  }
+  os.addObserver(observer, "bookmarks-restore-success", false);
+  os.addObserver(observer, "bookmarks-restore-failed", false);
 }
 
 function continue_test() {
-  var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
+  let bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
            getService(Ci.nsINavBookmarksService);
 
   // Check that default bookmarks have been restored.
-  var itemId = bs.getIdForItemAt(bs.toolbarFolder, SMART_BOOKMARKS_ON_TOOLBAR + 1);
+  let itemId = bs.getIdForItemAt(bs.toolbarFolder, SMART_BOOKMARKS_ON_TOOLBAR);
   do_check_true(itemId > 0);
+  do_check_eq(bs.getItemTitle(itemId), "Getting Started");
 
   do_test_finished();
 }
--- a/browser/components/places/tests/unit/test_browserGlue_distribution.js
+++ b/browser/components/places/tests/unit/test_browserGlue_distribution.js
@@ -42,32 +42,22 @@
  * bookmark on init, we should not try to import.
  */
 
 const PREF_SMART_BOOKMARKS_VERSION = "browser.places.smartBookmarksVersion";
 const PREF_BMPROCESSED = "distribution.516444.bookmarksProcessed";
 const PREF_DISTRIBUTION_ID = "distribution.id";
 
 const TOPIC_FINAL_UI_STARTUP = "final-ui-startup";
+const TOPIC_PLACES_INIT_COMPLETE = "places-init-complete";
 const TOPIC_CUSTOMIZATION_COMPLETE = "distribution-customization-complete";
 
-let os = Cc["@mozilla.org/observer-service;1"].
-         getService(Ci.nsIObserverService);
+function run_test() {
+  do_test_pending();
 
-let observer = {
-  observe: function(aSubject, aTopic, aData) {
-    if (aTopic == TOPIC_CUSTOMIZATION_COMPLETE) {
-      os.removeObserver(this, TOPIC_CUSTOMIZATION_COMPLETE);
-      do_timeout(0, continue_test);
-    }
-  }
-}
-os.addObserver(observer, TOPIC_CUSTOMIZATION_COMPLETE, false);
-
-function run_test() {
   // Copy distribution.ini file to our app dir.
   let distroDir = dirSvc.get("XCurProcD", Ci.nsIFile);
   distroDir.append("distribution");
   let iniFile = distroDir.clone();
   iniFile.append("distribution.ini");
   if (iniFile.exists()) {
     iniFile.remove(false);
     print("distribution.ini already exists, did some test forget to cleanup?");
@@ -77,34 +67,51 @@ function run_test() {
   testDistributionFile.append("distribution.ini");
   testDistributionFile.copyTo(distroDir, "distribution.ini");
   do_check_true(testDistributionFile.exists());
 
   // Disable Smart Bookmarks creation.
   let ps = Cc["@mozilla.org/preferences-service;1"].
            getService(Ci.nsIPrefBranch);
   ps.setIntPref(PREF_SMART_BOOKMARKS_VERSION, -1);
+  // Avoid migrateUI, we are just simulating a partial startup.
+  ps.setIntPref("browser.migration.version", 1);
 
-  // Initialize Places through the History Service, so it won't trigger
-  // browserGlue::_initPlaces since browserGlue is not yet in context.
+  // Initialize Places through the History Service.
   let hs = Cc["@mozilla.org/browser/nav-history-service;1"].
            getService(Ci.nsINavHistoryService);
   // Check a new database has been created.
   // nsBrowserGlue will use databaseStatus to manage initialization.
   do_check_eq(hs.databaseStatus, hs.DATABASE_STATUS_CREATE);
 
   // Initialize nsBrowserGlue.
-  Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsIBrowserGlue);
+  let bg = Cc["@mozilla.org/browser/browserglue;1"].
+           getService(Ci.nsIBrowserGlue);
+
+  let os = Cc["@mozilla.org/observer-service;1"].
+           getService(Ci.nsIObserverService);
+  let observer = {
+    observe: function(aSubject, aTopic, aData) {
+      os.removeObserver(this, TOPIC_PLACES_INIT_COMPLETE);
 
-  os.notifyObservers(null, TOPIC_FINAL_UI_STARTUP, null);
-  // places-init-complete is an enqueued notification so it will be notified
-  // when exiting from this scope.
-
-  do_test_pending();
-  // Test will continue on customization complete notification.
+      // Simulate browser startup.
+      bg.QueryInterface(Ci.nsIObserver).observe(null,
+                                                TOPIC_FINAL_UI_STARTUP,
+                                                null);
+      // Test will continue on customization complete notification.
+      let observer = {
+        observe: function(aSubject, aTopic, aData) {
+          os.removeObserver(this, TOPIC_CUSTOMIZATION_COMPLETE);
+          continue_test();
+        }
+      }
+      os.addObserver(observer, TOPIC_CUSTOMIZATION_COMPLETE, false);
+    }
+  }
+  os.addObserver(observer, TOPIC_PLACES_INIT_COMPLETE, false);
 }
 
 function continue_test() {
   let bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
            getService(Ci.nsINavBookmarksService);
 
   dump_table("moz_bookmarks");
 
--- a/browser/components/places/tests/unit/test_browserGlue_migrate.js
+++ b/browser/components/places/tests/unit/test_browserGlue_migrate.js
@@ -10,17 +10,17 @@
  *
  * 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 Places Unit Test code.
  *
- * The Initial Developer of the Original Code is Mozilla Corp.
+ * The Initial Developer of the Original Code is Mozilla Foundation.
  * Portions created by the Initial Developer are Copyright (C) 2009
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *  Marco Bonardo <mak77@bonardo.net>
  *
  * 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
@@ -39,18 +39,16 @@
 /**
  * Tests that nsBrowserGlue does not overwrite bookmarks imported from the
  * migrators.  They usually run before nsBrowserGlue, so if we find any
  * bookmark on init, we should not try to import.
  */
 
 const PREF_SMART_BOOKMARKS_VERSION = "browser.places.smartBookmarksVersion";
 
-const TOPIC_PLACES_INIT_COMPLETE = "places-init-complete";
-
 function run_test() {
   // Create our bookmarks.html copying bookmarks.glue.html to the profile
   // folder.  It will be ignored.
   create_bookmarks_html("bookmarks.glue.html");
 
   // Remove current database file.
   let db = gProfD.clone();
   db.append("places.sqlite");
@@ -74,23 +72,18 @@ function run_test() {
   // A migrator would run before nsBrowserGlue, so we mimic that behavior
   // adding a bookmark.
   let bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
            getService(Ci.nsINavBookmarksService);
   bs.insertBookmark(bs.bookmarksMenuFolder, uri("http://mozilla.org/"),
                     bs.DEFAULT_INDEX, "migrated");
 
   // Initialize nsBrowserGlue.
-  Cc["@mozilla.org/browser/browserglue;1"].getService(Ci.nsIBrowserGlue);
-
-  // Places initialization has already happened, so we need to simulate
-  // it. This will force browserGlue::_initPlaces().
-  let os = Cc["@mozilla.org/observer-service;1"].
-           getService(Ci.nsIObserverService);
-  os.notifyObservers(null, TOPIC_PLACES_INIT_COMPLETE, null);
+  let bg = Cc["@mozilla.org/browser/browserglue;1"].
+           getService(Ci.nsIBrowserGlue);
 
   // Import could take some time, usually less than 1s, but to be sure we will
   // check after 3s.
   do_test_pending();
   do_timeout(3000, continue_test);
 }
 
 function continue_test() {
@@ -100,10 +93,12 @@ function continue_test() {
   // Check the created bookmarks still exist.
   let itemId = bs.getIdForItemAt(bs.bookmarksMenuFolder, 0);
   do_check_eq(bs.getItemTitle(itemId), "migrated");
 
   // Check that we have not imported any new bookmark.
   do_check_eq(bs.getIdForItemAt(bs.bookmarksMenuFolder, 1), -1);
   do_check_eq(bs.getIdForItemAt(bs.toolbarFolder, 0), -1);
 
+  remove_bookmarks_html();
+
   do_test_finished();
 }
--- a/browser/components/places/tests/unit/test_browserGlue_restore.js
+++ b/browser/components/places/tests/unit/test_browserGlue_restore.js
@@ -10,17 +10,17 @@
  *
  * 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 Places Unit Test code.
  *
- * The Initial Developer of the Original Code is Mozilla Corp.
+ * The Initial Developer of the Original Code is Mozilla Foundation.
  * Portions created by the Initial Developer are Copyright (C) 2009
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *  Marco Bonardo <mak77@bonardo.net>
  *
  * 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
@@ -37,16 +37,18 @@
  * ***** END LICENSE BLOCK ***** */
 
 /**
  * Tests that nsBrowserGlue correctly restores bookmarks from a JSON backup if
  * database has been created and one backup is available.
  */
 
 function run_test() {
+  do_test_pending();
+
   // Create our bookmarks.html copying bookmarks.glue.html to the profile
   // folder.  It will be ignored.
   create_bookmarks_html("bookmarks.glue.html");
 
   // Create our JSON backup copying bookmarks.glue.json to the profile
   // folder.  It will be ignored.
   create_JSON_backup("bookmarks.glue.json");
 
@@ -63,30 +65,38 @@ function run_test() {
 
   // Initialize Places through the History Service.
   let hs = Cc["@mozilla.org/browser/nav-history-service;1"].
            getService(Ci.nsINavHistoryService);
   // Check a new database has been created.
   // nsBrowserGlue uses databaseStatus to manage initialization.
   do_check_eq(hs.databaseStatus, hs.DATABASE_STATUS_CREATE);
 
-  // Restore could take some time, usually less than 1s.
-  // We will poll later in continue_test() to be sure restore has finished.
-  do_test_pending();
-  do_timeout(1000, continue_test);
+  // Wait for restore to finish.
+  let os = Cc["@mozilla.org/observer-service;1"].
+           getService(Ci.nsIObserverService);
+  let observer = {
+    observe: function(aSubject, aTopic, aData) {
+      os.removeObserver(observer, "bookmarks-restore-success");
+      os.removeObserver(observer, "bookmarks-restore-failed");
+      do_check_eq(aTopic, "bookmarks-restore-success");
+      do_check_eq(aData, "json");
+      continue_test();
+    }
+  }
+  os.addObserver(observer, "bookmarks-restore-success", false);
+  os.addObserver(observer, "bookmarks-restore-failed", false);
 }
 
 function continue_test() {
   let bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
            getService(Ci.nsINavBookmarksService);
 
-  if (bs.getIdForItemAt(bs.toolbarFolder, 0) == -1) {
-    // Not enough time to complete restore, poll again later.
-    do_timeout(1000, continue_test);
-    return;
-  }
+  // Check that JSON backup has been restored.
+  // Notice restore from JSON notification is fired before smart bookmarks creation.
+  let itemId = bs.getIdForItemAt(bs.toolbarFolder, 0);
+  do_check_eq(bs.getItemTitle(itemId), "examplejson");
 
-  // Check that JSON backup has been restored.
-  let itemId = bs.getIdForItemAt(bs.toolbarFolder, SMART_BOOKMARKS_ON_TOOLBAR);
-  do_check_eq(bs.getItemTitle(itemId), "examplejson");
+  remove_bookmarks_html();
+  remove_all_JSON_backups();
 
   do_test_finished();
 }
--- a/browser/components/places/tests/unit/test_browserGlue_shutdown.js
+++ b/browser/components/places/tests/unit/test_browserGlue_shutdown.js
@@ -10,17 +10,17 @@
  *
  * 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 Places Unit Test code.
  *
- * The Initial Developer of the Original Code is Mozilla Corp.
+ * The Initial Developer of the Original Code is Mozilla Foundation.
  * Portions created by the Initial Developer are Copyright (C) 2009
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *  Marco Bonardo <mak77@bonardo.net>
  *
  * 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
@@ -36,17 +36,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 /**
  * Tests that nsBrowserGlue is correctly exporting based on preferences values,
  * and creating bookmarks backup if one does not exist for today.
  */
 
-// Initialize nsBrowserGlue.
+// Initialize nsBrowserGlue after Places.
 let bg = Cc["@mozilla.org/browser/browserglue;1"].
          getService(Ci.nsIBrowserGlue);
 
 // Initialize Places through Bookmarks Service.
 let bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
          getService(Ci.nsINavBookmarksService);
 
 // Get other services.
@@ -63,20 +63,29 @@ let tests = [];
 
 //------------------------------------------------------------------------------
 
 tests.push({
   description: "Export to bookmarks.html if autoExportHTML is true.",
   exec: function() {
     // Sanity check: we should have bookmarks on the toolbar.
     do_check_true(bs.getIdForItemAt(bs.toolbarFolder, 0) > 0);
+
     // Set preferences.
     ps.setBoolPref(PREF_AUTO_EXPORT_HTML, true);
+
     // Force nsBrowserGlue::_shutdownPlaces().
-    os.notifyObservers(null, TOPIC_QUIT_APPLICATION_GRANTED, null);
+    try {
+      bg.QueryInterface(Ci.nsIObserver).observe(null,
+                                                TOPIC_QUIT_APPLICATION_GRANTED,
+                                                null);
+    }
+    catch(ex) {
+      // This throws due to idle observer, we can ignore that.
+    }
 
     // Check bookmarks.html has been created.
     check_bookmarks_html();
     // Check JSON backup has been created.
     check_JSON_backup();
 
     // Check preferences have not been reverted.
     do_check_true(ps.getBoolPref(PREF_AUTO_EXPORT_HTML));
@@ -89,25 +98,35 @@ tests.push({
 
 //------------------------------------------------------------------------------
 
 tests.push({
   description: "Export to bookmarks.html if autoExportHTML is true and a bookmarks.html exists.",
   exec: function() {
     // Sanity check: we should have bookmarks on the toolbar.
     do_check_true(bs.getIdForItemAt(bs.toolbarFolder, 0) > 0);
-    // Setpreferences.
+
+    // Set preferences.
     ps.setBoolPref(PREF_AUTO_EXPORT_HTML, true);
+
     // Create a bookmarks.html in the profile.
     let profileBookmarksHTMLFile = create_bookmarks_html("bookmarks.glue.html");
     // Get file lastModified and size.
     let lastMod = profileBookmarksHTMLFile.lastModifiedTime;
     let fileSize = profileBookmarksHTMLFile.fileSize;
+
     // Force nsBrowserGlue::_shutdownPlaces().
-    os.notifyObservers(null, TOPIC_QUIT_APPLICATION_GRANTED, null);
+    try {
+      bg.QueryInterface(Ci.nsIObserver).observe(null,
+                                                TOPIC_QUIT_APPLICATION_GRANTED,
+                                                null);
+    }
+    catch(ex) {
+      // This throws due to idle observer, we can ignore that.
+    }
 
     // Check a new bookmarks.html has been created.
     let profileBookmarksHTMLFile = check_bookmarks_html();
     //XXX not working on Linux unit boxes. Could be filestats caching issue.
     //do_check_true(profileBookmarksHTMLFile.lastModifiedTime > lastMod);
     do_check_neq(profileBookmarksHTMLFile.fileSize, fileSize);
 
     // Check preferences have not been reverted.
@@ -121,23 +140,32 @@ tests.push({
 
 //------------------------------------------------------------------------------
 
 tests.push({
   description: "Backup to JSON should be a no-op if a backup for today already exists.",
   exec: function() {
     // Sanity check: we should have bookmarks on the toolbar.
     do_check_true(bs.getIdForItemAt(bs.toolbarFolder, 0) > 0);
+
     // Create a JSON backup in the profile.
     let profileBookmarksJSONFile = create_JSON_backup("bookmarks.glue.json");
     // Get file lastModified and size.
     let lastMod = profileBookmarksJSONFile.lastModifiedTime;
     let fileSize = profileBookmarksJSONFile.fileSize;
+
     // Force nsBrowserGlue::_shutdownPlaces().
-    os.notifyObservers(null, TOPIC_QUIT_APPLICATION_GRANTED, null);
+    try {
+      bg.QueryInterface(Ci.nsIObserver).observe(null,
+                                                TOPIC_QUIT_APPLICATION_GRANTED,
+                                                null);
+    }
+    catch(ex) {
+      // This throws due to idle observer, we can ignore that.
+    }
 
     // Check a new JSON backup has not been created.
     do_check_true(profileBookmarksJSONFile.exists());
     do_check_eq(profileBookmarksJSONFile.lastModifiedTime, lastMod);
     do_check_eq(profileBookmarksJSONFile.fileSize, fileSize);
 
     do_test_finished();
   }
@@ -158,21 +186,22 @@ function next_test() {
 
   // Execute next test.
   let test = tests.shift();
   dump("\nTEST " + (++testIndex) + ": " + test.description);
   test.exec();
 }
 
 function run_test() {
+  do_test_pending();
+
   // Clean up bookmarks.
   remove_all_bookmarks();
 
   // Create some bookmarks.
   bs.insertBookmark(bs.bookmarksMenuFolder, uri("http://mozilla.org/"),
                     bs.DEFAULT_INDEX, "bookmark-on-menu");
   bs.insertBookmark(bs.toolbarFolder, uri("http://mozilla.org/"),
                     bs.DEFAULT_INDEX, "bookmark-on-toolbar");
 
   // Kick-off tests.
-  do_test_pending();
   next_test();
 }
--- a/browser/components/preferences/main.js
+++ b/browser/components/preferences/main.js
@@ -373,18 +373,17 @@ var gMainPane = {
    * indicates that it is a download folder and whose path is as determined by
    * the XPCOM directory service via the download manager's attribute 
    * defaultDownloadsDirectory.
    *
    * @throws if aFolder is not "Desktop" or "Downloads"
    */
   _getDownloadsFolder: function (aFolder)
   {
-    switch(aFolder)
-    {
+    switch (aFolder) {
       case "Desktop":
         var fileLoc = Components.classes["@mozilla.org/file/directory_service;1"]
                                     .getService(Components.interfaces.nsIProperties);
         return fileLoc.get("Desk", Components.interfaces.nsILocalFile);
       break;
       case "Downloads":
         var dnldMgr = Components.classes["@mozilla.org/download-manager;1"]
                                 .getService(Components.interfaces.nsIDownloadManager);
@@ -435,17 +434,17 @@ var gMainPane = {
   },
 
   /**
    * Returns the value for the browser.download.folderList preference.
    */
   getFolderListPref: function ()
   {
     var folderListPref = document.getElementById("browser.download.folderList");
-    switch(folderListPref.value) {
+    switch (folderListPref.value) {
       case 0: // Desktop
       case 1: // Downloads
         return folderListPref.value;
       break;
       case 2: // Custom
         var currentDirPref = document.getElementById("browser.download.dir");
         if (currentDirPref.value) {
           // Resolve to a known location if possible. We are writing out
--- a/browser/components/preferences/tests/browser_bug410900.js
+++ b/browser/components/preferences/tests/browser_bug410900.js
@@ -14,25 +14,23 @@ function test() {
 
   var hserv = Cc["@mozilla.org/uriloader/handler-service;1"].
               getService(Ci.nsIHandlerService);
   hserv.store(info);
 
   var obs = Cc["@mozilla.org/observer-service;1"].
             getService(Ci.nsIObserverService);
 
-  var observer = {
-    observe: function(win, topic, data) {
-      if (topic != "app-handler-pane-loaded")
-        return;
+  function observer(win, topic, data) {
+    if (topic != "app-handler-pane-loaded")
+      return;
 
-      obs.removeObserver(observer, "app-handler-pane-loaded");
-      runTest(win);
-    }
-  };
+    obs.removeObserver(observer, "app-handler-pane-loaded");
+    runTest(win);
+  }
   obs.addObserver(observer, "app-handler-pane-loaded", false);
 
   openDialog("chrome://browser/content/preferences/preferences.xul", "Preferences",
              "chrome,titlebar,toolbar,centerscreen,dialog=no", "paneApplications");
 }
 
 function runTest(win) {
   var sel = win.document.documentElement.getAttribute("lastSelected");
--- a/browser/components/privatebrowsing/test/browser/browser_console_clear.js
+++ b/browser/components/privatebrowsing/test/browser/browser_console_clear.js
@@ -40,55 +40,55 @@
 
 function test() {
   // initialization
   gPrefService.setBoolPref("browser.privatebrowsing.keep_current_session", true);
   let pb = Cc["@mozilla.org/privatebrowsing;1"].
            getService(Ci.nsIPrivateBrowsingService);
   let consoleService = Cc["@mozilla.org/consoleservice;1"].
                        getService(Ci.nsIConsoleService);
-  const kExitMessage = "Message to signal the end of the test";
+  const EXIT_MESSAGE = "Message to signal the end of the test";
   waitForExplicitFinish();
 
   let consoleObserver = {
     observe: function (aMessage) {
       if (!aMessage.message)
         this.gotNull = true;
-      else if (aMessage.message == kExitMessage) {
+      else if (aMessage.message == EXIT_MESSAGE) {
         // make sure that the null message was received
         ok(this.gotNull, "Console should be cleared after leaving the private mode");
-        // make sure the console does not contain kTestMessage
+        // make sure the console does not contain TEST_MESSAGE
         ok(!messageExists(), "Message should not exist after leaving the private mode");
 
         consoleService.unregisterListener(consoleObserver);
         gPrefService.clearUserPref("browser.privatebrowsing.keep_current_session");
         finish();
       }
     },
     gotNull: false
   };
   consoleService.registerListener(consoleObserver);
 
   function messageExists() {
     let out = {};
     consoleService.getMessageArray(out, {});
     let messages = out.value || [];
     for (let i = 0; i < messages.length; ++i) {
-      if (messages[i].message == kTestMessage)
+      if (messages[i].message == TEST_MESSAGE)
         return true;
     }
     return false;
   }
 
-  const kTestMessage = "Test message from the private browsing test";
+  const TEST_MESSAGE = "Test message from the private browsing test";
   // make sure that the console is not empty
-  consoleService.logStringMessage(kTestMessage);
+  consoleService.logStringMessage(TEST_MESSAGE);
   ok(!consoleObserver.gotNull, "Console shouldn't be cleared yet");
   ok(messageExists(), "Message should exist before leaving the private mode");
 
   pb.privateBrowsingEnabled = true;
   ok(!consoleObserver.gotNull, "Console shouldn't be cleared yet");
   ok(messageExists(), "Message should exist after entering the private mode");
   pb.privateBrowsingEnabled = false;
 
   // signal the end of the test
-  consoleService.logStringMessage(kExitMessage);
+  consoleService.logStringMessage(EXIT_MESSAGE);
 }
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_beforeunload.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_beforeunload.js
@@ -35,136 +35,135 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // This test makes sure that cancelling the unloading of a page with a beforeunload
 // handler prevents the private browsing mode transition.
 
 function test() {
-  const kTestPage1 = "data:text/html,<body%20onbeforeunload='return%20false;'>first</body>";
-  const kTestPage2 = "data:text/html,<body%20onbeforeunload='return%20false;'>second</body>";
+  const TEST_PAGE_1 = "data:text/html,<body%20onbeforeunload='return%20false;'>first</body>";
+  const TEST_PAGE_2 = "data:text/html,<body%20onbeforeunload='return%20false;'>second</body>";
   let pb = Cc["@mozilla.org/privatebrowsing;1"]
              .getService(Ci.nsIPrivateBrowsingService);
 
-  let promptHelper = {
-    rejectDialog: 0,
-    acceptDialog: 0,
-    confirmCalls: 0,
-
-    observe: function(aSubject, aTopic, aData) {
-      let dialogWin = aSubject.QueryInterface(Ci.nsIDOMWindow);
-      this.confirmCalls++;
-      let button;
-      if (this.acceptDialog-- > 0)
-        button = dialogWin.document.documentElement.getButton("accept").click();
-      else if (this.rejectDialog-- > 0)
-        button = dialogWin.document.documentElement.getButton("cancel").click();
-    }
-  };
+  let rejectDialog = 0;
+  let acceptDialog = 0;
+  let confirmCalls = 0;
+  function promptObserver(aSubject, aTopic, aData) {
+    let dialogWin = aSubject.QueryInterface(Ci.nsIDOMWindow);
+    confirmCalls++;
+    if (acceptDialog-- > 0)
+      dialogWin.document.documentElement.getButton("accept").click();
+    else if (rejectDialog-- > 0)
+      dialogWin.document.documentElement.getButton("cancel").click();
+  }
 
   Cc["@mozilla.org/observer-service;1"]
     .getService(Ci.nsIObserverService)
-    .addObserver(promptHelper, "common-dialog-loaded", false);
+    .addObserver(promptObserver, "common-dialog-loaded", false);
 
   waitForExplicitFinish();
   let browser1 = gBrowser.getBrowserForTab(gBrowser.addTab());
   browser1.addEventListener("load", function() {
     browser1.removeEventListener("load", arguments.callee, true);
 
     let browser2 = gBrowser.getBrowserForTab(gBrowser.addTab());
     browser2.addEventListener("load", function() {
       browser2.removeEventListener("load", arguments.callee, true);
 
-      promptHelper.rejectDialog = 1;
+      rejectDialog = 1;
       pb.privateBrowsingEnabled = true;
 
       ok(!pb.privateBrowsingEnabled, "Private browsing mode should not have been activated");
-      is(promptHelper.confirmCalls, 1, "Only one confirm box should be shown");
+      is(confirmCalls, 1, "Only one confirm box should be shown");
       is(gBrowser.tabContainer.childNodes.length, 3,
          "No tabs should be closed because private browsing mode transition was canceled");
       is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild).currentURI.spec, "about:blank",
          "The first tab should be a blank tab");
-      is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild.nextSibling).currentURI.spec, kTestPage1,
+      is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild.nextSibling).currentURI.spec, TEST_PAGE_1,
          "The middle tab should be the same one we opened");
-      is(gBrowser.getBrowserForTab(gBrowser.tabContainer.lastChild).currentURI.spec, kTestPage2,
+      is(gBrowser.getBrowserForTab(gBrowser.tabContainer.lastChild).currentURI.spec, TEST_PAGE_2,
          "The last tab should be the same one we opened");
-      is(promptHelper.rejectDialog, 0, "Only one confirm dialog should have been rejected");
+      is(rejectDialog, 0, "Only one confirm dialog should have been rejected");
 
-      promptHelper.confirmCalls = 0;
-      promptHelper.acceptDialog = 2;
+      confirmCalls = 0;
+      acceptDialog = 2;
       pb.privateBrowsingEnabled = true;
 
       ok(pb.privateBrowsingEnabled, "Private browsing mode should have been activated");
-      is(promptHelper.confirmCalls, 2, "Only two confirm boxes should be shown");
+      is(confirmCalls, 2, "Only two confirm boxes should be shown");
       is(gBrowser.tabContainer.childNodes.length, 1,
          "Incorrect number of tabs after transition into private browsing");
       gBrowser.selectedBrowser.addEventListener("load", function() {
         gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
 
-        is(gBrowser.selectedBrowser.currentURI.spec, "about:privatebrowsing",
+        is(gBrowser.currentURI.spec, "about:privatebrowsing",
            "Incorrect page displayed after private browsing transition");
-        is(promptHelper.acceptDialog, 0, "Two confirm dialogs should have been accepted");
+        is(acceptDialog, 0, "Two confirm dialogs should have been accepted");
 
         gBrowser.selectedBrowser.addEventListener("load", function() {
           gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
 
           gBrowser.selectedTab = gBrowser.addTab();
           gBrowser.selectedBrowser.addEventListener("load", function() {
             gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
 
-            promptHelper.confirmCalls = 0;
-            promptHelper.rejectDialog = 1;
+            confirmCalls = 0;
+            rejectDialog = 1;
             pb.privateBrowsingEnabled = false;
 
             ok(pb.privateBrowsingEnabled, "Private browsing mode should not have been deactivated");
-            is(promptHelper.confirmCalls, 1, "Only one confirm box should be shown");
+            is(confirmCalls, 1, "Only one confirm box should be shown");
             is(gBrowser.tabContainer.childNodes.length, 2,
                "No tabs should be closed because private browsing mode transition was canceled");
-            is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild).currentURI.spec, kTestPage1,
+            is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild).currentURI.spec, TEST_PAGE_1,
                "The first tab should be the same one we opened");
-            is(gBrowser.getBrowserForTab(gBrowser.tabContainer.lastChild).currentURI.spec, kTestPage2,
+            is(gBrowser.getBrowserForTab(gBrowser.tabContainer.lastChild).currentURI.spec, TEST_PAGE_2,
                "The last tab should be the same one we opened");
-            is(promptHelper.rejectDialog, 0, "Only one confirm dialog should have been rejected");
+            is(rejectDialog, 0, "Only one confirm dialog should have been rejected");
 
-            promptHelper.confirmCalls = 0;
-            promptHelper.acceptDialog = 2;
+            confirmCalls = 0;
+            acceptDialog = 2;
             pb.privateBrowsingEnabled = false;
 
             ok(!pb.privateBrowsingEnabled, "Private browsing mode should have been deactivated");
-            is(promptHelper.confirmCalls, 2, "Only two confirm boxes should be shown");
+            is(confirmCalls, 2, "Only two confirm boxes should be shown");
             is(gBrowser.tabContainer.childNodes.length, 3,
                "Incorrect number of tabs after transition into private browsing");
 
             let loads = 0;
             function waitForLoad(event) {
               gBrowser.removeEventListener("load", arguments.callee, true);
 
               if (++loads != 3)
                 return;
 
               is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild).currentURI.spec, "about:blank",
                  "The first tab should be a blank tab");
-              is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild.nextSibling).currentURI.spec, kTestPage1,
+              is(gBrowser.getBrowserForTab(gBrowser.tabContainer.firstChild.nextSibling).currentURI.spec, TEST_PAGE_1,
                  "The middle tab should be the same one we opened");
-              is(gBrowser.getBrowserForTab(gBrowser.tabContainer.lastChild).currentURI.spec, kTestPage2,
+              is(gBrowser.getBrowserForTab(gBrowser.tabContainer.lastChild).currentURI.spec, TEST_PAGE_2,
                  "The last tab should be the same one we opened");
-                      is(promptHelper.acceptDialog, 0, "Two confirm dialogs should have been accepted");
-              is(promptHelper.acceptDialog, 0, "Two prompts should have been raised");
+              is(acceptDialog, 0, "Two confirm dialogs should have been accepted");
+              is(acceptDialog, 0, "Two prompts should have been raised");
 
-              promptHelper.acceptDialog = 2;
+              acceptDialog = 2;
               gBrowser.removeTab(gBrowser.tabContainer.lastChild);
               gBrowser.removeTab(gBrowser.tabContainer.lastChild);
 
+              Cc["@mozilla.org/observer-service;1"]
+                .getService(Ci.nsIObserverService)
+                .removeObserver(promptObserver, "common-dialog-loaded", false);
               finish();
             }
             for (let i = 0; i < gBrowser.browsers.length; ++i)
               gBrowser.browsers[i].addEventListener("load", waitForLoad, true);
           }, true);
-          gBrowser.selectedBrowser.loadURI(kTestPage2);
+          gBrowser.selectedBrowser.loadURI(TEST_PAGE_2);
         }, true);
-        gBrowser.selectedBrowser.loadURI(kTestPage1);
+        gBrowser.selectedBrowser.loadURI(TEST_PAGE_1);
       }, true);
     }, true);
-    browser2.loadURI(kTestPage2);
+    browser2.loadURI(TEST_PAGE_2);
   }, true);
-  browser1.loadURI(kTestPage1);
+  browser1.loadURI(TEST_PAGE_1);
 }
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_certexceptionsui.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_certexceptionsui.js
@@ -60,58 +60,54 @@ function test() {
       exceptionAdded : false,
       location: INVALID_CERT_LOCATION,
       handlePrivateBrowsing : true,
       prefetchCert: true,
     };
     function testCheckbox() {
       let obsSvc = Cc["@mozilla.org/observer-service;1"].
                    getService(Ci.nsIObserverService);
-      obsSvc.addObserver({
-        observe: function(aSubject, aTopic, aData) {
-          obsSvc.removeObserver(this, "cert-exception-ui-ready", false);
-          ok(win.gCert, "The certificate information should be available now");
+      obsSvc.addObserver(function (aSubject, aTopic, aData) {
+        obsSvc.removeObserver(arguments.callee, "cert-exception-ui-ready", false);
+        ok(win.gCert, "The certificate information should be available now");
 
-          let checkbox = win.document.getElementById("permanent");
-          ok(checkbox.hasAttribute("disabled"),
-            "the permanent checkbox should be disabled when handling the private browsing mode");
-          ok(!checkbox.hasAttribute("checked"),
-            "the permanent checkbox should not be checked when handling the private browsing mode");
-          win.close();
-          step2();
-        }
+        let checkbox = win.document.getElementById("permanent");
+        ok(checkbox.hasAttribute("disabled"),
+          "the permanent checkbox should be disabled when handling the private browsing mode");
+        ok(!checkbox.hasAttribute("checked"),
+          "the permanent checkbox should not be checked when handling the private browsing mode");
+        win.close();
+        step2();
       }, "cert-exception-ui-ready", false);
     }
     var win = openDialog(EXCEPTIONS_DLG_URL, "", EXCEPTIONS_DLG_FEATURES, params);
     win.addEventListener("load", testCheckbox, false);
   }
 
   // Test the certificate excetions dialog as it is invoked from the Preferences dialog
   function step2() {
     let params = {
       exceptionAdded : false,
       location: INVALID_CERT_LOCATION,
       prefetchCert: true,
     };
     function testCheckbox() {
       let obsSvc = Cc["@mozilla.org/observer-service;1"].
                    getService(Ci.nsIObserverService);
-      obsSvc.addObserver({
-        observe: function(aSubject, aTopic, aData) {
-          obsSvc.removeObserver(this, "cert-exception-ui-ready", false);
-          ok(win.gCert, "The certificate information should be available now");
+      obsSvc.addObserver(function (aSubject, aTopic, aData) {
+        obsSvc.removeObserver(arguments.callee, "cert-exception-ui-ready", false);
+        ok(win.gCert, "The certificate information should be available now");
 
-          let checkbox = win.document.getElementById("permanent");
-          ok(!checkbox.hasAttribute("disabled"),
-            "the permanent checkbox should not be disabled when not handling the private browsing mode");
-          ok(checkbox.hasAttribute("checked"),
-            "the permanent checkbox should be checked when not handling the private browsing mode");
-          win.close();
-          cleanup();
-        }
+        let checkbox = win.document.getElementById("permanent");
+        ok(!checkbox.hasAttribute("disabled"),
+          "the permanent checkbox should not be disabled when not handling the private browsing mode");
+        ok(checkbox.hasAttribute("checked"),
+          "the permanent checkbox should be checked when not handling the private browsing mode");
+        win.close();
+        cleanup();
       }, "cert-exception-ui-ready", false);
     }
     var win = openDialog(EXCEPTIONS_DLG_URL, "", EXCEPTIONS_DLG_FEATURES, params);
     win.addEventListener("load", testCheckbox, false);
   }
 
   function cleanup() {
     // leave the private browsing mode
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_commandline_toggle.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_commandline_toggle.js
@@ -112,21 +112,19 @@ function test() {
     while (categories.hasMoreElements()) {
       let category = categories.getNext().QueryInterface(Ci.nsISupportsCString).data;
       let contractID = catMan.getCategoryEntry("command-line-handler", category);
       let handler = Cc[contractID].getService(Ci.nsICommandLineHandler);
       handler.handle(testcl);
     }
   }
 
-  let observer = {
-    observe: function (aSubject, aTopic, aData) {
-      isnot(aTopic, "domwindowopened", "The -private-toggle argument should be silent");
-    }
-  };
+  function observer(aSubject, aTopic, aData) {
+    isnot(aTopic, "domwindowopened", "The -private-toggle argument should be silent");
+  }
   ww.registerNotification(observer);
 
   let tab = gBrowser.selectedTab;
   let browser = gBrowser.getBrowserForTab(tab);
   browser.addEventListener("load", function () {
     browser.removeEventListener("load", arguments.callee, true);
     ok(!pb.privateBrowsingEnabled, "The private browsing mode should not be started");
     is(browser.contentWindow.location, "about:", "The correct page has been loaded");
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_cookieacceptdialog.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_cookieacceptdialog.js
@@ -45,43 +45,42 @@ function test() {
   let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
            getService(Ci.nsIWindowWatcher);
   let cp = Cc["@mozilla.org/embedcomp/cookieprompt-service;1"].
            getService(Ci.nsICookiePromptService);
 
   waitForExplicitFinish();
 
   function checkRememberOption(expectedDisabled, callback) {
-    let observer = {
-      observe: function(aSubject, aTopic, aData) {
-        if (aTopic === "domwindowopened") {
-          ww.unregisterNotification(this);
-          let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
-          win.addEventListener("load", function onLoad(event) {
-            win.removeEventListener("load", onLoad, false);
+    function observer(aSubject, aTopic, aData) {
+      if (aTopic != "domwindowopened")
+        return;
 
-            executeSoon(function() {
-              let doc = win.document;
-              let remember = doc.getElementById("persistDomainAcceptance");
-              ok(remember, "The remember checkbox should exist");
+      ww.unregisterNotification(observer);
+      let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
+      win.addEventListener("load", function onLoad(event) {
+        win.removeEventListener("load", onLoad, false);
 
-              if (expectedDisabled)
-                is(remember.getAttribute("disabled"), "true",
-                   "The checkbox should be disabled");
-              else
-                ok(!remember.hasAttribute("disabled"),
-                   "The checkbox should not be disabled");
+        executeSoon(function () {
+          let doc = win.document;
+          let remember = doc.getElementById("persistDomainAcceptance");
+          ok(remember, "The remember checkbox should exist");
 
-              win.close();
-              callback();
-            });
-          }, false);
-        }
-      }
-    };
+          if (expectedDisabled)
+            is(remember.getAttribute("disabled"), "true",
+               "The checkbox should be disabled");
+          else
+            ok(!remember.hasAttribute("disabled"),
+               "The checkbox should not be disabled");
+
+          win.close();
+          callback();
+        });
+      }, false);
+    }
     ww.registerNotification(observer);
 
     let remember = {};
     const time = (new Date("Jan 1, 2030")).getTime() / 1000;
     let cookie = {
       name: "foo",
       value: "bar",
       isDomain: true,
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_fastswitch.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_fastswitch.js
@@ -39,52 +39,48 @@
 // browsing mode too quickly, hence be proctected from symptoms in bug 526194.
 
 function test() {
   // initialization
   let pb = Cc["@mozilla.org/privatebrowsing;1"].
            getService(Ci.nsIPrivateBrowsingService);
   let os = Cc["@mozilla.org/observer-service;1"].
            getService(Ci.nsIObserverService);
-  let ss = Cc["@mozilla.org/browser/sessionstore;1"].
-           getService(Ci.nsISessionStore);
   let pbCmd = document.getElementById("Tools:PrivateBrowsing");
   waitForExplicitFinish();
 
-  let observer = {
-    pass: 1,
-    observe: function(aSubject, aTopic, aData) {
-      switch (aTopic) {
-        case "private-browsing":
-          setTimeout(function() {
-            ok(document.getElementById("Tools:PrivateBrowsing").hasAttribute("disabled"),
-               "The private browsing command should be disabled immediately after the mode switch");
-          }, 0);
-          break;
+  let pass = 1;
+  function observer(aSubject, aTopic, aData) {
+    switch (aTopic) {
+      case "private-browsing":
+        setTimeout(function () {
+          ok(document.getElementById("Tools:PrivateBrowsing").hasAttribute("disabled"),
+             "The private browsing command should be disabled immediately after the mode switch");
+        }, 0);
+        break;
 
-        case "private-browsing-transition-complete":
-          if (this.pass++ == 1) {
-            setTimeout(function() {
-              ok(!pbCmd.hasAttribute("disabled"),
-                 "The private browsing command should be re-enabled after entering the private browsing mode");
+      case "private-browsing-transition-complete":
+        if (pass++ == 1) {
+          setTimeout(function () {
+            ok(!pbCmd.hasAttribute("disabled"),
+               "The private browsing command should be re-enabled after entering the private browsing mode");
 
-              pb.privateBrowsingEnabled = false;
-            }, 100);
-          }
-          else {
-            setTimeout(function() {
-              ok(!pbCmd.hasAttribute("disabled"),
-                 "The private browsing command should be re-enabled after exiting the private browsing mode");
+            pb.privateBrowsingEnabled = false;
+          }, 100);
+        }
+        else {
+          setTimeout(function () {
+            ok(!pbCmd.hasAttribute("disabled"),
+               "The private browsing command should be re-enabled after exiting the private browsing mode");
 
-              os.removeObserver(observer, "private-browsing");
-              os.removeObserver(observer, "private-browsing-transition-complete");
-              finish();
-            }, 100);
-          }
-          break;
-      }
+            os.removeObserver(observer, "private-browsing");
+            os.removeObserver(observer, "private-browsing-transition-complete");
+            finish();
+          }, 100);
+        }
+        break;
     }
-  };
+  }
   os.addObserver(observer, "private-browsing", false);
   os.addObserver(observer, "private-browsing-transition-complete", false);
 
   pb.privateBrowsingEnabled = true;
 }
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_forgetthissite.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_forgetthissite.js
@@ -50,64 +50,63 @@ function test() {
   const TEST_URI = "http://www.mozilla.org/privatebrowsing";
   ok(PlacesUtils, "checking PlacesUtils, running in chrome context?");
   let history = PlacesUtils.history;
   let visitId = history.addVisit(PlacesUtils._uri(TEST_URI), Date.now() * 1000,
                                  null, PlacesUtils.history.TRANSITION_TYPED, false, 0);
   ok(visitId > 0, TEST_URI + " successfully marked visited");
 
   function testForgetThisSiteVisibility(expected, funcNext) {
-    let observer = {
-      observe: function(aSubject, aTopic, aData) {
-        if (aTopic === "domwindowopened") {
-          ww.unregisterNotification(this);
-          let organizer = aSubject.QueryInterface(Ci.nsIDOMWindow);
-          organizer.addEventListener("load", function onLoad(event) {
-            organizer.removeEventListener("load", onLoad, false);
-            executeSoon(function () {
-              // Select History in the left pane.
-              let PO = organizer.PlacesOrganizer;
-              PO.selectLeftPaneQuery('History');
-              let histContainer = PO._places.selectedNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
-              histContainer.containerOpen = true;
-              PO._places.selectNode(histContainer.getChild(0));
-              // Select the first history entry.
-              let doc = organizer.document;
-              let tree = PO._content;
-              let selection = tree.view.selection;
-              selection.clearSelection();
-              selection.rangedSelect(0, 0, true);
-              is(tree.selectedNode.uri, TEST_URI, "The correct history item has been selected");
-              // Open the context menu
-              let contextmenu = doc.getElementById("placesContext");
-              contextmenu.addEventListener("popupshown", function() {
-                contextmenu.removeEventListener("popupshown", arguments.callee, false);
-                let forgetThisSite = doc.getElementById("placesContext_deleteHost");
-                is(forgetThisSite.hidden, !expected,
-                  "The Forget This Site menu item should " + (expected ? "not " : "") + "be hidden");
-                let forgetThisSiteCmd = doc.getElementById("placesCmd_deleteDataHost");
-                if (forgetThisSiteCmd.disabled, !expected,
-                  "The Forget This Site command should " + (expected ? "not " : "") + "be disabled");
-                // Close the context menu
-                contextmenu.hidePopup();
-                // Close Library window.
-                organizer.close();
-                // Proceed
-                funcNext();
-              }, false);
-              let event = document.createEvent("MouseEvents");
-              event.initMouseEvent("contextmenu", true, true, organizer, 0,
-                                   0, 0, 0, 0, false, false, false, false,
-                                   0, null);
-              tree.dispatchEvent(event);
-            });
+    function observer(aSubject, aTopic, aData) {
+      if (aTopic != "domwindowopened")
+        return;
+
+      ww.unregisterNotification(observer);
+      let organizer = aSubject.QueryInterface(Ci.nsIDOMWindow);
+      organizer.addEventListener("load", function onLoad(event) {
+        organizer.removeEventListener("load", onLoad, false);
+        executeSoon(function () {
+          // Select History in the left pane.
+          let PO = organizer.PlacesOrganizer;
+          PO.selectLeftPaneQuery('History');
+          let histContainer = PO._places.selectedNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
+          histContainer.containerOpen = true;
+          PO._places.selectNode(histContainer.getChild(0));
+          // Select the first history entry.
+          let doc = organizer.document;
+          let tree = PO._content;
+          let selection = tree.view.selection;
+          selection.clearSelection();
+          selection.rangedSelect(0, 0, true);
+          is(tree.selectedNode.uri, TEST_URI, "The correct history item has been selected");
+          // Open the context menu
+          let contextmenu = doc.getElementById("placesContext");
+          contextmenu.addEventListener("popupshown", function() {
+            contextmenu.removeEventListener("popupshown", arguments.callee, false);
+            let forgetThisSite = doc.getElementById("placesContext_deleteHost");
+            is(forgetThisSite.hidden, !expected,
+              "The Forget This Site menu item should " + (expected ? "not " : "") + "be hidden");
+            let forgetThisSiteCmd = doc.getElementById("placesCmd_deleteDataHost");
+            if (forgetThisSiteCmd.disabled, !expected,
+              "The Forget This Site command should " + (expected ? "not " : "") + "be disabled");
+            // Close the context menu
+            contextmenu.hidePopup();
+            // Close Library window.
+            organizer.close();
+            // Proceed
+            funcNext();
           }, false);
-        }
-      }
-    };
+          let event = document.createEvent("MouseEvents");
+          event.initMouseEvent("contextmenu", true, true, organizer, 0,
+                               0, 0, 0, 0, false, false, false, false,
+                               0, null);
+          tree.dispatchEvent(event);
+        });
+      }, false);
+    }
 
     ww.registerNotification(observer);
     ww.openWindow(null,
                   "chrome://browser/content/places/places.xul",
                   "",
                   "chrome,toolbar=yes,dialog=no,resizable",
                   null);
   }
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_openlocation.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_openlocation.js
@@ -42,19 +42,18 @@ function test() {
   // initialization
   let pb = Cc["@mozilla.org/privatebrowsing;1"].
            getService(Ci.nsIPrivateBrowsingService);
   let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
            getService(Ci.nsIWindowWatcher);
   waitForExplicitFinish();
 
   function openLocation(url, autofilled, callback) {
-    let observer = {
-      observe: function(aSubject, aTopic, aData) {
-        switch (aTopic) {
+    function observer(aSubject, aTopic, aData) {
+      switch (aTopic) {
         case "domwindowopened":
           let dialog = aSubject.QueryInterface(Ci.nsIDOMWindow);
           dialog.addEventListener("load", function () {
             dialog.removeEventListener("load", arguments.callee, false);
 
             let browser = gBrowser.selectedBrowser;
             browser.addEventListener("load", function() {
               browser.removeEventListener("load", arguments.callee, true);
@@ -71,21 +70,20 @@ function test() {
               for (let i = 0; i < url.length; ++i)
                 EventUtils.synthesizeKey(url[i], {}, dialog);
               EventUtils.synthesizeKey("VK_RETURN", {}, dialog);
             });
           }, false);
           break;
 
         case "domwindowclosed":
-          ww.unregisterNotification(this);
+          ww.unregisterNotification(arguments.callee);
           break;
-        }
       }
-    };
+    }
 
     ww.registerNotification(observer);
     gPrefService.setIntPref("general.open_location.last_window_choice", 0);
     openDialog("chrome://browser/content/openLocation.xul", "_blank",
                "chrome,titlebar", window);
   }
 
 
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_transition.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_transition.js
@@ -39,62 +39,61 @@
 // browsing mode. This ensures that all private data is removed on exit, e.g.
 // a cookie set in on unload handler, see bug 476463.
 let cookieManager = Cc["@mozilla.org/cookiemanager;1"].
                     getService(Ci.nsICookieManager2);
 let pb = Cc["@mozilla.org/privatebrowsing;1"].
          getService(Ci.nsIPrivateBrowsingService);
 let _obs = Cc["@mozilla.org/observer-service;1"].
            getService(Ci.nsIObserverService);
-let observerNotified = 0,  firstUnloadFired = 0, secondUnloadFired = 0;
+let observerNotified = 0, firstUnloadFired = 0, secondUnloadFired = 0;
 
-let pbObserver = {
-  observe: function(aSubject, aTopic, aData) {
-    if (aTopic == "private-browsing") {
-      switch(aData) {
-        case "enter":
-          observerNotified++;
-          is(observerNotified, 1, "This should be the first notification");
-          is(firstUnloadFired, 1, "The first unload event should have been processed by now");
-          break;
-        case "exit":
-          _obs.removeObserver(this, "private-browsing");
-          observerNotified++;
-          is(observerNotified, 2, "This should be the second notification");
-          is(secondUnloadFired, 1, "The second unload event should have been processed by now");
-          break;
-      }
-    }
+function pbObserver(aSubject, aTopic, aData) {
+  if (aTopic != "private-browsing")
+    return;
+  switch (aData) {
+    case "enter":
+      observerNotified++;
+      is(observerNotified, 1, "This should be the first notification");
+      is(firstUnloadFired, 1, "The first unload event should have been processed by now");
+      break;
+    case "exit":
+      _obs.removeObserver(pbObserver, "private-browsing");
+      observerNotified++;
+      is(observerNotified, 2, "This should be the second notification");
+      is(secondUnloadFired, 1, "The second unload event should have been processed by now");
+      break;
   }
 }
+
 function test() {
   waitForExplicitFinish();
   _obs.addObserver(pbObserver, "private-browsing", false);
   is(gBrowser.tabContainer.childNodes.length, 1, "There should only be one tab");
   let testTab = gBrowser.addTab();
   gBrowser.selectedTab = testTab;
-  testTab.linkedBrowser.addEventListener("unload", (function() {
+  testTab.linkedBrowser.addEventListener("unload", function () {
     testTab.linkedBrowser.removeEventListener("unload", arguments.callee, true);
     firstUnloadFired++;
     is(observerNotified, 0, "The notification shouldn't have been sent yet");
-  }), true);
+  }, true);
 
   pb.privateBrowsingEnabled = true;
   let testTab = gBrowser.addTab();
   gBrowser.selectedTab = testTab;
-  testTab.linkedBrowser.addEventListener("unload", (function() {
+  testTab.linkedBrowser.addEventListener("unload", function () {
     testTab.linkedBrowser.removeEventListener("unload", arguments.callee, true);
     secondUnloadFired++;
     is(observerNotified, 1, "The notification shouldn't have been sent yet");
     cookieManager.add("example.com", "test/", "PB", "1", false, false, false, 1000000000000);
-  }), true);
+  }, true);
 
   pb.privateBrowsingEnabled = false;
-  gBrowser.tabContainer.lastChild.linkedBrowser.addEventListener("unload", (function() {
+  gBrowser.tabContainer.lastChild.linkedBrowser.addEventListener("unload", function () {
     gBrowser.tabContainer.lastChild.linkedBrowser.removeEventListener("unload", arguments.callee, true);
     let count = cookieManager.countCookiesFromHost("example.com");
     is(count, 0, "There shouldn't be any cookies once pb mode has exited");
     cookieManager.QueryInterface(Ci.nsICookieManager);
     cookieManager.remove("example.com", "PB", "test/", false);
-  }), true);
+  }, true);
   gBrowser.removeCurrentTab();
   finish();
 }
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_ui.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_ui.js
@@ -38,23 +38,21 @@
 // This test makes sure that the gPrivateBrowsingUI object, the Private Browsing
 // menu item and its XUL <command> element work correctly.
 
 function test() {
   // initialization
   gPrefService.setBoolPref("browser.privatebrowsing.keep_current_session", true);
   let pb = Cc["@mozilla.org/privatebrowsing;1"].
            getService(Ci.nsIPrivateBrowsingService);
-  let observer = {
-    observe: function (aSubject, aTopic, aData) {
-      if (aTopic == "private-browsing")
-        this.data = aData;
-    },
-    data: null
-  };
+  let observerData;
+  function observer(aSubject, aTopic, aData) {
+    if (aTopic == "private-browsing")
+      observerData = aData;
+  }
   let os = Cc["@mozilla.org/observer-service;1"].
            getService(Ci.nsIObserverService);
   os.addObserver(observer, "private-browsing", false);
   let pbMenuItem = document.getElementById("privateBrowsingItem");
   // add a new blank tab to ensure the title can be meaningfully compared later
   gBrowser.selectedTab = gBrowser.addTab();
   let originalTitle = document.title;
 
@@ -63,37 +61,37 @@ function test() {
   is(pb.privateBrowsingEnabled, false, "The private browsing mode should not be started initially");
   is(gPrivateBrowsingUI.privateBrowsingEnabled, false, "gPrivateBrowsingUI should expose the correct private browsing status");
   ok(pbMenuItem, "The Private Browsing menu item exists");
   is(pbMenuItem.getAttribute("label"), pbMenuItem.getAttribute("startlabel"), "The Private Browsing menu item should read \"Start Private Browsing\"");
   gPrivateBrowsingUI.toggleMode();
   is(pb.privateBrowsingEnabled, true, "The private browsing mode should be started");
   is(gPrivateBrowsingUI.privateBrowsingEnabled, true, "gPrivateBrowsingUI should expose the correct private browsing status");
   // check to see if the Private Browsing mode was activated successfully
-  is(observer.data, "enter", "Private Browsing mode was activated using the gPrivateBrowsingUI object");
+  is(observerData, "enter", "Private Browsing mode was activated using the gPrivateBrowsingUI object");
   is(pbMenuItem.getAttribute("label"), pbMenuItem.getAttribute("stoplabel"), "The Private Browsing menu item should read \"Stop Private Browsing\"");
   gPrivateBrowsingUI.toggleMode()
   is(pb.privateBrowsingEnabled, false, "The private browsing mode should not be started");
   is(gPrivateBrowsingUI.privateBrowsingEnabled, false, "gPrivateBrowsingUI should expose the correct private browsing status");
   // check to see if the Private Browsing mode was deactivated successfully
-  is(observer.data, "exit", "Private Browsing mode was deactivated using the gPrivateBrowsingUI object");
+  is(observerData, "exit", "Private Browsing mode was deactivated using the gPrivateBrowsingUI object");
   is(pbMenuItem.getAttribute("label"), pbMenuItem.getAttribute("startlabel"), "The Private Browsing menu item should read \"Start Private Browsing\"");
 
   // now, test using the <command> object
   let cmd = document.getElementById("Tools:PrivateBrowsing");
   isnot(cmd, null, "XUL command object for the private browsing service exists");
   var func = new Function("", cmd.getAttribute("oncommand"));
   func.call(cmd);
   // check to see if the Private Browsing mode was activated successfully
-  is(observer.data, "enter", "Private Browsing mode was activated using the command object");
+  is(observerData, "enter", "Private Browsing mode was activated using the command object");
   // check to see that the window title has been changed correctly
   isnot(document.title, originalTitle, "Private browsing mode has correctly changed the title");
   func.call(cmd);
   // check to see if the Private Browsing mode was deactivated successfully
-  is(observer.data, "exit", "Private Browsing mode was deactivated using the command object");
+  is(observerData, "exit", "Private Browsing mode was deactivated using the command object");
   // check to see that the window title has been restored correctly
   is(document.title, originalTitle, "Private browsing mode has correctly restored the title");
 
   // cleanup
   gBrowser.removeCurrentTab();
   os.removeObserver(observer, "private-browsing");
   gPrefService.clearUserPref("browser.privatebrowsing.keep_current_session");
 }
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_viewsource.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_viewsource.js
@@ -47,58 +47,55 @@ function test() {
 
   gBrowser.selectedTab = gBrowser.addTab();
   let aboutBrowser = gBrowser.selectedBrowser;
   aboutBrowser.addEventListener("load", function () {
     aboutBrowser.removeEventListener("load", arguments.callee, true);
 
     let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
              getService(Ci.nsIWindowWatcher);
-    let observer = {
-      observe: function(aSubject, aTopic, aData) {
-        if (aTopic == "domwindowopened") {
-          ww.unregisterNotification(this);
+    function observer(aSubject, aTopic, aData) {
+      if (aTopic != "domwindowopened")
+        return;
 
-          let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget);
-          win.addEventListener("load", function() {
-            win.removeEventListener("load", arguments.callee, false);
+      ww.unregisterNotification(observer);
+
+      let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget);
+      win.addEventListener("load", function () {
+        win.removeEventListener("load", arguments.callee, false);
 
-            let browser = win.gBrowser;
-            browser.addEventListener("load", function() {
-              browser.removeEventListener("load", arguments.callee, true);
-              
-              // view source window is loaded, proceed with the rest of the test
-              step1();
-            }, true);
-          }, false);
-        }
-      }
-    };
+        let browser = win.gBrowser;
+        browser.addEventListener("load", function () {
+          browser.removeEventListener("load", arguments.callee, true);
+          
+          // view source window is loaded, proceed with the rest of the test
+          step1();
+        }, true);
+      }, false);
+    }
     ww.registerNotification(observer);
 
     openViewSource();
 
     function openViewSource() {
       // invoke the View Source command
       document.getElementById("View:PageSource").doCommand();
     }
 
     function step1() {
-      observer = {
-        observe: function(aSubject, aTopic, aData) {
-          if (aTopic == "domwindowclosed") {
-            ok(true, "Entering the private browsing mode should close the view source window");
-            ww.unregisterNotification(observer);
+      function observer(aSubject, aTopic, aData) {
+        if (aTopic == "domwindowclosed") {
+          ok(true, "Entering the private browsing mode should close the view source window");
+          ww.unregisterNotification(observer);
 
-            step2();
-          }
-          else if (aTopic == "domwindowopened")
-            ok(false, "Entering the private browsing mode should not open any view source window");
+          step2();
         }
-      };
+        else if (aTopic == "domwindowopened")
+          ok(false, "Entering the private browsing mode should not open any view source window");
+      }
       ww.registerNotification(observer);
 
       gBrowser.addTabsProgressListener({
         onLocationChange: function() {},
         onProgressChange: function() {},
         onSecurityChange: function() {},
         onStatusChange: function() {},
         onRefreshAttempted: function() {},
@@ -118,76 +115,73 @@ function test() {
 
     let events = 0, step2, step3;
     step2 = step3 = function() {
       if (++events == 2)
         step4();
     }
 
     function step4() {
-      observer = {
-        observe: function(aSubject, aTopic, aData) {
-          if (aTopic == "domwindowopened") {
-            ww.unregisterNotification(this);
+      function observer(aSubject, aTopic, aData) {
+        if (aTopic != "domwindowopened")
+          return;
 
-            let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget);
-            win.addEventListener("load", function() {
-              win.removeEventListener("load", arguments.callee, false);
+        ww.unregisterNotification(observer);
+
+        let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget);
+        win.addEventListener("load", function () {
+          win.removeEventListener("load", arguments.callee, false);
 
-              let browser = win.gBrowser;
-              browser.addEventListener("load", function() {
-                browser.removeEventListener("load", arguments.callee, true);
-                
-                // view source window inside private browsing mode opened
-                step5();
-              }, true);
-            }, false);
-          }
-        }
-      };
+          let browser = win.gBrowser;
+          browser.addEventListener("load", function () {
+            browser.removeEventListener("load", arguments.callee, true);
+            
+            // view source window inside private browsing mode opened
+            step5();
+          }, true);
+        }, false);
+      }
       ww.registerNotification(observer);
 
       openViewSource();
     }
 
     function step5() {
       let events = 0;
 
-      observer = {
-        observe: function(aSubject, aTopic, aData) {
-          if (aTopic == "domwindowclosed") {
-            ok(true, "Leaving the private browsing mode should close the existing view source window");
-            if (++events == 2)
-              ww.unregisterNotification(observer);
-          }
-          else if (aTopic == "domwindowopened") {
-            ok(true, "Leaving the private browsing mode should restore the previous view source window");
-            if (++events == 2)
-              ww.unregisterNotification(observer);
+      function observer(aSubject, aTopic, aData) {
+        if (aTopic == "domwindowclosed") {
+          ok(true, "Leaving the private browsing mode should close the existing view source window");
+          if (++events == 2)
+            ww.unregisterNotification(observer);
+        }
+        else if (aTopic == "domwindowopened") {
+          ok(true, "Leaving the private browsing mode should restore the previous view source window");
+          if (++events == 2)
+            ww.unregisterNotification(observer);
 
-            let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget);
-            win.addEventListener("load", function() {
-              win.removeEventListener("load", arguments.callee, false);
+          let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget);
+          win.addEventListener("load", function () {
+            win.removeEventListener("load", arguments.callee, false);
 
-              let browser = win.gBrowser;
-              browser.addEventListener("load", function() {
-                browser.removeEventListener("load", arguments.callee, true);
-                
-                is(win.content.location.href, "view-source:about:",
-                  "The correct view source window should be restored");
+            let browser = win.gBrowser;
+            browser.addEventListener("load", function () {
+              browser.removeEventListener("load", arguments.callee, true);
+              
+              is(win.content.location.href, "view-source:about:",
+                "The correct view source window should be restored");
 
-                // cleanup
-                win.close();
-                gBrowser.removeCurrentTab();
-                finish();
-              }, true);
-            }, false);
-          }
+              // cleanup
+              win.close();
+              gBrowser.removeCurrentTab();
+              finish();
+            }, true);
+          }, false);
         }
-      };
+      }
       ww.registerNotification(observer);
 
       // exit private browsing mode
       pb.privateBrowsingEnabled = false;
     }
   }, true);
   aboutBrowser.loadURI("about:");
 }
--- a/browser/components/safebrowsing/content/blockedSite.xhtml
+++ b/browser/components/safebrowsing/content/blockedSite.xhtml
@@ -104,17 +104,17 @@
         } catch (e) {
           return getURL();
         }
       }
       
       function initPage()
       {
         // Handoff to the appropriate initializer, based on error code
-        switch(getErrorCode()) {
+        switch (getErrorCode()) {
           case "malwareBlocked" :
             initPage_malware();
             break;
           case "phishingBlocked" :
             initPage_phishing();
             break;
         }
       }        
--- a/browser/components/search/test/browser_415700.js
+++ b/browser/components/search/test/browser_415700.js
@@ -33,31 +33,29 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 var gSS = Cc["@mozilla.org/browser/search-service;1"].
            getService(Ci.nsIBrowserSearchService);
 var gObs = Cc["@mozilla.org/observer-service;1"].
            getService(Ci.nsIObserverService);
 
-var observers = {
-  observe: function(aSubject, aTopic, aData) {
-    switch (aData) {
-      case "engine-added":
-        test2();
-        break;
-      case "engine-current":
-        test3();
-        break;
-      case "engine-removed":
-        test4();
-        break;
-    }
+function observers(aSubject, aTopic, aData) {
+  switch (aData) {
+    case "engine-added":
+      test2();
+      break;
+    case "engine-current":
+      test3();
+      break;
+    case "engine-removed":
+      test4();
+      break;
   }
-};
+}
 
 function test() {
   waitForExplicitFinish();
   gObs.addObserver(observers, "browser-search-engine-modified", false);
 
   gSS.addEngine("http://localhost:8888/browser/browser/components/search/test/testEngine.xml",
                 Ci.nsISearchEngine.DATA_XML, "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC",
                 false);
--- a/browser/components/search/test/browser_426329.js
+++ b/browser/components/search/test/browser_426329.js
@@ -8,36 +8,34 @@ function test() {
 
   searchBar.value = "test";
 
   var obs = Cc["@mozilla.org/observer-service;1"].
             getService(Ci.nsIObserverService);
   var ss = Cc["@mozilla.org/browser/search-service;1"].
            getService(Ci.nsIBrowserSearchService);
 
-  var observer = {
-    observe: function(aSub, aTopic, aData) {
-      switch (aData) {
-        case "engine-added":
-          var engine = ss.getEngineByName("Bug 426329");
-          ok(engine, "Engine was added.");
-          //XXX Bug 493051
-          //ss.currentEngine = engine;
-          break;
-        case "engine-current":
-          ok(ss.currentEngine.name == "Bug 426329", "currentEngine set");
-          testReturn();
-          break;
-        case "engine-removed":
-          obs.removeObserver(this, "browser-search-engine-modified");
-          finish();
-          break;
-      }
+  function observer(aSub, aTopic, aData) {
+    switch (aData) {
+      case "engine-added":
+        var engine = ss.getEngineByName("Bug 426329");
+        ok(engine, "Engine was added.");
+        //XXX Bug 493051
+        //ss.currentEngine = engine;
+        break;
+      case "engine-current":
+        ok(ss.currentEngine.name == "Bug 426329", "currentEngine set");
+        testReturn();
+        break;
+      case "engine-removed":
+        obs.removeObserver(observer, "browser-search-engine-modified");
+        finish();
+        break;
     }
-  };
+  }
 
   obs.addObserver(observer, "browser-search-engine-modified", false);
   ss.addEngine("http://localhost:8888/browser/browser/components/search/test/426329.xml",
                Ci.nsISearchEngine.DATA_XML, "data:image/x-icon,%00",
                false);
 
   var preSelectedBrowser, preTabNo;
   function init() {
--- a/browser/components/search/test/browser_483086.js
+++ b/browser/components/search/test/browser_483086.js
@@ -36,55 +36,51 @@
 let gSS = Cc["@mozilla.org/browser/search-service;1"].
            getService(Ci.nsIBrowserSearchService);
 let gObs = Cc["@mozilla.org/observer-service;1"].
            getService(Ci.nsIObserverService);
 
 function test() {
   waitForExplicitFinish();
 
-  let observer = {
-    observe: function(aSubject, aTopic, aData) {
-      switch (aData) {
-        case "engine-added":
-          let engine = gSS.getEngineByName("483086a");
-          ok(engine, "Test engine 1 installed");
-          isnot(engine.searchForm, "foo://example.com",
-                "Invalid SearchForm URL dropped");
-          gSS.removeEngine(engine);
-          break;
-        case "engine-removed":
-          gObs.removeObserver(this, "browser-search-engine-modified");
-          test2();
-          break;
-      }
+  function observer(aSubject, aTopic, aData) {
+    switch (aData) {
+      case "engine-added":
+        let engine = gSS.getEngineByName("483086a");
+        ok(engine, "Test engine 1 installed");
+        isnot(engine.searchForm, "foo://example.com",
+              "Invalid SearchForm URL dropped");
+        gSS.removeEngine(engine);
+        break;
+      case "engine-removed":
+        gObs.removeObserver(observer, "browser-search-engine-modified");
+        test2();
+        break;
     }
-  };
+  }
 
   gObs.addObserver(observer, "browser-search-engine-modified", false);
   gSS.addEngine("http://localhost:8888/browser/browser/components/search/test/483086-1.xml",
                 Ci.nsISearchEngine.DATA_XML, "data:image/x-icon;%00",
                 false);
 }
 
 function test2() {
-  let observer = {
-    observe: function(aSubject, aTopic, aData) {
-      switch (aData) {
-        case "engine-added":
-          let engine = gSS.getEngineByName("483086b");
-          ok(engine, "Test engine 2 installed");
-          is(engine.searchForm, "http://example.com", "SearchForm is correct");
-          gSS.removeEngine(engine);
-          break;
-        case "engine-removed":  
-          gObs.removeObserver(this, "browser-search-engine-modified");
-          finish();
-          break;
-      }
+  function observer(aSubject, aTopic, aData) {
+    switch (aData) {
+      case "engine-added":
+        let engine = gSS.getEngineByName("483086b");
+        ok(engine, "Test engine 2 installed");
+        is(engine.searchForm, "http://example.com", "SearchForm is correct");
+        gSS.removeEngine(engine);
+        break;
+      case "engine-removed":  
+        gObs.removeObserver(observer, "browser-search-engine-modified");
+        finish();
+        break;
     }
-  };
+  }
 
   gObs.addObserver(observer, "browser-search-engine-modified", false);
   gSS.addEngine("http://localhost:8888/browser/browser/components/search/test/483086-2.xml",
                 Ci.nsISearchEngine.DATA_XML, "data:image/x-icon;%00",
                 false);
 }
--- a/browser/components/sessionstore/test/browser/browser_248970_a.js
+++ b/browser/components/sessionstore/test/browser/browser_248970_a.js
@@ -62,30 +62,26 @@ function test() {
     else
       return -1;
   }
 
   let os = Cc["@mozilla.org/observer-service;1"].
            getService(Ci.nsIObserverService);
   function waitForFileExistence(aMessage, aDoNext) {
     const TOPIC = "sessionstore-state-write-complete";
-    let observer = {
-      observe: function(aSubject, aTopic, aData)
-      {
-        // Remove the observer so we do not leak.
-        os.removeObserver(this, TOPIC);
+    os.addObserver(function (aSubject, aTopic, aData) {
+      // Remove the observer so we do not leak.
+      os.removeObserver(arguments.callee, TOPIC);
 
-        // Check that the file exists.
-        ok(getSessionstoreFile().exists(), aMessage);
+      // Check that the file exists.
+      ok(getSessionstoreFile().exists(), aMessage);
 
-        // Run our next set of work.
-        aDoNext();
-      }
-    };
-    os.addObserver(observer, TOPIC, false);
+      // Run our next set of work.
+      aDoNext();
+    }, TOPIC, false);
   }
 
   function actualTest() {
 
     //////////////////////////////////////////////////////////////////
     // Test (A) : No data recording while in private browsing mode  //
     //////////////////////////////////////////////////////////////////
 
--- a/browser/components/sessionstore/test/browser/browser_354894.js
+++ b/browser/components/sessionstore/test/browser/browser_354894.js
@@ -157,30 +157,27 @@ function test() {
   let observing = {
     "browser-lastwindow-close-requested": 0,
     "browser-lastwindow-close-granted": 0
   };
 
   /**
    * Helper: Will observe and handle the notifications for us
    */
-  let observer = {
-    hitCount: 0,
-
-    observe: function(aCancel, aTopic, aData) {
-      // count so that we later may compare
-      observing[aTopic]++;
+  let hitCount = 0;
+  function observer(aCancel, aTopic, aData) {
+    // count so that we later may compare
+    observing[aTopic]++;
 
-      // handle some tests
-      if (++this.hitCount == 1) {
-        // Test 6
-        aCancel.QueryInterface(Ci.nsISupportsPRBool).data = true;
-      }
+    // handle some tests
+    if (++hitCount == 1) {
+      // Test 6
+      aCancel.QueryInterface(Ci.nsISupportsPRBool).data = true;
     }
-  };
+  }
   let observerService = Cc["@mozilla.org/observer-service;1"].
                         getService(Ci.nsIObserverService);
 
   /**
    * Helper: Sets prefs as the testsuite requires
    * @note Will be reset in cleanTestSuite just before finishing the tests
    */
   function setPrefs() {
@@ -192,42 +189,40 @@ function test() {
     gPrefService.setBoolPref("browser.tabs.warnOnClose", false);
   }
 
   /**
    * Helper: Sets up this testsuite
    */
   function setupTestsuite(testFn) {
     // Register our observers
-    for (let o in observing) {
+    for (let o in observing)
       observerService.addObserver(observer, o, false);
-    }
 
     // Make the main test window not count as a browser window any longer
     oldWinType = document.documentElement.getAttribute("windowtype");
     document.documentElement.setAttribute("windowtype", "navigator:testrunner");
   }
 
   /**
    * Helper: Cleans up behind the testsuite
    */
   function cleanupTestsuite(callback) {
     // Finally remove observers again
-    for (let o in observing) {
+    for (let o in observing)
       observerService.removeObserver(observer, o, false);
-    }
+
     // Reset the prefs we touched
-    for each (let pref in [
+    [
       "browser.startup.page",
       "browser.privatebrowsing.keep_current_session"
-    ]) {
-      if (gPrefService.prefHasUserValue(pref)) {
+    ].forEach(function (pref) {
+      if (gPrefService.prefHasUserValue(pref))
         gPrefService.clearUserPref(pref);
-      }
-    }
+    });
     gPrefService.setBoolPref("browser.tabs.warnOnClose", oldWarnTabsOnClose);
 
     // Reset the window type
     document.documentElement.setAttribute("windowtype", oldWinType);
   }
 
   /**
    * Helper: sets the prefs and a new window with our test tabs
--- a/browser/components/sessionstore/test/browser/browser_394759_privatebrowsing.js
+++ b/browser/components/sessionstore/test/browser/browser_394759_privatebrowsing.js
@@ -71,21 +71,21 @@ function test() {
   });
   ss.setBrowserState(blankState);
 
   // Wait for the sessionstore.js file to be written before going on.
   // Note: we don't wait for the complete event, since if asyncCopy fails we
   // would timeout.
   let os = Cc["@mozilla.org/observer-service;1"].
            getService(Ci.nsIObserverService);
-  os.addObserver({observe: function(aSubject, aTopic, aData) {
-    os.removeObserver(this, aTopic);
+  os.addObserver(function (aSubject, aTopic, aData) {
+    os.removeObserver(arguments.callee, aTopic);
     info("sessionstore.js is being written");
     executeSoon(continue_test);
-  }}, "sessionstore-state-write", false);
+  }, "sessionstore-state-write", false);
 
   // Remove the sessionstore.js file before setting the interval to 0
   let profilePath = Cc["@mozilla.org/file/directory_service;1"].
                     getService(Ci.nsIProperties).
                     get("ProfD", Ci.nsIFile);
   let sessionStoreJS = profilePath.clone();
   sessionStoreJS.append("sessionstore.js");
   if (sessionStoreJS.exists())
--- a/browser/components/sessionstore/test/browser/browser_448741.js
+++ b/browser/components/sessionstore/test/browser/browser_448741.js
@@ -31,71 +31,67 @@
  * 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 448741 **/
-  
+
   // test setup
   let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
   let os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
   waitForExplicitFinish();
-  
+
   let uniqueName = "bug 448741";
   let uniqueValue = "as good as unique: " + Date.now();
-  
+
   // set a unique value on a new, blank tab
   var tab = gBrowser.addTab();
   tab.linkedBrowser.stop();
   ss.setTabValue(tab, uniqueName, uniqueValue);
   let valueWasCleaned = false;
-  
+
   // prevent our value from being written to disk
-  let cleaningObserver = {
-    observe: function(aSubject, aTopic, aData) {
-      ok(aTopic == "sessionstore-state-write", "observed correct topic?");
-      ok(aSubject instanceof Ci.nsISupportsString, "subject is a string?");
-      ok(aSubject.data.indexOf(uniqueValue) > -1, "data contains our value?");
-      
-      // find the data for the newly added tab and delete it
-      let state = eval(aSubject.data);
-      state.windows.forEach(function (winData) {
-        winData.tabs.forEach(function (tabData) {
-          if (tabData.extData && uniqueName in tabData.extData &&
-              tabData.extData[uniqueName] == uniqueValue) {
-            delete tabData.extData[uniqueName];
-            valueWasCleaned = true;
-          }
-        });
+  function cleaningObserver(aSubject, aTopic, aData) {
+    ok(aTopic == "sessionstore-state-write", "observed correct topic?");
+    ok(aSubject instanceof Ci.nsISupportsString, "subject is a string?");
+    ok(aSubject.data.indexOf(uniqueValue) > -1, "data contains our value?");
+
+    // find the data for the newly added tab and delete it
+    let state = eval(aSubject.data);
+    state.windows.forEach(function (winData) {
+      winData.tabs.forEach(function (tabData) {
+        if (tabData.extData && uniqueName in tabData.extData &&
+            tabData.extData[uniqueName] == uniqueValue) {
+          delete tabData.extData[uniqueName];
+          valueWasCleaned = true;
+        }
       });
-      
-      ok(valueWasCleaned, "found and removed the specific tab value");
-      aSubject.data = uneval(state);
-      os.removeObserver(this, aTopic, false);
-    }
-  };
-  
+    });
+
+    ok(valueWasCleaned, "found and removed the specific tab value");
+    aSubject.data = uneval(state);
+    os.removeObserver(cleaningObserver, aTopic, false);
+  }
+
   // make sure that all later observers don't see that value any longer
-  let checkingObserver = {
-    observe: function(aSubject, aTopic, aData) {
-      ok(valueWasCleaned && aSubject instanceof Ci.nsISupportsString,
-         "ready to check the cleaned state?");
-      ok(aSubject.data.indexOf(uniqueValue) == -1, "data no longer contains our value?");
-      
-      // clean up
-      gBrowser.removeTab(tab);
-      os.removeObserver(this, aTopic, false);
-      if (gPrefService.prefHasUserValue("browser.sessionstore.interval"))
-        gPrefService.clearUserPref("browser.sessionstore.interval");
-      finish();
-    }
-  };
-  
+  function checkingObserver(aSubject, aTopic, aData) {
+    ok(valueWasCleaned && aSubject instanceof Ci.nsISupportsString,
+       "ready to check the cleaned state?");
+    ok(aSubject.data.indexOf(uniqueValue) == -1, "data no longer contains our value?");
+
+    // clean up
+    gBrowser.removeTab(tab);
+    os.removeObserver(checkingObserver, aTopic, false);
+    if (gPrefService.prefHasUserValue("browser.sessionstore.interval"))
+      gPrefService.clearUserPref("browser.sessionstore.interval");
+    finish();
+  }
+
   // last added observers are invoked first
   os.addObserver(checkingObserver, "sessionstore-state-write", false);
   os.addObserver(cleaningObserver, "sessionstore-state-write", false);
-  
+
   // trigger an immediate save operation
   gPrefService.setIntPref("browser.sessionstore.interval", 0);
 }
--- a/browser/components/sessionstore/test/browser/browser_490040.js
+++ b/browser/components/sessionstore/test/browser/browser_490040.js
@@ -62,59 +62,57 @@ function test() {
 
   function testWithState(aState) {
     // Ensure we can store the window if needed.
     let curClosedWindowCount = ss.getClosedWindowCount();
     gPrefService.setIntPref("browser.sessionstore.max_windows_undo",
                             curClosedWindowCount + 1);
 
     var origWin;
-    let windowObserver = {
-      observe: function(aSubject, aTopic, aData) {
-        let theWin = aSubject.QueryInterface(Ci.nsIDOMWindow);
-        if (origWin && theWin != origWin)
-          return;
+    function windowObserver(aSubject, aTopic, aData) {
+      let theWin = aSubject.QueryInterface(Ci.nsIDOMWindow);
+      if (origWin && theWin != origWin)
+        return;
 
-        switch (aTopic) {
-          case "domwindowopened":
-            origWin = theWin;
-            theWin.addEventListener("load", function () {
-              theWin.removeEventListener("load", arguments.callee, false);
-              executeSoon(function() {
-                // Close the window as soon as the first tab loads, or
-                // immediately if there are no tabs.
-                if (aState.windowState.windows[0].tabs[0].entries.length) {
-                  theWin.gBrowser.addEventListener("load", function() {
-                    theWin.gBrowser.removeEventListener("load",
-                                                        arguments.callee, true);
-                    theWin.close();
-                  }, true);
-                } else {
-                  executeSoon(function() {
-                    theWin.close();
-                  });
-                }
-                ss.setWindowState(theWin, JSON.stringify(aState.windowState),
-                                  true);
-              });
-            }, false);
-            break;
+      switch (aTopic) {
+        case "domwindowopened":
+          origWin = theWin;
+          theWin.addEventListener("load", function () {
+            theWin.removeEventListener("load", arguments.callee, false);
+            executeSoon(function () {
+              // Close the window as soon as the first tab loads, or
+              // immediately if there are no tabs.
+              if (aState.windowState.windows[0].tabs[0].entries.length) {
+                theWin.gBrowser.addEventListener("load", function() {
+                  theWin.gBrowser.removeEventListener("load",
+                                                      arguments.callee, true);
+                  theWin.close();
+                }, true);
+              } else {
+                executeSoon(function () {
+                  theWin.close();
+                });
+              }
+              ss.setWindowState(theWin, JSON.stringify(aState.windowState),
+                                true);
+            });
+          }, false);
+          break;
 
-          case "domwindowclosed":
-            ww.unregisterNotification(this);
-            // Use executeSoon to ensure this happens after SS observer.
-            executeSoon(function() {
-              is(ss.getClosedWindowCount(),
-                 curClosedWindowCount + (aState.shouldBeAdded ? 1 : 0),
-                 "That window should " + (aState.shouldBeAdded ? "" : "not ") +
-                 "be restorable");
-              executeSoon(runNextTest);
-            });
-            break;
-        }
+        case "domwindowclosed":
+          ww.unregisterNotification(windowObserver);
+          // Use executeSoon to ensure this happens after SS observer.
+          executeSoon(function () {
+            is(ss.getClosedWindowCount(),
+               curClosedWindowCount + (aState.shouldBeAdded ? 1 : 0),
+               "That window should " + (aState.shouldBeAdded ? "" : "not ") +
+               "be restorable");
+            executeSoon(runNextTest);
+          });
+          break;
       }
     }
     ww.registerNotification(windowObserver);
     ww.openWindow(null,
                   location,
                   "_blank",
                   "chrome,all,dialog=no",
                   null);
--- a/browser/components/sessionstore/test/browser/browser_526613.js
+++ b/browser/components/sessionstore/test/browser/browser_526613.js
@@ -72,42 +72,40 @@ function test() {
       { tabs: [{ entries: [{ url: "http://example.com/" }] }], selected: 1 },
       { tabs: [{ entries: [{ url: "about:robots"        }] }], selected: 1 },
     ],
     // make sure the first window is focused, otherwise when restoring the
     // old state, the first window is closed and the test harness gets unloaded
     selectedWindow: 1
   };
 
-  let observer = {
-    pass: 1,
-    observe: function(aSubject, aTopic, aData) {
-      is(aTopic, "sessionstore-browser-state-restored",
-         "The sessionstore-browser-state-restored notification was observed");
+  let pass = 1;
+  function observer(aSubject, aTopic, aData) {
+    is(aTopic, "sessionstore-browser-state-restored",
+       "The sessionstore-browser-state-restored notification was observed");
 
-      if (this.pass++ == 1) {
-        browserWindowsCount(2);
+    if (pass++ == 1) {
+      browserWindowsCount(2);
 
-        // let the first window be focused (see above)
-        function pollMostRecentWindow() {
-          if (wm.getMostRecentWindow("navigator:browser") == window) {
-            ss.setBrowserState(oldState);
-          } else {
-            info("waiting for the current window to become active");
-            setTimeout(pollMostRecentWindow, 0);
-            window.focus(); //XXX Why is this needed?
-          }
+      // let the first window be focused (see above)
+      function pollMostRecentWindow() {
+        if (wm.getMostRecentWindow("navigator:browser") == window) {
+          ss.setBrowserState(oldState);
+        } else {
+          info("waiting for the current window to become active");
+          setTimeout(pollMostRecentWindow, 0);
+          window.focus(); //XXX Why is this needed?
         }
-        pollMostRecentWindow();
       }
-      else {
-        browserWindowsCount(1);
-        ok(!window.closed, "Restoring the old state should have left this window open");
-        os.removeObserver(this, "sessionstore-browser-state-restored");
-        finish();
-      }
+      pollMostRecentWindow();
     }
-  };
+    else {
+      browserWindowsCount(1);
+      ok(!window.closed, "Restoring the old state should have left this window open");
+      os.removeObserver(observer, "sessionstore-browser-state-restored");
+      finish();
+    }
+  }
   os.addObserver(observer, "sessionstore-browser-state-restored", false);
 
   // set browser to test state
   ss.setBrowserState(JSON.stringify(testState));
 }
--- a/browser/components/wintaskbar/WindowsPreviewPerTab.jsm
+++ b/browser/components/wintaskbar/WindowsPreviewPerTab.jsm
@@ -414,17 +414,17 @@ TabWindow.prototype = {
   },
   get height () {
     return this.win.innerHeight;
   },
 
   // Invoked when the given tab is added to this window
   newTab: function (tab) {
     let controller = new PreviewController(this, tab);
-    let preview = AeroPeek.taskbar.createTaskbarTabPreview(this.tabbrowser.docShell, controller);
+    let preview = AeroPeek.taskbar.createTaskbarTabPreview(tab.linkedBrowser.docShell, controller);
     preview.title = tab.label;
     preview.tooltip = tab.label;
     preview.visible = AeroPeek.enabled;
     preview.active = this.tabbrowser.selectedTab == tab;
     // Grab the default favicon
     getFaviconAsImage(null, function (img) {
       // It is possible that we've already gotten the real favicon, so make sure
       // we have not set one before setting this default one.
@@ -468,17 +468,21 @@ TabWindow.prototype = {
     this.updateTabOrdering();
   },
 
   previewFromTab: function (tab) {
     return this.previews[tab._tPos];
   },
 
   updateTabOrdering: function () {
-    for (let i = 0; i < this.previews.length; i++) {
+    // Since the internal taskbar array has not yet been updated we must force
+    // on it the sorting order of our local array.  To do so we must walk
+    // the local array backwards, otherwise we would send move requests in the
+    // wrong order.  See bug 522610 for details.
+    for (let i = this.previews.length - 1; i >= 0; i--) {
       let p = this.previews[i];
       let next = i == this.previews.length - 1 ? null : this.previews[i+1];
       p.move(next);
     }
   },
 
   //// nsIDOMEventListener
   handleEvent: function (evt) {
--- a/browser/config/version.txt
+++ b/browser/config/version.txt
@@ -1,1 +1,1 @@
-3.7a1pre
+3.7a2pre
--- a/browser/fuel/src/fuelApplication.js
+++ b/browser/fuel/src/fuelApplication.js
@@ -81,21 +81,21 @@ var Utilities = {
   makeURI : function(aSpec) {
     if (!aSpec)
       return null;
     var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
     return ios.newURI(aSpec, null, null);
   },
 
   free : function() {
-    this.bookmarks = null;
-    this.livemarks = null;
-    this.annotations = null;
-    this.history = null;
-    this.windowMediator = null;
+    delete this.bookmarks;
+    delete this.livemarks
+    delete this.annotations;
+    delete this.history;
+    delete this.windowMediator;
   }
 };
 
 
 //=================================================
 // Window implementation
 function Window(aWindow) {
   this._window = aWindow;
--- a/browser/fuel/test/browser_ApplicationQuitting.js
+++ b/browser/fuel/test/browser_ApplicationQuitting.js
@@ -1,21 +1,18 @@
 function test() {
-  let quitRequestObserver = {
-    observe: function(aSubject, aTopic, aData) {
-      ok(aTopic == "quit-application-requested" &&
-         aSubject instanceof Components.interfaces.nsISupportsPRBool,
-         "Received a quit request we're going to deny");
-      aSubject.data = true;
-    }
-  };
+  function quitRequestObserver(aSubject, aTopic, aData) {
+    ok(aTopic == "quit-application-requested" &&
+       aSubject instanceof Components.interfaces.nsISupportsPRBool,
+       "Received a quit request we're going to deny");
+    aSubject.data = true;
+  }
   
   // ensure that we don't accidentally quit
-  let os = Components.classes["@mozilla.org/observer-service;1"]
-                     .getService(Components.interfaces.nsIObserverService);
+  let os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
   os.addObserver(quitRequestObserver, "quit-application-requested", false);
   
   ok(!Application.quit(),    "Tried to quit - and didn't succeed");
   ok(!Application.restart(), "Tried to restart - and didn't succeed");
   
   // clean up
   os.removeObserver(quitRequestObserver, "quit-application-requested", false);
 }
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -86,17 +86,21 @@
 @BINPATH@/plugins/libnullplugin.so
 #elifdef XP_WIN32
 #ifndef WINCE
 @BINPATH@/plugins/npnul32.dll
 #endif
 #elifdef XP_OS2
 @BINPATH@/plugins/npnulos2.dll
 #endif
+#ifndef XP_OS2
 @BINPATH@/@DLL_PREFIX@mozsqlite3@DLL_SUFFIX@
+#else
+@BINPATH@/mozsqlt3@DLL_SUFFIX@
+#endif
 @BINPATH@/README.txt
 @BINPATH@/LICENSE
 @BINPATH@/blocklist.xml
 #ifdef XP_UNIX
 #ifndef XP_MACOSX
 @BINPATH@/mozilla-xremote-client
 @BINPATH@/run-mozilla.sh
 #endif
--- a/browser/locales/en-US/chrome/overrides/appstrings.properties
+++ b/browser/locales/en-US/chrome/overrides/appstrings.properties
@@ -57,8 +57,9 @@ unsafeContentType=The page you are tryin
 externalProtocolTitle=External Protocol Request
 externalProtocolPrompt=An external application must be launched to handle %1$S: links.\n\n\nRequested link:\n\n%2$S\n\nApplication: %3$S\n\n\nIf you were not expecting this request it may be an attempt to exploit a weakness in that other program. Cancel this request unless you are sure it is not malicious.\n
 #LOCALIZATION NOTE (externalProtocolUnknown): The following string is shown if the application name can't be determined
 externalProtocolUnknown=<Unknown>
 externalProtocolChkMsg=Remember my choice for all links of this type.
 externalProtocolLaunchBtn=Launch application
 malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences.
 phishingBlocked=The web site at %S has been reported as a web forgery designed to trick users into sharing personal or financial information.
+cspFrameAncestorBlocked=This page has a content security policy that prevents it from being embedded in this way.
--- a/browser/locales/en-US/chrome/overrides/netError.dtd
+++ b/browser/locales/en-US/chrome/overrides/netError.dtd
@@ -158,16 +158,19 @@ be temporary, and you can try again late
 ">
 
 <!ENTITY phishingBlocked.title "Suspected Web Forgery!">
 <!ENTITY phishingBlocked.longDesc "
 <p>Entering any personal information on this page may result in identity theft or other fraud.</p>
 <p>These types of web forgeries are used in scams known as phishing attacks, in which fraudulent web pages and emails are used to imitate sources you may trust.</p>
 ">
 
+<!ENTITY cspFrameAncestorBlocked.title "Blocked by Content Security Policy">
+<!ENTITY cspFrameAncestorBlocked.longDesc "<p>&brandShortName; prevented this page from loading in this way because the page has a content security policy that disallows it.</p>">
+
 <!ENTITY securityOverride.linkText "Or you can add an exception…">
 <!ENTITY securityOverride.getMeOutOfHereButton "Get me out of here!">
 <!ENTITY securityOverride.exceptionButtonLabel "Add Exception…">
 
 <!-- LOCALIZATION NOTE (securityOverride.warningText) - Do not translate the
 contents of the <xul:button> tags.  The only language content is the label= field,
 which uses strings already defined above. The button is included here (instead of
 netError.xhtml) because it exposes functionality specific to firefox. -->
--- a/browser/themes/pinstripe/browser/browser.css
+++ b/browser/themes/pinstripe/browser/browser.css
@@ -1752,20 +1752,16 @@ tabbrowser > tabbox {
   -moz-margin-end: 2px;
 }
 
 /* All Tabs Menupopup */
 .alltabs-item > .menu-iconic-left > .menu-iconic-icon {
   list-style-image: url("chrome://global/skin/tree/item.png");
 }
 
-.alltabs-item[selected="true"] {
-  font-weight: bold;
-}
-
 .alltabs-item[busy] > .menu-iconic-left > .menu-iconic-icon {
   list-style-image: url("chrome://global/skin/icons/loading_16.png") !important;
 }
 
 /* Tabstrip close button */
 .tabs-closebutton {
   -moz-padding-end: 4px;
   list-style-image: url("chrome://global/skin/icons/closetab.png");
--- a/browser/themes/pinstripe/browser/preferences/applications.css
+++ b/browser/themes/pinstripe/browser/preferences/applications.css
@@ -41,31 +41,43 @@
  * Also make sure the labels are the same distance away from the icons.
  */
 .actionsMenu {
   -moz-margin-start: -2px;
   margin-top: 0;
   margin-bottom: -1px;
 }
 
-.typeIcon,
-.actionIcon {
+richlistitem label {
   -moz-margin-start: 3px;
-  -moz-margin-end: 3px;
-}
-
-richlistitem label {
-  -moz-margin-start: 1px;
   margin-top: 2px;
 }
 
 richlistitem {
   min-height: 22px;
 }
 
+.typeIcon,
+.actionIcon {
+  -moz-margin-start: 3px;
+}
+
+.typeIcon,
+.actionIcon,
+.actionsMenu .menulist-icon {
+  -moz-margin-end: 2px;
+}
+
+.actionsMenu > menupopup > menuitem > .menu-iconic-left {
+  /* Undo content/browser/preferences/handlers.css - we don't
+   * want icon-less labels to line up with the other labels.
+   */
+  min-width: 0;
+}
+
 richlistitem[appHandlerIcon="ask"],
 menuitem[appHandlerIcon="ask"] {
   list-style-image: url("chrome://browser/skin/preferences/alwaysAsk.png");
 }
 
 richlistitem[appHandlerIcon="save"],
 menuitem[appHandlerIcon="save"] {
   list-style-image: url("chrome://browser/skin/preferences/saveFile.png");
@@ -76,16 +88,18 @@ menuitem[appHandlerIcon="feed"] {
   list-style-image: url("chrome://browser/skin/page-livemarks.png");
 }
 
 richlistitem[appHandlerIcon="plugin"],
 menuitem[appHandlerIcon="plugin"] {
   list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric-16.png");
 }
 
-.actionsMenu .menulist-icon {
-  -moz-margin-end: 1px;
+/* Repeat what menu.css does for .menuitem-iconic */
+menuitem[appHandlerIcon] {
+  padding-top: 1px;
+  padding-bottom: 3px;
 }
 
-.actionsMenu > menupopup > menuitem > .menu-iconic-left {
-  -moz-padding-start: 3px;
-  -moz-padding-end: 1px;
+menuitem[appHandlerIcon] > .menu-iconic-left > .menu-iconic-icon {
+  -moz-margin-start: 0;
+  width: 16px;
 }
--- a/browser/themes/pinstripe/browser/searchbar.css
+++ b/browser/themes/pinstripe/browser/searchbar.css
@@ -140,12 +140,8 @@
 
 .search-go-button {
   padding: 1px;
   list-style-image: url("chrome://browser/skin/Search.png");
   margin: 0;
   padding: 0;
   -moz-padding-end: 6px;
 }
-
-.searchbar-engine-menuitem[selected="true"] > .menu-iconic-text {
-  font-weight: bold;
-}
--- a/build/automationutils.py
+++ b/build/automationutils.py
@@ -31,17 +31,17 @@
 # use your version of this file under the terms of the MPL, indicate your
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK ***** */
 
-import glob, logging, os, subprocess, sys
+import glob, logging, os, shutil, subprocess, sys
 import re
 
 __all__ = [
   "addCommonOptions",
   "checkForCrashes",
   "dumpLeakLog",
   "processLeakLog",
   "getDebuggerInfo",
@@ -113,17 +113,23 @@ def checkForCrashes(dumpDir, symbolsPath
     else:
       if not symbolsPath:
         print "No symbols path given, can't process dump."
       if not stackwalkPath:
         print "MINIDUMP_STACKWALK not set, can't process dump."
       else:
         if not os.path.exists(stackwalkPath):
           print "MINIDUMP_STACKWALK binary not found: %s" % stackwalkPath
-    os.remove(d)
+    dumpSavePath = os.environ.get('MINIDUMP_SAVE_PATH', None)
+    if dumpSavePath:
+      shutil.move(d, dumpSavePath)
+      print "Saved dump as %s" % os.path.join(dumpSavePath,
+                                              os.path.basename(d))
+    else:
+      os.remove(d)
     extra = os.path.splitext(d)[0] + ".extra"
     if os.path.exists(extra):
       os.remove(extra)
     foundCrash = True
 
   return foundCrash
   
 def getFullPath(directory, path):
--- a/build/package/wince/make_wince_cab.py
+++ b/build/package/wince/make_wince_cab.py
@@ -16,82 +16,90 @@
 # The Initial Developer of the Original Code is
 # Mozilla Foundation.
 # Portions created by the Initial Developer are Copyright (C) 2007
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
 #  John Wolfe <wolfe@lobo.us>
 #  Vladimir Vukicevic <vladimir@pobox.com>
+#  Alex Pakhotin <alexp@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
 # 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 *****
 ################################################################
 #
-# make-wince-cab.py --- Given a directory, walk it and make an
+# make_wince_cab.py --- Given a directory, walk it and make an
 #          installer based upon the contents of that directory
 #
 # Usage:
-#   python make-wince-inf.py [-s] [CABWIZ_PATH] SOURCE_DIR PROGRAM_NAME CAB_FINAL_NAME
+#   python make_wince_cab.py [-setupdll] [-s] [-faststart] [CABWIZ_PATH] SOURCE_DIR PROGRAM_NAME CAB_FINAL_NAME
 #
 # Walk through the relative directory SOURCE_DIR, parsing filenames
 #   Checks for duplicate filenames and renames where needed
 #   Then builds a WinMobile INF file based upon results
 # 
 # Each directory in SOURCE_DIR may have a file named
 # 'install-exceptions', which lists files in SOURCE_DIR that
 # need not be placed into an installation CAB file. The
 # 'install-exceptions' file itself is always ignored.
 # 
 # Blank lines and '#' comments in the 'install-exceptions' file are
 # ignored.
 #
-# EXAMPLE OF COMMAND LINE:
-#   python make_wince_inf.py /c/Program\ Files/Microsoft\ Visual\ Studio\ 9.0/SmartDevices/SDK/SDKTools/cabwiz.exe dist/fennec Fennec fennec-0.11.en-US.wince-arm.cab
+# ARGS:
+#   -setupdll - Make a small additional CAB including Setup.dll.
+#               This is to add Fennec to the system list of installed applications
+#               available in Settings - System - Remove Programs.
 #
-# ARGS:
 #   -s - Don't pass /compress to cabwiz (generate CAB compatible with Windows CE)
 #
+#   -faststart - Add FastStart shortcut
+#
 #   CABWIZ_PATH - If specified, will use this cabwiz.exe executable.  Otherwise, will attempt
 #                 to find one using $VSINSTALLDIR.
 #
 #   SOURCE_DIR - sub-directory which contains the target program 
 #                NOTE: It is assumed that the application name is SOURCE_DIR.exe
 #                EXAMPLE: source_dir=fennec, there should be a fennec/fennec.exe application
 #
 #   PROGRAM_NAME - Name of the program to place inside the INF file
 #
 #   CAB_FINAL_NAME - actual final name for the produced CAB file
 #
+# EXAMPLE OF COMMAND LINE:
+#   python make_wince_cab.py /c/Program\ Files/Microsoft\ Visual\ Studio\ 9.0/SmartDevices/SDK/SDKTools/cabwiz.exe dist/fennec Fennec fennec-0.11.en-US.wince-arm.cab
+#
 # NOTE: In our example, "fennec" is the directory [source_name]
 #                       "fennec.exe" is the application [$(source_name).exe], and
 #                       "Fennec" is the shortcut name [program_name]
 ################################################################
 
 import sys
 import os
 from os.path import join
 from subprocess import call, STDOUT
 import fnmatch
 import string
 import shutil
 
 CompressFlag = "/compress"
 FaststartFlag = 0
+MakeSetupDllCab = 0
 
 class FileEntry:
     def __init__(self, dirpath, dircount, filename, filecount, actual_filename):
         self.dirpath = dirpath
         self.dircount = dircount
         self.filename = filename
         self.filecount = filecount
         self.actual_filename = actual_filename
@@ -304,37 +312,78 @@ def output_inf_file(program_name, app_na
     output_destinationdirs_section(f, dirs)
     output_directory_sections(f, dirs)
     output_registry_section(f)
     output_shortcuts_section(f, app_name)
     f.close()
 
 
 
+def output_setup_dll_inf_file(source_dir, program_name, app_name):
+    inf_name = "%s.inf" % program_name
+    f = open(inf_name, 'w')
+
+    f.write("""; Additional CAB to create Fennec entry in the installed programs list
+
+[Version]
+Signature   = "$Windows NT$"        ; required as-is
+Provider    = "Mozilla"             ; maximum of 30 characters, full app name will be \"<Provider> <AppName>\"
+CESignature = "$Windows CE$"        ; required as-is
+
+[CEStrings]
+AppName     = "%s"              ; maximum of 40 characters, full app name will be \"<Provider> <AppName>\"\n""" % program_name)
+
+    f.write("InstallDir  = %CE1%\\%AppName%       ; Program Files\Fennec\n\n")
+
+    f.write("[SourceDisksNames]                  ; directory that holds the application's files\n")
+    f.write('1 = , "%s",,%s\n\n' % (source_dir, source_dir))
+
+    f.write("[SourceDisksFiles]                  ; list of files to be included in .cab\n")
+    f.write("Setup.dll = 1\n\n")
+
+    f.write("""[DefaultInstall]                    ; operations to be completed during install
+CopyFiles   = Files.%s
+AddReg      = RegData
+CESetupDLL  = "Setup.dll"
+\n""" % program_name)
+
+    f.write("[DestinationDirs]                   ; default destination directories for each operation section\n")
+    f.write("Files.%s = 0, %%InstallDir%%\n\n" % program_name)
+
+    f.write("""[Files.%s]
+;No files to copy
+
+[RegData]
+;No registry entries
+""" % program_name)
+
+    f.close()
+
+
 def make_cab_file(cabwiz_path, program_name, cab_final_name):
     make_cab_command = "\"%s\" %s %s.inf" % (cabwiz_path, CompressFlag, program_name)
     print "INFORMATION: Executing command to make %s CAB file (only works on BASH)" % program_name
     print "    [%s]" % make_cab_command
     sys.stdout.flush()
 
     success = call([cabwiz_path, "%s.inf" % program_name, CompressFlag],
                    stdout=open("NUL:","w"), stderr=STDOUT)
 
     if not os.path.isfile("%s.CAB" % program_name):
         print """***************************************************************************
 ERROR: CAB FILE NOT CREATED.
        You can try running the command by hand:
-          %s" % make_cab_comman
+       %s
  ---- 
  NOTE: If you see an error like this:
        Error: File XXXXXXXXXX.inf contains DirIDs, which are not supported
  -- 
  this may mean that your PYTHON is outputting Windows files WITHOUT CR-LF
  line endings.  Please verify that your INF file has CR-LF line endings.
-***************************************************************************"""
+***************************************************************************""" % make_cab_command
         sys.exit(2)
 
     print "INFORMATION: Executing command to move %s.CAB to %s" % (program_name, cab_final_name)
     sys.stdout.flush()
     shutil.move("%s.CAB" % program_name, cab_final_name)
 
 
 def purge_copied_files():
@@ -342,22 +391,27 @@ def purge_copied_files():
         if entry.filename != entry.actual_filename:
             new_relative_filename = join(entry.dirpath, entry.actual_filename)
             os.remove(new_relative_filename)
 
 
 def main():
     args = sys.argv
     if len(args) < 4 or len(args) > 7:
-        print >> sys.stderr, "Usage: %s [-s] [-faststart] [CABWIZ_PATH] SOURCE_DIR PROGRAM_NAME CAB_FINAL_NAME" % args[0]
+        print >> sys.stderr, "Usage: %s [-setupdll] [-s] [-faststart] [CABWIZ_PATH] SOURCE_DIR PROGRAM_NAME CAB_FINAL_NAME" % args[0]
         print >> sys.stderr, "Example: %s /c/Program\ Files/Microsoft\ Visual\ Studio\ 9.0/ fennec Fennec fennec-0.11.en-US.wince-arm.cab" % args[0]
         sys.exit(1)
 
     args = args[1:]
 
+    if args[0] == "-setupdll":
+        global MakeSetupDllCab
+        MakeSetupDllCab = 1
+        args = args[1:]
+
     if args[0] == "-s":
         global CompressFlag
         CompressFlag = ""
         args = args[1:]
 
     if args[0] == "-faststart":
         global FaststartFlag
         FaststartFlag = 1
@@ -378,19 +432,25 @@ def main():
 
     if cabwiz_path is None or not os.path.isfile(cabwiz_path):
         print """***************************************************************************
 ERROR: CABWIZ_PATH is not a valid file, or cabwiz couldn't be found!
        EXITING...
 ***************************************************************************"""
         sys.exit(2)
 
-    walk_tree(source_dir, ignored_patterns)
-    sys.stdout.flush()
-    output_inf_file(program_name, app_name)
-    sys.stdout.flush()
-    make_cab_file(cabwiz_path, program_name, cab_final_name)
-    purge_copied_files()
+    if MakeSetupDllCab:
+        output_setup_dll_inf_file(source_dir, program_name, app_name)
+        sys.stdout.flush()
+        make_cab_file(cabwiz_path, program_name, cab_final_name)
+        os.remove("%s/setup.dll" % source_dir)
+    else:
+        walk_tree(source_dir, ignored_patterns)
+        sys.stdout.flush()
+        output_inf_file(program_name, app_name)
+        sys.stdout.flush()
+        make_cab_file(cabwiz_path, program_name, cab_final_name)
+        purge_copied_files()
 
 
 # run main if run directly
 if __name__ == "__main__":
     main()
--- a/config/milestone.txt
+++ b/config/milestone.txt
@@ -5,9 +5,9 @@
 #    x.x.x.x
 #    x.x.x+
 #
 # Referenced by milestone.pl.
 # Hopefully I'll be able to automate replacement of *all*
 # hardcoded milestones in the tree from these two files.
 #--------------------------------------------------------
 
-1.9.3a1pre
+1.9.3a2pre
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -224,22 +224,16 @@ endif # ENABLE_TESTS
 # Library rules
 #
 # If BUILD_STATIC_LIBS or FORCE_STATIC_LIB is set, build a static library.
 # Otherwise, build a shared library.
 #
 
 ifndef LIBRARY
 ifdef STATIC_LIBRARY_NAME
-ifeq (OS2,$(OS_ARCH))
-ifdef SHORT_LIBNAME
-STATIC_LIBRARY_NAME	:= $(SHORT_LIBNAME)
-SHARED_LIBRARY_NAME	:= $(SHORT_LIBNAME)
-endif
-endif
 LIBRARY			:= $(LIB_PREFIX)$(STATIC_LIBRARY_NAME).$(LIB_SUFFIX)
 endif # STATIC_LIBRARY_NAME
 endif # LIBRARY
 
 ifndef HOST_LIBRARY
 ifdef HOST_LIBRARY_NAME
 HOST_LIBRARY		:= $(LIB_PREFIX)$(HOST_LIBRARY_NAME).$(LIB_SUFFIX)
 endif
@@ -248,30 +242,36 @@ endif
 ifdef LIBRARY
 ifneq (_1,$(FORCE_SHARED_LIB)_$(BUILD_STATIC_LIBS))
 ifdef MKSHLIB
 
 ifdef LIB_IS_C_ONLY
 MKSHLIB			= $(MKCSHLIB)
 endif
 
+ifneq (,$(filter OS2 WINNT WINCE,$(OS_ARCH)))
+IMPORT_LIBRARY		:= $(LIB_PREFIX)$(SHARED_LIBRARY_NAME).$(IMPORT_LIB_SUFFIX)
+endif
+
+ifeq (OS2,$(OS_ARCH))
+ifdef SHORT_LIBNAME
+SHARED_LIBRARY_NAME	:= $(SHORT_LIBNAME)
+endif
+endif
+
 ifdef MAKE_FRAMEWORK
 SHARED_LIBRARY		:= $(SHARED_LIBRARY_NAME)
 else
 SHARED_LIBRARY		:= $(DLL_PREFIX)$(SHARED_LIBRARY_NAME)$(DLL_SUFFIX)
 endif
 
 ifeq ($(OS_ARCH),OS2)
 DEF_FILE		:= $(SHARED_LIBRARY:.dll=.def)
 endif
 
-ifneq (,$(filter OS2 WINNT WINCE,$(OS_ARCH)))
-IMPORT_LIBRARY		:= $(LIB_PREFIX)$(SHARED_LIBRARY_NAME).$(IMPORT_LIB_SUFFIX)
-endif
-
 ifdef MOZ_ENABLE_LIBXUL
 EMBED_MANIFEST_AT=2
 endif
 
 endif # MKSHLIB
 endif # FORCE_SHARED_LIB && !BUILD_STATIC_LIBS
 endif # LIBRARY
 
--- a/configure.in
+++ b/configure.in
@@ -243,16 +243,19 @@ fi
 
 dnl ========================================================
 dnl Checks for compilers.
 dnl ========================================================
 dnl Set CROSS_COMPILE in the environment when running configure
 dnl to use the cross-compile setup for now
 dnl ========================================================
 
+dnl AR_FLAGS set here so HOST_AR_FLAGS can be set correctly (see bug 538269)
+AR_FLAGS='cr $@'
+
 if test "$COMPILE_ENVIRONMENT"; then
 
 dnl Do some special WinCE toolchain stuff
 case "$target" in
 *wince|*winmo)
 
     MOZ_ARG_WITH_STRING(wince-sdk,
     [  --with-wince-sdk=WINCE_SDK_DIR
@@ -321,16 +324,19 @@ if test -n "$CROSS_COMPILE" && test "$ta
         HOST_CFLAGS="$CFLAGS"
     fi
     if test -z "$HOST_CXXFLAGS"; then
         HOST_CXXFLAGS="$CXXFLAGS"
     fi
     if test -z "$HOST_LDFLAGS"; then
         HOST_LDFLAGS="$LDFLAGS"
     fi
+    if test -z "$HOST_AR_FLAGS"; then
+        HOST_AR_FLAGS="$AR_FLAGS"
+    fi
     AC_CHECK_PROGS(HOST_RANLIB, $HOST_RANLIB ranlib, ranlib, :)
     AC_CHECK_PROGS(HOST_AR, $HOST_AR ar, ar, :)
     CC="$HOST_CC"
     CFLAGS="$HOST_CFLAGS"
     LDFLAGS="$HOST_LDFLAGS"
 
     AC_MSG_CHECKING([whether the host c compiler ($HOST_CC $HOST_CFLAGS $HOST_LDFLAGS) works])
     AC_TRY_COMPILE([], [return(0);], 
@@ -410,17 +416,20 @@ else
     fi
     if test -z "$HOST_LDFLAGS"; then
         HOST_LDFLAGS="$LDFLAGS"
     fi
     if test -z "$HOST_RANLIB"; then
         HOST_RANLIB="$RANLIB"
     fi
     if test -z "$HOST_AR"; then
-       HOST_AR="$AR"
+        HOST_AR="$AR"
+    fi
+    if test -z "$HOST_AR_FLAGS"; then
+        HOST_AR_FLAGS="$AR_FLAGS"
     fi
 fi
 
 GNU_AS=
 GNU_LD=
 GNU_CC=
 GNU_CXX=
 CC_VERSION='N/A'
@@ -1025,17 +1034,16 @@ AC_PATH_XTRA
 XCFLAGS="$X_CFLAGS"
 
 fi # COMPILE_ENVIRONMENT
 
 dnl ========================================================
 dnl set the defaults first
 dnl ========================================================
 AS_BIN=$AS
-AR_FLAGS='cr $@'
 AR_LIST='$(AR) t'
 AR_EXTRACT='$(AR) x'
 AR_DELETE='$(AR) d'
 AS='$(CC)'
 AS_DASH_C_FLAG='-c'
 DLL_PREFIX=lib
 LIB_PREFIX=lib
 DLL_SUFFIX=.so
@@ -1043,17 +1051,16 @@ OBJ_SUFFIX=o
 LIB_SUFFIX=a
 ASM_SUFFIX=s
 IMPORT_LIB_SUFFIX=
 TARGET_MD_ARCH=unix
 DIRENT_INO=d_ino
 CYGWIN_WRAPPER=
 WIN_TOP_SRC=
 MOZ_USER_DIR=".mozilla"
-HOST_AR_FLAGS='$(AR_FLAGS)'
 
 MOZ_JPEG_CFLAGS=
 MOZ_JPEG_LIBS='$(call EXPAND_LIBNAME_PATH,mozjpeg,$(DEPTH)/jpeg)'
 MOZ_ZLIB_CFLAGS=
 MOZ_ZLIB_LIBS='$(call EXPAND_LIBNAME_PATH,mozz,$(DEPTH)/modules/zlib/src)'
 MOZ_BZ2_CFLAGS=
 MOZ_BZ2_LIBS='$(call EXPAND_LIBNAME_PATH,bz2,$(DEPTH)/modules/libbz2/src)'
 MOZ_PNG_CFLAGS=
@@ -2525,17 +2532,17 @@ case "$target" in
     BIN_FLAGS='-Zlinker /ST:0x100000'
     IMPLIB='emximp -o'
     FILTER='emxexp -o'
     LDFLAGS='-Zmap'
     WARNINGS_AS_ERRORS='-Werror'
     MOZ_DEBUG_FLAGS="-g -fno-inline"
     MOZ_OPTIMIZE_FLAGS="-O2"
     MOZ_OPTIMIZE_LDFLAGS="-s -Zlinker /EXEPACK:2 -Zlinker /PACKCODE -Zlinker /PACKDATA"
-    DYNAMIC_XPCOM_LIBS='-L$(LIBXUL_DIST)/lib $(LIBXUL_DIST)/lib/xpcom.lib $(LIBXUL_DIST)/lib/xpcomcor.lib'
+    DYNAMIC_XPCOM_LIBS='-L$(LIBXUL_DIST)/lib $(LIBXUL_DIST)/lib/xpcom.lib $(LIBXUL_DIST)/lib/xpcom_core.lib'
     LIBXUL_LIBS='-L$(LIBXUL_DIST)/lib $(LIBXUL_DIST)/lib/xpcom.lib $(LIBXUL_DIST)/lib/xul.lib'
     TARGET_MD_ARCH=os2
     _PLATFORM_DEFAULT_TOOLKIT="cairo-os2"
     MOZ_ENABLE_POSTSCRIPT=
     RC=rc.exe
     RCFLAGS='-n'
     MOZ_USER_DIR="Mozilla"
 
@@ -4371,20 +4378,20 @@ else
         \$(LIBXUL_DIST)/lib/\$(DLL_PREFIX)smime$NSS_VERSION\$(DLL_SUFFIX) \
         \$(LIBXUL_DIST)/lib/\$(DLL_PREFIX)ssl$NSS_VERSION\$(DLL_SUFFIX) \
         \$(LIBXUL_DIST)/lib/\$(DLL_PREFIX)nss$NSS_VERSION\$(DLL_SUFFIX) \
         \$(LIBXUL_DIST)/lib/\$(DLL_PREFIX)nssutil$NSS_VERSION\$(DLL_SUFFIX)"
 
    if test -z "$GNU_CC" && test "$OS_ARCH" = "WINNT" -o "$OS_ARCH" = "WINCE" -o "$OS_ARCH" = "OS2"; then
        NSS_LIBS="\
         \$(LIBXUL_DIST)/lib/\$(LIB_PREFIX)crmf.\$(LIB_SUFFIX) \
-        \$(LIBXUL_DIST)/lib/\$(LIB_PREFIX)smime$NSS_VERSION.\$(IMPORT_LIB_SUFFIX) \
-        \$(LIBXUL_DIST)/lib/\$(LIB_PREFIX)ssl$NSS_VERSION.\$(IMPORT_LIB_SUFFIX) \
-        \$(LIBXUL_DIST)/lib/\$(LIB_PREFIX)nss$NSS_VERSION.\$(IMPORT_LIB_SUFFIX) \
-        \$(LIBXUL_DIST)/lib/\$(LIB_PREFIX)nssutil$NSS_VERSION.\$(IMPORT_LIB_SUFFIX)"
+        \$(LIBXUL_DIST)/lib/\$(LIB_PREFIX)smime$NSS_VERSION.\$(LIB_SUFFIX) \
+        \$(LIBXUL_DIST)/lib/\$(LIB_PREFIX)ssl$NSS_VERSION.\$(LIB_SUFFIX) \
+        \$(LIBXUL_DIST)/lib/\$(LIB_PREFIX)nss$NSS_VERSION.\$(LIB_SUFFIX) \
+        \$(LIBXUL_DIST)/lib/\$(LIB_PREFIX)nssutil$NSS_VERSION.\$(LIB_SUFFIX)"
    else
        NSS_LIBS='$(LIBS_DIR)'" -lcrmf -lsmime$NSS_VERSION -lssl$NSS_VERSION -lnss$NSS_VERSION -lnssutil$NSS_VERSION"
    fi
 fi
 
 if test -z "$SKIP_LIBRARY_CHECKS"; then
 dnl system JPEG support
 dnl ========================================================
--- a/content/base/public/nsContentErrors.h
+++ b/content/base/public/nsContentErrors.h
@@ -82,9 +82,13 @@
   NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_CONTENT, 12)
 
 #define NS_FINDBROADCASTER_FOUND \
   NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_CONTENT, 13)
 
 #define NS_FINDBROADCASTER_AWAIT_OVERLAYS \
   NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_CONTENT, 14)
 
+/* Error codes for CSP */
+#define NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION \
+  NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_SECURITY, 99)
+
 #endif // nsContentErrors_h___
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -41,30 +41,30 @@
 
 #ifndef nsContentUtils_h___
 #define nsContentUtils_h___
 
 #include "jsprvtd.h"
 #include "jsnum.h"
 #include "nsAString.h"
 #include "nsIStatefulFrame.h"
-#include "nsIPref.h"
 #include "nsINodeInfo.h"
 #include "nsNodeInfoManager.h"
 #include "nsContentList.h"
 #include "nsDOMClassInfoID.h"
 #include "nsIClassInfo.h"
 #include "nsIDOM3Node.h"
 #include "nsDataHashtable.h"
 #include "nsIScriptRuntime.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIDOMEvent.h"
 #include "nsTArray.h"
 #include "nsTextFragment.h"
 #include "nsReadableUtils.h"
+#include "nsIPrefBranch2.h"
 
 struct nsNativeKeyEvent; // Don't include nsINativeKeyBindings.h here: it will force strange compilation error!
 
 class nsIDOMScriptObjectFactory;
 class nsIXPConnect;
 class nsINode;
 class nsIContent;
 class nsIDOMNode;
@@ -79,50 +79,55 @@ class nsIThreadJSContextStack;
 class nsIParserService;
 class nsIIOService;
 class nsIURI;
 class imgIContainer;
 class imgIDecoderObserver;
 class imgIRequest;
 class imgILoader;
 class imgICache;
-class nsIPrefBranch;
+class nsIPrefBranch2;
 class nsIImageLoadingContent;
 class nsIDOMHTMLFormElement;
 class nsIDOMDocument;
 class nsIConsoleService;
 class nsIStringBundleService;
 class nsIStringBundle;
 class nsIContentPolicy;
 class nsILineBreaker;
 class nsIWordBreaker;
 class nsIJSRuntimeService;
 class nsIEventListenerManager;
 class nsIScriptContext;
 class nsIRunnable;
 class nsIInterfaceRequestor;
 template<class E> class nsCOMArray;
-class nsIPref;
 struct JSRuntime;
 class nsICaseConversion;
 class nsIUGenCategory;
 class nsIWidget;
 class nsIDragSession;
 class nsPIDOMWindow;
 class nsPIDOMEventTarget;
 class nsIPresShell;
 class nsIXPConnectJSObjectHolder;
+class nsPrefOldCallback;
 #ifdef MOZ_XTF
 class nsIXTFService;
 #endif
 #ifdef IBMBIDI
 class nsIBidiKeyboard;
 #endif
 class nsIMIMEHeaderParam;
 
+#ifndef have_PrefChangedFunc_typedef
+typedef int (*PR_CALLBACK PrefChangedFunc)(const char *, void *);
+#define have_PrefChangedFunc_typedef
+#endif
+
 extern const char kLoadAsData[];
 
 enum EventNameType {
   EventNameType_None = 0x0000,
   EventNameType_HTML = 0x0001,
   EventNameType_XUL = 0x0002,
   EventNameType_SVGGraphic = 0x0004, // svg graphic elements
   EventNameType_SVGSVG = 0x0008, // the svg element
@@ -145,27 +150,16 @@ struct nsShortcutCandidate {
   PRBool   mIgnoreShift;
 };
 
 class nsContentUtils
 {
 public:
   static nsresult Init();
 
-  // You MUST pass the old ownerDocument of aContent in as aOldDocument and the
-  // new one as aNewDocument.  aNewParent is allowed to be null; in that case
-  // aNewDocument will be assumed to be the parent.  Note that at this point
-  // the actual ownerDocument of aContent may not yet be aNewDocument.
-  // XXXbz but then if it gets wrapped after we do this call but before its
-  // ownerDocument actually changes, things will break...
-  static nsresult ReparentContentWrapper(nsIContent *aNode,
-                                         nsIContent *aNewParent,
-                                         nsIDocument *aNewDocument,
-                                         nsIDocument *aOldDocument);
-
   /**
    * Get a scope from aOldDocument and one from aNewDocument. Also get a
    * context through one of the scopes, from the stack or the safe context.
    *
    * @param aOldDocument The document to get aOldScope from.
    * @param aNewDocument The document to get aNewScope from.
    * @param aCx [out] Context gotten through one of the scopes, from the stack
    *                  or the safe context.
@@ -393,23 +387,19 @@ public:
    *
    * HTML 4.01 also lists U+200B (zero-width space).
    */
   static PRBool IsHTMLWhitespace(PRUnichar aChar);
 
   static void Shutdown();
 
   /**
-   * Checks whether two nodes come from the same origin. aTrustedNode is
-   * considered 'safe' in that a user can operate on it and that it isn't
-   * a js-object that implements nsIDOMNode.
-   * Never call this function with the first node provided by script, it
-   * must always be known to be a 'real' node!
+   * Checks whether two nodes come from the same origin.
    */
-  static nsresult CheckSameOrigin(nsIDOMNode* aTrustedNode,
+  static nsresult CheckSameOrigin(nsINode* aTrustedNode,
                                   nsIDOMNode* aUnTrustedNode);
 
   // Check if the (JS) caller can access aNode.
   static PRBool CanCallerAccess(nsIDOMNode *aNode);
 
   // Check if the (JS) caller can access aWindow.
   // aWindow can be either outer or inner window.
   static PRBool CanCallerAccess(nsPIDOMWindow* aWindow);
@@ -569,17 +559,17 @@ public:
   static void RegisterPrefCallback(const char *aPref,
                                    PrefChangedFunc aCallback,
                                    void * aClosure);
   static void UnregisterPrefCallback(const char *aPref,
                                      PrefChangedFunc aCallback,
                                      void * aClosure);
   static void AddBoolPrefVarCache(const char* aPref, PRBool* aVariable);
   static void AddIntPrefVarCache(const char* aPref, PRInt32* aVariable);
-  static nsIPrefBranch *GetPrefBranch()
+  static nsIPrefBranch2 *GetPrefBranch()
   {
     return sPrefBranch;
   }
 
   static nsILineBreaker* LineBreaker()
   {
     return sLineBreaker;
   }
@@ -1519,23 +1509,16 @@ public:
   {
     return WrapNative(cx, scope, native, nsnull, vp, aHolder, aAllowWrapping);
   }
 
 private:
 
   static PRBool InitializeEventTable();
 
-  static nsresult doReparentContentWrapper(nsIContent *aChild,
-                                           JSContext *cx,
-                                           JSObject *aOldGlobal,
-                                           JSObject *aNewGlobal,
-                                           nsIDocument *aOldDocument,
-                                           nsIDocument *aNewDocument);
-
   static nsresult EnsureStringBundle(PropertiesFile aFile);
 
   static nsIDOMScriptObjectFactory *GetDOMScriptObjectFactory();
 
   static nsresult HoldScriptObject(PRUint32 aLangID, void* aObject);
   static void DropScriptObject(PRUint32 aLangID, void *aObject, void *aClosure);
 
   static PRBool CanCallerAccess(nsIPrincipal* aSubjectPrincipal,
@@ -1554,19 +1537,19 @@ private:
   static nsINameSpaceManager *sNameSpaceManager;
 
   static nsIIOService *sIOService;
 
 #ifdef MOZ_XTF
   static nsIXTFService *sXTFService;
 #endif
 
-  static nsIPrefBranch *sPrefBranch;
-
-  static nsIPref *sPref;
+  static nsIPrefBranch2 *sPrefBranch;
+  // For old compatibility of RegisterPrefCallback
+  static nsCOMArray<nsPrefOldCallback> *sPrefCallbackList;
 
   static imgILoader* sImgLoader;
   static imgICache* sImgCache;
 
   static nsIConsoleService* sConsoleService;
 
   static nsDataHashtable<nsISupportsHashKey, EventNameMapping>* sEventTable;
 
--- a/content/base/src/nsContentSink.cpp
+++ b/content/base/src/nsContentSink.cpp
@@ -185,25 +185,25 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mNodeInfoManager,
                                                   nsNodeInfoManager)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 
 nsContentSink::nsContentSink()
 {
   // We have a zeroing operator new
-  NS_ASSERTION(mLayoutStarted == PR_FALSE, "What?");
-  NS_ASSERTION(mDynamicLowerValue == PR_FALSE, "What?");
-  NS_ASSERTION(mParsing == PR_FALSE, "What?");
+  NS_ASSERTION(!mLayoutStarted, "What?");
+  NS_ASSERTION(!mDynamicLowerValue, "What?");
+  NS_ASSERTION(!mParsing, "What?");
   NS_ASSERTION(mLastSampledUserEventTime == 0, "What?");
   NS_ASSERTION(mDeflectedCount == 0, "What?");
-  NS_ASSERTION(mDroppedTimer == PR_FALSE, "What?");
+  NS_ASSERTION(!mDroppedTimer, "What?");
   NS_ASSERTION(mInMonolithicContainer == 0, "What?");
   NS_ASSERTION(mInNotification == 0, "What?");
-  NS_ASSERTION(mDeferredLayoutStart == PR_FALSE, "What?");
+  NS_ASSERTION(!mDeferredLayoutStart, "What?");
 
 #ifdef NS_DEBUG
   if (!gContentSinkLogModuleInfo) {
     gContentSinkLogModuleInfo = PR_NewLogModule("nscontentsink");
   }
 #endif
 }
 
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -43,17 +43,17 @@
 /* A namespace class for static layout utilities. */
 
 #include "nsJSUtils.h"
 #include "nsCOMPtr.h"
 #include "nsAString.h"
 #include "nsPrintfCString.h"
 #include "nsUnicharUtils.h"
 #include "nsIPrefService.h"
-#include "nsIPrefBranch.h"
+#include "nsIPrefBranch2.h"
 #include "nsIPrefLocalizedString.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptContext.h"
 #include "nsIDOMScriptObjectFactory.h"
 #include "nsDOMCID.h"
 #include "nsContentUtils.h"
 #include "nsIXPConnect.h"
@@ -193,18 +193,17 @@ nsIXPConnect *nsContentUtils::sXPConnect
 nsIScriptSecurityManager *nsContentUtils::sSecurityManager;
 nsIThreadJSContextStack *nsContentUtils::sThreadJSContextStack;
 nsIParserService *nsContentUtils::sParserService = nsnull;
 nsINameSpaceManager *nsContentUtils::sNameSpaceManager;
 nsIIOService *nsContentUtils::sIOService;
 #ifdef MOZ_XTF
 nsIXTFService *nsContentUtils::sXTFService = nsnull;
 #endif
-nsIPrefBranch *nsContentUtils::sPrefBranch = nsnull;
-nsIPref *nsContentUtils::sPref = nsnull;
+nsIPrefBranch2 *nsContentUtils::sPrefBranch = nsnull;
 imgILoader *nsContentUtils::sImgLoader;
 imgICache *nsContentUtils::sImgCache;
 nsIConsoleService *nsContentUtils::sConsoleService;
 nsDataHashtable<nsISupportsHashKey, EventNameMapping>* nsContentUtils::sEventTable = nsnull;
 nsIStringBundleService *nsContentUtils::sStringBundleService;
 nsIStringBundle *nsContentUtils::sStringBundles[PropertiesFile_COUNT];
 nsIContentPolicy *nsContentUtils::sContentPolicyService;
 PRBool nsContentUtils::sTriedToGetContentPolicy = PR_FALSE;
@@ -226,16 +225,18 @@ PRUint32 nsContentUtils::sRunnersCountAt
 PRUint32 nsContentUtils::sScriptBlockerCountWhereRunnersPrevented = 0;
 nsIInterfaceRequestor* nsContentUtils::sSameOriginChecker = nsnull;
 
 nsIJSRuntimeService *nsAutoGCRoot::sJSRuntimeService;
 JSRuntime *nsAutoGCRoot::sJSScriptRuntime;
 
 PRBool nsContentUtils::sInitialized = PR_FALSE;
 
+nsCOMArray<nsPrefOldCallback> *nsContentUtils::sPrefCallbackList = nsnull;
+
 static PLDHashTable sEventListenerManagersHash;
 
 class EventListenerManagerMapEntry : public PLDHashEntryHdr
 {
 public:
   EventListenerManagerMapEntry(const void *aKey)
     : mKey(aKey)
   {
@@ -275,16 +276,53 @@ EventListenerManagerHashClearEntry(PLDHa
 class nsSameOriginChecker : public nsIChannelEventSink,
                             public nsIInterfaceRequestor
 {
   NS_DECL_ISUPPORTS
   NS_DECL_NSICHANNELEVENTSINK
   NS_DECL_NSIINTERFACEREQUESTOR
 };
 
+// For nsContentUtils::RegisterPrefCallback/UnregisterPrefCallback
+class nsPrefOldCallback : public nsIObserver
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIOBSERVER
+
+public:
+  nsPrefOldCallback(const char *aPref, PrefChangedFunc aCallback, void *aClosure) : mPref(aPref), mCallback(aCallback), mClosure(aClosure) {
+  }
+
+  PRBool IsEqual(const char *aPref, PrefChangedFunc aCallback, void *aClosure) {
+    return aCallback == mCallback &&
+           aClosure == mClosure &&
+           mPref.Equals(aPref);
+  }
+
+public:
+  nsCString       mPref;
+  PrefChangedFunc mCallback;
+  void            *mClosure;
+};
+
+NS_IMPL_ISUPPORTS1(nsPrefOldCallback, nsIObserver)
+
+NS_IMETHODIMP
+nsPrefOldCallback::Observe(nsISupports   *aSubject,
+                         const char      *aTopic,
+                         const PRUnichar *aData)
+{
+  NS_ASSERTION(!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID),
+               "invalid topic");
+  mCallback(NS_LossyConvertUTF16toASCII(aData).get(), mClosure);
+
+  return NS_OK;
+}
+
 // static
 nsresult
 nsContentUtils::Init()
 {
   if (sInitialized) {
     NS_WARNING("Init() called twice");
 
     return NS_OK;
@@ -292,19 +330,16 @@ nsContentUtils::Init()
 
   nsresult rv = CallGetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID,
                                &sSecurityManager);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // It's ok to not have a pref service.
   CallGetService(NS_PREFSERVICE_CONTRACTID, &sPrefBranch);
 
-  // It's ok to not have prefs too.
-  CallGetService(NS_PREF_CONTRACTID, &sPref);
-
   rv = NS_GetNameSpaceManager(&sNameSpaceManager);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = CallGetService(nsIXPConnect::GetCID(), &sXPConnect);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = CallGetService(kJSStackContractID, &sThreadJSContextStack);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -881,16 +916,30 @@ nsContentUtils::Shutdown()
   NS_HTMLParanoidFragmentSinkShutdown();
   NS_XHTMLParanoidFragmentSinkShutdown();
 
   NS_IF_RELEASE(sContentPolicyService);
   sTriedToGetContentPolicy = PR_FALSE;
   PRUint32 i;
   for (i = 0; i < PropertiesFile_COUNT; ++i)
     NS_IF_RELEASE(sStringBundles[i]);
+
+  // Clean up c-style's observer 
+  if (sPrefCallbackList) {
+    while (sPrefCallbackList->Count() > 0) {
+      nsCOMPtr<nsPrefOldCallback> callback = (*sPrefCallbackList)[0];
+      NS_ABORT_IF_FALSE(callback, "Invalid c-style callback is appended");
+      if (sPrefBranch)
+        sPrefBranch->RemoveObserver(callback->mPref.get(), callback);
+      sPrefCallbackList->RemoveObject(callback);
+    }
+    delete sPrefCallbackList;
+    sPrefCallbackList = nsnull;
+  }
+
   NS_IF_RELEASE(sStringBundleService);
   NS_IF_RELEASE(sConsoleService);
   NS_IF_RELEASE(sDOMScriptObjectFactory);
   if (sJSGCThingRootCount == 0 && sXPConnect)
     NS_RELEASE(sXPConnect);
   NS_IF_RELEASE(sSecurityManager);
   NS_IF_RELEASE(sThreadJSContextStack);
   NS_IF_RELEASE(sNameSpaceManager);
@@ -901,17 +950,16 @@ nsContentUtils::Shutdown()
   NS_IF_RELEASE(sCaseConv);
   NS_IF_RELEASE(sGenCat);
 #ifdef MOZ_XTF
   NS_IF_RELEASE(sXTFService);
 #endif
   NS_IF_RELEASE(sImgLoader);
   NS_IF_RELEASE(sImgCache);
   NS_IF_RELEASE(sPrefBranch);
-  NS_IF_RELEASE(sPref);
 #ifdef IBMBIDI
   NS_IF_RELEASE(sBidiKeyboard);
 #endif
 
   delete sEventTable;
   sEventTable = nsnull;
 
   if (sPtrsToPtrsToRelease) {
@@ -975,39 +1023,38 @@ nsContentUtils::IsCallerTrustedForCapabi
  * Checks whether two nodes come from the same origin. aTrustedNode is
  * considered 'safe' in that a user can operate on it and that it isn't
  * a js-object that implements nsIDOMNode.
  * Never call this function with the first node provided by script, it
  * must always be known to be a 'real' node!
  */
 // static
 nsresult
-nsContentUtils::CheckSameOrigin(nsIDOMNode *aTrustedNode,
+nsContentUtils::CheckSameOrigin(nsINode *aTrustedNode,
                                 nsIDOMNode *aUnTrustedNode)
 {
   NS_PRECONDITION(aTrustedNode, "There must be a trusted node");
 
   PRBool isSystem = PR_FALSE;
   sSecurityManager->SubjectPrincipalIsSystem(&isSystem);
   if (isSystem) {
     // we're running as system, grant access to the node.
 
     return NS_OK;
   }
 
   /*
    * Get hold of each node's principal
    */
-  nsCOMPtr<nsINode> trustedNode = do_QueryInterface(aTrustedNode);
   nsCOMPtr<nsINode> unTrustedNode = do_QueryInterface(aUnTrustedNode);
 
   // Make sure these are both real nodes
-  NS_ENSURE_TRUE(trustedNode && unTrustedNode, NS_ERROR_UNEXPECTED);
-
-  nsIPrincipal* trustedPrincipal = trustedNode->NodePrincipal();
+  NS_ENSURE_TRUE(aTrustedNode && unTrustedNode, NS_ERROR_UNEXPECTED);
+
+  nsIPrincipal* trustedPrincipal = aTrustedNode->NodePrincipal();
   nsIPrincipal* unTrustedPrincipal = unTrustedNode->NodePrincipal();
 
   if (trustedPrincipal == unTrustedPrincipal) {
     return NS_OK;
   }
 
   PRBool equal;
   // XXXbz should we actually have a Subsumes() check here instead?  Or perhaps
@@ -1103,55 +1150,16 @@ nsContentUtils::InProlog(nsINode *aNode)
   }
 
   nsIDocument* doc = static_cast<nsIDocument*>(parent);
   nsIContent* root = doc->GetRootContent();
 
   return !root || doc->IndexOf(aNode) < doc->IndexOf(root);
 }
 
-// static
-nsresult
-nsContentUtils::doReparentContentWrapper(nsIContent *aNode,
-                                         JSContext *cx,
-                                         JSObject *aOldGlobal,
-                                         JSObject *aNewGlobal,
-                                         nsIDocument *aOldDocument,
-                                         nsIDocument *aNewDocument)
-{
-  nsCOMPtr<nsIXPConnectJSObjectHolder> old_wrapper;
-
-  nsresult rv;
-
-  rv = sXPConnect->ReparentWrappedNativeIfFound(cx, aOldGlobal, aNewGlobal,
-                                                aNode,
-                                                getter_AddRefs(old_wrapper));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Whether or not aChild is already wrapped we must iterate through
-  // its descendants since there's no guarantee that a descendant isn't
-  // wrapped even if this child is not wrapped. That used to be true
-  // when every DOM node's JSObject was parented at the DOM node's
-  // parent's JSObject, but that's no longer the case.
-
-  PRUint32 i, count = aNode->GetChildCount();
-
-  for (i = 0; i < count; i++) {
-    nsIContent *child = aNode->GetChildAt(i);
-    NS_ENSURE_TRUE(child, NS_ERROR_UNEXPECTED);
-
-    rv = doReparentContentWrapper(child, cx, 
-                                  aOldGlobal, aNewGlobal,
-                                  aOldDocument, aNewDocument);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  return rv;
-}
-
 static JSContext *
 GetContextFromDocument(nsIDocument *aDocument, JSObject** aGlobalObject)
 {
   nsIScriptGlobalObject *sgo = aDocument->GetScopeObject();
   if (!sgo) {
     // No script global, no context.
 
     *aGlobalObject = nsnull;
@@ -1168,43 +1176,16 @@ GetContextFromDocument(nsIDocument *aDoc
     return nsnull;
   }
 
   return (JSContext *)scx->GetNativeContext();
 }
 
 // static
 nsresult
-nsContentUtils::ReparentContentWrapper(nsIContent *aContent,
-                                       nsIContent *aNewParent,
-                                       nsIDocument *aNewDocument,
-                                       nsIDocument *aOldDocument)
-{
-  // If we can't find our old document we don't know what our old
-  // scope was so there's no way to find the old wrapper.
-  if (!aOldDocument || !aNewDocument || aNewDocument == aOldDocument) {
-    return NS_OK;
-  }
-
-  JSContext *cx;
-  JSObject *oldScope, *newScope;
-  nsresult rv = GetContextAndScopes(aOldDocument, aNewDocument, &cx, &oldScope,
-                                    &newScope);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (!cx) {
-    return NS_OK;
-  }
-
-  return doReparentContentWrapper(aContent, cx, oldScope, newScope, 
-                                  aOldDocument, aNewDocument);
-}
-
-// static
-nsresult
 nsContentUtils::GetContextAndScopes(nsIDocument *aOldDocument,
                                     nsIDocument *aNewDocument, JSContext **aCx,
                                     JSObject **aOldScope, JSObject **aNewScope)
 {
   *aCx = nsnull;
   *aOldScope = nsnull;
   *aNewScope = nsnull;
 
@@ -1241,17 +1222,17 @@ nsContentUtils::GetContextAndScopes(nsID
 
       sThreadJSContextStack->Peek(&cx);
 
       if (!cx) {
         sThreadJSContextStack->GetSafeJSContext(&cx);
 
         if (!cx) {
           // No safe context reachable, bail.
-          NS_WARNING("No context reachable in ReparentContentWrapper()!");
+          NS_WARNING("No context reachable in GetContextAndScopes()!");
 
           return NS_ERROR_NOT_AVAILABLE;
         }
       }
     }
   }
 
   *aCx = cx;
@@ -2640,34 +2621,64 @@ nsContentUtils::GetStringPref(const char
     if (theString) {
       theString->ToString(getter_Copies(result));
     }
   }
 
   return result;
 }
 
+// RegisterPrefCallback/UnregisterPrefCallback are backward compatiblity for
+// c-style observer.
+
 // static
 void
 nsContentUtils::RegisterPrefCallback(const char *aPref,
                                      PrefChangedFunc aCallback,
                                      void * aClosure)
 {
-  if (sPref)
-    sPref->RegisterCallback(aPref, aCallback, aClosure);
+  if (sPrefBranch) {
+    if (!sPrefCallbackList) {
+      sPrefCallbackList = new nsCOMArray<nsPrefOldCallback> ();
+      if (!sPrefCallbackList)
+        return;
+    }
+
+    nsPrefOldCallback *callback = new nsPrefOldCallback(aPref, aCallback, aClosure);
+    if (callback) {
+      if (NS_SUCCEEDED(sPrefBranch->AddObserver(aPref, callback, PR_FALSE))) {
+        sPrefCallbackList->AppendObject(callback);
+        return;
+      }
+      // error to get/add nsIPrefBranch2.  Destroy callback information
+      delete callback;
+    }
+  }
 }
 
 // static
 void
 nsContentUtils::UnregisterPrefCallback(const char *aPref,
                                        PrefChangedFunc aCallback,
                                        void * aClosure)
 {
-  if (sPref)
-    sPref->UnregisterCallback(aPref, aCallback, aClosure);
+  if (sPrefBranch) {
+    if (!sPrefCallbackList)
+      return;
+
+    int i;
+    for (i = 0; i < sPrefCallbackList->Count(); i++) {
+      nsCOMPtr<nsPrefOldCallback> callback = (*sPrefCallbackList)[i];
+      if (callback && callback->IsEqual(aPref, aCallback, aClosure)) {
+        sPrefBranch->RemoveObserver(aPref, callback);
+        sPrefCallbackList->RemoveObject(callback);
+        return;
+      }
+    }
+  }
 }
 
 static int
 BoolVarChanged(const char *aPref, void *aClosure)
 {
   PRBool* cache = static_cast<PRBool*>(aClosure);
   *cache = nsContentUtils::GetBoolPref(aPref, PR_FALSE);
   
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -2340,16 +2340,35 @@ nsDocument::InitCSP()
       {
         PR_LOG(gCspPRLog, PR_LOG_DEBUG, 
                ("CSP refined, policy: \"%s\"",
                 NS_ConvertUTF16toUTF8(cspHeaderValue).get()));
       }
 #endif
     }
 
+    // Check for frame-ancestor violation
+    nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocumentContainer);
+    if (docShell) {
+        PRBool safeAncestry = false;
+
+        // PermitsAncestry sends violation reports when necessary
+        rv = mCSP->PermitsAncestry(docShell, &safeAncestry);
+        NS_ENSURE_SUCCESS(rv, rv);
+
+        if (!safeAncestry) {
+#ifdef PR_LOGGING
+            PR_LOG(gCspPRLog, PR_LOG_DEBUG, 
+                   ("CSP doesn't like frame's ancestry, not loading."));
+#endif
+            // stop!  ERROR page!
+            mChannel->Cancel(NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION);
+        }
+    }
+
     //Copy into principal
     nsIPrincipal* principal = GetPrincipal();
 
     if (principal) {
         principal->SetCsp(mCSP);
 #ifdef PR_LOGGING
         PR_LOG(gCspPRLog, PR_LOG_DEBUG, 
                 ("Inserted CSP into principal %p", principal));
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -1119,17 +1119,18 @@ nsNSElementTearoff::SetCapture(PRBool aR
 {
   // If there is already an active capture, ignore this request. This would
   // occur if a splitter, frame resizer, etc had already captured and we don't
   // want to override those.
   nsCOMPtr<nsIDOMNode> node = do_QueryInterface(nsIPresShell::GetCapturingContent());
   if (node)
     return NS_OK;
 
-  nsIPresShell::SetCapturingContent(mContent, aRetargetToElement ? CAPTURE_RETARGETTOELEMENT : 0);
+  nsIPresShell::SetCapturingContent(mContent, CAPTURE_PREVENTDRAG |
+    (aRetargetToElement ? CAPTURE_RETARGETTOELEMENT : 0));
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsNSElementTearoff::ReleaseCapture()
 {
   if (nsIPresShell::GetCapturingContent() == mContent) {
     nsIPresShell::SetCapturingContent(nsnull, 0);
@@ -3915,21 +3916,20 @@ nsGenericElement::doReplaceOrInsertBefor
         if (newContent->GetNodeParent() ||
             !IsAllowedAsChild(newContent, nodeType, aParent, aDocument,
                               PR_FALSE, refContent)) {
           return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
         }
       }
     }
 
-    if (!newContent->IsXUL()) {
-      nsContentUtils::ReparentContentWrapper(newContent, aParent,
-                                             container->GetOwnerDoc(),
-                                             container->GetOwnerDoc());
-    }
+    // FIXME https://bugzilla.mozilla.org/show_bug.cgi?id=544654
+    //       We need to reparent here for nodes for which the parent of their
+    //       wrapper is not the wrapper for their ownerDocument (XUL elements,
+    //       form controls, ...).
 
     res = container->InsertChildAt(newContent, insPos, PR_TRUE);
     NS_ENSURE_SUCCESS(res, res);
   }
 
   returnVal.swap(*aReturn);
 
   return res;
--- a/content/base/src/nsTreeWalker.cpp
+++ b/content/base/src/nsTreeWalker.cpp
@@ -141,19 +141,17 @@ NS_IMETHODIMP nsTreeWalker::GetCurrentNo
     *aCurrentNode = nsnull;
 
     return NS_OK;
 }
 NS_IMETHODIMP nsTreeWalker::SetCurrentNode(nsIDOMNode * aCurrentNode)
 {
     NS_ENSURE_TRUE(aCurrentNode, NS_ERROR_DOM_NOT_SUPPORTED_ERR);
 
-    // This QI is dumb, but this shouldn't be a critical operation
-    nsCOMPtr<nsIDOMNode> domRoot = do_QueryInterface(mRoot);
-    nsresult rv = nsContentUtils::CheckSameOrigin(domRoot, aCurrentNode);
+    nsresult rv = nsContentUtils::CheckSameOrigin(mRoot, aCurrentNode);
     NS_ENSURE_SUCCESS(rv, rv);
 
     mCurrentNode = do_QueryInterface(aCurrentNode);
     mPossibleIndexes.Clear();
     mPossibleIndexesPos = -1;
 
     return NS_OK;
 }
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -332,16 +332,20 @@ include $(topsrcdir)/config/rules.mk
 		file_bug503481.sjs \
 		test_bug503481b.html \
 		file_bug503481b_inner.html \
 		test_viewport_scroll.html \
 		test_CSP.html \
 		file_CSP.sjs \
 		file_CSP_main.html \
 		file_CSP_main.js \
+ 		test_CSP_frameancestors.html \
+ 		file_CSP_frameancestors.sjs \
+ 		file_CSP_frameancestors_main.html \
+ 		file_CSP_frameancestors_main.js \
 		test_bug540854.html \
 		bug540854.sjs \
 		$(NULL)
 
 # Disabled; see bug 492181
 #		test_plugin_freezing.html
 
 # Disabled for now. Mochitest isn't reliable enough for these.
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_CSP_frameancestors.sjs
@@ -0,0 +1,57 @@
+// SJS file for CSP frame ancestor mochitests
+function handleRequest(request, response)
+{
+  var query = {};
+  request.queryString.split('&').forEach(function (val) {
+    var [name, value] = val.split('=');
+    query[name] = unescape(value);
+  });
+
+  var isPreflight = request.method == "OPTIONS";
+
+
+  //avoid confusing cache behaviors
+  response.setHeader("Cache-Control", "no-cache", false);
+
+  // grab the desired policy from the query, and then serve a page
+  if (query['csp'])
+    response.setHeader("X-Content-Security-Policy", 
+                        unescape(query['csp']),
+                        false);
+  if (query['scriptedreport']) {
+    // spit back a script that records that the page loaded
+    response.setHeader("Content-Type", "text/javascript", false);
+    response.write('netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");');
+    if (query['double'])
+      response.write('window.parent.parent.parent.frameLoaded("' + query['scriptedreport'] + '", ' +
+                                                       'window.location.toString());');
+    else
+      response.write('window.parent.parent.frameLoaded("' + query['scriptedreport'] + '", ' +
+                                                'window.location.toString());');
+  } else if (query['internalframe']) {
+    // spit back an internal iframe (one that might be blocked)
+    response.setHeader("Content-Type", "text/html", false);
+    response.write('<html><head>');
+    if (query['double'])
+      response.write('<script src="file_CSP_frameancestors.sjs?double=1&scriptedreport=' + query['testid'] + '"></script>');
+    else 
+      response.write('<script src="file_CSP_frameancestors.sjs?scriptedreport=' + query['testid'] + '"></script>');
+    response.write('</head><body>');
+    response.write(unescape(query['internalframe']));
+    response.write('</body></html>');
+  } else if (query['externalframe']) {
+    // spit back an internal iframe (one that won't be blocked, and probably
+    // has no CSP)
+    response.setHeader("Content-Type", "text/html", false);
+    response.write('<html><head>');
+    response.write('</head><body>');
+    response.write(unescape(query['externalframe']));
+    response.write('</body></html>');
+  } else {
+    // default case: error.
+    response.setHeader("Content-Type", "text/html", false);
+    response.write('<html><body>');
+    response.write("ERROR: not sure what to serve.");
+    response.write('</body></html>');
+  }
+}
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_CSP_frameancestors_main.html
@@ -0,0 +1,44 @@
+<html>
+  <head>
+    <title>CSP frame ancestors tests</title>
+
+    <!-- this page shouldn't have a CSP, just the sub-pages. -->
+    <script src='file_CSP_frameancestors_main.js'></script>
+
+  </head>
+  <body>
+    
+<!-- These iframes will get populated by the attached javascript. -->
+<tt>  aa_allow:   /* innermost frame allows a */</tt><br/>
+<iframe id='aa_allow'></iframe><br/>
+
+<tt>  aa_block:     /* innermost frame denies a */</tt><br/>
+<iframe id='aa_block'></iframe><br/>
+
+<tt>  ab_allow:     /* innermost frame allows a */</tt><br/>
+<iframe id='ab_allow'></iframe><br/>
+
+<tt>  ab_block:     /* innermost frame denies a */</tt><br/>
+<iframe id='ab_block'></iframe><br/>
+
+<tt>  aba_allow:    /* innermost frame allows b,a */</tt><br/>
+<iframe id='aba_allow'></iframe><br/>
+
+<tt>  aba_block:    /* innermost frame denies b */</tt><br/>
+<iframe id='aba_block'></iframe><br/>
+
+<tt>  aba2_block:   /* innermost frame denies a */</tt><br/>
+<iframe id='aba2_block'></iframe><br/>
+
+<tt>  abb_allow:    /* innermost frame allows b,a */</tt><br/>
+<iframe id='abb_allow'></iframe><br/>
+
+<tt>  abb_block:    /* innermost frame denies b */</tt><br/>
+<iframe id='abb_block'></iframe><br/>
+
+<tt>  abb2_block:   /* innermost frame denies a */</tt><br/>
+<iframe id='abb2_block'></iframe><br/>
+
+
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/base/test/file_CSP_frameancestors_main.js
@@ -0,0 +1,65 @@
+// Script to populate the test frames in the frame ancestors mochitest.
+//
+function setupFrames() {
+
+  var $ = function(v) { return document.getElementById(v); }
+  var base = {
+        self: '/tests/content/base/test/file_CSP_frameancestors.sjs',
+        a: 'http://localhost:8888/tests/content/base/test/file_CSP_frameancestors.sjs',
+        b: 'http://example.com/tests/content/base/test/file_CSP_frameancestors.sjs'
+  };
+
+  var host = { a: 'http://localhost:8888', b: 'http://example.com:80' };
+
+  var innerframeuri = null;
+  var elt = null;
+
+  elt = $('aa_allow');
+  elt.src = base.a + "?testid=aa_allow&internalframe=aa_a&csp=" + 
+            escape("allow 'none'; frame-ancestors " + host.a + "; script-src 'self'");
+
+  elt = $('aa_block');
+  elt.src = base.a + "?testid=aa_block&internalframe=aa_b&csp=" + 
+            escape("allow 'none'; frame-ancestors 'none'; script-src 'self'");
+
+  elt = $('ab_allow');
+  elt.src = base.b + "?testid=ab_allow&internalframe=ab_a&csp=" +
+            escape("allow 'none'; frame-ancestors " + host.a + "; script-src 'self'");
+
+  elt = $('ab_block');
+  elt.src = base.b + "?testid=ab_block&internalframe=ab_b&csp=" +
+            escape("allow 'none'; frame-ancestors 'none'; script-src 'self'");
+
+   /* .... two-level framing */
+  elt = $('aba_allow');
+  innerframeuri = base.a + "?testid=aba_allow&double=1&internalframe=aba_a&csp=" +
+                  escape("allow 'none'; frame-ancestors " + host.a + " " + host.b + "; script-src 'self'");
+  elt.src = base.b + "?externalframe=" + escape('<iframe src="' + innerframeuri + '"></iframe>');
+
+  elt = $('aba_block');
+  innerframeuri = base.a + "?testid=aba_allow&double=1&internalframe=aba_b&csp=" +
+                  escape("allow 'none'; frame-ancestors " + host.a + "; script-src 'self'");
+  elt.src = base.b + "?externalframe=" + escape('<iframe src="' + innerframeuri + '"></iframe>');
+
+  elt = $('aba2_block');
+  innerframeuri = base.a + "?testid=aba_allow&double=1&internalframe=aba2_b&csp=" +
+                  escape("allow 'none'; frame-ancestors " + host.b + "; script-src 'self'");
+  elt.src = base.b + "?externalframe=" + escape('<iframe src="' + innerframeuri + '"></iframe>');
+
+  elt = $('abb_allow');
+  innerframeuri = base.b + "?testid=abb_allow&double=1&internalframe=abb_a&csp=" +
+                  escape("allow 'none'; frame-ancestors " + host.a + " " + host.b + "; script-src 'self'");
+  elt.src = base.b + "?externalframe=" + escape('<iframe src="' + innerframeuri + '"></iframe>');
+
+  elt = $('abb_block');
+  innerframeuri = base.b + "?testid=abb_allow&double=1&internalframe=abb_b&csp=" +
+                  escape("allow 'none'; frame-ancestors " + host.a + "; script-src 'self'");
+  elt.src = base.b + "?externalframe=" + escape('<iframe src="' + innerframeuri + '"></iframe>');
+
+  elt = $('abb2_block');
+  innerframeuri = base.b + "?testid=abb_allow&double=1&internalframe=abb2_b&csp=" +
+                  escape("allow 'none'; frame-ancestors " + host.b + "; script-src 'self'");
+  elt.src = base.b + "?externalframe=" + escape('<iframe src="' + innerframeuri + '"></iframe>');
+}
+
+window.addEventListener('load', setupFrames, false);
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_CSP_frameancestors.html
@@ -0,0 +1,120 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for Content Security Policy Frame Ancestors directive</title>
+  <script type="text/javascript" src="/MochiKit/packed.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>        
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+  
+</div>
+
+<iframe style="width:100%;height:300px;" id='cspframe'></iframe>
+<script class="testbody" type="text/javascript">
+
+var path = "/tests/content/base/test/";
+
+// These are test results: -1 means it hasn't run, 
+// true/false is the pass/fail result.
+var framesThatShouldLoad = {
+  aa_allow: -1,    /* innermost frame allows a */
+  //aa_block: -1,    /* innermost frame denies a */
+  ab_allow: -1,    /* innermost frame allows a */
+  //ab_block: -1,    /* innermost frame denies a */
+  aba_allow: -1,   /* innermost frame allows b,a */
+  //aba_block: -1,   /* innermost frame denies b */
+  //aba2_block: -1,  /* innermost frame denies a */
+  abb_allow: -1,   /* innermost frame allows b,a */
+  //abb_block: -1,   /* innermost frame denies b */
+  //abb2_block: -1,  /* innermost frame denies a */
+};
+
+var expectedViolationsLeft = 6;
+
+// This is used to watch the blocked data bounce off CSP and allowed data 
+// get sent out to the wire.
+function examiner() {
+  netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+  this.obsvc = Components.classes['@mozilla.org/observer-service;1']
+                        .getService(Components.interfaces.nsIObserverService);
+  this.obsvc.addObserver(this, "csp-on-violate-policy", false);
+}
+examiner.prototype  = {
+  observe: function(subject, topic, data) {
+    netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+    // subject should be an nsURI, and should be either allowed or blocked.
+    if(!subject.QueryInterface) return;
+      
+    if (topic === "csp-on-violate-policy") {
+      //these were blocked... record that they were blocked
+      var uri = subject.QueryInterface(Components.interfaces.nsIURI);
+      window.frameBlocked(uri.asciiSpec, data);
+    }
+  },
+
+  // must eventually call this to remove the listener, 
+  // or mochitests might get borked.
+  remove: function() {
+    netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+    this.obsvc.removeObserver(this, "csp-on-violate-policy");
+  }
+}
+
+// called when a frame is loaded
+// -- if it's not enumerated above, it should not load!
+var frameLoaded = function(testname, uri) {
+  //test already complete.... forget it... remember the first result.
+  if (window.framesThatShouldLoad[testname] != -1)
+    return;
+
+  if (typeof window.framesThatShouldLoad[testname] === 'undefined') {
+    // uh-oh, we're not expecting this frame to load!
+    ok(false, testname + ' framed site should not have loaded: ' + uri);
+  } else {
+    framesThatShouldLoad[testname] = true;
+    ok(true, testname + ' framed site when allowed by csp (' + uri + ')');
+  }
+  checkTestResults();
+}
+
+// called when a frame is blocked
+// -- we can't determine *which* frame was blocked, but at least we can count them
+var frameBlocked = function(uri, policy) {
+  ok(true, 'a CSP policy blocked frame from being loaded: ' + policy);
+  expectedViolationsLeft--;
+  checkTestResults();
+}
+
+
+// Check to see if all the tests have run
+var checkTestResults = function() {
+  // if any test is incomplete, keep waiting
+  for (var v in framesThatShouldLoad)
+    if(framesThatShouldLoad[v] == -1)
+      return;
+
+  if (expectedViolationsLeft > 0)
+    return;
+
+  // ... otherwise, finish
+  window.examiner.remove();
+  SimpleTest.finish();
+}
+
+//////////////////////////////////////////////////////////////////////
+// set up and go
+window.examiner = new examiner();
+SimpleTest.waitForExplicitFinish();
+
+// save this for last so that our listeners are registered.
+// ... this loads the testbed of good and bad requests.
+document.getElementById('cspframe').src = 'file_CSP_frameancestors_main.html';
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -782,18 +782,17 @@ nsEventStateManager::Init()
 {
   nsresult rv;
   nsCOMPtr<nsIObserverService> observerService =
            do_GetService("@mozilla.org/observer-service;1", &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_TRUE);
 
-  nsCOMPtr<nsIPrefBranch2> prefBranch =
-    do_QueryInterface(nsContentUtils::GetPrefBranch());
+  nsIPrefBranch2* prefBranch = nsContentUtils::GetPrefBranch();
 
   if (prefBranch) {
     if (sESMInstanceCount == 1) {
       sLeftClickOnly =
         nsContentUtils::GetBoolPref("nglayout.events.dispatchLeftClickOnly",
                                     sLeftClickOnly);
 
       sChromeAccessModifier =
@@ -862,18 +861,17 @@ nsEventStateManager::~nsEventStateManage
     }
   }
 
 }
 
 nsresult
 nsEventStateManager::Shutdown()
 {
-  nsCOMPtr<nsIPrefBranch2> prefBranch =
-    do_QueryInterface(nsContentUtils::GetPrefBranch());
+  nsIPrefBranch2* prefBranch = nsContentUtils::GetPrefBranch();
 
   if (prefBranch) {
     prefBranch->RemoveObserver("accessibility.accesskeycausesactivation", this);
     prefBranch->RemoveObserver("nglayout.events.dispatchLeftClickOnly", this);
     prefBranch->RemoveObserver("ui.key.generalAccessKey", this);
     prefBranch->RemoveObserver("ui.key.chromeAccess", this);
     prefBranch->RemoveObserver("ui.key.contentAccess", this);
 #if 0
@@ -1886,16 +1884,22 @@ nsEventStateManager::GenerateDragGesture
     {
       nsCOMPtr<nsFrameSelection> frameSel = mCurrentTarget->GetFrameSelection();
       if (frameSel && frameSel->GetMouseDownState()) {
         StopTrackingDragGesture();
         return;
       }
     }
 
+    // If non-native code is capturing the mouse don't start a drag.
+    if (nsIPresShell::IsMouseCapturePreventingDrag()) {
+      StopTrackingDragGesture();
+      return;
+    }
+
     static PRInt32 pixelThresholdX = 0;
     static PRInt32 pixelThresholdY = 0;
 
     if (!pixelThresholdX) {
       nsILookAndFeel *lf = aPresContext->LookAndFeel();
       lf->GetMetric(nsILookAndFeel::eMetric_DragThresholdX, pixelThresholdX);
       lf->GetMetric(nsILookAndFeel::eMetric_DragThresholdY, pixelThresholdY);
       if (!pixelThresholdX)
--- a/content/events/src/nsXMLEventsManager.cpp
+++ b/content/events/src/nsXMLEventsManager.cpp
@@ -316,17 +316,17 @@ PRBool nsXMLEventsManager::RemoveListene
 }
 
 void nsXMLEventsManager::AddListeners(nsIDocument* aDocument)
 {
   nsIContent *cur;
   for (int i = 0; i < mIncomplete.Count(); ++i) {
     cur = mIncomplete[i];
     //If this succeeds, the object will be removed from mIncomplete
-    if (nsXMLEventsListener::InitXMLEventsListener(aDocument, this, cur) == PR_TRUE)
+    if (nsXMLEventsListener::InitXMLEventsListener(aDocument, this, cur))
       --i;
   }
 }
 
 void 
 nsXMLEventsManager::BeginUpdate(nsIDocument* aDocument, nsUpdateType aUpdateType) {}
 void 
 nsXMLEventsManager::EndUpdate(nsIDocument* aDocument, nsUpdateType aUpdateType) {}
new file mode 100644
--- /dev/null
+++ b/content/html/content/reftests/41464-1-ref.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<title>Dynamic manipulation of textarea.wrap</title>
+<link rel=help href=http://www.whatwg.org/html5/#dom-textarea-wrap>
+<link rel=author title=Ms2ger href=mailto:ms2ger@gmail.com>
+<textarea wrap=soft cols=20>01234567890 01234567890 01234567890</textarea>
new file mode 100644
--- /dev/null
+++ b/content/html/content/reftests/41464-1a.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<title>Dynamic manipulation of textarea.wrap</title>
+<link rel=help href=http://www.whatwg.org/html5/#dom-textarea-wrap>
+<link rel=author title=Ms2ger href=mailto:ms2ger@gmail.com>
+<textarea wrap=off cols=20>01234567890 01234567890 01234567890</textarea>
+<script>
+document.getElementsByTagName("textarea")[0].wrap = "soft";
+</script>
new file mode 100644
--- /dev/null
+++ b/content/html/content/reftests/41464-1b.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<title>Dynamic manipulation of textarea.wrap</title>
+<link rel=help href=http://www.whatwg.org/html5/#dom-textarea-wrap>
+<link rel=author title=Ms2ger href=mailto:ms2ger@gmail.com>
+<textarea wrap=off cols=20>01234567890 01234567890 01234567890</textarea>
+<script>
+document.getElementsByTagName("textarea")[0].setAttribute("wrap", "soft");
+</script>
--- a/content/html/content/reftests/reftest.list
+++ b/content/html/content/reftests/reftest.list
@@ -1,7 +1,9 @@
+== 41464-1a.html 41464-1-ref.html
+== 41464-1b.html 41464-1-ref.html
 != 468263-1a.html about:blank
 != 468263-1b.html about:blank
 != 468263-1c.html about:blank
 != 468263-1d.html about:blank
 == 468263-2.html 468263-2-ref.html
 == 468263-2.html 468263-2-alternate-ref.html
 == 484200-1.html 484200-1-ref.html
--- a/content/html/content/src/nsHTMLTextAreaElement.cpp
+++ b/content/html/content/src/nsHTMLTextAreaElement.cpp
@@ -373,16 +373,17 @@ nsHTMLTextAreaElement::IsHTMLFocusable(P
 NS_IMPL_STRING_ATTR(nsHTMLTextAreaElement, AccessKey, accesskey)
 NS_IMPL_INT_ATTR(nsHTMLTextAreaElement, Cols, cols)
 NS_IMPL_BOOL_ATTR(nsHTMLTextAreaElement, Disabled, disabled)
 NS_IMPL_INT_ATTR(nsHTMLTextAreaElement, MaxLength, maxlength)
 NS_IMPL_STRING_ATTR(nsHTMLTextAreaElement, Name, name)
 NS_IMPL_BOOL_ATTR(nsHTMLTextAreaElement, ReadOnly, readonly)
 NS_IMPL_INT_ATTR(nsHTMLTextAreaElement, Rows, rows)
 NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsHTMLTextAreaElement, TabIndex, tabindex, 0)
+NS_IMPL_STRING_ATTR(nsHTMLTextAreaElement, Wrap, wrap)
   
 
 NS_IMETHODIMP 
 nsHTMLTextAreaElement::GetType(nsAString& aType)
 {
   aType.AssignLiteral("textarea");
 
   return NS_OK;
@@ -550,16 +551,18 @@ nsChangeHint
 nsHTMLTextAreaElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
                                               PRInt32 aModType) const
 {
   nsChangeHint retval =
       nsGenericHTMLFormElement::GetAttributeChangeHint(aAttribute, aModType);
   if (aAttribute == nsGkAtoms::rows ||
       aAttribute == nsGkAtoms::cols) {
     NS_UpdateHint(retval, NS_STYLE_HINT_REFLOW);
+  } else if (aAttribute == nsGkAtoms::wrap) {
+    NS_UpdateHint(retval, nsChangeHint_ReconstructFrame);
   }
   return retval;
 }
 
 NS_IMETHODIMP_(PRBool)
 nsHTMLTextAreaElement::IsAttributeMapped(const nsIAtom* aAttribute) const
 {
   static const MappedAttributeEntry* const map[] = {
@@ -791,16 +794,19 @@ nsHTMLTextAreaElement::SetSelectionRange
 
 nsresult
 nsHTMLTextAreaElement::Reset()
 {
   nsresult rv;
   // If the frame is there, we have to set the value so that it will show up.
   nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE);
   if (formControlFrame) {
+    // To get the initial spellchecking, reset value to
+    // empty string before setting the default value.
+    SetValue(EmptyString());
     nsAutoString resetVal;
     GetDefaultValue(resetVal);
     rv = SetValue(resetVal);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   SetValueChanged(PR_FALSE);
   return NS_OK;
 }
--- a/content/html/content/test/Makefile.in
+++ b/content/html/content/test/Makefile.in
@@ -51,16 +51,17 @@ include $(topsrcdir)/config/rules.mk
 		test_bug696.html \
 		test_bug1297.html \
 		test_bug1366.html \
 		test_bug1400.html \
 		test_bug2082.html \
 		test_bug3348.html \
 		test_bug6296.html \
 		test_bug24958.html \
+		test_bug41464.html \
 		bug100533_load.html \
 		bug100533_iframe.html \
 		test_bug100533.html \
 		test_bug143220.html \
 		test_bug237071.html \
 		bug242709_iframe.html \
 		bug242709_load.html \
 		test_bug242709.html \
@@ -134,16 +135,17 @@ include $(topsrcdir)/config/rules.mk
 		test_bug347174_xsl.html \
 		test_bug347174_xslp.html \
 		347174transformable.xml \
 		347174transform.xsl \
 		test_bug481335.xhtml \
 		test_bug500885.html \
 		test_bug514856.html \
 		bug514856_iframe.html \
+		test_bug518122.html \
 		test_bug519987.html \
 		test_bug523771.html \
 		form_submit_server.sjs \
 		test_bug529819.html \
 		test_bug529859.html \
 		test_bug535043.html \
 		$(NULL)
 
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_bug41464.html
@@ -0,0 +1,52 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=41464
+-->
+<head>
+  <title>Test for Bug 41464</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=41464">Mozilla Bug 41464</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<textarea wrap=cheesecake></textarea>  
+</div>
+<pre id="test">
+<script type="application/javascript">
+/** Test for Bug 41464 **/
+var textarea = document.getElementById("content").getElementsByTagName("textarea")[0];
+is(textarea.wrap, "cheesecake");
+is(textarea.hasAttribute("wrap"), true);
+is(textarea.getAttribute("wrap"), "cheesecake");
+
+textarea.setAttribute("wrap", "off");
+is(textarea.wrap, "off");
+is(textarea.hasAttribute("wrap"), true);
+is(textarea.getAttribute("wrap"), "off");
+
+textarea.wrap = "soft";
+is(textarea.wrap, "soft");
+is(textarea.hasAttribute("wrap"), true);
+is(textarea.getAttribute("wrap"), "soft");
+
+textarea.wrap = undefined;
+is(textarea.wrap, "undefined");
+is(textarea.hasAttribute("wrap"), true);
+is(textarea.getAttribute("wrap"), "undefined");
+
+textarea.wrap = null;
+is(textarea.wrap, "null");
+is(textarea.hasAttribute("wrap"), true);
+is(textarea.getAttribute("wrap"), "null");
+
+textarea.removeAttribute("wrap");
+is(textarea.wrap, "");
+is(textarea.hasAttribute("wrap"), false);
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_bug518122.html
@@ -0,0 +1,122 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=518122
+-->
+<head>
+  <title>Test for Bug 518122</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onload="runTests()">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=518122">Mozilla Bug 518122</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 518122 **/
+
+SimpleTest.waitForExplicitFinish();
+
+var simple_tests = [ ["foo", "foo"],
+                     ["", ""],
+                     [null, ""],
+                     [undefined , "undefined"],
+                     ["\n", "\n"],
+                     ["\r", "\n"],
+                     ["\rfoo", "\nfoo"],
+                     ["foo\r", "foo\n"],
+                     ["foo\rbar", "foo\nbar"],
+                     ["foo\rbar\r", "foo\nbar\n"],
+                     ["\r\n", "\n"],
+                     ["\r\nfoo", "\nfoo"],
+                     ["foo\r\n", "foo\n"],
+                     ["foo\r\nbar", "foo\nbar"],
+                     ["foo\r\nbar\r\n", "foo\nbar\n"] ];
+
+var value_append_tests = [ ["foo", "bar", "foobar"],
+                           ["foo", "foo", "foofoo"],
+                           ["foobar", "bar", "foobarbar"],
+                           ["foobar", "foo", "foobarfoo"],
+                           ["foo\n", "foo", "foo\nfoo"],
+                           ["foo\r", "foo", "foo\nfoo"],
+                           ["foo\r\n", "foo", "foo\nfoo"],
+                           ["\n", "\n", "\n\n"],
+                           ["\r", "\r", "\n\n"],
+                           ["\r\n", "\r\n", "\n\n"],
+                           ["\r", "\r\n", "\n\n"],
+                           ["\r\n", "\r", "\n\n"],
+                           [null, null, "null"],
+                           [null, undefined, "undefined"],
+                           ["", "", ""]
+                           ];
+
+
+var simple_tests_for_input = [ ["foo", "foo"],
+                               ["", ""],
+                               [null, ""],
+                               [undefined , "undefined"],
+                               ["\n", ""],
+                               ["\r", ""],
+                               ["\rfoo", " foo"],
+                               ["foo\r", "foo"],
+                               ["foo\rbar", "foo bar"],
+                               ["foo\rbar\r", "foo bar"],
+                               ["\r\n", ""],
+                               ["\r\nfoo", " foo"],
+                               ["foo\r\n", "foo"],
+                               ["foo\r\nbar", "foo bar"],
+                               ["foo\r\nbar\r\n", "foo bar"] ];
+
+var value_append_tests_for_input = [ ["foo", "bar", "foobar"],
+                                     ["foo", "foo", "foofoo"],
+                                     ["foobar", "bar", "foobarbar"],
+                                     ["foobar", "foo", "foobarfoo"],
+                                     ["foo\n", "foo", "foofoo"],
+                                     ["foo\r", "foo", "foofoo"],
+                                     ["foo\r\n", "foo", "foofoo"],
+                                     ["\n", "\n", ""],
+                                     ["\r", "\r", ""],
+                                     ["\r\n", "\r\n", ""],
+                                     ["\r", "\r\n", ""],
+                                     ["\r\n", "\r", ""],
+                                     [null, null, "null"],
+                                     [null, undefined, "undefined"],
+                                     ["", "", ""]
+                                     ];
+function runTestsFor(el, simpleTests, appendTests) {
+  for(var i = 0; i < simpleTests.length; ++i) {
+    el.value = simpleTests[i][0];
+    is(el.value, simpleTests[i][1], "Wrong value (wrap=" + el.getAttribute('wrap') + ", simple_test=" + i + ")");
+  }
+  for (var j = 0; j < appendTests.length; ++j) {
+    el.value = appendTests[j][0];
+    el.value += appendTests[j][1];
+    is(el.value, appendTests[j][2], "Wrong value (wrap=" + el.getAttribute('wrap') + ", value_append_test=" + j + ")");
+  }
+}
+
+function runTests() {
+  var textareas = document.getElementsByTagName("textarea");
+  for (var i = 0; i < textareas.length; ++i) {
+    runTestsFor(textareas[i], simple_tests, value_append_tests);
+  }
+  runTestsFor(document.getElementsByTagName("input")[0],
+              simple_tests_for_input, value_append_tests_for_input);
+  SimpleTest.finish();
+}
+
+
+</script>
+</pre>
+<textarea cols="30" rows="7" wrap="none"></textarea>
+<textarea cols="30" rows="7" wrap="off"></textarea><br>
+<textarea cols="30" rows="7" wrap="soft"></textarea>
+<textarea cols="30" rows="7" wrap="hard"></textarea>
+<input type="text">
+</body>
+</html>
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -686,16 +686,22 @@ nsHTMLDocument::StartDocumentLoad(const 
   if (contentType.Equals("application/xhtml+xml") &&
       (!aCommand || nsCRT::strcmp(aCommand, "view-source") != 0)) {
     // We're parsing XHTML as XML, remember that.
 
     mIsRegularHTML = PR_FALSE;
     mCompatMode = eCompatibility_FullStandards;
     loadAsHtml5 = PR_FALSE;
   }
+#ifdef DEBUG
+  else {
+    NS_ASSERTION(mIsRegularHTML,
+                 "Hey, someone forgot to reset mIsRegularHTML!!!");
+  }
+#endif
   
   if (loadAsHtml5 && 
       !(contentType.EqualsLiteral("text/html") && 
         aCommand && 
         !nsCRT::strcmp(aCommand, "view"))) {
     loadAsHtml5 = PR_FALSE;
   }
   
@@ -711,23 +717,16 @@ nsHTMLDocument::StartDocumentLoad(const 
       nsCAutoString str;
       uri->GetSpec(str);
       if (str.EqualsLiteral("about:blank")) {
         loadAsHtml5 = PR_FALSE;    
       }
     }
   }
   
-#ifdef DEBUG
-  else {
-    NS_ASSERTION(mIsRegularHTML,
-                 "Hey, someone forgot to reset mIsRegularHTML!!!");
-  }
-#endif
-
   CSSLoader()->SetCompatibilityMode(mCompatMode);
   
   PRBool needsParser = PR_TRUE;
   if (aCommand)
   {
     if (!nsCRT::strcmp(aCommand, "view delayedContentLoad")) {
       needsParser = PR_FALSE;
     }
@@ -2980,17 +2979,17 @@ nsHTMLDocument::GetDesignMode(nsAString 
     aDesignMode.AssignLiteral("off");
   }
   return NS_OK;
 }
 
 void
 nsHTMLDocument::MaybeEditingStateChanged()
 {
-  if (mUpdateNestLevel == 0 && mContentEditableCount > 0 != IsEditingOn()) {
+  if (mUpdateNestLevel == 0 && (mContentEditableCount > 0) != IsEditingOn()) {
     if (nsContentUtils::IsSafeToRunScript()) {
       EditingStateChanged();
     } else if (!mInDestructor) {
       nsContentUtils::AddScriptRunner(
         NS_NEW_RUNNABLE_METHOD(nsHTMLDocument, this, MaybeEditingStateChanged));
     }
   }
 }
@@ -3008,17 +3007,17 @@ nsHTMLDocument::ChangeContentEditableCou
                                            PRInt32 aChange)
 {
   NS_ASSERTION(mContentEditableCount + aChange >= 0,
                "Trying to decrement too much.");
 
   mContentEditableCount += aChange;
 
   if (mParser ||
-      (mUpdateNestLevel > 0 && mContentEditableCount > 0 != IsEditingOn())) {
+      (mUpdateNestLevel > 0 && (mContentEditableCount > 0) != IsEditingOn())) {
     return NS_OK;
   }
 
   EditingState oldState = mEditingState;
 
   nsresult rv = EditingStateChanged();
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/content/html/document/test/test_bug486741.html
+++ b/content/html/document/test/test_bug486741.html
@@ -21,26 +21,23 @@ https://bugzilla.mozilla.org/show_bug.cg
 /** Test for Bug 486741 **/
 SimpleTest.waitForExplicitFinish();
 addLoadEvent(function() {
   var d = $("f").contentDocument;
   var root = d.documentElement;
   is(root.tagName, "HTML", "Unexpected root");
 
   d.open();
-  var newRoot = d.documentElement;
-  is(newRoot.tagName, "HTML", "Unexpected new root");
-  isnot(newRoot, root, "Shouldn't be the same node");
+  isnot(d.documentElement, root, "Shouldn't have the old root element");
 
   d.write("Test");
   d.close();
 
-  var newNewRoot = d.documentElement;
-  is(newNewRoot.tagName, "HTML", "Unexpected new root after write");
-  is(newNewRoot, newNewRoot, "write+close shouldn't change the root");
+  isnot(d.documentElement, root, "Still shouldn't have the old root element");
+  is(d.documentElement.tagName, "HTML", "Unexpected new root after write");
 
   SimpleTest.finish();
 });
 
 </script>
 </pre>
 </body>
 </html>
--- a/content/media/test/Makefile.in
+++ b/content/media/test/Makefile.in
@@ -93,16 +93,17 @@ include $(topsrcdir)/config/rules.mk
 		test_currentTime.html \
 		test_decode_error.html \
 		test_decoder_disable.html \
 		test_load.html \
 		test_media_selection.html \
 		test_mozLoadFrom.html \
 		test_networkState.html \
 		test_paused.html \
+		test_play_twice.html \
 		test_playback.html \
 		test_playback_errors.html \
 		test_reactivate.html \
 		test_readyState.html \
 		test_seek2.html \
 		test_volume.html \
 		use_large_cache.js \
 		$(NULL)
@@ -143,16 +144,17 @@ endif
 		bug504843.ogv \
 		bug506094.ogv \
 		bug516323.ogv \
 		bug520493.ogg \
 		bug520500.ogg \
 		bug520908.ogv \
 		bug520908.ogv^headers^ \
 		bug523816.ogv \
+		bug533822.ogg \
 		chain.ogv \
 		dirac.ogg \
 		seek.ogv \
 		short-video.ogv \
 		small-shot.ogg \
 		sound.ogg \
 		$(NULL)
 
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..a8e506910e6c031fe42aadd4cab0abf33959f6ad
GIT binary patch
literal 35010
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
HeFp&mF7I{A
--- a/content/media/test/manifest.js
+++ b/content/media/test/manifest.js
@@ -12,16 +12,22 @@ var gSmallTests = [
 
 // Used by test_mozLoadFrom.  Need one test file per decoder backend, plus
 // anything for testing clone-specific bugs.
 var gCloneTests = gSmallTests.concat([
   // Actual duration is ~200ms, we have Content-Duration lie about it.
   { name:"bug520908.ogv", type:"video/ogg", duration:9000 },
 ]);
 
+// Used by test_play_twice.  Need one test file per decoder backend, plus
+// anything for testing bugs that occur when replying a played file.
+var gReplayTests = gSmallTests.concat([
+  { name:"bug533822.ogg", type:"audio/ogg" },
+]);
+
 // These are files that we want to make sure we can play through.  We can
 // also check metadata.  Put files of the same type together in this list so if
 // something crashes we have some idea of which backend is responsible.
 // Used by test_playback, which expects no error event and one ended event.
 var gPlayTests = [
   // 8-bit samples
   { name:"r11025_u8_c1.wav", type:"audio/x-wav", duration:1.0 },
   // 8-bit samples, file is truncated
new file mode 100644
--- /dev/null
+++ b/content/media/test/test_play_twice.html
@@ -0,0 +1,93 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test playback of media files that should play OK</title>
+  <script type="text/javascript" src="/MochiKit/packed.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <script type="text/javascript" src="manifest.js"></script>
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+var PARALLEL_TESTS = 2;
+
+var testIndex = 0;
+var videos = [];
+
+var testsWaiting = 0;
+
+function startTests() {
+  for (var i = 0; i < videos.length; ++i) {
+    document.body.removeChild(videos[i]);
+  }
+  videos = [];
+  while (videos.length < PARALLEL_TESTS && testIndex < gReplayTests.length) {
+    var v = document.createElement('video');
+    var test = gReplayTests[testIndex];
+    ++testIndex;
+    if (!v.canPlayType(test.type))
+      continue;
+
+    v.src = test.name;
+    var check = function(test, v) { return function() {
+      checkMetadata(test.name, v, test);
+    }}(test, v);
+    var noLoad = function(test, v) { return function() {
+      ok(false, test.name + " should not fire 'load' event");
+    }}(test, v);
+    var checkEnded = function(test, v) { return function() {
+      if (test.duration) {
+        ok(Math.abs(v.currentTime - test.duration) < 0.1,
+           test.name + " current time at end: " + v.currentTime);
+      }
+      is(v.readyState, v.HAVE_CURRENT_DATA, test.name + " checking readyState");
+      ok(v.readyState != v.NETWORK_LOADED, test.name + " shouldn't report NETWORK_LOADED");
+      ok(v.ended, test.name + " checking playback has ended");
+      if (v._playedOnce) {
+        --testsWaiting;
+        if (testsWaiting == 0) {
+          setTimeout(startTests, 0);
+        }
+      } else {
+        v._playedOnce = true;
+        v.play();
+      }
+    }}(test, v);
+    var checkSuspended = function(test, v) { return function() {
+      if (v.seenSuspend)
+        return;
+
+      v.seenSuspend = true;
+      ok(true, test.name + " got suspend");
+      --testsWaiting;
+      if (testsWaiting == 0) {
+        setTimeout(startTests, 0);
+      }
+    }}(test, v);
+    v.addEventListener("load", noLoad, false);
+    v.addEventListener("loadedmetadata", check, false);
+
+    // We should get "ended" and "suspend" events for every resource
+    v.addEventListener("ended", checkEnded, false);
+    v.addEventListener("suspend", checkSuspended, false);
+    testsWaiting += 2;
+
+    document.body.appendChild(v);
+    v.play();
+    videos.push(v);
+  }
+  if (videos.length == 0) {
+    // No new tests were spawned, perhaps the remaining tests on the list are
+    // not supported, or we just reached the end of the list.
+    SimpleTest.finish();
+  }
+}
+
+SimpleTest.waitForExplicitFinish();
+
+addLoadEvent(startTests);
+</script>
+</pre>
+</body>
+</html>
--- a/content/smil/nsSMILAnimationFunction.cpp
+++ b/content/smil/nsSMILAnimationFunction.cpp
@@ -863,27 +863,27 @@ nsSMILAnimationFunction::CheckKeySplines
 
 PRBool
 nsSMILAnimationFunction::GetAccumulate() const
 {
   const nsAttrValue* value = GetAttr(nsGkAtoms::accumulate);
   if (!value)
     return PR_FALSE;
 
-  return (value->GetEnumValue() == PR_TRUE);
+  return value->GetEnumValue();
 }
 
 PRBool
 nsSMILAnimationFunction::GetAdditive() const
 {
   const nsAttrValue* value = GetAttr(nsGkAtoms::additive);
   if (!value)
     return PR_FALSE;
 
-  return (value->GetEnumValue() == PR_TRUE);
+  return value->GetEnumValue();
 }
 
 nsSMILAnimationFunction::nsSMILCalcMode
 nsSMILAnimationFunction::GetCalcMode() const
 {
   const nsAttrValue* value = GetAttr(nsGkAtoms::calcMode);
   if (!value)
     return CALC_LINEAR;
--- a/content/svg/content/src/nsSVGElement.cpp
+++ b/content/svg/content/src/nsSVGElement.cpp
@@ -1521,16 +1521,28 @@ nsSVGElement::DidChangePreserveAspectRat
 
   nsAutoString newStr;
   preserveAspectRatio->GetBaseValueString(newStr);
 
   SetAttr(kNameSpaceID_None, nsGkAtoms::preserveAspectRatio,
           newStr, PR_TRUE);
 }
 
+void
+nsSVGElement::DidAnimatePreserveAspectRatio()
+{
+  nsIFrame* frame = GetPrimaryFrame();
+  
+  if (frame) {
+    frame->AttributeChanged(kNameSpaceID_None,
+                            nsGkAtoms::preserveAspectRatio,
+                            nsIDOMMutationEvent::MODIFICATION);
+  }
+}
+
 nsSVGElement::StringAttributesInfo
 nsSVGElement::GetStringInfo()
 {
   return StringAttributesInfo(nsnull, nsnull, 0);
 }
 
 void nsSVGElement::StringAttributesInfo::Reset(PRUint8 aAttrEnum)
 {
@@ -1744,16 +1756,22 @@ nsSVGElement::GetAnimatedAttr(const nsIA
     BooleanAttributesInfo info = GetBooleanInfo();
     for (PRUint32 i = 0; i < info.mBooleanCount; i++) {
       if (aName == *info.mBooleanInfo[i].mName) {
         return info.mBooleans[i].ToSMILAttr(this);
       }
     }
   }
 
+  // preserveAspectRatio:
+  if (aName == nsGkAtoms::preserveAspectRatio) {
+    nsSVGPreserveAspectRatio *preserveAspectRatio = GetPreserveAspectRatio();
+    return preserveAspectRatio ? preserveAspectRatio->ToSMILAttr(this) : nsnull;
+  }
+
   return nsnull;
 }
 
 void
 nsSVGElement::AnimationNeedsResample()
 {
   nsIDocument* doc = GetCurrentDoc();
   if (doc) {
--- a/content/svg/content/src/nsSVGElement.h
+++ b/content/svg/content/src/nsSVGElement.h
@@ -154,16 +154,17 @@ public:
   virtual void DidChangeViewBox(PRBool aDoSetAttr);
   virtual void DidChangePreserveAspectRatio(PRBool aDoSetAttr);
   virtual void DidChangeString(PRUint8 aAttrEnum) {}
 
   virtual void DidAnimateLength(PRUint8 aAttrEnum);
   virtual void DidAnimateNumber(PRUint8 aAttrEnum);
   virtual void DidAnimateBoolean(PRUint8 aAttrEnum);
   virtual void DidAnimateEnum(PRUint8 aAttrEnum);
+  virtual void DidAnimatePreserveAspectRatio();
 
   void GetAnimatedLengthValues(float *aFirst, ...);
   void GetAnimatedNumberValues(float *aFirst, ...);
   void GetAnimatedIntegerValues(PRInt32 *aFirst, ...);
 
 #ifdef MOZ_SMIL
   virtual nsISMILAttr* GetAnimatedAttr(const nsIAtom* aName);
   void AnimationNeedsResample();
--- a/content/svg/content/src/nsSVGFilters.cpp
+++ b/content/svg/content/src/nsSVGFilters.cpp
@@ -325,16 +325,22 @@ nsSVGFE::DidAnimateNumber(PRUint8 aAttrE
 
 void
 nsSVGFE::DidAnimateEnum(PRUint8 aAttrEnum)
 {
   DidAnimateAttr(this);
 }
 
 void
+nsSVGFE::DidAnimatePreserveAspectRatio(PRUint8 aAttrEnum)
+{
+  DidAnimateAttr(this);
+}
+
+void
 nsSVGFE::DidAnimateBoolean(PRUint8 aAttrEnum)
 {
   DidAnimateAttr(this);
 }
 
 //---------------------Gaussian Blur------------------------
 
 typedef nsSVGFE nsSVGFEGaussianBlurElementBase;
@@ -4820,29 +4826,33 @@ nsSVGFELightingElement::Filter(nsSVGFilt
   }
   float lightPos[3], pointsAt[3], specularExponent, cosConeAngle;
   if (pointLight) {
     static_cast<nsSVGFEPointLightElement*>
       (pointLight.get())->GetAnimatedNumberValues(lightPos,
                                                   lightPos + 1,
                                                   lightPos + 2,
                                                   nsnull);
+    instance->ConvertLocation(lightPos);
   }
   if (spotLight) {
     float limitingConeAngle;
     static_cast<nsSVGFESpotLightElement*>
       (spotLight.get())->GetAnimatedNumberValues(lightPos,
                                                  lightPos + 1,
                                                  lightPos + 2,
                                                  pointsAt,
                                                  pointsAt + 1,
                                                  pointsAt + 2,
                                                  &specularExponent,
                                                  &limitingConeAngle,
                                                  nsnull);
+    instance->ConvertLocation(lightPos);
+    instance->ConvertLocation(pointsAt);
+
     nsCOMPtr<nsIContent> spot = do_QueryInterface(spotLight);
     if (spot->HasAttr(kNameSpaceID_None, nsGkAtoms::limitingConeAngle)) {
       cosConeAngle = NS_MAX<double>(cos(limitingConeAngle * radPerDeg), 0.0);
     } else {
       cosConeAngle = 0;
     }
   }
 
@@ -5454,17 +5464,18 @@ nsSVGFEImageElement::Filter(nsSVGFilterI
 
     PRInt32 nativeWidth, nativeHeight;
     imageContainer->GetWidth(&nativeWidth);
     imageContainer->GetHeight(&nativeHeight);
 
     const gfxRect& filterSubregion = aTarget->mFilterPrimitiveSubregion;
 
     gfxMatrix viewBoxTM =
-      nsSVGUtils::GetViewBoxTransform(filterSubregion.Width(), filterSubregion.Height(),
+      nsSVGUtils::GetViewBoxTransform(this,
+                                      filterSubregion.Width(), filterSubregion.Height(),
                                       0,0, nativeWidth, nativeHeight,
                                       mPreserveAspectRatio);
 
     gfxMatrix xyTM = gfxMatrix().Translate(gfxPoint(filterSubregion.X(), filterSubregion.Y()));
 
     gfxMatrix TM = viewBoxTM * xyTM;
     
     gfxContext ctx(aTarget->mImage);
--- a/content/svg/content/src/nsSVGFilters.h
+++ b/content/svg/content/src/nsSVGFilters.h
@@ -216,16 +216,17 @@ protected:
   }
 
   // nsSVGElement specializations:
   virtual LengthAttributesInfo GetLengthInfo();
   virtual void DidAnimateLength(PRUint8 aAttrEnum);
   virtual void DidAnimateNumber(PRUint8 aAttrEnum);
   virtual void DidAnimateEnum(PRUint8 aAttrEnum);
   virtual void DidAnimateBoolean(PRUint8 aAttrEnum);
+  virtual void DidAnimatePreserveAspectRatio(PRUint8 aAttrEnum);
 
   // nsIDOMSVGFitlerPrimitiveStandardAttributes values
   enum { X, Y, WIDTH, HEIGHT };
   nsSVGLength2 mLengthAttributes[4];
   static LengthInfo sLengthInfo[4];
 };
 
 #endif
--- a/content/svg/content/src/nsSVGMarkerElement.cpp
+++ b/content/svg/content/src/nsSVGMarkerElement.cpp
@@ -409,17 +409,18 @@ nsSVGMarkerElement::GetViewBoxTransform(
     if (viewbox.width <= 0.0f || viewbox.height <= 0.0f) {
       return gfxMatrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // invalid - don't paint element
     }
 
     float refX = mLengthAttributes[REFX].GetAnimValue(mCoordCtx);
     float refY = mLengthAttributes[REFY].GetAnimValue(mCoordCtx);
 
     gfxMatrix viewBoxTM =
-      nsSVGUtils::GetViewBoxTransform(viewportWidth, viewportHeight,
+      nsSVGUtils::GetViewBoxTransform(this,
+                                      viewportWidth, viewportHeight,
                                       viewbox.x, viewbox.y,
                                       viewbox.width, viewbox.height,
                                       mPreserveAspectRatio,
                                       PR_TRUE);
 
     gfxPoint ref = viewBoxTM.Transform(gfxPoint(refX, refY));
 
     gfxMatrix TM = viewBoxTM * gfxMatrix().Translate(gfxPoint(-ref.x, -ref.y));
--- a/content/svg/content/src/nsSVGPreserveAspectRatio.cpp
+++ b/content/svg/content/src/nsSVGPreserveAspectRatio.cpp
@@ -33,16 +33,22 @@
  * 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 "nsSVGPreserveAspectRatio.h"
 #include "nsWhitespaceTokenizer.h"
+#ifdef MOZ_SMIL
+#include "nsSMILValue.h"
+#include "SMILEnumType.h"
+#endif // MOZ_SMIL
+
+using namespace mozilla;
 
 ////////////////////////////////////////////////////////////////////////
 // nsSVGPreserveAspectRatio class
 
 NS_SVG_VAL_IMPL_CYCLE_COLLECTION(
   nsSVGPreserveAspectRatio::DOMBaseVal, mSVGElement)
 NS_SVG_VAL_IMPL_CYCLE_COLLECTION(
   nsSVGPreserveAspectRatio::DOMAnimVal, mSVGElement)
@@ -153,38 +159,36 @@ nsSVGPreserveAspectRatio::ToDOMAnimVal(n
   *aResult = new DOMAnimVal(this, aSVGElement);
   if (!*aResult)
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*aResult);
   return NS_OK;
 }
 
-nsresult
-nsSVGPreserveAspectRatio::SetBaseValueString(const nsAString &aValueAsString,
-                                             nsSVGElement *aSVGElement,
-                                             PRBool aDoSetAttr)
+static nsresult
+ToPreserveAspectRatio(const nsAString &aString,
+                      nsSVGPreserveAspectRatio::PreserveAspectRatio *aValue)
 {
-  if (aValueAsString.IsEmpty() ||
-      NS_IsAsciiWhitespace(aValueAsString[0])) {
+  if (aString.IsEmpty() || NS_IsAsciiWhitespace(aString[0])) {
     return NS_ERROR_DOM_SYNTAX_ERR;
   }
 
-  nsWhitespaceTokenizer tokenizer(aValueAsString);
+  nsWhitespaceTokenizer tokenizer(aString);
   if (!tokenizer.hasMoreTokens()) {
     return NS_ERROR_DOM_SYNTAX_ERR;
   }
   const nsAString &token = tokenizer.nextToken();
 
   nsresult rv;
-  PreserveAspectRatio val;
+  nsSVGPreserveAspectRatio::PreserveAspectRatio val;
 
-  val.mDefer = token.EqualsLiteral("defer");
+  val.SetDefer(token.EqualsLiteral("defer"));
 
-  if (val.mDefer) {
+  if (val.GetDefer()) {
     if (!tokenizer.hasMoreTokens()) {
       return NS_ERROR_DOM_SYNTAX_ERR;
     }
     rv = val.SetAlign(GetAlignForString(tokenizer.nextToken()));
   } else {
     rv = val.SetAlign(GetAlignForString(token));
   }
 
@@ -193,25 +197,45 @@ nsSVGPreserveAspectRatio::SetBaseValueSt
   }
 
   if (tokenizer.hasMoreTokens()) {
     rv = val.SetMeetOrSlice(GetMeetOrSliceForString(tokenizer.nextToken()));
     if (NS_FAILED(rv)) {
       return NS_ERROR_DOM_SYNTAX_ERR;
     }
   } else {
-    val.mMeetOrSlice = nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET;
+    val.SetMeetOrSlice(nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET);
   }
 
   if (tokenizer.hasMoreTokens()) {
     return NS_ERROR_DOM_SYNTAX_ERR;
   }
 
+  *aValue = val;
+  return NS_OK;
+}
+
+nsresult
+nsSVGPreserveAspectRatio::SetBaseValueString(const nsAString &aValueAsString,
+                                             nsSVGElement *aSVGElement,
+                                             PRBool aDoSetAttr)
+{
+  PreserveAspectRatio val;
+  nsresult res = ToPreserveAspectRatio(aValueAsString, &val);
+  if (NS_FAILED(res)) {
+    return res;
+  }
+
   mAnimVal = mBaseVal = val;
   aSVGElement->DidChangePreserveAspectRatio(aDoSetAttr);
+#ifdef MOZ_SMIL
+  if (mIsAnimated) {
+    aSVGElement->AnimationNeedsResample();
+  }
+#endif
   return NS_OK;
 }
 
 void
 nsSVGPreserveAspectRatio::GetBaseValueString(nsAString & aValueAsString)
 {
   nsAutoString tmpString;
 
@@ -237,37 +261,121 @@ nsresult
 nsSVGPreserveAspectRatio::SetBaseAlign(PRUint16 aAlign,
                                        nsSVGElement *aSVGElement)
 {
   nsresult rv = mBaseVal.SetAlign(aAlign);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mAnimVal.mAlign = mBaseVal.mAlign;
   aSVGElement->DidChangePreserveAspectRatio(PR_TRUE);
-
+#ifdef MOZ_SMIL
+  if (mIsAnimated) {
+    aSVGElement->AnimationNeedsResample();
+  }
+#endif
+  
   return NS_OK;
 }
 
 nsresult
 nsSVGPreserveAspectRatio::SetBaseMeetOrSlice(PRUint16 aMeetOrSlice,
                                              nsSVGElement *aSVGElement)
 {
   nsresult rv = mBaseVal.SetMeetOrSlice(aMeetOrSlice);
   NS_ENSURE_SUCCESS(rv, rv);
 
   mAnimVal.mMeetOrSlice = mBaseVal.mMeetOrSlice;
   aSVGElement->DidChangePreserveAspectRatio(PR_TRUE);
+#ifdef MOZ_SMIL
+  if (mIsAnimated) {
+    aSVGElement->AnimationNeedsResample();
+  }
+#endif
+  
+  return NS_OK;
+}
 
-  return NS_OK;
+void
+nsSVGPreserveAspectRatio::SetAnimValue(PRUint64 aPackedValue, nsSVGElement *aSVGElement)
+{
+  mAnimVal.SetDefer(((aPackedValue & 0xff0000) >> 16) ? PR_TRUE : PR_FALSE);
+  mAnimVal.SetAlign(PRUint16((aPackedValue & 0xff00) >> 8));
+  mAnimVal.SetMeetOrSlice(PRUint16(aPackedValue & 0xff));
+  mIsAnimated = PR_TRUE;
+  aSVGElement->DidAnimatePreserveAspectRatio();
 }
 
 nsresult
 nsSVGPreserveAspectRatio::ToDOMAnimatedPreserveAspectRatio(
   nsIDOMSVGAnimatedPreserveAspectRatio **aResult,
   nsSVGElement *aSVGElement)
 {
   *aResult = new DOMAnimPAspectRatio(this, aSVGElement);
   if (!*aResult)
     return NS_ERROR_OUT_OF_MEMORY;
 
   NS_ADDREF(*aResult);
   return NS_OK;
 }
+
+#ifdef MOZ_SMIL
+nsISMILAttr*
+nsSVGPreserveAspectRatio::ToSMILAttr(nsSVGElement *aSVGElement)
+{
+  return new SMILPreserveAspectRatio(this, aSVGElement);
+}
+
+static PRUint64
+PackPreserveAspectRatio(const nsSVGPreserveAspectRatio::PreserveAspectRatio& par)
+{
+  // All preserveAspectRatio values are enum values (do not interpolate), so we
+  // can safely collate them and treat them as a single enum as for SMIL.
+  PRUint64 packed = 0;
+  packed |= PRUint64(par.GetDefer() ? 1 : 0) << 16;
+  packed |= PRUint64(par.GetAlign()) << 8;
+  packed |= PRUint64(par.GetMeetOrSlice());
+  return packed;
+}
+
+nsresult
+nsSVGPreserveAspectRatio::SMILPreserveAspectRatio
+                        ::ValueFromString(const nsAString& aStr,
+                                          const nsISMILAnimationElement* /*aSrcElement*/,
+                                          nsSMILValue& aValue) const
+{
+  PreserveAspectRatio par;
+  nsresult res = ToPreserveAspectRatio(aStr, &par);
+  NS_ENSURE_SUCCESS(res, res);
+
+  nsSMILValue val(&SMILEnumType::sSingleton);
+  val.mU.mUint = PackPreserveAspectRatio(par);
+  aValue = val;
+  return NS_OK;
+}
+
+nsSMILValue
+nsSVGPreserveAspectRatio::SMILPreserveAspectRatio::GetBaseValue() const
+{
+  nsSMILValue val(&SMILEnumType::sSingleton);
+  val.mU.mUint = PackPreserveAspectRatio(mVal->GetBaseValue());
+  return val;
+}
+
+void
+nsSVGPreserveAspectRatio::SMILPreserveAspectRatio::ClearAnimValue()
+{
+  if (mVal->mIsAnimated) {
+    mVal->SetAnimValue(PackPreserveAspectRatio(mVal->GetBaseValue()), mSVGElement);
+    mVal->mIsAnimated = PR_FALSE;
+  }
+}
+
+nsresult
+nsSVGPreserveAspectRatio::SMILPreserveAspectRatio::SetAnimValue(const nsSMILValue& aValue)
+{
+  NS_ASSERTION(aValue.mType == &SMILEnumType::sSingleton,
+               "Unexpected type to assign animated value");
+  if (aValue.mType == &SMILEnumType::sSingleton) {
+    mVal->SetAnimValue(aValue.mU.mUint, mSVGElement);
+  }
+  return NS_OK;
+}
+#endif // MOZ_SMIL
--- a/content/svg/content/src/nsSVGPreserveAspectRatio.h
+++ b/content/svg/content/src/nsSVGPreserveAspectRatio.h
@@ -90,38 +90,51 @@ public:
     PRPackedBool mDefer;
   };
 
   void Init() {
     mBaseVal.mAlign = nsIDOMSVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID;
     mBaseVal.mMeetOrSlice = nsIDOMSVGPreserveAspectRatio::SVG_MEETORSLICE_MEET;
     mBaseVal.mDefer = PR_FALSE;
     mAnimVal = mBaseVal;
+    mIsAnimated = PR_FALSE;
   }
 
   nsresult SetBaseValueString(const nsAString& aValue,
                               nsSVGElement *aSVGElement,
                               PRBool aDoSetAttr);
   void GetBaseValueString(nsAString& aValue);
 
   nsresult SetBaseAlign(PRUint16 aAlign, nsSVGElement *aSVGElement);
   nsresult SetBaseMeetOrSlice(PRUint16 aMeetOrSlice, nsSVGElement *aSVGElement);
+  void SetAnimValue(PRUint64 aPackedValue, nsSVGElement *aSVGElement);
+
   const PreserveAspectRatio &GetBaseValue() const
     { return mBaseVal; }
-  const PreserveAspectRatio &GetAnimValue() const
-    { return mAnimVal; }
+  const PreserveAspectRatio &GetAnimValue(nsSVGElement *aSVGElement) const
+  {
+#ifdef MOZ_SMIL
+    aSVGElement->FlushAnimations();
+#endif
+    return mAnimVal;
+  }
 
   nsresult ToDOMAnimatedPreserveAspectRatio(
     nsIDOMSVGAnimatedPreserveAspectRatio **aResult,
     nsSVGElement* aSVGElement);
+#ifdef MOZ_SMIL
+  // Returns a new nsISMILAttr object that the caller must delete
+  nsISMILAttr* ToSMILAttr(nsSVGElement* aSVGElement);
+#endif // MOZ_SMIL
 
 private:
 
   PreserveAspectRatio mAnimVal;
   PreserveAspectRatio mBaseVal;
+  PRPackedBool mIsAnimated;
 
   nsresult ToDOMBaseVal(nsIDOMSVGPreserveAspectRatio **aResult,
                         nsSVGElement* aSVGElement);
   nsresult ToDOMAnimVal(nsIDOMSVGPreserveAspectRatio **aResult,
                         nsSVGElement* aSVGElement);
 
   struct DOMBaseVal : public nsIDOMSVGPreserveAspectRatio
   {
@@ -152,22 +165,22 @@ private:
 
     DOMAnimVal(nsSVGPreserveAspectRatio* aVal, nsSVGElement *aSVGElement)
       : mVal(aVal), mSVGElement(aSVGElement) {}
     
     nsSVGPreserveAspectRatio* mVal; // kept alive because it belongs to mSVGElement
     nsRefPtr<nsSVGElement> mSVGElement;
     
     NS_IMETHOD GetAlign(PRUint16* aAlign)
-      { *aAlign = mVal->GetAnimValue().GetAlign(); return NS_OK; }
+      { *aAlign = mVal->GetAnimValue(mSVGElement).GetAlign(); return NS_OK; }
     NS_IMETHOD SetAlign(PRUint16 aAlign)
       { return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; }
 
     NS_IMETHOD GetMeetOrSlice(PRUint16* aMeetOrSlice)
-      { *aMeetOrSlice = mVal->GetAnimValue().GetMeetOrSlice(); return NS_OK; }
+      { *aMeetOrSlice = mVal->GetAnimValue(mSVGElement).GetMeetOrSlice(); return NS_OK; }
     NS_IMETHOD SetMeetOrSlice(PRUint16 aValue)
       { return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; }
   };
 
   struct DOMAnimPAspectRatio : public nsIDOMSVGAnimatedPreserveAspectRatio
   {
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     NS_DECL_CYCLE_COLLECTION_CLASS(DOMAnimPAspectRatio)
@@ -180,11 +193,33 @@ private:
 
     NS_IMETHOD GetBaseVal(nsIDOMSVGPreserveAspectRatio **aBaseVal)
       { return mVal->ToDOMBaseVal(aBaseVal, mSVGElement); }
 
     NS_IMETHOD GetAnimVal(nsIDOMSVGPreserveAspectRatio **aAnimVal)
       { return mVal->ToDOMAnimVal(aAnimVal, mSVGElement); }
   };
 
+#ifdef MOZ_SMIL
+  struct SMILPreserveAspectRatio : public nsISMILAttr
+  {
+  public:
+    SMILPreserveAspectRatio(nsSVGPreserveAspectRatio* aVal, nsSVGElement* aSVGElement)
+      : mVal(aVal), mSVGElement(aSVGElement) {}
+
+    // These will stay alive because a nsISMILAttr only lives as long
+    // as the Compositing step, and DOM elements don't get a chance to
+    // die during that.
+    nsSVGPreserveAspectRatio* mVal;
+    nsSVGElement* mSVGElement;
+
+    // nsISMILAttr methods
+    virtual nsresult ValueFromString(const nsAString& aStr,
+                                     const nsISMILAnimationElement* aSrcElement,
+                                     nsSMILValue& aValue) const;
+    virtual nsSMILValue GetBaseValue() const;
+    virtual void ClearAnimValue();
+    virtual nsresult SetAnimValue(const nsSMILValue& aValue);
+  };
+#endif // MOZ_SMIL
 };
 
 #endif //__NS_SVGPRESERVEASPECTRATIO_H__
--- a/content/svg/content/src/nsSVGSVGElement.cpp
+++ b/content/svg/content/src/nsSVGSVGElement.cpp
@@ -995,17 +995,18 @@ nsSVGSVGElement::GetViewBoxTransform()
     viewBox.width  = viewportWidth;
     viewBox.height = viewportHeight;
   }
 
   if (viewBox.width <= 0.0f || viewBox.height <= 0.0f) {
     return gfxMatrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // singular
   }
 
-  return nsSVGUtils::GetViewBoxTransform(viewportWidth, viewportHeight,
+  return nsSVGUtils::GetViewBoxTransform(this,
+                                         viewportWidth, viewportHeight,
                                          viewBox.x, viewBox.y,
                                          viewBox.width, viewBox.height,
                                          mPreserveAspectRatio);
 }
 
 #ifdef MOZ_SMIL
 nsresult
 nsSVGSVGElement::BindToTree(nsIDocument* aDocument,
@@ -1220,13 +1221,21 @@ nsSVGSVGElement::GetViewBox()
 void
 nsSVGSVGElement::DidChangePreserveAspectRatio(PRBool aDoSetAttr)
 {
   nsSVGSVGElementBase::DidChangePreserveAspectRatio(aDoSetAttr);
 
   InvalidateTransformNotifyFrame();
 }
 
+void
+nsSVGSVGElement::DidAnimatePreserveAspectRatio()
+{
+  nsSVGSVGElementBase::DidAnimatePreserveAspectRatio();
+
+  InvalidateTransformNotifyFrame();
+}
+
 nsSVGPreserveAspectRatio *
 nsSVGSVGElement::GetPreserveAspectRatio()
 {
   return &mPreserveAspectRatio;
 }
--- a/content/svg/content/src/nsSVGSVGElement.h
+++ b/content/svg/content/src/nsSVGSVGElement.h
@@ -192,16 +192,18 @@ public:
 
   // nsSVGElement specializations:
   virtual gfxMatrix PrependLocalTransformTo(const gfxMatrix &aMatrix);
   virtual void DidChangeLength(PRUint8 aAttrEnum, PRBool aDoSetAttr);
   virtual void DidChangeEnum(PRUint8 aAttrEnum, PRBool aDoSetAttr);
   virtual void DidChangeViewBox(PRBool aDoSetAttr);
   virtual void DidChangePreserveAspectRatio(PRBool aDoSetAttr);
 
+  virtual void DidAnimatePreserveAspectRatio();
+  
   // nsSVGSVGElement methods:
   float GetLength(PRUint8 mCtxType);
   float GetMMPerPx(PRUint8 mCtxType = 0);
 
   // public helpers:
   gfxMatrix GetViewBoxTransform();
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
--- a/content/xbl/src/nsXBLProtoImplField.cpp
+++ b/content/xbl/src/nsXBLProtoImplField.cpp
@@ -54,17 +54,17 @@ nsXBLProtoImplField::nsXBLProtoImplField
     mFieldTextLength(0),
     mLineNumber(0)
 {
   MOZ_COUNT_CTOR(nsXBLProtoImplField);
   mName = NS_strdup(aName);  // XXXbz make more sense to use a stringbuffer?
   
   mJSAttributes = JSPROP_ENUMERATE;
   if (aReadOnly) {
-    nsAutoString readOnly; readOnly.Assign(*aReadOnly);
+    nsAutoString readOnly; readOnly.Assign(aReadOnly);
     if (readOnly.LowerCaseEqualsLiteral("true"))
       mJSAttributes |= JSPROP_READONLY;
   }
 }
 
 nsXBLProtoImplField::~nsXBLProtoImplField()
 {