Merge. manually merged. modules/plugin/test/testplugin/nptest.cpp, testing/xpcshell/head.js.
authorDoug Turner <dougt@dougt.org>
Wed, 10 Mar 2010 19:13:35 -0800
changeset 46712 eef101881cce4afc54a89aeeddeb67fb8aa3d81c
parent 46711 faf9ae9323b389b69884689e8f84806c4b640c28 (current diff)
parent 39241 5295a7cfd05c8e8f461c9ef86d88014b6b808011 (diff)
child 46713 6c553cbfd7caff0a19a9e3e59d9b9e2eb8ca5573
push idunknown
push userunknown
push dateunknown
milestone1.9.3a3pre
Merge. manually merged. modules/plugin/test/testplugin/nptest.cpp, testing/xpcshell/head.js.
browser/app/profile/firefox.js
build/automation.py.in
build/devicemanager.py
content/base/src/nsGkAtomList.h
content/html/content/reftests/href-attr-removal-restyles-ref.html
content/html/content/reftests/href-attr-removal-restyles.html
dom/base/nsGlobalWindow.cpp
embedding/components/ui/Makefile.in
embedding/components/ui/helperAppDlg/Makefile.in
embedding/components/ui/helperAppDlg/nsHelperAppDlg.js
embedding/components/ui/helperAppDlg/nsHelperAppDlg.xul
embedding/components/ui/jar.mn
embedding/components/ui/progressDlg/Makefile.in
embedding/components/ui/progressDlg/nsProgressDialog.js
embedding/components/ui/progressDlg/nsProgressDialog.xul
gfx/thebes/public/gfxCoreTextFonts.h
gfx/thebes/src/gfxCoreTextFonts.cpp
layout/reftests/svg/href-attr-removal-restyles-ref.svg
layout/reftests/svg/href-attr-removal-restyles.svg
modules/plugin/base/src/nsPluginHost.cpp
modules/plugin/test/mochitest/Makefile.in
modules/plugin/test/testplugin/nptest.cpp
modules/plugin/test/testplugin/nptest.h
netwerk/protocol/http/src/nsHttpHandler.cpp
netwerk/test/Makefile.in
parser/htmlparser/tests/mochitest/regressions.txt
testing/xpcshell/head.js
testing/xpcshell/runxpcshelltests.py
toolkit/locales/en-US/chrome/global/nsHelperAppDlg.dtd
toolkit/locales/en-US/chrome/global/nsHelperAppDlg.properties
toolkit/locales/en-US/chrome/global/nsProgressDialog.dtd
toolkit/locales/en-US/chrome/global/nsProgressDialog.properties
widget/src/qt/nsWindow.cpp
widget/src/windows/nsWindow.cpp
widget/src/windows/nsWindowGfx.cpp
xpcom/tests/TestPermanentAtoms.cpp
--- a/Makefile.in
+++ b/Makefile.in
@@ -80,16 +80,21 @@ include $(topsrcdir)/config/config.mk
 
 GARBAGE_DIRS += dist _javagen _profile _tests staticlib
 DIST_GARBAGE = config.cache config.log config.status config-defs.h \
    dependencies.beos config/autoconf.mk \
    unallmakefiles mozilla-config.h \
    netwerk/necko-config.h xpcom/xpcom-config.h xpcom/xpcom-private.h \
    $(topsrcdir)/.mozconfig.mk $(topsrcdir)/.mozconfig.out
 
+ifdef WINCE
+check::
+	$(PYTHON) $(topsrcdir)/build/mobile/devicemanager-utils.py copy $(DIST)/bin
+endif
+
 default alldep all:: $(topsrcdir)/configure config.status
 	$(RM) -rf $(DIST)/sdk
 	$(RM) -rf $(DIST)/include
 	$(RM) -rf $(DIST)/private
 	$(RM) -rf $(DIST)/public
 	$(RM) -rf $(DIST)/bin/components
 	$(RM) -rf _tests
 
new file mode 100644
--- /dev/null
+++ b/accessible/src/base/nsAccCache.h
@@ -0,0 +1,108 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla 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 ***** */
+
+#ifndef _nsAccCache_H_
+#define _nsAccCache_H_
+
+#include "nsRefPtrHashtable.h"
+#include "nsCycleCollectionParticipant.h"
+
+class nsAccessNode;
+class nsAccessible;
+class nsIAccessNode;
+
+typedef nsRefPtrHashtable<nsVoidPtrHashKey, nsAccessNode>
+  nsAccessNodeHashtable;
+
+typedef nsRefPtrHashtable<nsVoidPtrHashKey, nsAccessible>
+  nsAccessibleHashtable;
+
+/**
+ * Shutdown and removes the accessible from cache.
+ */
+template <class T>
+static PLDHashOperator
+ClearCacheEntry(const void* aKey, nsRefPtr<T>& aAccessNode, void* aUserArg)
+{
+  NS_ASSERTION(aAccessNode, "Calling ClearCacheEntry with a NULL pointer!");
+  if (aAccessNode)
+    aAccessNode->Shutdown();
+
+  return PL_DHASH_REMOVE;
+}
+
+/**
+ * Clear the cache and shutdown the accessibles.
+ */
+template <class T>
+static void
+ClearCache(nsRefPtrHashtable<nsVoidPtrHashKey, T> & aCache)
+{
+  aCache.Enumerate(ClearCacheEntry<T>, nsnull);
+}
+
+/**
+ * Traverse the accessible cache entry for cycle collector.
+ */
+template <class T>
+static PLDHashOperator
+CycleCollectorTraverseCacheEntry(const void *aKey, T *aAccessNode,
+                                 void *aUserArg)
+{
+  nsCycleCollectionTraversalCallback *cb =
+    static_cast<nsCycleCollectionTraversalCallback*>(aUserArg);
+
+  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "accessible cache entry");
+
+  nsISupports *supports = static_cast<nsIAccessNode*>(aAccessNode);
+  cb->NoteXPCOMChild(supports);
+  return PL_DHASH_NEXT;
+}
+
+/**
+ * Traverse the accessible cache for cycle collector.
+ */
+template <class T>
+static void
+CycleCollectorTraverseCache(nsRefPtrHashtable<nsVoidPtrHashKey, T> & aCache,
+                            nsCycleCollectionTraversalCallback *aCallback)
+{
+  aCache.EnumerateRead(CycleCollectorTraverseCacheEntry<T>, aCallback);
+}
+
+#endif
--- a/accessible/src/base/nsAccEvent.cpp
+++ b/accessible/src/base/nsAccEvent.cpp
@@ -208,17 +208,17 @@ nsAccEvent::GetAccessibleByNode()
 
     if (multiSelect) {
       PRInt32 treeIndex = -1;
       multiSelect->GetCurrentIndex(&treeIndex);
       if (treeIndex >= 0) {
         nsRefPtr<nsXULTreeAccessible> treeAcc =
           nsAccUtils::QueryAccessibleTree(accessible);
         if (treeAcc)
-          treeAcc->GetTreeItemAccessible(treeIndex, getter_AddRefs(accessible));
+          accessible = treeAcc->GetTreeItemAccessible(treeIndex);
       }
     }
   }
 #endif
 
   return accessible.forget();
 }
 
--- a/accessible/src/base/nsAccessNode.cpp
+++ b/accessible/src/base/nsAccessNode.cpp
@@ -703,34 +703,16 @@ nsAccessNode::GetDocAccessibleFor(nsIDOM
   nsCOMPtr<nsIDocument> doc(do_QueryInterface(aNode));
   if (doc) {
     return GetDocAccessibleFor(doc);
   }
 
   return nsnull;
 }
 
-// Callback used when clearing the cache, see nsAccessNode::ClearCache() method.
-static PLDHashOperator
-ClearCacheEntry(const void* aKey, nsCOMPtr<nsAccessNode>& aAccessNode,
-                void* aUserArg)
-{
-  NS_ASSERTION(aAccessNode, "Calling ClearCacheEntry with a NULL pointer!");
-  if (aAccessNode)
-    aAccessNode->Shutdown();
-
-  return PL_DHASH_REMOVE;
-}
-
-void
-nsAccessNode::ClearCache(nsAccessNodeHashtable& aCache)
-{
-  aCache.Enumerate(ClearCacheEntry, nsnull);
-}
-
 already_AddRefed<nsIDOMNode> nsAccessNode::GetCurrentFocus()
 {
   nsCOMPtr<nsIPresShell> shell = nsCoreUtils::GetPresShellFor(mDOMNode);
   NS_ENSURE_TRUE(shell, nsnull);
   nsCOMPtr<nsIDocument> doc = shell->GetDocument();
   NS_ENSURE_TRUE(doc, nsnull);
 
   nsIDOMWindow* win = doc->GetWindow();
--- a/accessible/src/base/nsAccessNode.h
+++ b/accessible/src/base/nsAccessNode.h
@@ -38,46 +38,42 @@
 
 /* For documentation of the accessibility architecture, 
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
 #ifndef _nsAccessNode_H_
 #define _nsAccessNode_H_
 
-#include "nsCOMPtr.h"
+#include "nsAccCache.h"
 #include "nsAccessibilityAtoms.h"
 #include "nsCoreUtils.h"
 #include "nsAccUtils.h"
 
 #include "nsIAccessibleTypes.h"
 #include "nsIAccessNode.h"
 #include "nsIContent.h"
 #include "nsIDOMNode.h"
 #include "nsINameSpaceManager.h"
 #include "nsIStringBundle.h"
 #include "nsWeakReference.h"
-#include "nsInterfaceHashtable.h"
 #include "nsAccessibilityService.h"
 
 class nsIPresShell;
 class nsPresContext;
 class nsIAccessibleDocument;
 class nsIFrame;
 class nsIDOMNodeList;
 class nsRootAccessible;
 class nsApplicationAccessibleWrap;
 class nsIDocShellTreeItem;
 
 #define ACCESSIBLE_BUNDLE_URL "chrome://global-platform/locale/accessible.properties"
 #define PLATFORM_KEYS_BUNDLE_URL "chrome://global-platform/locale/platformKeys.properties"
 
-typedef nsInterfaceHashtable<nsVoidPtrHashKey, nsAccessNode>
-        nsAccessNodeHashtable;
-
 // What we want is: NS_INTERFACE_MAP_ENTRY(self) for static IID accessors,
 // but some of our classes have an ambiguous base class of nsISupports which
 // prevents this from working (the default macro converts it to nsISupports,
 // then addrefs it, then returns it). Therefore, we expand the macro here and
 // change it so that it works. Yuck.
 #define NS_INTERFACE_MAP_STATIC_AMBIGUOUS(_class) \
   if (aIID.Equals(NS_GET_IID(_class))) { \
   NS_ADDREF(this); \
@@ -122,21 +118,16 @@ class nsAccessNode: public nsIAccessNode
     static void InitXPAccessibility();
     static void ShutdownXPAccessibility();
 
     /**
      * Return an application accessible.
      */
     static already_AddRefed<nsApplicationAccessibleWrap> GetApplicationAccessible();
 
-  /**
-   * Clear the cache and shutdown the access nodes.
-   */
-  static void ClearCache(nsAccessNodeHashtable& aCache);
-
     // Static cache methods for global document cache
     static already_AddRefed<nsIAccessibleDocument> GetDocAccessibleFor(nsIDocument *aDocument);
     static already_AddRefed<nsIAccessibleDocument> GetDocAccessibleFor(nsIWeakReference *aWeakShell);
     static already_AddRefed<nsIAccessibleDocument> GetDocAccessibleFor(nsIDocShellTreeItem *aContainer, PRBool aCanCreate = PR_FALSE);
     static already_AddRefed<nsIAccessibleDocument> GetDocAccessibleFor(nsIDOMNode *aNode);
 
     already_AddRefed<nsRootAccessible> GetRootAccessible();
 
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -2995,30 +2995,25 @@ nsAccessible::CacheChildren()
     child->SetParent(this);
   }
 }
 
 void
 nsAccessible::TestChildCache(nsAccessible *aCachedChild)
 {
 #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 initialized!");
+    NS_ASSERTION(!mAreChildrenInitialized, "No children but initialized!");
     return;
   }
 
-  nsAccessible *child;
+  nsAccessible *child = nsnull;
   for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
-    child = GetChildAt(childIdx);
+    child = mChildren[childIdx];
     if (child == aCachedChild)
       break;
   }
 
   NS_ASSERTION(child == aCachedChild,
                "[TestChildCache] cached accessible wasn't found. Wrong accessible tree!");  
 #endif
 }
@@ -3035,17 +3030,17 @@ nsAccessible::EnsureChildren()
     return PR_FALSE;
 
   mAreChildrenInitialized = PR_TRUE; // Prevent reentry
   CacheChildren();
 
   return PR_FALSE;
 }
 
-nsIAccessible*
+nsAccessible*
 nsAccessible::GetSiblingAtOffset(PRInt32 aOffset, nsresult* aError)
 {
   if (IsDefunct()) {
     if (aError)
       *aError = NS_ERROR_FAILURE;
 
     return nsnull;
   }
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -297,17 +297,18 @@ 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.
+   * Assert if child not in parent's cache if the cache was initialized at this
+   * point.
    */
   void TestChildCache(nsAccessible *aCachedChild);
 
 protected:
 
   //////////////////////////////////////////////////////////////////////////////
   // Initializing, cache and tree traverse methods
 
@@ -319,18 +320,18 @@ protected:
   /**
    * 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,
-                                            nsresult* aError = nsnull);
+  virtual nsAccessible* GetSiblingAtOffset(PRInt32 aOffset,
+                                           nsresult *aError = nsnull);
 
   //////////////////////////////////////////////////////////////////////////////
   // Miscellaneous helpers
 
   virtual nsIFrame* GetBoundsFrame();
   virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
   PRBool IsVisible(PRBool *aIsOffscreen); 
 
--- a/accessible/src/base/nsApplicationAccessible.cpp
+++ b/accessible/src/base/nsApplicationAccessible.cpp
@@ -178,17 +178,17 @@ nsApplicationAccessible::InvalidateChild
 
 void
 nsApplicationAccessible::CacheChildren()
 {
   // Nothing to do. Children are keeped up to dated by Add/RemoveRootAccessible
   // method calls.
 }
 
-nsIAccessible*
+nsAccessible*
 nsApplicationAccessible::GetSiblingAtOffset(PRInt32 aOffset, nsresult* aError)
 {
   if (IsDefunct()) {
     if (aError)
       *aError = NS_ERROR_FAILURE;
 
     return nsnull;
   }
--- a/accessible/src/base/nsApplicationAccessible.h
+++ b/accessible/src/base/nsApplicationAccessible.h
@@ -86,14 +86,14 @@ public:
   // nsApplicationAccessible
   virtual nsresult AddRootAccessible(nsIAccessible *aRootAccWrap);
   virtual nsresult RemoveRootAccessible(nsIAccessible *aRootAccWrap);
 
 protected:
 
   // nsAccessible
   virtual void CacheChildren();
-  virtual nsIAccessible* GetSiblingAtOffset(PRInt32 aOffset,
-                                            nsresult *aError = nsnull);
+  virtual nsAccessible* GetSiblingAtOffset(PRInt32 aOffset,
+                                           nsresult *aError = nsnull);
 };
 
 #endif
 
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -130,40 +130,28 @@ nsDocAccessible::nsDocAccessible(nsIDOMN
 nsDocAccessible::~nsDocAccessible()
 {
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsISupports
 
-// Callback used when traversing the cache by cycle collector.
-static PLDHashOperator
-ElementTraverser(const void *aKey, nsAccessNode *aAccessNode, void *aUserArg)
-{
-  nsCycleCollectionTraversalCallback *cb = 
-    static_cast<nsCycleCollectionTraversalCallback*>(aUserArg);
-
-  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mAccessNodeCache entry");
-  cb->NoteXPCOMChild(aAccessNode);
-  return PL_DHASH_NEXT;
-}
-
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDocAccessible)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDocAccessible, nsAccessible)
   NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mEventQueue");
   cb.NoteXPCOMChild(tmp->mEventQueue.get());
 
-  tmp->mAccessNodeCache.EnumerateRead(ElementTraverser, &cb);
+  CycleCollectorTraverseCache(tmp->mAccessNodeCache, &cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDocAccessible, nsAccessible)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mEventQueue)
-  tmp->ClearCache(tmp->mAccessNodeCache);
+  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(nsISupportsWeakReference)
--- a/accessible/src/base/nsRootAccessible.cpp
+++ b/accessible/src/base/nsRootAccessible.cpp
@@ -720,18 +720,17 @@ nsresult nsRootAccessible::HandleEventWi
       do_QueryInterface(aTargetNode);
     if (multiSelect) {
       PRInt32 treeIndex = -1;
       multiSelect->GetCurrentIndex(&treeIndex);
       if (treeIndex >= 0) {
         nsRefPtr<nsXULTreeAccessible> treeAcc =
           nsAccUtils::QueryAccessibleTree(accessible);
         if (treeAcc) {
-          treeAcc->GetTreeItemAccessible(treeIndex,
-                                         getter_AddRefs(treeItemAccessible));
+          treeItemAccessible = treeAcc->GetTreeItemAccessible(treeIndex);
           if (treeItemAccessible)
             accessible = treeItemAccessible;
         }
       }
     }
   }
 #endif
 
--- a/accessible/src/xul/nsXULTreeAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeAccessible.cpp
@@ -43,62 +43,45 @@
 #include "nsIDOMXULElement.h"
 #include "nsIDOMXULMultSelectCntrlEl.h"
 #include "nsIDOMXULTreeElement.h"
 #include "nsITreeSelection.h"
 #include "nsIMutableArray.h"
 #include "nsComponentManagerUtils.h"
 
 ////////////////////////////////////////////////////////////////////////////////
-// Internal static functions
-////////////////////////////////////////////////////////////////////////////////
-
-// Callback used when traversing the cache by cycle collector.
-static PLDHashOperator
-ElementTraverser(const void *aKey, nsAccessNode *aAccessNode, void *aUserArg)
-{
-  nsCycleCollectionTraversalCallback *cb = 
-    static_cast<nsCycleCollectionTraversalCallback*>(aUserArg);
-
-  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mAccessNodeCache of XUL tree entry");
-  cb->NoteXPCOMChild(aAccessNode);
-  return PL_DHASH_NEXT;
-}
-
-
-////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsXULTreeAccessible::
   nsXULTreeAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell) :
   nsXULSelectableAccessible(aDOMNode, aShell)
 {
   nsCoreUtils::GetTreeBoxObject(aDOMNode, getter_AddRefs(mTree));
   if (mTree)
     mTree->GetView(getter_AddRefs(mTreeView));
 
   NS_ASSERTION(mTree && mTreeView, "Can't get mTree or mTreeView!\n");
 
-  mAccessNodeCache.Init(kDefaultTreeCacheSize);
+  mAccessibleCache.Init(kDefaultTreeCacheSize);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeAccessible: nsISupports and cycle collection implementation
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULTreeAccessible)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXULTreeAccessible,
                                                   nsAccessible)
-tmp->mAccessNodeCache.EnumerateRead(ElementTraverser, &cb);
+CycleCollectorTraverseCache(tmp->mAccessibleCache, &cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXULTreeAccessible,
                                                 nsAccessible)
-tmp->ClearCache(tmp->mAccessNodeCache);
+ClearCache(tmp->mAccessibleCache);
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXULTreeAccessible)
 NS_INTERFACE_MAP_STATIC_AMBIGUOUS(nsXULTreeAccessible)
 NS_INTERFACE_MAP_END_INHERITING(nsXULSelectableAccessible)
 
 NS_IMPL_ADDREF_INHERITED(nsXULTreeAccessible, nsXULSelectableAccessible)
 NS_IMPL_RELEASE_INHERITED(nsXULTreeAccessible, nsXULSelectableAccessible)
@@ -178,17 +161,17 @@ nsXULTreeAccessible::IsDefunct()
 
 nsresult
 nsXULTreeAccessible::Shutdown()
 {
   // XXX: we don't remove accessible from document cache if shutdown wasn't
   // initiated by document destroying. Note, we can't remove accessible from
   // document cache here while document is going to be shutdown. Note, this is
   // not unique place where we have similar problem.
-  ClearCache(mAccessNodeCache);
+  ClearCache(mAccessibleCache);
 
   mTree = nsnull;
   mTreeView = nsnull;
 
   nsXULSelectableAccessible::Shutdown();
   return NS_OK;
 }
 
@@ -233,17 +216,17 @@ nsXULTreeAccessible::GetFocusedChild(nsI
     return NS_OK;
 
   nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelect =
     do_QueryInterface(mDOMNode);
   if (multiSelect) {
     PRInt32 row = -1;
     multiSelect->GetCurrentIndex(&row);
     if (row >= 0)
-      GetTreeItemAccessible(row, aFocusedChild);
+      NS_IF_ADDREF(*aFocusedChild = GetTreeItemAccessible(row));
   }
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeAccessible: nsAccessible implementation (DON'T put methods here)
 
@@ -274,28 +257,28 @@ nsXULTreeAccessible::GetChildAtPoint(PRI
                    childEltUnused);
 
   // If we failed to find tree cell for the given point then it might be
   // tree columns.
   if (row == -1 || !column)
     return nsXULSelectableAccessible::
       GetChildAtPoint(aX, aY, aDeepestChild, aChild);
 
-  GetTreeItemAccessible(row, aChild);
-  if (aDeepestChild && *aChild) {
+  nsAccessible *child = GetTreeItemAccessible(row);
+  if (aDeepestChild && child) {
     // Look for accessible cell for the found item accessible.
-    nsRefPtr<nsXULTreeItemAccessibleBase> treeitemAcc =
-      nsAccUtils::QueryObject<nsXULTreeItemAccessibleBase>(*aChild);
+    nsRefPtr<nsXULTreeItemAccessibleBase> treeitem =
+      nsAccUtils::QueryObject<nsXULTreeItemAccessibleBase>(child);
 
-    nsCOMPtr<nsIAccessible> cellAccessible;
-    treeitemAcc->GetCellAccessible(column, getter_AddRefs(cellAccessible));
-    if (cellAccessible)
-      cellAccessible.swap(*aChild);
+    nsAccessible *cell = treeitem->GetCellAccessible(column);
+    if (cell)
+      child = cell;
   }
 
+  NS_IF_ADDREF(*aChild = child);
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeAccessible: nsAccessibleSelectable implementation
 
 NS_IMETHODIMP nsXULTreeAccessible::GetSelectedChildren(nsIArray **_retval)
 {
@@ -314,21 +297,20 @@ NS_IMETHODIMP nsXULTreeAccessible::GetSe
   NS_ENSURE_STATE(selectedAccessibles);
 
   PRInt32 rowIndex, rowCount;
   PRBool isSelected;
   mTreeView->GetRowCount(&rowCount);
   for (rowIndex = 0; rowIndex < rowCount; rowIndex++) {
     selection->IsSelected(rowIndex, &isSelected);
     if (isSelected) {
-      nsCOMPtr<nsIAccessible> tempAccess;
-      GetTreeItemAccessible(rowIndex, getter_AddRefs(tempAccess));
-      NS_ENSURE_STATE(tempAccess);
+      nsIAccessible *tempAccessible = GetTreeItemAccessible(rowIndex);
+      NS_ENSURE_STATE(tempAccessible);
 
-      selectedAccessibles->AppendElement(tempAccess, PR_FALSE);
+      selectedAccessibles->AppendElement(tempAccessible, PR_FALSE);
     }
   }
 
   PRUint32 length;
   selectedAccessibles->GetLength(&length);
   if (length != 0) {
     *_retval = selectedAccessibles;
     NS_IF_ADDREF(*_retval);
@@ -416,17 +398,17 @@ nsXULTreeAccessible::RefSelection(PRInt3
   PRInt32 rowIndex, rowCount;
   PRInt32 selCount = 0;
   PRBool isSelected;
   mTreeView->GetRowCount(&rowCount);
   for (rowIndex = 0; rowIndex < rowCount; rowIndex++) {
     selection->IsSelected(rowIndex, &isSelected);
     if (isSelected) {
       if (selCount == aIndex) {
-        GetTreeItemAccessible(rowIndex, aAccessible);
+        NS_IF_ADDREF(*aAccessible = GetTreeItemAccessible(rowIndex));
         return NS_OK;
       }
       selCount++;
     }
   }
 
   return NS_OK;
 }
@@ -466,22 +448,17 @@ nsXULTreeAccessible::GetChildAt(PRUint32
 {
   PRInt32 childCount = nsAccessible::GetChildCount();
   if (childCount == -1)
     return nsnull;
 
   if (static_cast<PRInt32>(aIndex) < childCount)
     return nsAccessible::GetChildAt(aIndex);
 
-  nsCOMPtr<nsIAccessible> child;
-  GetTreeItemAccessible(aIndex - childCount, getter_AddRefs(child));
-
-  nsRefPtr<nsAccessible> childAcc =
-    nsAccUtils::QueryObject<nsAccessible>(child);
-  return childAcc;
+  return GetTreeItemAccessible(aIndex - childCount);
 }
 
 PRInt32
 nsXULTreeAccessible::GetChildCount()
 {
   // tree's children count is row count + treecols count.
   PRInt32 childCount = nsAccessible::GetChildCount();
   if (childCount == -1)
@@ -509,113 +486,110 @@ nsXULTreeAccessible::GetIndexOf(nsIAcces
 
   return nsAccessible::GetChildCount() + item->GetRowIndex();
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeAccessible: public implementation
 
-void
-nsXULTreeAccessible::GetTreeItemAccessible(PRInt32 aRow,
-                                           nsIAccessible** aAccessible)
+nsAccessible*
+nsXULTreeAccessible::GetTreeItemAccessible(PRInt32 aRow)
 {
-  *aAccessible = nsnull;
-
   if (aRow < 0 || IsDefunct())
-    return;
+    return nsnull;
 
   PRInt32 rowCount = 0;
   nsresult rv = mTreeView->GetRowCount(&rowCount);
   if (NS_FAILED(rv) || aRow >= rowCount)
-    return;
+    return nsnull;
 
   void *key = reinterpret_cast<void*>(aRow);
-  nsRefPtr<nsAccessNode> accessNode = mAccessNodeCache.GetWeak(key);
+  nsRefPtr<nsAccessible> accessible = mAccessibleCache.GetWeak(key);
+
+  if (!accessible) {
+    accessible = CreateTreeItemAccessible(aRow);
+    if (!accessible)
+      return nsnull;
 
-  if (!accessNode) {
-    CreateTreeItemAccessible(aRow, getter_AddRefs(accessNode));
-    if (!accessNode)
-      return;
+    nsresult rv = accessible->Init();
+    if (NS_FAILED(rv)) {
+      accessible->Shutdown();
+      return nsnull;
+    }
 
-    nsresult rv = accessNode->Init();
-    if (NS_FAILED(rv))
-      return;
-
-    mAccessNodeCache.Put(key, accessNode);
+    if (!mAccessibleCache.Put(key, accessible))
+      return nsnull;
   }
 
-  CallQueryInterface(accessNode.get(), aAccessible);
+  return accessible;
 }
 
 void
 nsXULTreeAccessible::InvalidateCache(PRInt32 aRow, PRInt32 aCount)
 {
   if (IsDefunct())
     return;
 
   // Do not invalidate the cache if rows have been inserted.
   if (aCount > 0)
     return;
 
   // Fire destroy event for removed tree items and delete them from caches.
   for (PRInt32 rowIdx = aRow; rowIdx < aRow - aCount; rowIdx++) {
 
     void* key = reinterpret_cast<void*>(rowIdx);
-    nsAccessNode* accessNode = mAccessNodeCache.GetWeak(key);
+    nsAccessible *accessible = mAccessibleCache.GetWeak(key);
 
-    if (accessNode) {
-      nsRefPtr<nsAccessible> accessible =
-        nsAccUtils::QueryAccessible(accessNode);
-
+    if (accessible) {
       nsRefPtr<nsAccEvent> event =
         new nsAccEvent(nsIAccessibleEvent::EVENT_HIDE, accessible, PR_FALSE);
       nsEventShell::FireEvent(event);
 
       accessible->Shutdown();
 
       // Remove accessible from document cache and tree cache.
       nsCOMPtr<nsIAccessibleDocument> docAccessible = GetDocAccessible();
       if (docAccessible) { 
         nsRefPtr<nsDocAccessible> docAcc =
           nsAccUtils::QueryAccessibleDocument(docAccessible);
         docAcc->RemoveAccessNodeFromCache(accessible);
       }
 
-      mAccessNodeCache.Remove(key);
+      mAccessibleCache.Remove(key);
     }
   }
 
   // We dealt with removed tree items already however we may keep tree items
   // having row indexes greater than row count. We should remove these dead tree
   // items silently from caches.
   PRInt32 newRowCount = 0;
   nsresult rv = mTreeView->GetRowCount(&newRowCount);
   if (NS_FAILED(rv))
     return;
 
   PRInt32 oldRowCount = newRowCount - aCount;
 
   for (PRInt32 rowIdx = newRowCount; rowIdx < oldRowCount; ++rowIdx) {
 
     void *key = reinterpret_cast<void*>(rowIdx);
-    nsAccessNode* accessNode = mAccessNodeCache.GetWeak(key);
+    nsAccessible *accessible = mAccessibleCache.GetWeak(key);
 
-    if (accessNode) {
-      accessNode->Shutdown();
+    if (accessible) {
+      accessible->Shutdown();
 
       // Remove accessible from document cache and tree cache.
       nsCOMPtr<nsIAccessibleDocument> docAccessible = GetDocAccessible();
       if (docAccessible) {
         nsRefPtr<nsDocAccessible> docAcc =
           nsAccUtils::QueryAccessibleDocument(docAccessible);
-        docAcc->RemoveAccessNodeFromCache(accessNode);
+        docAcc->RemoveAccessNodeFromCache(accessible);
       }
 
-      mAccessNodeCache.Remove(key);
+      mAccessibleCache.Remove(key);
     }
   }
 }
 
 void
 nsXULTreeAccessible::TreeViewInvalidated(PRInt32 aStartRow, PRInt32 aEndRow,
                                          PRInt32 aStartCol, PRInt32 aEndCol)
 {
@@ -648,21 +622,21 @@ nsXULTreeAccessible::TreeViewInvalidated
       return;
 
     endCol = colCount - 1;
   }
 
   for (PRInt32 rowIdx = aStartRow; rowIdx <= endRow; ++rowIdx) {
 
     void *key = reinterpret_cast<void*>(rowIdx);
-    nsAccessNode* accessNode = mAccessNodeCache.GetWeak(key);
+    nsAccessible *accessible = mAccessibleCache.GetWeak(key);
 
-    if (accessNode) {
+    if (accessible) {
       nsRefPtr<nsXULTreeItemAccessibleBase> treeitemAcc =
-        nsAccUtils::QueryObject<nsXULTreeItemAccessibleBase>(accessNode);
+        nsAccUtils::QueryObject<nsXULTreeItemAccessibleBase>(accessible);
       NS_ASSERTION(treeitemAcc, "Wrong accessible at the given key!");
 
       treeitemAcc->RowInvalidated(aStartCol, endCol);
     }
   }
 }
 
 void
@@ -676,38 +650,39 @@ nsXULTreeAccessible::TreeViewChanged()
   // in cache.
   nsRefPtr<nsAccEvent> eventDestroy =
     new nsAccEvent(nsIAccessibleEvent::EVENT_HIDE, this, PR_FALSE);
   if (!eventDestroy)
     return;
 
   FirePlatformEvent(eventDestroy);
 
-  ClearCache(mAccessNodeCache);
+  ClearCache(mAccessibleCache);
 
   mTree->GetView(getter_AddRefs(mTreeView));
 
   nsRefPtr<nsAccEvent> eventCreate =
     new nsAccEvent(nsIAccessibleEvent::EVENT_SHOW, this, PR_FALSE);
   if (!eventCreate)
     return;
 
   FirePlatformEvent(eventCreate);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeAccessible: protected implementation
 
-void
-nsXULTreeAccessible::CreateTreeItemAccessible(PRInt32 aRow,
-                                              nsAccessNode** aAccessNode)
+already_AddRefed<nsAccessible>
+nsXULTreeAccessible::CreateTreeItemAccessible(PRInt32 aRow)
 {
-  *aAccessNode = new nsXULTreeItemAccessible(mDOMNode, mWeakShell, this,
-                                             mTree, mTreeView, aRow);
-  NS_IF_ADDREF(*aAccessNode);
+  nsRefPtr<nsAccessible> accessible =
+    new nsXULTreeItemAccessible(mDOMNode, mWeakShell, this, mTree, mTreeView,
+                                aRow);
+
+  return accessible.forget();
 }
                              
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeItemAccessibleBase
 ////////////////////////////////////////////////////////////////////////////////
 
 nsXULTreeItemAccessibleBase::
   nsXULTreeItemAccessibleBase(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
@@ -860,18 +835,17 @@ nsXULTreeItemAccessibleBase::GetRelation
     PRInt32 parentIndex;
     if (NS_SUCCEEDED(mTreeView->GetParentIndex(mRow, &parentIndex))) {
       if (parentIndex == -1)
         return nsRelUtils::AddTarget(aRelationType, aRelation, mParent);
 
       nsRefPtr<nsXULTreeAccessible> treeAcc =
         nsAccUtils::QueryAccessibleTree(mParent);
 
-      nsCOMPtr<nsIAccessible> logicalParent;
-      treeAcc->GetTreeItemAccessible(parentIndex, getter_AddRefs(logicalParent));
+      nsAccessible *logicalParent = treeAcc->GetTreeItemAccessible(parentIndex);
       return nsRelUtils::AddTarget(aRelationType, aRelation, logicalParent);
     }
 
     return NS_OK;
   }
 
   return nsAccessible::GetRelationByType(aRelationType, aRelation);
 }
@@ -1110,17 +1084,17 @@ nsXULTreeItemAccessibleBase::DispatchCli
     columns->GetPrimaryColumn(getter_AddRefs(column));
     pseudoElm = NS_LITERAL_CSTRING("twisty");
   }
 
   if (column)
     nsCoreUtils::DispatchClickEvent(mTree, mRow, column, pseudoElm);
 }
 
-nsIAccessible*
+nsAccessible*
 nsXULTreeItemAccessibleBase::GetSiblingAtOffset(PRInt32 aOffset,
                                                 nsresult* aError)
 {
   if (mRow + aOffset < 0)
     return nsAccessible::GetSiblingAtOffset(mRow + aOffset, aError);
 
   if (IsDefunct()) {
     if (aError)
@@ -1137,19 +1111,17 @@ nsXULTreeItemAccessibleBase::GetSiblingA
   if (!treeAcc)
     return nsnull;
 
   PRInt32 rowCount = 0;
   mTreeView->GetRowCount(&rowCount);
   if (mRow + aOffset >= rowCount)
     return nsnull;
 
-  nsCOMPtr<nsIAccessible> sibling;
-  treeAcc->GetTreeItemAccessible(mRow + aOffset, getter_AddRefs(sibling));
-  return sibling;
+  return treeAcc->GetTreeItemAccessible(mRow + aOffset);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeItemAccessibleBase: protected implementation
 
 PRBool
 nsXULTreeItemAccessibleBase::IsExpandable()
 {
@@ -1285,17 +1257,17 @@ nsXULTreeItemAccessible::CacheChildren()
 ////////////////////////////////////////////////////////////////////////////////
 
 nsXULTreeColumnsAccessible::
   nsXULTreeColumnsAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell):
   nsXULColumnsAccessible(aDOMNode, aShell)
 {
 }
 
-nsIAccessible*
+nsAccessible*
 nsXULTreeColumnsAccessible::GetSiblingAtOffset(PRInt32 aOffset,
                                                nsresult* aError)
 {
   if (aOffset < 0)
     return nsXULColumnsAccessible::GetSiblingAtOffset(aOffset, aError);
 
   if (IsDefunct()) {
     if (aError)
@@ -1315,20 +1287,17 @@ nsXULTreeColumnsAccessible::GetSiblingAt
     tree->GetView(getter_AddRefs(treeView));
     if (treeView) {
       PRInt32 rowCount = 0;
       treeView->GetRowCount(&rowCount);
       if (rowCount > 0 && aOffset <= rowCount) {
         nsRefPtr<nsXULTreeAccessible> treeAcc =
           nsAccUtils::QueryAccessibleTree(mParent);
 
-        if (treeAcc) {
-          nsCOMPtr<nsIAccessible> sibling;
-          treeAcc->GetTreeItemAccessible(aOffset - 1, getter_AddRefs(sibling));
-          return sibling;
-        }
+        if (treeAcc)
+          return treeAcc->GetTreeItemAccessible(aOffset - 1);
       }
     }
   }
 
   return nsnull;
 }
 
--- a/accessible/src/xul/nsXULTreeAccessible.h
+++ b/accessible/src/xul/nsXULTreeAccessible.h
@@ -97,19 +97,18 @@ public:
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEACCESSIBLE_IMPL_CID)
 
   /**
    * Return tree item accessible at the givem row. If accessible doesn't exist
    * in the cache then create and cache it.
    *
    * @param aRow         [in] the given row index
-   * @param aAccessible  [out] tree item accessible
    */
-  void GetTreeItemAccessible(PRInt32 aRow, nsIAccessible **aAccessible);
+  nsAccessible* GetTreeItemAccessible(PRInt32 aRow);
 
   /**
    * Invalidates the number of cached treeitem accessibles.
    *
    * @param aRow    [in] row index the invalidation starts from
    * @param aCount  [in] the number of treeitem accessibles to invalidate,
    *                 the number sign specifies whether rows have been
    *                 inserted (plus) or removed (minus)
@@ -132,22 +131,21 @@ public:
    * Invalidates children created for previous tree view.
    */
   void TreeViewChanged();
 
 protected:
   /**
    * Creates tree item accessible for the given row index.
    */
-  virtual void CreateTreeItemAccessible(PRInt32 aRowIndex,
-                                        nsAccessNode** aAccessNode);
+  virtual already_AddRefed<nsAccessible> CreateTreeItemAccessible(PRInt32 aRow);
 
   nsCOMPtr<nsITreeBoxObject> mTree;
   nsCOMPtr<nsITreeView> mTreeView;
-  nsAccessNodeHashtable mAccessNodeCache;
+  nsAccessibleHashtable mAccessibleCache;
 
   NS_IMETHOD ChangeSelection(PRInt32 aIndex, PRUint8 aMethod, PRBool *aSelState);
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsXULTreeAccessible,
                               NS_XULTREEACCESSIBLE_IMPL_CID)
 
 /**
@@ -210,32 +208,31 @@ public:
    * Return row index associated with the accessible.
    */
   PRInt32 GetRowIndex() const { return mRow; }
 
   /**
    * Return cell accessible for the given column. If XUL tree accessible is not
    * accessible table then return null.
    */
-  virtual void GetCellAccessible(nsITreeColumn *aColumn,
-                                 nsIAccessible **aCellAcc)
-    { *aCellAcc = nsnull; }
+  virtual nsAccessible* GetCellAccessible(nsITreeColumn *aColumn)
+    { return nsnull; }
 
   /**
    * Proccess row invalidation. Used to fires name change events.
    */
   virtual void RowInvalidated(PRInt32 aStartColIdx, PRInt32 aEndColIdx) = 0;
 
 protected:
   enum { eAction_Click = 0, eAction_Expand = 1 };
 
   // nsAccessible
   virtual void DispatchClickEvent(nsIContent *aContent, PRUint32 aActionIndex);
-  virtual nsIAccessible* GetSiblingAtOffset(PRInt32 aOffset,
-                                            nsresult* aError = nsnull);
+  virtual nsAccessible* GetSiblingAtOffset(PRInt32 aOffset,
+                                           nsresult *aError = nsnull);
 
   // nsXULTreeItemAccessibleBase
 
   /**
    * Return true if the tree item accessible is expandable (contains subrows).
    */
   PRBool IsExpandable();
 
@@ -288,12 +285,13 @@ protected:
 class nsXULTreeColumnsAccessible : public nsXULColumnsAccessible
 {
 public:
   nsXULTreeColumnsAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell);
 
 protected:
 
   // nsAccessible
-  nsIAccessible* GetSiblingAtOffset(PRInt32 aOffset, nsresult* aError = nsnull);
+  virtual nsAccessible* GetSiblingAtOffset(PRInt32 aOffset,
+                                           nsresult *aError = nsnull);
 };
 
 #endif
--- a/accessible/src/xul/nsXULTreeGridAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeGridAccessible.cpp
@@ -37,33 +37,16 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsXULTreeGridAccessibleWrap.h"
 
 #include "nsITreeSelection.h"
 #include "nsServiceManagerUtils.h"
 
 ////////////////////////////////////////////////////////////////////////////////
-// Internal static functions
-////////////////////////////////////////////////////////////////////////////////
-
-// Callback used when traversing the cache by cycle collector.
-static PLDHashOperator
-ElementTraverser(const void *aKey, nsAccessNode *aAccessNode, void *aUserArg)
-{
-  nsCycleCollectionTraversalCallback *cb = 
-    static_cast<nsCycleCollectionTraversalCallback*>(aUserArg);
-
-  NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb,
-                                     "mAccessNodeCache of XUL tree row entry");
-  cb->NoteXPCOMChild(aAccessNode);
-  return PL_DHASH_NEXT;
-}
-
-////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeGridAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsXULTreeGridAccessible::
   nsXULTreeGridAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell) :
   nsXULTreeAccessible(aDOMNode, aShell)
 {
 }
@@ -357,30 +340,29 @@ nsXULTreeGridAccessible::GetCellAt(PRInt
                                    nsIAccessible **aCell)
 {
   NS_ENSURE_ARG_POINTER(aCell);
   *aCell = nsnull;
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  nsCOMPtr<nsIAccessible> rowAccessible;
-  GetTreeItemAccessible(aRowIndex, getter_AddRefs(rowAccessible));
+  nsAccessible *rowAccessible = GetTreeItemAccessible(aRowIndex);
   if (!rowAccessible)
     return NS_ERROR_INVALID_ARG;
 
   nsCOMPtr<nsITreeColumn> column =
   nsCoreUtils::GetSensibleColumnAt(mTree, aColumnIndex);
   if (!column)
     return NS_ERROR_INVALID_ARG;
 
   nsRefPtr<nsXULTreeItemAccessibleBase> rowAcc =
     nsAccUtils::QueryObject<nsXULTreeItemAccessibleBase>(rowAccessible);
 
-  rowAcc->GetCellAccessible(column, aCell);
+  NS_IF_ADDREF(*aCell = rowAcc->GetCellAccessible(column));
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULTreeGridAccessible::GetCellIndexAt(PRInt32 aRowIndex, PRInt32 aColumnIndex,
                                         PRInt32 *aCellIndex)
 {
   NS_ENSURE_ARG_POINTER(aCellIndex);
@@ -583,52 +565,53 @@ nsXULTreeGridAccessible::GetRoleInternal
     nsIAccessibleRole::ROLE_TABLE;
 
   return NS_OK;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeGridAccessible: nsXULTreeAccessible implementation
 
-void
-nsXULTreeGridAccessible::CreateTreeItemAccessible(PRInt32 aRow,
-                                                  nsAccessNode** aAccessNode)
+already_AddRefed<nsAccessible>
+nsXULTreeGridAccessible::CreateTreeItemAccessible(PRInt32 aRow)
 {
-  *aAccessNode = new nsXULTreeGridRowAccessible(mDOMNode, mWeakShell, this,
-                                                mTree, mTreeView, aRow);
-  NS_IF_ADDREF(*aAccessNode);
+  nsRefPtr<nsAccessible> accessible =
+    new nsXULTreeGridRowAccessible(mDOMNode, mWeakShell, this, mTree,
+                                   mTreeView, aRow);
+
+  return accessible.forget();
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeGridRowAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsXULTreeGridRowAccessible::
   nsXULTreeGridRowAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
                              nsAccessible *aTreeAcc, nsITreeBoxObject* aTree,
                              nsITreeView *aTreeView, PRInt32 aRow) :
   nsXULTreeItemAccessibleBase(aDOMNode, aShell, aTreeAcc, aTree, aTreeView, aRow)
 {
-  mAccessNodeCache.Init(kDefaultTreeCacheSize);
+  mAccessibleCache.Init(kDefaultTreeCacheSize);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeGridRowAccessible: nsISupports and cycle collection implementation
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULTreeGridRowAccessible)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXULTreeGridRowAccessible,
                                                   nsAccessible)
-tmp->mAccessNodeCache.EnumerateRead(ElementTraverser, &cb);
+CycleCollectorTraverseCache(tmp->mAccessibleCache, &cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXULTreeGridRowAccessible,
                                                 nsAccessible)
-tmp->ClearCache(tmp->mAccessNodeCache);
+ClearCache(tmp->mAccessibleCache);
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXULTreeGridRowAccessible)
 NS_INTERFACE_MAP_STATIC_AMBIGUOUS(nsXULTreeGridRowAccessible)
 NS_INTERFACE_MAP_END_INHERITING(nsXULTreeItemAccessibleBase)
 
 NS_IMPL_ADDREF_INHERITED(nsXULTreeGridRowAccessible,
                          nsXULTreeItemAccessibleBase)
@@ -636,17 +619,17 @@ NS_IMPL_RELEASE_INHERITED(nsXULTreeGridR
                           nsXULTreeItemAccessibleBase)
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeGridRowAccessible: nsAccessNode implementation
 
 nsresult
 nsXULTreeGridRowAccessible::Shutdown()
 {
-  ClearCache(mAccessNodeCache);
+  ClearCache(mAccessibleCache);
   return nsXULTreeItemAccessibleBase::Shutdown();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeGridRowAccessible: nsAccessible implementation
 
 nsresult
 nsXULTreeGridRowAccessible::GetRoleInternal(PRUint32 *aRole)
@@ -680,36 +663,32 @@ nsXULTreeGridRowAccessible::GetChildAtPo
   nsCAutoString childEltUnused;
   mTree->GetCellAt(clientX, clientY, &row, getter_AddRefs(column),
                    childEltUnused);
 
   // Return if we failed to find tree cell in the row for the given point.
   if (row != mRow || !column)
     return NS_OK;
 
-  GetCellAccessible(column, aChild);
+  NS_IF_ADDREF(*aChild = GetCellAccessible(column));
   return NS_OK;
 }
 
 nsAccessible*
 nsXULTreeGridRowAccessible::GetChildAt(PRUint32 aIndex)
 {
   if (IsDefunct())
     return nsnull;
 
   nsCOMPtr<nsITreeColumn> column =
     nsCoreUtils::GetSensibleColumnAt(mTree, aIndex);
   if (!column)
     return nsnull;
 
-  nsCOMPtr<nsIAccessible> cell;
-  GetCellAccessible(column, getter_AddRefs(cell));
-
-  nsRefPtr<nsAccessible> cellAcc = nsAccUtils::QueryObject<nsAccessible>(cell);
-  return cellAcc;
+  return GetCellAccessible(column);
 }
 
 PRInt32
 nsXULTreeGridRowAccessible::GetChildCount()
 {
   if (IsDefunct())
     return -1;
 
@@ -726,58 +705,58 @@ nsXULTreeGridRowAccessible::GetIndexOf(n
     nsAccUtils::QueryObject<nsXULTreeGridCellAccessible>(aChild);
 
   return cell ? cell->GetColumnIndex() : -1;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeGridRowAccessible: nsXULTreeItemAccessibleBase implementation
 
-void
-nsXULTreeGridRowAccessible::GetCellAccessible(nsITreeColumn* aColumn,
-                                              nsIAccessible** aAccessible)
+nsAccessible*
+nsXULTreeGridRowAccessible::GetCellAccessible(nsITreeColumn* aColumn)
 {
   NS_PRECONDITION(aColumn, "No tree column!");
-  *aAccessible = nsnull;
 
   void* key = static_cast<void*>(aColumn);
-  nsRefPtr<nsAccessNode> accessNode = mAccessNodeCache.GetWeak(key);
+  nsRefPtr<nsAccessible> accessible = mAccessibleCache.GetWeak(key);
 
-  if (!accessNode) {
-    accessNode =
+  if (!accessible) {
+    accessible =
       new nsXULTreeGridCellAccessibleWrap(mDOMNode, mWeakShell, this, mTree,
                                           mTreeView, mRow, aColumn);
-    if (!accessNode)
-      return;
+    if (!accessible)
+      return nsnull;
 
-    nsresult rv = accessNode->Init();
-    if (NS_FAILED(rv))
-      return;
+    nsresult rv = accessible->Init();
+    if (NS_FAILED(rv)) {
+      accessible->Shutdown();
+      return nsnull;
+    }
 
-    mAccessNodeCache.Put(key, accessNode);
+    if (!mAccessibleCache.Put(key, accessible))
+      return nsnull;
   }
 
-  CallQueryInterface(accessNode.get(), aAccessible);
+  return accessible;
 }
 
 void
 nsXULTreeGridRowAccessible::RowInvalidated(PRInt32 aStartColIdx,
                                            PRInt32 aEndColIdx)
 {
   nsCOMPtr<nsITreeColumns> treeColumns;
   mTree->GetColumns(getter_AddRefs(treeColumns));
   if (!treeColumns)
     return;
 
   for (PRInt32 colIdx = aStartColIdx; colIdx <= aEndColIdx; ++colIdx) {
     nsCOMPtr<nsITreeColumn> column;
     treeColumns->GetColumnAt(colIdx, getter_AddRefs(column));
     if (column && !nsCoreUtils::IsColumnHidden(column)) {
-      nsCOMPtr<nsIAccessible> cellAccessible;
-      GetCellAccessible(column, getter_AddRefs(cellAccessible));
+      nsAccessible *cellAccessible = GetCellAccessible(column);
       if (cellAccessible) {
         nsRefPtr<nsXULTreeGridCellAccessible> cellAcc =
           nsAccUtils::QueryObject<nsXULTreeGridCellAccessible>(cellAccessible);
 
         cellAcc->CellInvalidated();
       }
     }
   }
@@ -1269,17 +1248,17 @@ nsXULTreeGridCellAccessible::CellInvalid
     nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE, this);
     mCachedTextEquiv = textEquiv;
   }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULTreeGridCellAccessible: nsAccessible protected implementation
 
-nsIAccessible*
+nsAccessible*
 nsXULTreeGridCellAccessible::GetSiblingAtOffset(PRInt32 aOffset,
                                                 nsresult* aError)
 {
   if (IsDefunct()) {
     if (aError)
       *aError = NS_ERROR_FAILURE;
 
     return nsnull;
@@ -1302,20 +1281,17 @@ nsXULTreeGridCellAccessible::GetSiblingA
   }
 
   if (!columnAtOffset)
     return nsnull;
 
   nsRefPtr<nsXULTreeItemAccessibleBase> rowAcc =
     nsAccUtils::QueryObject<nsXULTreeItemAccessibleBase>(mParent);
 
-  nsCOMPtr<nsIAccessible> sibling;
-  rowAcc->GetCellAccessible(columnAtOffset, getter_AddRefs(sibling));
-
-  return sibling;
+  return rowAcc->GetCellAccessible(columnAtOffset);
 }
 
 void
 nsXULTreeGridCellAccessible::DispatchClickEvent(nsIContent *aContent,
                                                 PRUint32 aActionIndex)
 {
   if (IsDefunct())
     return;
--- a/accessible/src/xul/nsXULTreeGridAccessible.h
+++ b/accessible/src/xul/nsXULTreeGridAccessible.h
@@ -60,18 +60,17 @@ public:
   NS_DECL_NSIACCESSIBLETABLE
 
   // nsAccessible
   virtual nsresult GetRoleInternal(PRUint32 *aRole);
 
 protected:
 
   // nsXULTreeAccessible
-  virtual void CreateTreeItemAccessible(PRInt32 aRow,
-                                        nsAccessNode** aAccessNode);
+  virtual already_AddRefed<nsAccessible> CreateTreeItemAccessible(PRInt32 aRow);
 };
 
 
 /**
  * Represents accessible for XUL tree item in the case when XUL tree has
  * multiple columns.
  */
 class nsXULTreeGridRowAccessible : public nsXULTreeItemAccessibleBase
@@ -95,26 +94,26 @@ public:
                                    PRBool aDeepestChild,
                                    nsIAccessible **aChild);
 
   virtual nsAccessible* GetChildAt(PRUint32 aIndex);
   virtual PRInt32 GetChildCount();
   virtual PRInt32 GetIndexOf(nsIAccessible *aChild);
 
   // nsXULTreeItemAccessibleBase
-  virtual void GetCellAccessible(nsITreeColumn *aColumn, nsIAccessible **aCell);
+  virtual nsAccessible* GetCellAccessible(nsITreeColumn *aColumn);
   virtual void RowInvalidated(PRInt32 aStartColIdx, PRInt32 aEndColIdx);
 
 protected:
 
   // nsAccessible
   virtual void CacheChildren();
 
   // nsXULTreeItemAccessibleBase
-  nsAccessNodeHashtable mAccessNodeCache;
+  nsAccessibleHashtable mAccessibleCache;
 };
 
 
 /**
  * Represents an accessible for XUL tree cell in the case when XUL tree has
  * multiple columns.
  */
 
@@ -177,18 +176,18 @@ public:
   /**
    * Fire name or state change event if the accessible text or value has been
    * changed.
    */
   void CellInvalidated();
 
 protected:
   // nsAccessible
-  virtual nsIAccessible* GetSiblingAtOffset(PRInt32 aOffset,
-                                            nsresult* aError = nsnull);
+  virtual nsAccessible* GetSiblingAtOffset(PRInt32 aOffset,
+                                           nsresult *aError = nsnull);
   virtual void DispatchClickEvent(nsIContent *aContent, PRUint32 aActionIndex);
 
   // nsXULTreeGridCellAccessible
 
   /**
    * Return true if value of cell can be modified.
    */
   PRBool IsEditable() const;
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -235,24 +235,26 @@ pref("browser.urlbar.maxRichResults", 12
 pref("browser.urlbar.delay", 50);
 
 // The special characters below can be typed into the urlbar to either restrict
 // the search to visited history, bookmarked, tagged pages; or force a match on
 // just the title text or url.
 pref("browser.urlbar.restrict.history", "^");
 pref("browser.urlbar.restrict.bookmark", "*");
 pref("browser.urlbar.restrict.tag", "+");
+pref("browser.urlbar.restrict.openpage", "%");
 pref("browser.urlbar.restrict.typed", "~");
 pref("browser.urlbar.match.title", "#");
 pref("browser.urlbar.match.url", "@");
 
 // The default behavior for the urlbar can be configured to use any combination
 // of the restrict or match filters with each additional filter restricting
 // more (intersection). Add the following values to set the behavior as the
-// default: 1: history, 2: bookmark, 4: tag, 8: title, 16: url, 32: typed
+// default: 1: history, 2: bookmark, 4: tag, 8: title, 16: url, 32: typed,
+//          64: javascript, 128: tabs
 // E.g., 0 = show all results (no filtering), 1 = only visited pages in history,
 // 2 = only bookmarks, 3 = visited bookmarks, 1+16 = history matching in the url
 pref("browser.urlbar.default.behavior", 0);
 
 // Number of milliseconds to wait for the http headers (and thus
 // the Content-Disposition filename) before giving up and falling back to 
 // picking a filename without that info in hand so that the user sees some
 // feedback from their action.
@@ -799,16 +801,17 @@ pref("places.frecency.fourthBucketCutoff
 pref("places.frecency.firstBucketWeight", 100);
 pref("places.frecency.secondBucketWeight", 70);
 pref("places.frecency.thirdBucketWeight", 50);
 pref("places.frecency.fourthBucketWeight", 30);
 pref("places.frecency.defaultBucketWeight", 10);
 
 // bonus (in percent) for visit transition types for frecency calculations
 pref("places.frecency.embedVisitBonus", 0);
+pref("places.frecency.framedLinkVisitBonus", 0);
 pref("places.frecency.linkVisitBonus", 100);
 pref("places.frecency.typedVisitBonus", 2000);
 pref("places.frecency.bookmarkVisitBonus", 75);
 pref("places.frecency.downloadVisitBonus", 0);
 pref("places.frecency.permRedirectVisitBonus", 0);
 pref("places.frecency.tempRedirectVisitBonus", 0);
 pref("places.frecency.defaultVisitBonus", 0);
 
--- a/browser/base/content/browser-fullZoom.js
+++ b/browser/base/content/browser-fullZoom.js
@@ -72,22 +72,16 @@ var FullZoom = {
 
   // Content Pref Service
   get _cps FullZoom_get__cps() {
     delete this._cps;
     return this._cps = Cc["@mozilla.org/content-pref/service;1"].
                        getService(Ci.nsIContentPrefService);
   },
 
-  get _prefBranch FullZoom_get__prefBranch() {
-    delete this._prefBranch;
-    return this._prefBranch = Cc["@mozilla.org/preferences-service;1"].
-                              getService(Ci.nsIPrefBranch2);
-  },
-
   // browser.zoom.siteSpecific preference cache
   _siteSpecificPref: undefined,
 
   // browser.zoom.updateBackgroundTabs preference cache
   updateBackgroundTabs: undefined,
 
   // whether we are in private browsing mode
   _inPrivateBrowsing: false,
@@ -130,29 +124,29 @@ var FullZoom = {
     os.addObserver(this, "private-browsing", true);
 
     // Retrieve the initial status of the Private Browsing mode.
     this._inPrivateBrowsing = Cc["@mozilla.org/privatebrowsing;1"].
                               getService(Ci.nsIPrivateBrowsingService).
                               privateBrowsingEnabled;
 
     this._siteSpecificPref =
-      this._prefBranch.getBoolPref("browser.zoom.siteSpecific");
+      gPrefService.getBoolPref("browser.zoom.siteSpecific");
     this.updateBackgroundTabs = 
-      this._prefBranch.getBoolPref("browser.zoom.updateBackgroundTabs");
+      gPrefService.getBoolPref("browser.zoom.updateBackgroundTabs");
     // Listen for changes to the browser.zoom branch so we can enable/disable
     // updating background tabs and per-site saving and restoring of zoom levels.
-    this._prefBranch.addObserver("browser.zoom.", this, true);
+    gPrefService.addObserver("browser.zoom.", this, true);
   },
 
   destroy: function FullZoom_destroy() {
     let os = Cc["@mozilla.org/observer-service;1"].
              getService(Ci.nsIObserverService);
     os.removeObserver(this, "private-browsing");
-    this._prefBranch.removeObserver("browser.zoom.", this);
+    gPrefService.removeObserver("browser.zoom.", this);
     this._cps.removeObserver(this.name, this);
     window.removeEventListener("DOMMouseScroll", this, false);
     delete this._cps;
   },
 
 
   //**************************************************************************//
   // Event Handlers
@@ -208,21 +202,21 @@ var FullZoom = {
   // nsIObserver
 
   observe: function (aSubject, aTopic, aData) {
     switch (aTopic) {
       case "nsPref:changed":
         switch (aData) {
           case "browser.zoom.siteSpecific":
             this._siteSpecificPref =
-              this._prefBranch.getBoolPref("browser.zoom.siteSpecific");
+              gPrefService.getBoolPref("browser.zoom.siteSpecific");
             break;
           case "browser.zoom.updateBackgroundTabs":
             this.updateBackgroundTabs =
-              this._prefBranch.getBoolPref("browser.zoom.updateBackgroundTabs");
+              gPrefService.getBoolPref("browser.zoom.updateBackgroundTabs");
             break;
         }
         break;
       case "private-browsing":
         switch (aData) {
           case "enter":
             this._inPrivateBrowsing = true;
             break;
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -541,19 +541,17 @@ var PlacesCommandHook = {
   /**
    * Opens the Places Organizer. 
    * @param   aLeftPaneRoot
    *          The query to select in the organizer window - options
    *          are: History, AllBookmarks, BookmarksMenu, BookmarksToolbar,
    *          UnfiledBookmarks and Tags.
    */
   showPlacesOrganizer: function PCH_showPlacesOrganizer(aLeftPaneRoot) {
-    var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
-             getService(Ci.nsIWindowMediator);
-    var organizer = wm.getMostRecentWindow("Places:Organizer");
+    var organizer = Services.wm.getMostRecentWindow("Places:Organizer");
     if (!organizer) {
       // No currently open places window, so open one with the specified mode.
       openDialog("chrome://browser/content/places/places.xul", 
                  "", "chrome,toolbar=yes,dialog=no,resizable", aLeftPaneRoot);
     }
     else {
       organizer.PlacesOrganizer.selectLeftPaneQuery(aLeftPaneRoot);
       organizer.focus();
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -38,29 +38,51 @@ toolbar[mode="icons"] > #reload-button[d
   background-position: bottom left;
 }
 
 /* ::::: location bar ::::: */
 #urlbar {
   -moz-binding: url(chrome://browser/content/urlbarBindings.xml#urlbar);
 }
 
+/* Some child nodes want to be ordered based on the locale's direction, while
+   everything else should be ltr. */
+#urlbar:-moz-locale-dir(rtl) > .autocomplete-textbox-container > .textbox-input-box {
+  direction: rtl;
+}
+
+#urlbar html|*.autocomplete-textbox {
+  direction: ltr;
+}
+
+/* For results that are actions, their description text is shown instead of
+   the URL - this needs to follow the locale's direction, unlike URLs. */
+richlistitem[type="action"]:-moz-locale-dir(rtl) > .ac-url-box {
+  direction: rtl;
+}
+
+#urlbar:not([actiontype]) > #urlbar-display {
+  display: none;
+}
+
 #wrapper-urlbar-container > #urlbar-container > #urlbar {
   -moz-user-input: disabled;
   cursor: -moz-grab;
 }
 
 #PopupAutoComplete {
   -moz-binding: url("chrome://browser/content/urlbarBindings.xml#browser-autocomplete-result-popup");
 }
 
 #PopupAutoCompleteRichResult {
   -moz-binding: url("chrome://browser/content/urlbarBindings.xml#urlbar-rich-result-popup");
 }
 
+
+
 #urlbar-throbber:not([busy="true"]),
 #urlbar-throbber[busy="true"] + #page-proxy-favicon {
   display: none;
 }
 
 #feed-button > .button-box > .box-inherit > .button-text,
 #feed-button > .button-box > .button-menu-dropmarker {
   display: none;
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -3830,17 +3830,16 @@ var XULBrowserWindow = {
   // Stored Status, Link and Loading values
   status: "",
   defaultStatus: "",
   jsStatus: "",
   jsDefaultStatus: "",
   overLink: "",
   startTime: 0,
   statusText: "",
-  lastURI: null,
   isBusy: false,
 
   _progressCollapseTimer: 0,
 
   QueryInterface: function (aIID) {
     if (aIID.equals(Ci.nsIWebProgressListener) ||
         aIID.equals(Ci.nsIWebProgressListener2) ||
         aIID.equals(Ci.nsISupportsWeakReference) ||
@@ -3894,17 +3893,16 @@ var XULBrowserWindow = {
     // XXXjag to avoid leaks :-/, see bug 60729
     delete this.throbberElement;
     delete this.statusMeter;
     delete this.stopCommand;
     delete this.reloadCommand;
     delete this.statusTextField;
     delete this.securityButton;
     delete this.statusText;
-    delete this.lastURI;
   },
 
   setJSStatus: function (status) {
     this.jsStatus = status;
     this.updateStatusField();
   },
 
   setJSDefaultStatus: function (status) {
@@ -4109,17 +4107,16 @@ var XULBrowserWindow = {
         newSpec = newSpec.substr(0, newSpec.indexOf("#"));
       if (newSpec != oldSpec) {
         // Remove all the notifications, except for those which want to
         // persist across the first location change.
         let nBox = gBrowser.getNotificationBox(selectedBrowser);
         nBox.removeTransientNotifications();
       }
     }
-    selectedBrowser.lastURI = aLocationURI;
 
     // Disable menu entries for images, enable otherwise
     if (content.document && mimeTypeIsTextBased(content.document.contentType))
       this.isImage.removeAttribute('disabled');
     else
       this.isImage.setAttribute('disabled', 'true');
 
     this.setOverLink("", null);
@@ -7481,8 +7478,49 @@ var LightWeightThemeWebInstaller = {
     return pm.testPermission(uri, "install") == pm.ALLOW_ACTION;
   },
 
   _getThemeFromNode: function (node) {
     return this._manager.parseTheme(node.getAttribute("data-browsertheme"),
                                     node.baseURI);
   }
 }
+
+function switchToTabHavingURI(aURI) {
+  function switchIfURIInWindow(aWindow) {
+    if (!("gBrowser" in aWindow))
+      return false;
+    let browsers = aWindow.gBrowser.browsers;
+    for (let i = 0; i < browsers.length; i++) {
+      let browser = browsers[i];
+      if (browser.currentURI.equals(aURI)) {
+        gURLBar.handleRevert();
+        aWindow.focus();
+        aWindow.gBrowser.tabContainer.selectedIndex = i;
+        return true;
+      }
+    }
+    return false;
+  }
+
+  // This can be passed either nsIURI or a string.
+  if (!(aURI instanceof Ci.nsIURI))
+    aURI = makeURI(aURI);
+
+  // Prioritise this window.
+  if (switchIfURIInWindow(window))
+    return true;
+
+  let windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"]
+                         .getService(Ci.nsIWindowMediator);
+  let winEnum = windowMediator.getEnumerator("navigator:browser");
+  while (winEnum.hasMoreElements()) {
+    let browserWin = winEnum.getNext();
+    // Skip closed (but not yet destroyed) windows,
+    // and the current window (which was checked earlier).
+    if (browserWin.closed || browserWin == window)
+      continue;
+    if (switchIfURIInWindow(browserWin))
+      return true;
+  }
+  // No opened tab has that url.
+  return false;
+}
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -400,16 +400,17 @@
                    title="&locationItem.title;" class="chromeclass-location" removable="true">
         <textbox id="urlbar" flex="1"
                  bookmarkhistoryplaceholder="&urlbar.bookmarkhistory.emptyText;"
                  bookmarkplaceholder="&urlbar.bookmark.emptyText;"
                  historyplaceholder="&urlbar.history.emptyText;"
                  noneplaceholder="&urlbar.none.emptyText;"
                  type="autocomplete"
                  autocompletesearch="history"
+                 autocompletesearchparam="enable-actions"
                  autocompletepopup="PopupAutoCompleteRichResult"
                  completeselectedindex="true"
                  tabscrolling="true"
                  showcommentcolumn="true"
                  showimagecolumn="true"
                  enablehistory="true"
                  maxrows="6"
                  newlines="stripsurroundingwhitespace"
@@ -438,16 +439,17 @@
                        onerror="this.removeAttribute('src');"/>
               </stack>
               <hbox id="identity-icon-labels">
                 <label id="identity-icon-label" class="plain" flex="1"/>
                 <label id="identity-icon-country-label" class="plain"/>
               </hbox>
             </hbox>
           </box>
+          <label id="urlbar-display" value="&urlbar.switchToTab.label;"/>
           <hbox id="urlbar-icons">
             <button type="menu"
                     style="-moz-user-focus: none"
                     class="plain urlbar-icon"
                     id="feed-button"
                     collapsed="true"
                     tooltiptext="&feedButton.tooltip;"
                     onclick="return FeedHandler.onFeedButtonClick(event);">
--- a/browser/base/content/tabbrowser.css
+++ b/browser/base/content/tabbrowser.css
@@ -39,14 +39,19 @@
 .tabs-newtab-button > .toolbarbutton-text {
   display: none;
 }
 
 tabpanels {
   background-color: white;
 }
 
+.tab-drop-indicator {
+  position: relative;
+  z-index: 1;
+}
+
 %ifdef MOZ_WIDGET_GTK2
 /* Favicons override the "images-in-menus" metric in xul.css */
 .alltabs-item > .menu-iconic-left {
   visibility: inherit;
 }
 %endif
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -62,29 +62,26 @@
     <resources>
       <stylesheet src="chrome://browser/content/tabbrowser.css"/>
     </resources>
 
     <content>
       <xul:stringbundle anonid="tbstringbundle" src="chrome://browser/locale/tabbrowser.properties"/>
       <xul:tabbox anonid="tabbox" flex="1" eventnode="document" xbl:inherits="handleCtrlPageUpDown"
                   onselect="if (event.target.localName == 'tabpanels') this.parentNode.updateCurrentBrowser();">
-        <xul:hbox class="tab-drop-indicator-bar" collapsed="true"
-                  ondragover="this.parentNode.parentNode._onDragOver(event);"
-                  ondragleave="this.parentNode.parentNode._onDragLeave(event);"
-                  ondrop="this.parentNode.parentNode._onDrop(event);">
-          <xul:hbox class="tab-drop-indicator" mousethrough="always"/>
-        </xul:hbox>
         <xul:hbox class="tabbrowser-strip" collapsed="true" tooltip="_child" context="_child"
                   anonid="strip"
                   ondragstart="this.parentNode.parentNode._onDragStart(event);"
                   ondragover="this.parentNode.parentNode._onDragOver(event);"
                   ondrop="this.parentNode.parentNode._onDrop(event);"
                   ondragend="this.parentNode.parentNode._onDragEnd(event);"
                   ondragleave="this.parentNode.parentNode._onDragLeave(event);">
+          <xul:hbox align="start">
+            <xul:image class="tab-drop-indicator" anonid="tab-drop-indicator" collapsed="true"/>
+          </xul:hbox>
           <xul:tooltip onpopupshowing="return this.parentNode.parentNode.parentNode.createTooltip(event);"/>
           <xul:menupopup anonid="tabContextMenu" onpopupshowing="this.parentNode.parentNode.parentNode.updatePopupMenu(this);">
             <xul:menuitem id="context_newTab" label="&newTab.label;" accesskey="&newTab.accesskey;"
                           command="cmd_newNavigatorTab"/>
             <xul:menuseparator/>
             <xul:menuitem id="context_reloadTab" label="&reloadTab.label;" accesskey="&reloadTab.accesskey;"
                           oncommand="var tabbrowser = this.parentNode.parentNode.parentNode.parentNode;
                                      tabbrowser.reloadTab(tabbrowser.mContextTab);"/>
@@ -152,21 +149,25 @@
       <field name="mURIFixup" readonly="true">
         Components.classes["@mozilla.org/docshell/urifixup;1"]
                   .getService(Components.interfaces.nsIURIFixup);
       </field>
       <field name="mFaviconService" readonly="true">
         Components.classes["@mozilla.org/browser/favicon-service;1"]
                   .getService(Components.interfaces.nsIFaviconService);
       </field>
+      <field name="mBrowserHistory">
+        Components.classes["@mozilla.org/browser/nav-history-service;1"]
+                  .getService(Components.interfaces.nsIBrowserHistory);
+      </field>
       <field name="mTabBox" readonly="true">
         document.getAnonymousElementByAttribute(this, "anonid", "tabbox");
       </field>
-      <field name="mTabDropIndicatorBar">
-        this.mTabBox.childNodes[0]
+      <field name="_tabDropIndicator">
+        document.getAnonymousElementByAttribute(this, "anonid", "tab-drop-indicator");
       </field>
       <field name="mStrip" readonly="true">
         document.getAnonymousElementByAttribute(this, "anonid", "strip");
       </field>
       <field name="mTabContainer" readonly="true">
         document.getAnonymousElementByAttribute(this, "anonid", "tabcontainer");
       </field>
       <field name="mPanelContainer" readonly="true">
@@ -525,42 +526,49 @@
 
               if (aWebProgress.DOMWindow == this.mBrowser.contentWindow &&
                   aWebProgress.isLoadingDocument)
                 this.mTabBrowser.getBrowserForTab(this.mTab).mIconURL = null;
 
               // changing location, clear out the missing plugins list
               this.mBrowser.missingPlugins = null;
 
-              if (this.mBlank)
-                return;
-
-              if (this.mTabBrowser.mCurrentTab == this.mTab) {
-                for (let i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
-                  let p = this.mTabBrowser.mProgressListeners[i];
+              var browserHistory = this.mTabBrowser.mBrowserHistory;
+              if ("lastURI" in this.mBrowser && this.mBrowser.lastURI)
+                browserHistory.unregisterOpenPage(this.mBrowser.lastURI);
+              browserHistory.registerOpenPage(aLocation);
+
+              if (!this.mBlank) {
+                if (this.mTabBrowser.mCurrentTab == this.mTab) {
+                  for (let i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
+                    let p = this.mTabBrowser.mProgressListeners[i];
+                    if (p)
+                      try {
+                        p.onLocationChange(aWebProgress, aRequest, aLocation);
+                      } catch (e) {
+                        // don't inhibit other listeners
+                        Components.utils.reportError(e);
+                      }
+                  }
+                }
+
+                for (let i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
+                  let p = this.mTabBrowser.mTabsProgressListeners[i];
                   if (p)
                     try {
-                      p.onLocationChange(aWebProgress, aRequest, aLocation);
+                      p.onLocationChange(this.mBrowser, aWebProgress, aRequest, aLocation);
                     } catch (e) {
                       // don't inhibit other listeners
                       Components.utils.reportError(e);
                     }
                 }
               }
 
-              for (let i = 0; i < this.mTabBrowser.mTabsProgressListeners.length; i++) {
-                let p = this.mTabBrowser.mTabsProgressListeners[i];
-                if (p)
-                  try {
-                    p.onLocationChange(this.mBrowser, aWebProgress, aRequest, aLocation);
-                  } catch (e) {
-                    // don't inhibit other listeners
-                    Components.utils.reportError(e);
-                  }
-              }
+              this.mBrowser.lastURI = aLocation;
+
             },
 
             onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage)
             {
               if (this.mBlank)
                 return;
 
               if (this.mTabBrowser.mCurrentTab == this.mTab) {
@@ -800,26 +808,27 @@
                 aURI = makeURI(aURI);
               return this.mFaviconService.isFailedFavicon(aURI);
             }
             return null;
           ]]>
         </body>
       </method>
 
-      <method name="updateTitlebar">
+      <method name="getWindowTitleForBrowser">
+        <parameter name="aBrowser"/>
         <body>
           <![CDATA[
             var newTitle = "";
             var docTitle;
             var docElement = this.ownerDocument.documentElement;
             var sep = docElement.getAttribute("titlemenuseparator");
 
-            if (this.docShell.contentViewer)
-              docTitle = this.contentTitle;
+            if (aBrowser.docShell.contentViewer)
+              docTitle = aBrowser.contentTitle;
 
             if (!docTitle)
               docTitle = docElement.getAttribute("titledefault");
 
             var modifier = docElement.getAttribute("titlemodifier");
             if (docTitle) {
               newTitle += docElement.getAttribute("titlepreface");
               newTitle += docTitle;
@@ -829,25 +838,33 @@
             newTitle += modifier;
 
             // If location bar is hidden and the URL type supports a host,
             // add the scheme and host to the title to prevent spoofing.
             // XXX https://bugzilla.mozilla.org/show_bug.cgi?id=22183#c239
             try {
               if (docElement.getAttribute("chromehidden").indexOf("location") != -1) {
                 var uri = this.mURIFixup.createExposableURI(
-                            this.mCurrentBrowser.currentURI);
+                            aBrowser.currentURI);
                 if (uri.scheme == "about")
                   newTitle = uri.spec + sep + newTitle;
                 else
                   newTitle = uri.prePath + sep + newTitle;
               }
             } catch (e) {}
 
-            this.ownerDocument.title = newTitle;
+            return newTitle;
+          ]]>
+        </body>
+      </method>
+
+      <method name="updateTitlebar">
+        <body>
+          <![CDATA[
+            this.ownerDocument.title = this.getWindowTitleForBrowser(this.mCurrentBrowser);
           ]]>
         </body>
       </method>
 
       <method name="updatePopupMenu">
         <parameter name="aPopupMenu"/>
         <body>
           <![CDATA[
@@ -925,22 +942,22 @@
                                                listener.mMessage, listener.mTotalProgress);
                   }
                 } catch (e) {
                   // don't inhibit other listeners or following code
                   Components.utils.reportError(e);
                 }
             }
 
-            // Don't switch the fast find - this tab switch is temporary
-            if (!this._previewMode)
+            // Don't switch the fast find or update the titlebar (bug 540248) - this tab switch is temporary
+            if (!this._previewMode) {
               this._fastFind.setDocShell(this.mCurrentBrowser.docShell);
 
-            // Update the window title.
-            this.updateTitlebar();
+              this.updateTitlebar();
+            }
 
             // If the new tab is busy, and our current state is not busy, then
             // we need to fire a start to all progress listeners.
             const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
             if (this.mCurrentTab.hasAttribute("busy") && !this.mIsBusy) {
               this.mIsBusy = true;
               for (i = 0; i < this.mProgressListeners.length; i++) {
                 p = this.mProgressListeners[i];
@@ -1554,16 +1571,20 @@
             aTab.dispatchEvent(evt);
 
             // Remove the tab's filter and progress listener.
             const filter = this.mTabFilters[aTab._tPos];
             browser.webProgress.removeProgressListener(filter);
             filter.removeProgressListener(this.mTabListeners[aTab._tPos]);
             this.mTabListeners[aTab._tPos].destroy();
 
+            let closedBrowser = this.getBrowserForTab(aTab);
+            if (closedBrowser.currentURI)
+              this.mBrowserHistory.unregisterOpenPage(closedBrowser.currentURI);
+
             // We are no longer the primary content area.
             browser.setAttribute("type", "content-targetable");
 
             // Remove this tab as the owner of any other tabs, since it's going away.
             Array.forEach(this.mTabs, function (tab) {
               if ("owner" in tab && tab.owner == aTab)
                 // |tab| is a child of the tab we're removing, make it an orphan
                 tab.owner = null;
@@ -2013,25 +2034,40 @@
                 return dt.effectAllowed = dt.dropEffect = "link";
               }
             }
             return dt.effectAllowed = "none";
           ]]>
         </body>
       </method>
 
+      <method name="_continueScroll">
+        <parameter name="aEvent"/>
+        <body><![CDATA[
+          // Workaround for bug 481904: Dragging a tab stops scrolling at
+          // the tab's position when dragging to the first/last tab and back.
+          var t = this.selectedTab;
+          if (aEvent.screenX >= t.boxObject.screenX &&
+              aEvent.screenX <= t.boxObject.screenX + t.boxObject.width &&
+              aEvent.screenY >= t.boxObject.screenY &&
+              aEvent.screenY <= t.boxObject.screenY + t.boxObject.height)
+            this.tabContainer.mTabstrip.ensureElementIsVisible(t);
+        ]]></body>
+      </method>
+
       <method name="_onDragOver">
         <parameter name="aEvent"/>
         <body>
           <![CDATA[
             var effects = this._setEffectAllowedForDataTransfer(aEvent);
 
-            var ib = this.mTabDropIndicatorBar;
+            var ind = this._tabDropIndicator;
             if (effects == "" || effects == "none") {
-              ib.collapsed = "true";
+              ind.collapsed = true;
+              this._continueScroll(aEvent);
               return;
             }
             aEvent.preventDefault();
             aEvent.stopPropagation();
 
             var tabStrip = this.mTabContainer.mTabstrip;
             var ltr = (window.getComputedStyle(this.parentNode, null).direction
                        == "ltr");
@@ -2060,31 +2096,21 @@
               if (!this.mDragTime) 
                 this.mDragTime = Date.now();
               if (Date.now() >= this.mDragTime + this.mDragOverDelay)
                 this.mTabContainer.selectedItem = aEvent.target;
               return;
             }
 
             var newIndex = this.getNewIndex(aEvent);
-            var ib = this.mTabDropIndicatorBar;
-            var ind = ib.firstChild;
             var scrollRect = tabStrip.scrollClientRect;
             var rect = this.getBoundingClientRect();
             var minMargin = scrollRect.left - rect.left;
-            // make sure we don't place the tab drop indicator past the
-            // edge, or the containing box will flex and stretch
-            // the tab drop indicator bar, which will flex the url bar.  
-            // XXX todo
-            // just use first value if you can figure out how to get
-            // the tab drop indicator to crop instead of flex and stretch
-            // the tab drop indicator bar.
             var maxMargin = Math.min(minMargin + scrollRect.width, 
-                                     ib.getBoundingClientRect().right -
-                                     ind.clientWidth);
+                                     scrollRect.right);
             if (!ltr)
               [minMargin, maxMargin] = [this.clientWidth - maxMargin,
                                         this.clientWidth - minMargin];
             var newMargin;
             if (pixelsToScroll) {
               // if we are scrolling, put the drop indicator at the edge
               // so that it doesn't jump while scrolling
               newMargin = (pixelsToScroll > 0) ? maxMargin : minMargin;
@@ -2106,19 +2132,25 @@
               }
               // ensure we never place the drop indicator beyond our limits
               if (newMargin < minMargin)
                 newMargin = minMargin;
               else if (newMargin > maxMargin)
                 newMargin = maxMargin;
             }
 
-            ind.style.MozMarginStart = newMargin + 'px';
-
-            ib.collapsed = false;
+            ind.collapsed = false;
+ 
+            newMargin += ind.clientWidth / 2;
+            if (!ltr)
+              newMargin *= -1;
+
+            ind.style.MozTransform = "translate(" + Math.round(newMargin) + "px)";
+            ind.style.MozMarginStart = (-ind.clientWidth) + "px";
+            ind.style.marginTop = (-ind.clientHeight) + "px";
           ]]>
         </body>
       </method>
 
       <method name="_onDrop">
         <parameter name="aEvent"/>
         <body>
           <![CDATA[
@@ -2127,17 +2159,17 @@
             var draggedTab;
             if (dropEffect != "link") { // copy or move
               draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
               // not our drop then
               if (!draggedTab)
                 return;
             }
 
-            this.mTabDropIndicatorBar.collapsed = true;
+            this._tabDropIndicator.collapsed = true;
             aEvent.stopPropagation();
 
             if (draggedTab && (dropEffect == "copy" ||
                 draggedTab.parentNode == this.mTabContainer)) {
               var newIndex = this.getNewIndex(aEvent);
               if (dropEffect == "copy") {
                 // copy the dropped tab (wherever it's from)
                 var newTab = this.duplicateTab(draggedTab);
@@ -2296,17 +2328,18 @@
 
             // This does not work at all (see bug 458613)
             var target = aEvent.relatedTarget;
             while (target && target != this)
               target = target.parentNode;
             if (target)
               return;
 
-            this.mTabDropIndicatorBar.collapsed = true;
+            this._tabDropIndicator.collapsed = true;
+            this._continueScroll(aEvent);
             aEvent.stopPropagation();
           ]]>
         </body>
       </method>
 
       <method name="moveTabTo">
         <parameter name="aTab"/>
         <parameter name="aIndex"/>
@@ -2796,16 +2829,18 @@
       <destructor>
         <![CDATA[
           for (var i = 0; i < this.mTabListeners.length; ++i) {
             this.getBrowserAtIndex(i).webProgress.removeProgressListener(this.mTabFilters[i]);
             this.mTabFilters[i].removeProgressListener(this.mTabListeners[i]);
             this.mTabFilters[i] = null;
             this.mTabListeners[i].destroy();
             this.mTabListeners[i] = null;
+            let browser = this.getBrowserAtIndex(i);
+            this.mBrowserHistory.unregisterOpenPage(browser.currentURI);
           }
           document.removeEventListener("keypress", this, false);
         ]]>
       </destructor>
     </implementation>
 
     <handlers>
       <handler event="DOMWindowClose" phase="capturing">
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -144,16 +144,17 @@ include $(topsrcdir)/config/rules.mk
                  feed_tab.html \
                  plugin_unknown.html \
                  plugin_test.html \
                  plugin_both.html \
                  plugin_both2.html \
                  alltabslistener.html \
                  zoom_test.html \
                  dummy_page.html \
+                 browser_tabMatchesInAwesomebar.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_tabMatchesInAwesomebar.js
@@ -0,0 +1,179 @@
+const TEST_URL_BASES = [
+  "http://example.org/browser/browser/base/content/test/dummy_page.html#tabmatch",
+  "http://example.org/browser/browser/base/content/test/moz.png#tabmatch"
+];
+
+var gIOService = Cc["@mozilla.org/network/io-service;1"].
+                   getService(Ci.nsIIOService);
+var gWindowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].
+                        getService(Ci.nsIWindowMediator);
+var gPrivateBrowsing = Cc["@mozilla.org/privatebrowsing;1"].
+                         getService(Ci.nsIPrivateBrowsingService);
+var gObserverService = Cc["@mozilla.org/observer-service;1"].
+                         getService(Ci.nsIObserverService);
+
+
+var gTabWaitCount = 0;
+var gTabCounter = 0;
+var gNewWindow = null;
+
+var gTestSteps = [
+  function() {
+    for (let i = 0; i < 10; i++) {
+      let tab = gBrowser.addTab();
+      loadTab(tab, TEST_URL_BASES[0] + (++gTabCounter));
+    }
+  },
+  function() {
+    gBrowser.selectTabAtIndex(1);
+    gBrowser.removeCurrentTab();
+    gBrowser.selectTabAtIndex(1);
+    gBrowser.removeCurrentTab();
+    for (let i = 1; i < gBrowser.mTabs.length; i++)
+      loadTab(gBrowser.mTabs[i], TEST_URL_BASES[1] + (++gTabCounter));
+  },
+  function() {
+    for (let i = 1; i < gBrowser.mTabs.length; i++)
+      loadTab(gBrowser.mTabs[i], TEST_URL_BASES[0] + gTabCounter);
+  },
+  function() {
+    gNewWindow = openNewWindowWith("about:blank");
+    gNewWindow.addEventListener("load", function () {
+      gNewWindow.removeEventListener("load", arguments.callee, false);
+      var delayedStartup = gNewWindow.delayedStartup;
+      gNewWindow.delayedStartup = function() {
+        delayedStartup.apply(gNewWindow, arguments);
+        loadTab(gNewWindow.gBrowser.mTabs[0], TEST_URL_BASES[0] + gTabCounter);
+      }
+    }, false);
+  },
+  function() {
+    gPrefService.setBoolPref("browser.tabs.warnOnClose", false);
+    gNewWindow.close();
+    if (gPrefService.prefHasUserValue("browser.tabs.warnOnClose"))
+      gPrefService.clearUserPref("browser.tabs.warnOnClose");
+    ensure_opentabs_match_db();
+    executeSoon(nextStep);
+  },
+  function() {
+    gPrivateBrowsing.privateBrowsingEnabled = true;
+
+    executeSoon(function() {
+      ensure_opentabs_match_db();
+      nextStep();
+    });
+  },
+  function() {
+    gPrivateBrowsing.privateBrowsingEnabled = false;
+    setTimeout(function() {
+      ensure_opentabs_match_db();
+      nextStep();
+    }, 100);
+  }
+];
+
+
+
+function test() {
+  waitForExplicitFinish();
+  nextStep();
+}
+
+function loadTab(tab, url) {
+  tab.linkedBrowser.addEventListener("load", function (event) {
+    event.currentTarget.removeEventListener("load", arguments.callee, true);
+
+    if (--gTabWaitCount > 0)
+      return;
+    is(gTabWaitCount, 0,
+       "sanity check, gTabWaitCount should not be decremented below 0");
+
+    try {
+      ensure_opentabs_match_db();
+    } catch (e) {
+      ok(false, "exception from ensure_openpages_match_db: " + e);
+    }
+
+    executeSoon(nextStep);
+  }, true);
+  gTabWaitCount++;
+  tab.linkedBrowser.loadURI(url);
+}
+
+function nextStep() {
+  if (gTestSteps.length == 0) {
+    while (gBrowser.mTabs.length > 1) {
+      gBrowser.selectTabAtIndex(1);
+      gBrowser.removeCurrentTab();
+    }
+    PlacesUtils.history.QueryInterface(Ci.nsIBrowserHistory).removeAllPages();
+    finish();
+    return;
+  }
+
+  var stepFunc = gTestSteps.shift();
+  stepFunc();
+}
+
+function ensure_opentabs_match_db() {
+  var tabs = {};
+
+  var winEnum = gWindowMediator.getEnumerator("navigator:browser");
+  while (winEnum.hasMoreElements()) {
+    let browserWin = winEnum.getNext();
+    // skip closed-but-not-destroyed windows
+    if (browserWin.closed)
+      continue;
+
+    for (let i = 0; i < browserWin.gBrowser.mTabContainer.childElementCount; i++) {
+      let browser = browserWin.gBrowser.getBrowserAtIndex(i);
+      let url = browser.currentURI.spec;
+      if (!(url in tabs))
+        tabs[url] = 1;
+      else
+        tabs[url]++;
+    }
+  }
+
+  var db = PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
+                              .DBConnection;
+
+  try {
+    var stmt = db.createStatement(
+                          "SELECT IFNULL(p_t.url, p.url) AS url, open_count, place_id " +
+                          "FROM moz_openpages_temp " +
+                          "LEFT JOIN moz_places p ON p.id=place_id " +
+                          "LEFT JOIN moz_places_temp p_t ON p_t.id=place_id");
+  } catch (e) {
+    ok(false, "error creating db statement: " + e);
+    return;
+  }
+
+  var dbtabs = [];
+  try {
+    while (stmt.executeStep()) {
+      ok(stmt.row.url in tabs,
+         "url is in db, should be in tab: " + stmt.row.url);
+      is(tabs[stmt.row.url], stmt.row.open_count,
+         "db count (" + stmt.row.open_count + ") " +
+         "should match actual open tab count " +
+         "(" + tabs[stmt.row.url] + "): " + stmt.row.url);
+      dbtabs.push(stmt.row.url);
+    }
+  } finally {
+    stmt.finalize();
+  }
+
+  for (let url in tabs) {
+    // ignore URLs that should never be in the places db
+    if (!is_expected_in_db(url))
+      continue;
+    ok(dbtabs.indexOf(url) > -1,
+       "tab is open (" + tabs[url] + " times) and should recorded in db: " + url);
+  }
+}
+
+function is_expected_in_db(url) {
+  var uri = gIOService.newURI(url, null, null);
+  return PlacesUtils.history.canAddURI(uri);
+}
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -56,31 +56,66 @@
         this._setPlaceholder();
 
         this._urlTooltip = document.getElementById("urlTooltip");
 
         this.inputField.controllers.insertControllerAt(0, this._copyCutController);
         this.inputField.addEventListener("mousedown", this, false);
         this.inputField.addEventListener("mousemove", this, false);
         this.inputField.addEventListener("mouseout", this, false);
-        this.inputField.addEventListener("overflow", this, false);
-        this.inputField.addEventListener("underflow", this, false);
+        this.inputField.addEventListener("overflow", this, false);
+        this.inputField.addEventListener("underflow", this, false);
       ]]></constructor>
 
       <destructor><![CDATA[
         this._prefs.removeObserver("", this);
         this._prefs = null;
         this.inputField.controllers.removeController(this._copyCutController);
         this.inputField.removeEventListener("mousedown", this, false);
         this.inputField.removeEventListener("mousemove", this, false);
         this.inputField.removeEventListener("mouseout", this, false);
-        this.inputField.removeEventListener("overflow", this, false);
-        this.inputField.removeEventListener("underflow", this, false);
+        this.inputField.removeEventListener("overflow", this, false);
+        this.inputField.removeEventListener("underflow", this, false);
       ]]></destructor>
 
+      <field name="_value"></field>
+
+      <!--
+        onBeforeValueGet is called by the base-binding's .value getter.
+        It can return an object with a "value" property, to override the
+        return value of the getter.
+      -->
+      <method name="onBeforeValueGet">
+        <body><![CDATA[
+          if (this.hasAttribute("actiontype"))
+            return {value: this._value};
+          return null;
+        ]]></body>
+      </method>
+
+      <!--
+        onBeforeValueSet is called by the base-binding's .value setter.
+        It should return the value that the setter should use.
+      -->
+      <method name="onBeforeValueSet">
+        <parameter name="aValue"/>
+        <body><![CDATA[
+          this._value = aValue;
+          var returnValue = aValue;
+          var action = this._parseActionUrl(aValue);
+          if (action) {
+            returnValue = action.param;
+            this.setAttribute("actiontype", action.type);
+          } else {
+            this.removeAttribute("actiontype");
+          }
+          return returnValue;
+        ]]></body>
+      </method>
+
       <method name="handleRevert">
         <body><![CDATA[
           var isScrolling = this.popupOpen;
 
           gBrowser.userTypedValue = null;
 
           // don't revert to last valid url unless page is NOT loading
           // and user is NOT key-scrolling through autocomplete list
@@ -103,16 +138,23 @@
         <body><![CDATA[
           if (aTriggeringEvent instanceof MouseEvent && aTriggeringEvent.button == 2)
             return; // Do nothing for right clicks
 
           var [url, postData] = this._canonizeURL(aTriggeringEvent);
           if (!url)
             return;
 
+          var action = this._parseActionUrl(url);
+          if (action) {
+            if (action.type == "switchtab")
+              switchToTabHavingURI(action.param);
+            return;
+          }
+
           this.value = url;
           gBrowser.userTypedValue = url;
           try {
             addToUrlbarHistory(url);
           } catch (ex) {
             // Things may go wrong when adding url to session history,
             // but don't let that interfere with the loading of the url.
             Cu.reportError(ex);
@@ -211,22 +253,22 @@
           }
 
           var postData = {};
           url = getShortcutOrURI(url, postData);
 
           return [url, postData.value];
         ]]></body>
       </method>
-
-      <field name="_contentIsCropped">false</field>
+
+      <field name="_contentIsCropped">false</field>
 
       <method name="_initURLTooltip">
         <body><![CDATA[
-          if (this.focused || !this._contentIsCropped)
+          if (this.focused || !this._contentIsCropped)
             return;
           if (this._tooltipTimer)
             clearTimeout(this._tooltipTimer);
           this._tooltipTimer = setTimeout(function (self) {
             self._tooltipTimer = 0;
             var label = self._urlTooltip.firstChild;
             label.value = self.value;
             var bO = self.boxObject;
@@ -384,23 +426,23 @@
               }
               break;
             case "mousemove":
               this._initURLTooltip();
               break;
             case "mouseout":
               this._hideURLTooltip();
               break;
-            case "overflow":
-              this._contentIsCropped = true;
-              break;
-            case "underflow":
-              this._contentIsCropped = false;
-              this._hideURLTooltip();
-              break;
+            case "overflow":
+              this._contentIsCropped = true;
+              break;
+            case "underflow":
+              this._contentIsCropped = false;
+              this._hideURLTooltip();
+              break;
           }
         ]]></body>
       </method>
 
       <property name="textValue"
                 onget="return this.value;">
         <setter>
           <![CDATA[
@@ -437,16 +479,31 @@
               case 2:
                 type = "bookmark";
                 break;
             }
           }
           this.placeholder = this.getAttribute(type + "placeholder");
         ]]></body>
       </method>
+
+      <method name="_parseActionUrl">
+        <parameter name="aUrl"/>
+        <body>
+          <![CDATA[
+            if (!/^moz-action:/.test(aUrl))
+              return null;
+
+            // url is in the format moz-action:ACTION,PARAM
+            let [, action, param] = aUrl.match(/^moz-action:([^,]+),(.*)$/);
+            return {type: action, param: param};
+          ]]>
+        </body>
+      </method>
+
     </implementation>
 
     <handlers>
       <handler event="draggesture" phase="capturing"><![CDATA[
         // TODO: This should use dragstart but editor code is still using
         //       the old drag & drop APIs, so we have to handle draggesture.
         //       This can be changed once editor code is updated to the new API.
         //       See bug 499008 for details.
@@ -608,16 +665,25 @@
           // Check for middle-click or modified clicks on the URL bar
           if (gURLBar && this.mInput == gURLBar) {
             var url = controller.getValueAt(this.selectedIndex);
 
             // close the autocomplete popup and revert the entered address
             this.closePopup();
             controller.handleEscape();
 
+            // Check if this is meant to be an action
+            let action = this.mInput._parseActionUrl(url);
+            if (action) {
+              if (action.type == "switchtab")
+                url = action.param;
+              else
+                return;
+            }
+
             // respect the usual clicking subtleties
             openUILink(url, aEvent);
           }
         ]]>
         </body>
       </method>
 
       <method name="createResultLabel">
@@ -635,9 +701,10 @@
             }
             return label;
           ]]>
         </body>
       </method>
 
     </implementation>
   </binding>
+
 </bindings>
--- a/browser/build.mk
+++ b/browser/build.mk
@@ -50,16 +50,19 @@ tier_app_dirs += $(MOZ_BRANDING_DIRECTOR
 tier_app_dirs += browser
 
 installer:
 	@$(MAKE) -C browser/installer installer
 
 package:
 	@$(MAKE) -C browser/installer
 
+package-compare:
+	@$(MAKE) -C browser/installer package-compare
+
 install::
 	@$(MAKE) -C browser/installer install
 
 clean::
 	@$(MAKE) -C browser/installer clean
 
 distclean::
 	@$(MAKE) -C browser/installer distclean
--- a/browser/components/places/content/utils.js
+++ b/browser/components/places/content/utils.js
@@ -758,40 +758,51 @@ var PlacesUIUtils = {
 
       node = node.parentNode;
     }
 
     return null;
   },
 
   /**
-   * By calling this before we visit a URL, we will use TRANSITION_TYPED
-   * as the transition for the visit to that URL (if we don't have a referrer).
+   * By calling this before visiting an URL, the visit will be associated to a
+   * TRANSITION_TYPED transition (if there is no a referrer).
    * This is used when visiting pages from the history menu, history sidebar,
    * url bar, url autocomplete results, and history searches from the places
-   * organizer.  If we don't call this, we'll treat those visits as
+   * organizer.  If this is not called visits will be marked as
    * TRANSITION_LINK.
    */
   markPageAsTyped: function PU_markPageAsTyped(aURL) {
     PlacesUtils.history.QueryInterface(Ci.nsIBrowserHistory)
                .markPageAsTyped(this.createFixedURI(aURL));
   },
 
   /**
-   * By calling this before we visit a URL, we will use TRANSITION_BOOKMARK
-   * as the transition for the visit to that URL (if we don't have a referrer).
+   * By calling this before visiting an URL, the visit will be associated to a
+   * TRANSITION_BOOKMARK transition.
    * This is used when visiting pages from the bookmarks menu, 
    * personal toolbar, and bookmarks from within the places organizer.
-   * If we don't call this, we'll treat those visits as TRANSITION_LINK.
+   * If this is not called visits will be marked as TRANSITION_LINK.
    */
   markPageAsFollowedBookmark: function PU_markPageAsFollowedBookmark(aURL) {
     PlacesUtils.history.markPageAsFollowedBookmark(this.createFixedURI(aURL));
   },
 
   /**
+   * By calling this before visiting an URL, any visit in frames will be
+   * associated to a TRANSITION_FRAMED_LINK transition.
+   * This is actually used to distinguish user-initiated visits in frames
+   * so automatic visits can be correctly ignored.
+   */
+  markPageAsFollowedLink: function PU_markPageAsUserClicked(aURL) {
+    PlacesUtils.history.QueryInterface(Ci.nsIBrowserHistory)
+               .markPageAsFollowedLink(this.createFixedURI(aURL));
+  },
+
+  /**
    * Allows opening of javascript/data URI only if the given node is
    * bookmarked (see bug 224521).
    * @param aURINode
    *        a URI node
    * @return true if it's safe to open the node in the browser, false otherwise.
    *
    */
   checkURLSecurity: function PU_checkURLSecurity(aURINode) {
--- a/browser/components/shell/src/nsMacShellService.cpp
+++ b/browser/components/shell/src/nsMacShellService.cpp
@@ -51,17 +51,17 @@
 #include "nsIURL.h"
 #include "nsIWebBrowserPersist.h"
 #include "nsMacShellService.h"
 #include "nsNetUtil.h"
 #include "nsShellService.h"
 #include "nsStringAPI.h"
 
 #include <CoreFoundation/CoreFoundation.h>
-#include <Carbon/Carbon.h>
+#include <ApplicationServices/ApplicationServices.h>
 
 #define NETWORK_PREFPANE NS_LITERAL_CSTRING("/System/Library/PreferencePanes/Network.prefPane")
 #define DESKTOP_PREFPANE NS_LITERAL_CSTRING("/System/Library/PreferencePanes/DesktopScreenEffectsPref.prefPane")
 
 #define SAFARI_BUNDLE_IDENTIFIER "com.apple.Safari"
 
 NS_IMPL_ISUPPORTS3(nsMacShellService, nsIMacShellService, nsIShellService, nsIWebProgressListener)
 
--- a/browser/components/wintaskbar/WindowsPreviewPerTab.jsm
+++ b/browser/components/wintaskbar/WindowsPreviewPerTab.jsm
@@ -253,16 +253,22 @@ PreviewController.prototype = {
     let r = { x: Math.floor(rect.left),
               y: Math.floor(rect.top),
               width: Math.ceil(rect.width),
               height: Math.ceil(rect.height)
             };
     this.dirtyRegion.unionRect(r.x, r.y, r.width, r.height);
   },
 
+  updateTitleAndTooltip: function () {
+    let title = this.win.tabbrowser.getWindowTitleForBrowser(this.linkedBrowser);
+    this.preview.title = title;
+    this.preview.tooltip = title;
+  },
+
   //////////////////////////////////////////////////////////////////////////////
   //// nsITaskbarPreviewController 
 
   get width() {
     return this.win.width;
   },
 
   get height() {
@@ -277,18 +283,18 @@ PreviewController.prototype = {
     let tabHeight = boxObject.height || 1;
     return tabWidth / tabHeight;
   },
 
   drawPreview: function (ctx) {
     let self = this;
     this.win.tabbrowser.previewTab(this.tab, function () self.previewTabCallback(ctx));
 
-    // We want a frame drawn around the preview
-    return true;
+    // We must avoid having the frame drawn around the window. See bug 520807
+    return false;
   },
 
   previewTabCallback: function (ctx) {
     let width = this.win.width;
     let height = this.win.height;
     // Draw our toplevel window
     ctx.drawWindow(this.win.win, 0, 0, width, height, "transparent");
 
@@ -340,19 +346,17 @@ PreviewController.prototype = {
         if (preview.visible)
           preview.invalidate();
         break;
       case "pageshow":
       case "DOMTitleChanged":
         // The tab's label is sometimes empty when dragging tabs between windows
         // so we force the tab title to be updated (see bug 520579)
         this.win.tabbrowser.setTabTitle(this.tab);
-        let title = this.tab.label;
-        this.preview.title = title;
-        this.preview.tooltip = title;
+        this.updateTitleAndTooltip();
         break;
     }
   }
 };
 
 XPCOMUtils.defineLazyGetter(PreviewController.prototype, "canvasPreviewFlags",
   function () { let canvasInterface = Ci.nsIDOMCanvasRenderingContext2D;
                 return canvasInterface.DRAWWINDOW_DRAW_VIEW
@@ -414,32 +418,37 @@ 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(tab.linkedBrowser.docShell, controller);
-    preview.title = tab.label;
-    preview.tooltip = tab.label;
+    let docShell = this.win
+                  .QueryInterface(Ci.nsIInterfaceRequestor)
+                  .getInterface(Ci.nsIWebNavigation)
+                  .QueryInterface(Ci.nsIDocShell);
+    let preview = AeroPeek.taskbar.createTaskbarTabPreview(docShell, controller);
     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.
       if (!preview.icon)
         preview.icon = img;
     });
 
     // It's OK to add the preview now while the favicon still loads.
     this.previews.splice(tab._tPos, 0, preview);
     AeroPeek.addPreview(preview);
+    // updateTitleAndTooltip relies on having controller.preview which is lazily resolved.
+    // Now that we've updated this.previews, it will resolve successfully.
+    controller.updateTitleAndTooltip();
   },
 
   // Invoked when the given tab is closed
   removeTab: function (tab) {
     let preview = this.previewFromTab(tab);
     preview.active = false;
     preview.visible = false;
     preview.move(null);
--- a/browser/installer/Makefile.in
+++ b/browser/installer/Makefile.in
@@ -104,26 +104,44 @@ endif
 
 ifndef LIBXUL_SDK
 INSTALL_SDK = 1
 endif
 
 include $(topsrcdir)/toolkit/mozapps/installer/packager.mk
 
 ifeq (bundle, $(MOZ_FS_LAYOUT))
-DEFINES += \
-  -DBINPATH=$(_BINPATH) \
-  -DAPPNAME=$(_APPNAME) \
-  $(NULL)
+BINPATH = $(_BINPATH)
+DEFINES += -DAPPNAME=$(_APPNAME)
 else
 # Every other platform just winds up in dist/bin
-DEFINES += -DBINPATH=bin
+BINPATH = bin
 endif
+DEFINES += -DBINPATH=$(BINPATH)
 
 libs::
 	$(MAKE) -C $(DEPTH)/browser/locales langpack PKG_LANGPACK_PATH=
 
 UPLOAD_EXTRA_FILES += $(PKG_LANGPACK_BASENAME).xpi
 
+ifeq (WINNT,$(OS_ARCH))
+PKGCOMP_FIND_OPTS =
+else
+PKGCOMP_FIND_OPTS = -L
+endif
+ifeq (Darwin, $(OS_ARCH))
+FINDPATH = $(_APPNAME)/Contents/MacOS
+else
+FINDPATH=bin
+endif
+
+package-compare:: $(MOZ_PKG_MANIFEST)
+ifdef MOZ_PKG_MANIFEST_P
+	cd $(DIST); find $(PKGCOMP_FIND_OPTS) $(FINDPATH) -type f | sort > bin-list.txt
+	grep "^$(BINPATH)" $(MOZ_PKG_MANIFEST) | sed -e 's/^\///' | sort > $(DIST)/pack-list.txt
+	-diff -u $(DIST)/pack-list.txt $(DIST)/bin-list.txt
+	rm -f $(DIST)/pack-list.txt $(DIST)/bin-list.txt
+endif
+
 installer:: removed-files
 ifdef INSTALLER_DIR
 	$(MAKE) -C $(INSTALLER_DIR)
 endif
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -202,16 +202,17 @@
 <!ENTITY showAllHistoryCmd.commandkey "H">
 
 <!ENTITY openCmd.commandkey           "l">
 <!ENTITY urlbar.bookmarkhistory.emptyText "Search Bookmarks and History">
 <!ENTITY urlbar.bookmark.emptyText    "Search Bookmarks">
 <!ENTITY urlbar.history.emptyText     "Search History">
 <!ENTITY urlbar.none.emptyText        "Type a Web address">
 <!ENTITY urlbar.accesskey             "d">
+<!ENTITY urlbar.switchToTab.label     "Switch to tab:">
 
 <!-- 
   Comment duplicated from browser-sets.inc:
 
   Search Command Key Logic works like this:
   
   Unix: Ctrl+J (0.8, 0.9 support)
         Ctrl+K (cross platform binding)
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..fed3d7f7cde2835388bf7ad5694e18d8042dba77
GIT binary patch
literal 293
zc%17D@N?(olHy`uVBq!ia0vp^;y^6G!3HG%>OYYHQY`6?zK#qG8~eHcB(eheoCO|{
z#S9F5hd`K7RKu$QC@5Lt8c`CQpH@<ySd_{TkeHcQqUYxtqEKe6XR2rD_uS$qP|+e!
z7sn6_|F;vpxta|`T<<zPJGWV5`olAGBYp)oZP_xnL}O|5I-PsWTzo#JP6r$L`550H
z|1e4AcTOU6eC#9Td)x=T(=Ki)+Iu9}=7=qWl-!<_XUD7OH_z!^aa5Hd%J|dy>HRWO
z=DSET@Sb0_Q?vA6U|*YhU5{b-Qmw)nKN#<?x+fg}ZjSbvt;Y}C%Qmt3c-HI1!k~$~
m{APuVmaaba{la~-3yjQFY5TRMSrdV-W$<+Mb6Mw<&;$U6Ic<Od
--- a/browser/themes/gnomestripe/browser/browser.css
+++ b/browser/themes/gnomestripe/browser/browser.css
@@ -795,16 +795,27 @@ toolbar[iconsize="small"] #fullscreen-bu
 #urlbar-search-splitter + #search-container > #searchbar > .searchbar-textbox {
   -moz-margin-start: 0;
 }
 
 #wrapper-urlbar-container #urlbar > .autocomplete-history-dropmarker {
   display: none;
 }
 
+#urlbar-display {
+  margin-top: -2px;
+  margin-bottom: -2px;
+  padding-top: 3px;
+  padding-bottom: 2px;
+  -moz-padding-end: 3px;
+  color: GrayText;
+  -moz-border-end: 1px solid #AAA;
+  -moz-margin-end: 3px;
+}
+
 #PopupAutoComplete,
 #PopupAutoCompleteRichResult {
   direction: ltr !important;
 }
 
 #PopupAutoComplete:-moz-locale-dir(rtl) > tree > treerows {
   direction: rtl;
 }
@@ -993,16 +1004,20 @@ toolbar[iconsize="small"] #fullscreen-bu
 .ac-extra > .ac-comment {
   font-size: inherit;
 }
 
 .ac-url-text {
   color: -moz-nativehyperlinktext;
 }
 
+richlistitem[type="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
+  list-style-image: url("chrome://browser/skin/actionicon-tab.png");
+}
+
 .autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
   color: GrayText;
 }
 
 .ac-comment[selected="true"], .ac-url-text[selected="true"] {
   color: inherit !important;
 }
 
@@ -1185,30 +1200,18 @@ statusbarpanel#statusbar-display {
   list-style-image: url("moz-icon://stock/gtk-undelete?size=menu");
 }
 
 #context_closeTab {
   list-style-image: url("moz-icon://stock/gtk-close?size=menu");
 }
 
 /* Tab drag and drop */
-.tab-drop-indicator-bar {
-  height: 11px;
-  margin-top: -11px;
-  position: relative;
-  /* set -moz-margin-start to -1/2 indicator width: */
-  -moz-margin-start: -5px;
-}
-
 .tab-drop-indicator {
-  height: 11px;
-  width: 11px;
-  margin-bottom: -5px;
-  position: relative;
-  background: url('chrome://browser/skin/tabbrowser/tabDragIndicator.png') 50% 50% no-repeat;
+  list-style-image: url(chrome://browser/skin/tabbrowser/tabDragIndicator.png);
 }
 
 /* In-tab close button */
 .tab-close-button > .toolbarbutton-icon {
   /* XXX Buttons have padding in widget/ that we don't want here but can't override with good CSS, so we must
      use evil CSS to give the impression of smaller content */
   margin: -3px !important;
 }
--- a/browser/themes/gnomestripe/browser/jar.mn
+++ b/browser/themes/gnomestripe/browser/jar.mn
@@ -1,16 +1,17 @@
 browser.jar:
 % skin browser classic/1.0 %skin/classic/browser/
 % override chrome://global/skin/icons/warning-16.png moz-icon://stock/gtk-dialog-warning?size=menu
   skin/classic/browser/sanitizeDialog.css             (sanitizeDialog.css)
 * skin/classic/browser/aboutPrivateBrowsing.css             (aboutPrivateBrowsing.css)
 * skin/classic/browser/aboutSessionRestore.css        (aboutSessionRestore.css)
   skin/classic/browser/aboutSessionRestore-window-icon.png
   skin/classic/browser/aboutCertError.css             (aboutCertError.css)
+  skin/classic/browser/actionicon-tab.png
 * skin/classic/browser/browser.css                    (browser.css)
 * skin/classic/browser/engineManager.css              (engineManager.css)
   skin/classic/browser/fullscreen-video.css
   skin/classic/browser/Geo.png
   skin/classic/browser/Go-arrow.png
   skin/classic/browser/identity.png
   skin/classic/browser/Info.png
   skin/classic/browser/KUI-close.png
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..fed3d7f7cde2835388bf7ad5694e18d8042dba77
GIT binary patch
literal 293
zc%17D@N?(olHy`uVBq!ia0vp^;y^6G!3HG%>OYYHQY`6?zK#qG8~eHcB(eheoCO|{
z#S9F5hd`K7RKu$QC@5Lt8c`CQpH@<ySd_{TkeHcQqUYxtqEKe6XR2rD_uS$qP|+e!
z7sn6_|F;vpxta|`T<<zPJGWV5`olAGBYp)oZP_xnL}O|5I-PsWTzo#JP6r$L`550H
z|1e4AcTOU6eC#9Td)x=T(=Ki)+Iu9}=7=qWl-!<_XUD7OH_z!^aa5Hd%J|dy>HRWO
z=DSET@Sb0_Q?vA6U|*YhU5{b-Qmw)nKN#<?x+fg}ZjSbvt;Y}C%Qmt3c-HI1!k~$~
m{APuVmaaba{la~-3yjQFY5TRMSrdV-W$<+Mb6Mw<&;$U6Ic<Od
--- a/browser/themes/pinstripe/browser/browser.css
+++ b/browser/themes/pinstripe/browser/browser.css
@@ -836,16 +836,27 @@ toolbar[iconsize="small"] #unified-back-
   -moz-border-radius-bottomleft: 0;
   -moz-box-shadow: -1px 0 rgba(0,0,0,.4) inset;
 }
 
 #urlbar-icons {
   -moz-box-align: center;
 }
 
+#urlbar-display {
+  margin-top: -2px;
+  margin-bottom: -2px;
+  padding-top: 3px;
+  padding-bottom: 2px;
+  -moz-padding-end: 3px;
+  color: GrayText;
+  -moz-border-end: 1px solid #AAA;
+  -moz-margin-end: 3px;
+}
+
 #urlbar-search-splitter {
   min-width: 8px;
   width: 8px;
   background-image: none;
   -moz-margin-start: -4px;
 }
 
 #urlbar-search-splitter + #urlbar-container > #urlbar,
@@ -953,16 +964,20 @@ richlistitem[selected="true"][current="t
   font-size: inherit;
 }
 
 .ac-url-text {
   color: -moz-nativehyperlinktext;
   font-size: 0.95em;
 }
 
+richlistitem[type="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
+  list-style-image: url("chrome://browser/skin/actionicon-tab.png");
+}
+
 .autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
   color: GrayText;
 }
 
 .ac-comment[selected="true"], .ac-url-text[selected="true"] {
   color: inherit !important;
 }
 
@@ -1613,30 +1628,19 @@ tabbrowser > tabbox {
 .tabbrowser-tabs[overflow="true"] .tabs-left {
   display: none;
 }
 
 /**
  * Tab Drag and Drop
  */
 
-.tab-drop-indicator-bar {
-  height: 10px;
-  margin-top: -10px;
-  position: relative;
-  /* set -moz-margin-start to -1/2 indicator width: */
-  -moz-margin-start: -4px;
-}
-
 .tab-drop-indicator {
-  height: 33px;
-  width: 10px;
-  margin-bottom: -24px;
-  position: relative;
-  background: url('chrome://browser/skin/tabbrowser/tabDragIndicator.png') 50% 40% no-repeat;
+  margin-top: -8px !important;
+  list-style-image: url(chrome://browser/skin/tabbrowser/tabDragIndicator.png);
 }
 
 /**
  * In-tab close button
  */
 
 .tab-close-button > .toolbarbutton-icon {
   -moz-margin-end: 0px !important;
--- a/browser/themes/pinstripe/browser/jar.mn
+++ b/browser/themes/pinstripe/browser/jar.mn
@@ -1,15 +1,16 @@
 browser.jar:
 % skin browser classic/1.0 %skin/classic/browser/
   skin/classic/browser/sanitizeDialog.css                   (sanitizeDialog.css)
 * skin/classic/browser/aboutPrivateBrowsing.css             (aboutPrivateBrowsing.css)
 * skin/classic/browser/aboutSessionRestore.css              (aboutSessionRestore.css)
   skin/classic/browser/aboutSessionRestore-window-icon.png
   skin/classic/browser/aboutCertError.css                   (aboutCertError.css)
+  skin/classic/browser/actionicon-tab.png
 * skin/classic/browser/browser.css                          (browser.css)
 * skin/classic/browser/engineManager.css                    (engineManager.css)
   skin/classic/browser/feed-icons.png
   skin/classic/browser/fullscreen-video.css
   skin/classic/browser/Geo.png
   skin/classic/browser/Go-arrow.png
   skin/classic/browser/home.png
   skin/classic/browser/hud-panel.png
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..fed3d7f7cde2835388bf7ad5694e18d8042dba77
GIT binary patch
literal 293
zc%17D@N?(olHy`uVBq!ia0vp^;y^6G!3HG%>OYYHQY`6?zK#qG8~eHcB(eheoCO|{
z#S9F5hd`K7RKu$QC@5Lt8c`CQpH@<ySd_{TkeHcQqUYxtqEKe6XR2rD_uS$qP|+e!
z7sn6_|F;vpxta|`T<<zPJGWV5`olAGBYp)oZP_xnL}O|5I-PsWTzo#JP6r$L`550H
z|1e4AcTOU6eC#9Td)x=T(=Ki)+Iu9}=7=qWl-!<_XUD7OH_z!^aa5Hd%J|dy>HRWO
z=DSET@Sb0_Q?vA6U|*YhU5{b-Qmw)nKN#<?x+fg}ZjSbvt;Y}C%Qmt3c-HI1!k~$~
m{APuVmaaba{la~-3yjQFY5TRMSrdV-W$<+Mb6Mw<&;$U6Ic<Od
--- a/browser/themes/winstripe/browser/browser.css
+++ b/browser/themes/winstripe/browser/browser.css
@@ -596,16 +596,27 @@ toolbar:not([iconsize="small"])[mode="ic
 #urlbar-search-splitter + #search-container > #searchbar > .searchbar-textbox {
   -moz-margin-start: 0;
 }
 
 #wrapper-urlbar-container > #urlbar-container > #urlbar > .autocomplete-history-dropmarker {
   display: none;
 }
 
+#urlbar-display {
+  margin-top: -2px;
+  margin-bottom: -2px;
+  padding-top: 3px;
+  padding-bottom: 2px;
+  -moz-padding-end: 3px;
+  color: GrayText;
+  -moz-border-end: 1px solid #AAA;
+  -moz-margin-end: 3px;
+}
+
 #urlbar > .autocomplete-textbox-container {
   direction: ltr;
   -moz-box-align: stretch;
 }
 
 /* identity box */
 
 #identity-box {
@@ -758,16 +769,20 @@ toolbar:not([iconsize="small"])[mode="ic
 .ac-url-text {
   color: -moz-nativehyperlinktext;
 }
 
 .ac-url-text:-moz-system-metric(windows-default-theme) {
   color: #006600;
 }
 
+richlistitem[type="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-icon {
+  list-style-image: url("chrome://browser/skin/actionicon-tab.png");
+}
+
 .autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
   color: GrayText;
 }
 
 .ac-comment[selected="true"], .ac-url-text[selected="true"] {
   color: inherit !important;
 }
 
@@ -1035,30 +1050,18 @@ toolbar:not([iconsize="small"])[mode="ic
   border: 1px dotted transparent;
 }
 
 .tabbrowser-tab:focus > .tab-text {
   border: 1px dotted -moz-DialogText;
 }
 
 /* Tab DnD indicator */
-.tab-drop-indicator-bar {
-  height: 11px;
-  margin-top: -11px;
-  position: relative;
-  /* set -moz-margin-start to -1/2 indicator width: */
-  -moz-margin-start: -5px;
-}
-
 .tab-drop-indicator {
-  height: 11px;
-  width: 11px;
-  margin-bottom: -5px;
-  position: relative;
-  background: url('chrome://browser/skin/tabbrowser/tabDragIndicator.png') 50% 50% no-repeat;
+  list-style-image: url(chrome://browser/skin/tabbrowser/tabDragIndicator.png);
 }
 
 /* Tab close button */
 .tab-close-button > .toolbarbutton-icon {
   -moz-margin-end: 0px !important;
   margin-top: 1px;
 }
 
--- a/browser/themes/winstripe/browser/jar.mn
+++ b/browser/themes/winstripe/browser/jar.mn
@@ -3,16 +3,17 @@ browser.jar:
 % skin browser classic/1.0 %skin/classic/browser/ os!=WINNT
 # NOTE: If you add a new file here, you'll need to add it to the aero
 # section at the bottom of this file
         skin/classic/browser/sanitizeDialog.css                      (sanitizeDialog.css)
 *       skin/classic/browser/aboutPrivateBrowsing.css                (aboutPrivateBrowsing.css)
 *       skin/classic/browser/aboutSessionRestore.css                 (aboutSessionRestore.css)
         skin/classic/browser/aboutSessionRestore-window-icon.png     (aboutSessionRestore-window-icon.png)
         skin/classic/browser/aboutCertError.css                      (aboutCertError.css)
+        skin/classic/browser/actionicon-tab.png
 *       skin/classic/browser/browser.css                             (browser.css)
 *       skin/classic/browser/engineManager.css                       (engineManager.css)
         skin/classic/browser/fullscreen-video.css
         skin/classic/browser/Geo.png                                 (Geo.png)
         skin/classic/browser/Info.png                                (Info.png)
         skin/classic/browser/identity.png                            (identity.png)
         skin/classic/browser/keyhole-forward-mask.svg
         skin/classic/browser/KUI-background.png
@@ -90,16 +91,17 @@ browser.jar:
 #ifdef XP_WIN
 browser.jar:
 % skin browser classic/1.0 %skin/classic/aero/browser/ os=WINNT osversion>=6
         skin/classic/aero/browser/sanitizeDialog.css                       (sanitizeDialog.css)
 *       skin/classic/aero/browser/aboutPrivateBrowsing.css           (aboutPrivateBrowsing.css)
 *       skin/classic/aero/browser/aboutSessionRestore.css            (aboutSessionRestore.css)
         skin/classic/aero/browser/aboutSessionRestore-window-icon.png (aboutSessionRestore-window-icon-aero.png)
         skin/classic/aero/browser/aboutCertError.css                 (aboutCertError.css)
+        skin/classic/aero/browser/actionicon-tab.png                 (actionicon-tab.png)
 *       skin/classic/aero/browser/browser.css                        (browser-aero.css)
 *       skin/classic/aero/browser/engineManager.css                  (engineManager.css)
         skin/classic/aero/browser/fullscreen-video.css
         skin/classic/aero/browser/Geo.png                            (Geo-aero.png)
         skin/classic/aero/browser/Info.png                           (Info-aero.png)
         skin/classic/aero/browser/identity.png                       (identity-aero.png)
         skin/classic/aero/browser/keyhole-forward-mask.svg
         skin/classic/aero/browser/KUI-background.png
--- a/build/Makefile.in
+++ b/build/Makefile.in
@@ -51,19 +51,26 @@ endif
 
 ifeq (WINNT,$(OS_ARCH))
 DIRS = win32
 endif
 
 ifdef WINCE
 # We need jemalloc built before the shunt
 ifdef MOZ_MEMORY
-DIRS += wince/tools $(DEPTH)/memory/jemalloc $(DEPTH)/memory/mozalloc wince/shunt
+DIRS += wince/tools \
+	$(DEPTH)/memory/jemalloc \
+	wince/shunt \
+	$(DEPTH)/memory/mozalloc \
+	$(NULL)
 else
-DIRS += wince/tools $(DEPTH)/memory/mozalloc wince/shunt
+DIRS += wince/tools \
+	wince/shunt \
+	$(DEPTH)/memory/mozalloc \
+	$(NULL)
 endif
 endif
 
 DIRS += pgo
 
 include $(topsrcdir)/config/rules.mk
 
 # we install to _leaktest/
new file mode 100644
--- /dev/null
+++ b/build/mobile/devicemanager-run-test.py
@@ -0,0 +1,89 @@
+# ***** 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 remote test framework.
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2010
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+import devicemanager
+import sys
+import os
+
+
+def main():
+    ip_addr = os.environ.get("DEVICE_IP")
+    port = os.environ.get("DEVICE_PORT")
+    gre_path = os.environ.get("REMOTE_GRE_PATH").replace('\\','/')
+
+    if ip_addr == None:
+        print "Error: please define the environment variable DEVICE_IP before running this test"
+        sys.exit(1)
+
+    if port == None:
+        print "Error: please define the environment variable DEVICE_PORT before running this test"
+        sys.exit(1)
+
+    if gre_path == None:
+        print "Error: please define the environment variable REMOTE_GRE_PATH before running this test"
+        sys.exit(1)
+
+    dm = devicemanager.DeviceManager(ip_addr, int(port))
+    if len(sys.argv) < 2:
+        print "usage python devicemanager-run-test.py <test program> [args1 [arg2..]]"
+        sys.exit(1)
+
+    cmd = sys.argv[1]
+    args = ' '
+    if len(sys.argv) > 2:
+        args = ' ' + ' '.join(sys.argv[2:])
+
+    dm.debug = 0
+    lastslash = cmd.rfind('/');
+    if lastslash == -1:
+        lastslash = 0
+    dm.pushFile(cmd, gre_path + cmd[lastslash:])
+    process = dm.launchProcess([gre_path  + cmd[lastslash:] + args])
+    output_list = dm.communicate(process)
+    ret = -1
+    if (output_list != None and output_list[0] != None):
+        try:
+            output = output_list[0]
+            index = output.find('exited with return code')
+            print output[0:index]
+            retstr = (output[index + 24 : output.find('\n', index)])
+            ret = int(retstr)
+        except ValueError:
+            ret = -1
+    sys.exit(ret)
+
+if __name__ == '__main__':
+    main()
new file mode 100644
--- /dev/null
+++ b/build/mobile/devicemanager-utils.py
@@ -0,0 +1,88 @@
+# ***** 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 remote test framework.
+#
+# The Initial Developer of the Original Code is
+# the Mozilla Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2010
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+import devicemanager
+import sys
+import os
+
+def copy(dm, gre_path):
+    file = sys.argv[2]
+    if len(sys.argv) >= 4:
+        path = sys.argv[3]
+    else:
+        path = gre_path
+    if os.path.isdir(file):
+        dm.pushDir(file, path.replace('\\','/'))
+    else:
+        dm.pushFile(file, path.replace('\\','/'))
+
+def delete(dm, gre_path):
+    file = sys.argv[2]
+    dm.removeFile(file)
+
+def main():
+    ip_addr = os.environ.get("DEVICE_IP")
+    port = os.environ.get("DEVICE_PORT")
+    gre_path = os.environ.get("REMOTE_GRE_PATH").replace('\\','/')
+
+    if ip_addr == None:
+        print "Error: please define the environment variable DEVICE_IP before running this test"
+        sys.exit(1)
+
+    if port == None:
+        print "Error: please define the environment variable DEVICE_PORT before running this test"
+        sys.exit(1)
+
+    if gre_path == None:
+        print "Error: please define the environment variable REMOTE_GRE_PATH before running this test"
+        sys.exit(1)
+
+    dm = devicemanager.DeviceManager(ip_addr, int(port))
+    dm.sendCMD(['cd '+ gre_path], sleep = 1)
+    dm.debug = 0
+
+    if len(sys.argv) < 3:
+        print "usage: python devicemanager-utils.py <cmd> <path> [arg]"
+    cmd = sys.argv[1]
+    if (cmd == 'copy'):
+        sys.exit(copy(dm, gre_path))
+    if (cmd == 'delete'):
+        sys.exit(delete(dm, gre_path))
+    print "unrecognized command. supported commands are copy and delete"
+    sys.exit(-1)
+
+if __name__ == '__main__':
+    main()
rename from build/devicemanager.py
rename to build/mobile/devicemanager.py
--- a/build/wince/shunt/Makefile.in
+++ b/build/wince/shunt/Makefile.in
@@ -78,26 +78,26 @@ EXPORTS_mozce_shunt += $(topsrcdir)/memo
 
 # We have to include the obj file directly, because we want to export
 # some of its symbols through our def file
 EXTRA_LIBS += $(OBJDIR)/memory/jemalloc/jemalloc.obj
 endif
 
 DEFFILE = mozce_shunt.def
 
-OS_LIBS += $(call EXPAND_LIBNAME, libcmt)
+OS_LIBS = $(call EXPAND_LIBNAME, libcmt)
 
 CPPSRCS = \
 	shunt.cpp \
 	environment.cpp \
 	time.cpp \
 	memory.cpp \
 	$(NULL)
 
-DEFINES += -DMOZCE_SHUNT_EXPORTS
+DEFINES += -DMOZCE_SHUNT_EXPORTS -DIN_SHUNT
 
 include $(topsrcdir)/config/rules.mk
 
 mozce_shunt.def: mozce_shunt.def.in
 	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $^ > $@
 
 .NOTPARALLEL:
 
--- a/build/wince/shunt/include/mozce_shunt.h
+++ b/build/wince/shunt/include/mozce_shunt.h
@@ -94,17 +94,17 @@ inline void operator delete[](void* ptr,
 // some reason, but it's a noop in any case)
 inline void *operator new(size_t, void *p) {
   return p;
 }
 inline void *operator new[](size_t, void *p) {
   return p;
 }
 
-
+#ifndef IN_SHUNT
 // for Gecko, include infallible mozalloc allocators.  elsewhere, define
 // operator new() normally.
 // NB: this include guard needs to be kept in sync with the one in nscore.h
 #if defined(_MOZILLA_CONFIG_H_) && !defined(XPCOM_GLUE) && !defined(NS_NO_XPCOM) && !defined(MOZ_NO_MOZALLOC)
 #  include "mozilla/mozalloc.h"
 #else
 
 inline void* operator new(size_t size) throw() {
@@ -116,17 +116,17 @@ inline void* operator new[](size_t size)
 inline void operator delete(void* ptr) throw() {
   free(ptr);
 }
 inline void operator delete[](void* ptr) throw() {
   free(ptr);
 }
 
 #endif  // if defined(_MOZILLA_CONFIG_H_)
-
+#endif
 
 extern "C" {
 #endif
 
 #undef _strdup
 #undef strdup
 #undef _strndup
 #undef strndup
--- a/build/wince/shunt/memory.cpp
+++ b/build/wince/shunt/memory.cpp
@@ -34,45 +34,39 @@
  * 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 "include/mozce_shunt.h"
 #include <stdlib.h>
 
-#include "mozilla/mozalloc_macro_wrappers.h" /* infallible malloc */
-
 #ifdef MOZ_MEMORY
 
 // declare the nothrow object
 const std::nothrow_t std::nothrow;
 
 char*
 _strndup(const char *src, size_t len) {
   char* dst = (char*)malloc(len + 1);
-  // FIXME/bug 507249: no need to null-check when infallible
-  // allocators are used
   if(dst)
     strncpy(dst, src, len + 1);
   return dst;
 }
 
 
 char*
 _strdup(const char *src) {
   size_t len = strlen(src);
   return _strndup(src, len );
 }
 
 wchar_t * 
 _wcsndup(const wchar_t *src, size_t len) {
   wchar_t* dst = (wchar_t*)malloc(sizeof(wchar_t) * (len + 1));
-  // FIXME/bug 507249: no need to null-check when infallible
-  // allocators are used
   if(dst)
     wcsncpy(dst, src, len + 1);
   return dst;
 }
 
 wchar_t * 
 _wcsdup(const wchar_t *src) {
   size_t len = wcslen(src);
--- a/build/wince/tools/Makefile.in
+++ b/build/wince/tools/Makefile.in
@@ -52,9 +52,11 @@ CFLAGS += -DMOZ_MEMORY
 endif
 
 include $(topsrcdir)/build/wince/tools/Makefile
 
 export::
 
 tools::
 
+check::
+
 .NOTPARALLEL:
--- a/chrome/src/nsChromeRegistry.cpp
+++ b/chrome/src/nsChromeRegistry.cpp
@@ -43,17 +43,17 @@
 
 #include <string.h>
 
 #include "prio.h"
 #include "prprf.h"
 #if defined(XP_WIN)
 #include <windows.h>
 #elif defined(XP_MACOSX)
-#include <Carbon/Carbon.h>
+#include <CoreServices/CoreServices.h>
 #elif defined(MOZ_WIDGET_GTK2)
 #include <gtk/gtk.h>
 #endif
 
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsArrayEnumerator.h"
 #include "nsStringEnumerator.h"
 #include "nsEnumeratorUtils.h"
--- a/client.py
+++ b/client.py
@@ -79,21 +79,23 @@ except IndexError:
 if action in ('checkout', 'co'):
     print >>sys.stderr, "Warning: client.py checkout is obsolete."
     pass
 elif action in ('update_nspr'):
     tag, = args[1:]
     if not options.cvsroot:
         options.cvsroot = os.environ.get('CVSROOT', CVSROOT_MOZILLA)
     do_cvs_export(NSPR_DIRS, tag, options.cvsroot, options.cvs)
+    print >>file("nsprpub/TAG-INFO", "w"), tag
 elif action in ('update_nss'):
     tag, = args[1:]
     if not options.cvsroot:
         options.cvsroot = os.environ.get('CVSROOT', CVSROOT_MOZILLA)
     do_cvs_export(NSS_DIRS, tag, options.cvsroot, options.cvs)
+    print >>file("security/nss/TAG-INFO", "w"), tag
 elif action in ('update_libffi'):
     tag, = args[1:]
     if not options.cvsroot:
         options.cvsroot = CVSROOT_LIBFFI
     do_cvs_export(LIBFFI_DIRS, tag, options.cvsroot, options.cvs)
 else:
     o.print_help()
     sys.exit(2)
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -142,16 +142,17 @@ MOZ_ACTIVEX_SCRIPTING_SUPPORT = @MOZ_ACT
 MOZ_DISABLE_VISTA_SDK_REQUIREMENTS = @MOZ_DISABLE_VISTA_SDK_REQUIREMENTS@
 MOZ_DISABLE_PARENTAL_CONTROLS = @MOZ_DISABLE_PARENTAL_CONTROLS@
 XPC_IDISPATCH_SUPPORT = @XPC_IDISPATCH_SUPPORT@
 NS_ENABLE_TSF = @NS_ENABLE_TSF@
 MOZ_SPELLCHECK = @MOZ_SPELLCHECK@
 MOZ_XPFE_COMPONENTS = @MOZ_XPFE_COMPONENTS@
 MOZ_PROFILELOCKING = @MOZ_PROFILELOCKING@
 MOZ_FEEDS = @MOZ_FEEDS@
+MOZ_TOOLKIT_SEARCH = @MOZ_TOOLKIT_SEARCH@
 MOZ_PLACES = @MOZ_PLACES@
 MOZ_PLACES_BOOKMARKS = @MOZ_PLACES_BOOKMARKS@
 MOZ_STORAGE = @MOZ_STORAGE@
 MOZ_SAFE_BROWSING = @MOZ_SAFE_BROWSING@
 MOZ_FASTSTART = @MOZ_FASTSTART@
 MOZ_URL_CLASSIFIER = @MOZ_URL_CLASSIFIER@
 MOZ_ZIPWRITER = @MOZ_ZIPWRITER@
 MOZ_MORK = @MOZ_MORK@
--- a/config/config.mk
+++ b/config/config.mk
@@ -812,23 +812,27 @@ ifdef LOCALE_MERGEDIR
 MAKE_JARS_FLAGS += -c $(LOCALE_MERGEDIR)/$(subst /locales,,$(relativesrcdir))
 endif
 MAKE_JARS_FLAGS += -c $(LOCALE_SRCDIR)
 ifdef LOCALE_MERGEDIR
 MAKE_JARS_FLAGS += -c $(topsrcdir)/$(relativesrcdir)/en-US
 endif
 endif
 
+ifdef WINCE
+RUN_TEST_PROGRAM = $(PYTHON) $(topsrcdir)/build/mobile/devicemanager-run-test.py
+else
 ifeq (,$(filter WINCE WINNT OS2,$(OS_ARCH)))
 RUN_TEST_PROGRAM = $(DIST)/bin/run-mozilla.sh
 endif
 
 ifeq ($(OS_ARCH),OS2)
 RUN_TEST_PROGRAM = $(topsrcdir)/build/os2/test_os2.cmd "$(DIST)"
 endif
+endif
 
 #
 # Java macros
 #
 
 # Make sure any compiled classes work with at least JVM 1.4
 JAVAC_FLAGS += -source 1.4
 
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -204,17 +204,17 @@ ifdef CPP_UNIT_TESTS
 CPPSRCS += $(CPP_UNIT_TESTS)
 SIMPLE_PROGRAMS += $(CPP_UNIT_TESTS:.cpp=$(BIN_SUFFIX))
 INCLUDES += -I$(DIST)/include/testing
 LIBS += $(XPCOM_GLUE_LDOPTS) $(NSPR_LIBS)
 
 # ...and run them the usual way
 check::
 	@$(EXIT_ON_ERROR) \
-	  for f in $(subst .cpp,,$(CPP_UNIT_TESTS)); do \
+	  for f in $(subst .cpp,$(BIN_SUFFIX),$(CPP_UNIT_TESTS)); do \
 	    XPCOM_DEBUG_BREAK=stack-and-abort $(RUN_TEST_PROGRAM) $(DIST)/bin/$$f; \
 	  done
 
 endif # CPP_UNIT_TESTS
 
 .PHONY: check xpcshell-tests check-interactive check-one
 
 endif # ENABLE_TESTS
@@ -1076,17 +1076,17 @@ endif
 # in one directory, it assumes everything to compile Foo is in
 # Foo.o (from either Foo.c or Foo.cpp).
 #
 # SIMPLE_PROGRAMS = Foo Bar
 # creates Foo.o Bar.o, links with LIBS to create Foo, Bar.
 #
 $(SIMPLE_PROGRAMS): %$(BIN_SUFFIX): %.$(OBJ_SUFFIX) $(LIBS_DEPS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
 ifeq (WINCE,$(OS_ARCH))
-	$(LD) -nologo  -entry:main -out:$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS) $(EXTRA_LIBS) $(OS_LIBS)
+	$(LD) -nologo  -entry:mainACRTStartup -out:$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS) $(EXTRA_LIBS) $(OS_LIBS)
 else
 ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
 	$(LD) -nologo -out:$@ -pdb:$(LINK_PDBFILE) $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(LIBS) $(EXTRA_LIBS) $(OS_LIBS)
 ifdef MSMANIFEST_TOOL
 	@if test -f $@.manifest; then \
 		mt.exe -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \
 		rm -f $@.manifest; \
 	fi
--- a/configure.in
+++ b/configure.in
@@ -4727,16 +4727,17 @@ MOZ_REFLOW_PERF=
 MOZ_SAFE_BROWSING=
 MOZ_FASTSTART=
 MOZ_HELP_VIEWER=
 MOZ_SPELLCHECK=1
 MOZ_SPLASHSCREEN=
 MOZ_STORAGE=1
 MOZ_SVG=1
 MOZ_TIMELINE=
+MOZ_TOOLKIT_SEARCH=1
 MOZ_UI_LOCALE=en-US
 MOZ_UNIVERSALCHARDET=1
 MOZ_URL_CLASSIFIER=
 MOZ_USE_NATIVE_UCONV=
 MOZ_VIEW_SOURCE=1
 MOZ_XPFE_COMPONENTS=1
 MOZ_XPINSTALL=1
 MOZ_XSLT_STANDALONE=
@@ -8197,16 +8198,17 @@ AC_SUBST(MOZ_INSURE)
 AC_SUBST(MOZ_INSURE_DIRS)
 AC_SUBST(MOZ_INSURE_EXCLUDE_DIRS)
 AC_SUBST(MOZ_QUANTIFY)
 AC_SUBST(MOZ_INSURIFYING)
 AC_SUBST(LIBICONV)
 AC_SUBST(MOZ_PLACES)
 AC_SUBST(MOZ_PLACES_BOOKMARKS)
 AC_SUBST(MOZ_STORAGE)
+AC_SUBST(MOZ_TOOLKIT_SEARCH)
 AC_SUBST(MOZ_FEEDS)
 AC_SUBST(NS_PRINTING)
 AC_SUBST(MOZ_WEBGL)
 
 AC_SUBST(MOZ_JAVAXPCOM)
 AC_SUBST(JAVA_INCLUDE_PATH)
 AC_SUBST(JAVA)
 AC_SUBST(JAVAC)
@@ -8728,22 +8730,31 @@ if test "$BUILD_CTYPES"; then
   ac_configure_args="--disable-shared --enable-static --disable-raw-api"
   if test "$MOZ_DEBUG"; then
     ac_configure_args="$ac_configure_args --enable-debug"
   fi
   if test "$DSO_PIC_CFLAGS"; then
     ac_configure_args="$ac_configure_args --with-pic"
   fi
   if test "$CROSS_COMPILE"; then
-    ac_configure_args="$ac_configure_args --build=$build --host=$target"
+    ac_configure_args="$ac_configure_args --build=$build --host=$target HOST_CC=\"$HOST_CC\" CC=\"$CC\""
   fi
   if test "$_MSC_VER"; then
     # Use a wrapper script for cl and ml that looks more like gcc.
     # autotools can't quite handle an MSVC build environment yet.
-    ac_configure_args="$ac_configure_args CC=$_topsrcdir/js/ctypes/libffi/msvcc.sh LD=link CPP=\"cl -nologo -EP\" SHELL=sh.exe"
+    ac_configure_args="$ac_configure_args LD=link CPP=\"cl -nologo -EP\" SHELL=sh.exe"
+    case "${target_cpu}" in
+    x86_64)
+      # Need target since MSYS tools into mozilla-build may be 32bit
+      ac_configure_args="$ac_configure_args CC=\"$_topsrcdir/js/ctypes/libffi/msvcc.sh -m64\" --build=$build --host=$target"
+      ;;
+    *)
+      ac_configure_args="$ac_configure_args CC=$_topsrcdir/js/ctypes/libffi/msvcc.sh"
+      ;;
+    esac
   fi
   if test "$SOLARIS_SUNPRO_CC"; then
     # Always use gcc for libffi on Solaris
     ac_configure_args="$ac_configure_args CC=gcc"
   fi
 
   # Use a separate cache file for libffi, since it does things differently
   # from our configure.
--- a/content/base/src/Link.cpp
+++ b/content/base/src/Link.cpp
@@ -464,27 +464,21 @@ Link::GetHash(nsAString &_hash)
 void
 Link::ResetLinkState(bool aNotify)
 {
   // If we are in our default state, bail early.
   if (mLinkState == defaultState) {
     return;
   }
 
-  // If we are not a link, revert to the default state and do no more work.
-  if (mLinkState == eLinkState_NotLink) {
-    mLinkState = defaultState;
-    return;
-  }
-
   nsIContent *content = Content();
 
-  // Tell the document to forget about this link.
+  // Tell the document to forget about this link if we were a link before.
   nsIDocument *doc = content->GetCurrentDoc();
-  if (doc) {
+  if (doc && mLinkState != eLinkState_NotLink) {
     doc->ForgetLink(this);
   }
 
   UnregisterFromHistory();
 
   // Update our state back to the default.
   mLinkState = defaultState;
 
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -7327,23 +7327,16 @@ nsDocument::MutationEventDispatched(nsIN
       mozAutoRemovableBlockerRemover blockerRemover(this);
 
       nsMutationEvent mutation(PR_TRUE, NS_MUTATION_SUBTREEMODIFIED);
       nsEventDispatcher::Dispatch(realTargets[k], nsnull, &mutation);
     }
   }
 }
 
-static PRUint32 GetURIHash(nsIURI* aURI)
-{
-  nsCAutoString str;
-  aURI->GetSpec(str);
-  return HashString(str);
-}
-
 void
 nsDocument::AddStyleRelevantLink(Link* aLink)
 {
   NS_ASSERTION(aLink, "Passing in a null link.  Expect crashes RSN!");
 #ifdef DEBUG
   nsPtrHashKey<Link>* entry = mStyledLinks.GetEntry(aLink);
   NS_ASSERTION(!entry, "Document already knows about this Link!");
   mStyledLinksCleared = false;
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -5169,19 +5169,19 @@ TryMatchingElementsInSubtree(nsINode* aR
                              ElementMatchedCallback aCallback,
                              void* aClosure)
 {
   /* To improve the performance of '+' and '~' combinators and the :nth-*
    * selectors, we keep track of the immediately previous sibling data.  That's
    * cheaper than heap-allocating all the datas and keeping track of them all,
    * and helps a good bit in the common cases.  We also keep track of the whole
    * parent data chain, since we have those Around anyway */
-  char databuf[2 * sizeof(RuleProcessorData)];
+  union { char c[2 * sizeof(RuleProcessorData)]; void *p; } databuf;
   RuleProcessorData* prevSibling = nsnull;
-  RuleProcessorData* data = reinterpret_cast<RuleProcessorData*>(databuf);
+  RuleProcessorData* data = reinterpret_cast<RuleProcessorData*>(databuf.c);
 
   PRBool continueIteration = PR_TRUE;
   for (nsINode::ChildIterator iter(aRoot); !iter.IsDone(); iter.Next()) {
     nsIContent* kid = iter;
     if (!kid->IsNodeOfType(nsINode::eELEMENT)) {
       continue;
     }
     /* See whether we match */
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1296,22 +1296,24 @@ GK_ATOM(keyTimes, "keyTimes")
 GK_ATOM(repeatCount, "repeatCount")
 GK_ATOM(repeatDur, "repeatDur")
 GK_ATOM(restart, "restart")
 GK_ATOM(to, "to")
 GK_ATOM(XML, "XML")
 #endif
 
 #ifdef MOZ_MATHML
-GK_ATOM(MOZcolumnalign, "-moz-math-columnalign")
-GK_ATOM(MOZcolumnline, "-moz-math-columnline") // different from columnlines_
-GK_ATOM(MOZfontsize, "-moz-math-font-size") // different from fontsize_
-GK_ATOM(MOZfontstyle, "-moz-math-font-style") // different from fontstyle_
-GK_ATOM(MOZrowalign, "-moz-math-rowalign")
-GK_ATOM(MOZrowline, "-moz-math-rowline") // different from rowlines_
+// internal MathML attributes: different from columnalign_, columnlines_,
+// fontstyle_, rowalign_ and rowlines_
+GK_ATOM(_moz_math_columnalign_, "_moz-math-columnalign")
+GK_ATOM(_moz_math_columnline_, "_moz-math-columnline")
+GK_ATOM(_moz_math_fontstyle_, "_moz-math-font-style")
+GK_ATOM(_moz_math_rowalign_, "_moz-math-rowalign")
+GK_ATOM(_moz_math_rowline_, "_moz-math-rowline")
+
 GK_ATOM(abs_, "abs")
 GK_ATOM(accent_, "accent")
 GK_ATOM(accentunder_, "accentunder")
 GK_ATOM(actiontype_, "actiontype")
 GK_ATOM(alignmentscope_, "alignmentscope")
 GK_ATOM(annotation_, "annotation")
 GK_ATOM(apply_, "apply")
 GK_ATOM(arccos_, "arccos")
--- a/content/base/src/nsXHTMLContentSerializer.cpp
+++ b/content/base/src/nsXHTMLContentSerializer.cpp
@@ -363,23 +363,16 @@ nsXHTMLContentSerializer::SerializeAttri
     if (kNameSpaceID_XMLNS != namespaceID) {
       nsContentUtils::NameSpaceManager()->GetNameSpaceURI(namespaceID, uriStr);
       addNSAttr = ConfirmPrefix(prefixStr, uriStr, aOriginalElement, PR_TRUE);
     }
 
     aContent->GetAttr(namespaceID, attrName, valueStr);
 
     nsDependentAtomString nameStr(attrName);
-
-    // XXX Hack to get around the fact that MathML can add
-    //     attributes starting with '-', which makes them
-    //     invalid XML. see Bug 475518
-    if (!nameStr.IsEmpty() && nameStr.First() == '-')
-      continue;
-
     PRBool isJS = PR_FALSE;
 
     if (kNameSpaceID_XHTML == contentNamespaceID) {
       //
       // Filter out special case of <br type="_moz"> or <br _moz*>,
       // used by the editor.  Bug 16988.  Yuck.
       //
       if (namespaceID == kNameSpaceID_None && aTagName == nsGkAtoms::br && attrName == nsGkAtoms::type
--- a/content/base/src/nsXMLContentSerializer.cpp
+++ b/content/base/src/nsXMLContentSerializer.cpp
@@ -60,16 +60,18 @@
 #include "nsString.h"
 #include "prprf.h"
 #include "nsUnicharUtils.h"
 #include "nsCRT.h"
 #include "nsContentUtils.h"
 #include "nsAttrName.h"
 #include "nsILineBreaker.h"
 
+static const char kMozStr[] = "moz";
+
 #define kXMLNS "xmlns"
 
 // to be readable, we assume that an indented line contains
 // at least this number of characters (arbitrary value here).
 // This is a limit for the indentation.
 #define MIN_INDENTED_LINE_LENGTH 15
 
 // the string used to indent.
@@ -848,38 +850,39 @@ nsXMLContentSerializer::SerializeAttribu
         continue;
     }
 
     const nsAttrName* name = aContent->GetAttrNameAt(index);
     PRInt32 namespaceID = name->NamespaceID();
     nsIAtom* attrName = name->LocalName();
     nsIAtom* attrPrefix = name->GetPrefix();
 
+    // Filter out any attribute starting with [-|_]moz
+    nsDependentAtomString attrNameStr(attrName);
+    if (StringBeginsWith(attrNameStr, NS_LITERAL_STRING("_moz")) ||
+        StringBeginsWith(attrNameStr, NS_LITERAL_STRING("-moz"))) {
+      continue;
+    }
+
     if (attrPrefix) {
       attrPrefix->ToString(prefixStr);
     }
     else {
       prefixStr.Truncate();
     }
 
     PRBool addNSAttr = PR_FALSE;
     if (kNameSpaceID_XMLNS != namespaceID) {
       nsContentUtils::NameSpaceManager()->GetNameSpaceURI(namespaceID, uriStr);
       addNSAttr = ConfirmPrefix(prefixStr, uriStr, aOriginalElement, PR_TRUE);
     }
     
     aContent->GetAttr(namespaceID, attrName, valueStr);
+
     nsDependentAtomString nameStr(attrName);
-
-    // XXX Hack to get around the fact that MathML can add
-    //     attributes starting with '-', which makes them
-    //     invalid XML. see Bug 475518
-    if (!nameStr.IsEmpty() && nameStr.First() == '-')
-      continue;
-
     PRBool isJS = IsJavaScript(aContent, attrName, namespaceID, valueStr);
 
     SerializeAttr(prefixStr, nameStr, valueStr, aStr, !isJS);
     
     if (addNSAttr) {
       NS_ASSERTION(!prefixStr.IsEmpty(),
                    "Namespaced attributes must have a prefix");
       SerializeAttr(xmlnsStr, prefixStr, uriStr, aStr, PR_TRUE);
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -52,17 +52,16 @@
 #include "nsIDOMSerializer.h"
 #include "nsXPCOM.h"
 #include "nsISupportsPrimitives.h"
 #include "nsGUIEvent.h"
 #include "nsIPrivateDOMEvent.h"
 #include "prprf.h"
 #include "nsIDOMEventListener.h"
 #include "nsIJSContextStack.h"
-#include "nsJSEnvironment.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsWeakPtr.h"
 #include "nsICharsetAlias.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIDOMClassInfo.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMFileInternal.h"
 #include "nsIDOMWindow.h"
@@ -2149,17 +2148,16 @@ nsXMLHttpRequest::RequestCompleted()
                           mUploadTransferred, mUploadTotal);
   }
 
   if (!(mState & XML_HTTP_REQUEST_GOT_FINAL_STOP)) {
     // We're a multipart request, so we're not done. Reset to opened.
     ChangeState(XML_HTTP_REQUEST_OPENED);
   }
 
-  nsJSContext::MaybeCC(PR_FALSE);
   return rv;
 }
 
 NS_IMETHODIMP
 nsXMLHttpRequest::SendAsBinary(const nsAString &aBody)
 {
   char *data = static_cast<char*>(NS_Alloc(aBody.Length() + 1));
   if (!data)
@@ -2931,17 +2929,16 @@ nsXMLHttpRequest::Error(nsIDOMEvent* aEv
   DispatchProgressEvent(this, NS_LITERAL_STRING(ERROR_STR), PR_FALSE,
                         mResponseBody.Length(), 0);
   if (mUpload && !mUploadComplete) {
     mUploadComplete = PR_TRUE;
     DispatchProgressEvent(mUpload, NS_LITERAL_STRING(ERROR_STR), PR_TRUE,
                           mUploadTransferred, mUploadTotal);
   }
 
-  nsJSContext::MaybeCC(PR_FALSE);
   return NS_OK;
 }
 
 nsresult
 nsXMLHttpRequest::ChangeState(PRUint32 aState, PRBool aBroadcast)
 {
   // If we are setting one of the mutually exclusive states,
   // unset those state bits first.
--- a/content/canvas/src/NativeJSContext.cpp
+++ b/content/canvas/src/NativeJSContext.cpp
@@ -6,17 +6,18 @@ nsIJSRuntimeService* NativeJSContext::sJ
 JSRuntime* NativeJSContext::sJSScriptRuntime = 0;
 
 PRBool
 NativeJSContext::AddGCRoot(void *aPtr, const char *aName)
 {
   if (!sJSScriptRuntime) {
     nsresult rv = CallGetService("@mozilla.org/js/xpc/RuntimeService;1",
                                  &sJSRuntimeService);
-    NS_ENSURE_TRUE(sJSRuntimeService, PR_FALSE);
+    NS_ENSURE_SUCCESS(rv, PR_FALSE);
+    NS_ABORT_IF_FALSE(sJSRuntimeService, "CallGetService succeeded but returned a null pointer?");
 
     sJSRuntimeService->GetRuntime(&sJSScriptRuntime);
     if (!sJSScriptRuntime) {
       NS_RELEASE(sJSRuntimeService);
       NS_WARNING("Unable to get JS runtime from JS runtime service");
       return PR_FALSE;
     }
   }
rename from content/html/content/reftests/href-attr-removal-restyles-ref.html
rename to content/html/content/reftests/href-attr-change-restyles-ref.html
--- a/content/html/content/reftests/href-attr-removal-restyles-ref.html
+++ b/content/html/content/reftests/href-attr-change-restyles-ref.html
@@ -1,20 +1,25 @@
 <!DOCTYPE html>
 <html>
 <head>
   <title>Test for bug 549797 - Removing href attribute doesn't remove link styling</title>
   <style type="text/css">
     a, link {
       display:block;
     }
-    link::before {
-      content:"Test link";
+    #link2::before {
+      content:"Test link 1";
+    }
+    #link4::before {
+      content:"Test link 2";
     }
   </style>
 </head>
 <body>
 <p>
-  <a>Test anchor</a>
-  <link/>
+  <a>Test anchor 1</a>
+  <link id="link2"/>
+  <a href="http://example.com/1">Test anchor 2</a>
+  <link id="link4" href="http://example.com/1"/>
 </p>
 </body>
 </html>
rename from content/html/content/reftests/href-attr-removal-restyles.html
rename to content/html/content/reftests/href-attr-change-restyles.html
--- a/content/html/content/reftests/href-attr-removal-restyles.html
+++ b/content/html/content/reftests/href-attr-change-restyles.html
@@ -1,29 +1,38 @@
 <!DOCTYPE html>
 <html>
 <head>
   <title>Test for bug 549797 - Removing href attribute doesn't remove link styling</title>
   <style type="text/css">
     link {
       display:block;
     }
-    link::before {
-      content:"Test link";
+    #link2::before {
+      content:"Test link 1";
+    }
+    #link4::before {
+      content:"Test link 2";
     }
   </style>
 </head>
 <body onload="run_test();">
 <script type="text/javascript">
 function run_test()
 {
   // Remove the href attributes of the links so they should be restyled as
   // non-links.
   document.getElementById("link1").removeAttribute("href");
   document.getElementById("link2").removeAttribute("href");
+
+  // Add the href attribute to the links so they should be restyled as links.
+  document.getElementById("link3").href = "http://example.com/1";
+  document.getElementById("link4").href = "http://example.com/1";
 }
 </script>
 <p>
-  <a id="link1" href="http://example.com/1">Test anchor</a>
+  <a id="link1" href="http://example.com/1">Test anchor 1</a>
   <link id="link2" href="http://example.com/1"/>
+  <a id="link3">Test anchor 2</a>
+  <link id="link4"/>
 </p>
 </body>
 </html>
--- a/content/html/content/reftests/reftest.list
+++ b/content/html/content/reftests/reftest.list
@@ -2,9 +2,9 @@
 == 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
-== href-attr-removal-restyles.html href-attr-removal-restyles-ref.html
+== href-attr-change-restyles.html href-attr-change-restyles-ref.html
--- a/content/smil/test/test_smilCSSFromBy.xhtml
+++ b/content/smil/test/test_smilCSSFromBy.xhtml
@@ -7,17 +7,18 @@
   <script type="text/javascript" src="db_smilCSSPropertyList.js"></script>
   <script type="text/javascript" src="db_smilCSSFromBy.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <p id="display"></p>
 <div id="content">
 <svg xmlns="http://www.w3.org/2000/svg"
-     width="200px" height="200px" font-size="50px" style="color: rgb(50,50,50)">
+     width="200px" height="200px" font-size="50px" style="color: rgb(50,50,50)"
+     onload="this.pauseAnimations()">
   <rect x="20" y="20" width="200" height="200"/>
   <!-- NOTE: hard-wiring 'line-height' so that computed value of 'font' is
        more predictable. (otherwise, line-height varies depending on platform)
     -->
   <text x="20" y="20" style="line-height: 10px !important">testing 123</text>
   <line/>
   <marker/>
   <filter><feDiffuseLighting/></filter>
@@ -34,18 +35,18 @@ function main()
   if (!SMILUtil.isSMILEnabled()) {
     ok(false, "SMIL dosn't seem to be enabled");
     SimpleTest.finish();
     return;
   }
 
   // Start out with document paused
   var svg = SMILUtil.getSVGRoot();
-  svg.pauseAnimations();
-  svg.setCurrentTime(0);
+  ok(svg.animationsPaused(), "should be paused by <svg> load handler");
+  is(svg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
 
   testBundleList(gFromByBundles, new SMILTimingData(1.0, 1.0));
 
   // Set "display:none" on everything and run the tests again
   SMILUtil.hideSubtree(SMILUtil.getSVGRoot(), false);
   testBundleList(gFromByBundles, new SMILTimingData(1.0, 1.0));
 
   SimpleTest.finish();
--- a/content/smil/test/test_smilCSSFromTo.xhtml
+++ b/content/smil/test/test_smilCSSFromTo.xhtml
@@ -7,17 +7,18 @@
   <script type="text/javascript" src="db_smilCSSPropertyList.js"></script>
   <script type="text/javascript" src="db_smilCSSFromTo.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <p id="display"></p>
 <div id="content">
 <svg xmlns="http://www.w3.org/2000/svg"
-     width="200px" height="200px" font-size="50px" style="color: rgb(50,50,50)">
+     width="200px" height="200px" font-size="50px" style="color: rgb(50,50,50)"
+     onload="this.pauseAnimations()">
   <rect x="20" y="20" width="200" height="200"/>
   <!-- NOTE: hard-wiring 'line-height' so that computed value of 'font' is
        more predictable. (otherwise, line-height varies depending on platform)
     -->
   <text x="20" y="20" style="line-height: 10px !important">testing 123</text>
   <line/>
   <image/>
   <marker/>
@@ -57,18 +58,18 @@ function main()
   if (!SMILUtil.isSMILEnabled()) {
     ok(false, "SMIL dosn't seem to be enabled");
     SimpleTest.finish();
     return;
   }
 
   // Start out with document paused
   var svg = SMILUtil.getSVGRoot();
-  svg.pauseAnimations();
-  svg.setCurrentTime(0);
+  ok(svg.animationsPaused(), "should be paused by <svg> load handler");
+  is(svg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
 
   // FIRST: Warn about any properties that are missing tests
   checkForUntestedProperties(gFromToBundles);
 
   // Run the actual tests
   testBundleList(gFromToBundles, new SMILTimingData(1.0, 1.0));
 
   // Set "display:none" on everything and run the tests again
--- a/content/smil/test/test_smilCSSInherit.xhtml
+++ b/content/smil/test/test_smilCSSInherit.xhtml
@@ -4,17 +4,18 @@
   <script type="text/javascript" src="/MochiKit/packed.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript" src="smilTestUtils.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">
-<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="300px" height="200px">
+<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="300px" height="200px"
+     onload="this.pauseAnimations()">
   <!--  At 50% through the animation, the following should be true:
    * First <g> has font-size = 5px (1/2 between 0px and 10px)
    * Next <g> has font-size = 10px (1/2 between inherit=5px and 15px)
    * Next <g> has font-size = 15px (1/2 between inherit=10px and 20px)
    * Next <g> has font-size = 20px (1/2 between inherit=15px and 25px)
    * Next <g> has font-size = 25px (1/2 between inherit=20px and 30px)
    * Next <g> has font-size = 30px (1/2 between inherit=25px and 35px)
    * Next <g> has font-size = 35px (1/2 between inherit=30px and 40px)
@@ -59,17 +60,18 @@ function main() {
   if (!SMILUtil.isSMILEnabled()) {
     ok(false, "SMIL dosn't seem to be enabled");
     SimpleTest.finish();
     return;
   }
 
   // Pause & seek to halfway through animation
   var svg = SMILUtil.getSVGRoot();
-  svg.pauseAnimations();
+  ok(svg.animationsPaused(), "should be paused by <svg> load handler");
+  is(svg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
   svg.setCurrentTime(0.5);
 
   var text = document.getElementsByTagName("text")[0];
   var computedVal = SMILUtil.getComputedStyleSimple(text, "font-size");
   var expectedVal = "75px";
 
   // NOTE: There's a very small chance (1/11! = 1/39,916,800) that we'll happen
   // to composite our 11 animations in the correct order, in which cast this
--- a/content/smil/test/test_smilCSSInvalidValues.xhtml
+++ b/content/smil/test/test_smilCSSInvalidValues.xhtml
@@ -5,17 +5,18 @@
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript" src="smilTestUtils.js"></script>
   <script type="text/javascript" src="db_smilCSSPropertyList.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <p id="display"></p>
 <div id="content">
-<svg xmlns="http://www.w3.org/2000/svg">
+<svg xmlns="http://www.w3.org/2000/svg"
+     onload="this.pauseAnimations()">
   <rect x="20" y="20" width="200" height="200"/>
 </svg>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 <![CDATA[
 
 SimpleTest.waitForExplicitFinish();
@@ -43,18 +44,18 @@ function main()
   if (!SMILUtil.isSMILEnabled()) {
     ok(false, "SMIL dosn't seem to be enabled");
     SimpleTest.finish();
     return;
   }
 
   // Start out with document paused
   var svg = SMILUtil.getSVGRoot();
-  svg.pauseAnimations();
-  svg.setCurrentTime(0);
+  ok(svg.animationsPaused(), "should be paused by <svg> load handler");
+  is(svg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
 
   // Run the tests
   testBundleList(invalidTestcaseBundles, new SMILTimingData(1.0, 1.0));
 
   SimpleTest.finish();
 }
 
 window.addEventListener("load", main, false);
--- a/content/smil/test/test_smilCSSPaced.xhtml
+++ b/content/smil/test/test_smilCSSPaced.xhtml
@@ -7,17 +7,18 @@
   <script type="text/javascript" src="db_smilCSSPropertyList.js"></script>
   <script type="text/javascript" src="db_smilCSSPaced.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <p id="display"></p>
 <div id="content">
 <svg xmlns="http://www.w3.org/2000/svg"
-     width="200px" height="200px" font-size="50px" style="color: rgb(50,50,50)">
+     width="200px" height="200px" font-size="50px" style="color: rgb(50,50,50)"
+     onload="this.pauseAnimations()">
   <rect x="20" y="20" width="200" height="200"/>
   <text x="20" y="20">testing 123</text>
   <marker/>
 </svg>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 <![CDATA[
@@ -29,18 +30,18 @@ function main()
   if (!SMILUtil.isSMILEnabled()) {
     ok(false, "SMIL dosn't seem to be enabled");
     SimpleTest.finish();
     return;
   }
 
   // Start out with document paused
   var svg = SMILUtil.getSVGRoot();
-  svg.pauseAnimations();
-  svg.setCurrentTime(0);
+  ok(svg.animationsPaused(), "should be paused by <svg> load handler");
+  is(svg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
 
   testBundleList(gPacedBundles, new SMILTimingData(1.0, 6.0));
   // Set "display:none" on everything and run the tests again
   SMILUtil.hideSubtree(SMILUtil.getSVGRoot(), false);
   testBundleList(gPacedBundles, new SMILTimingData(1.0, 6.0));
 
   SimpleTest.finish();
 }
--- a/content/smil/test/test_smilChangeAfterFrozen.xhtml
+++ b/content/smil/test/test_smilChangeAfterFrozen.xhtml
@@ -5,17 +5,18 @@
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript" src="smilTestUtils.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=533291">Mozilla Bug 533291</a>
 <p id="display"></p>
 <div id="content" style="display: none">
-<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px">
+<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px"
+     onload="this.pauseAnimations()">
   <g id="circleParent">
     <circle cx="0" cy="20" r="15" fill="blue" id="circle"/>
   </g>
 </svg>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 <![CDATA[
@@ -53,17 +54,19 @@ const gCircleParent = document.getElemen
 
 
 SimpleTest.waitForExplicitFinish();
 
 // MAIN FUNCTION
 // -------------
 
 function main() {
-  gSvg.pauseAnimations();
+  ok(gSvg.animationsPaused(), "should be paused by <svg> load handler");
+  is(gSvg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
+
   if (gNextTestIndex != 0) {
     ok(false, "expecting to start at first test in array.");
   }
   // Kick off first test.  (It will kick off the one after it, and so on.)
   runNextTest();
 }
 
 // HELPER FUNCTIONS
--- a/content/smil/test/test_smilContainerBinding.xhtml
+++ b/content/smil/test/test_smilContainerBinding.xhtml
@@ -4,33 +4,34 @@
   <title>Test for adding and removing animations from a time container</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">
-<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px">
+<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px"
+     onload="this.pauseAnimations()">
   <circle cx="-20" cy="20" r="15" fill="blue" id="circle">
     <set attributeName="cy" to="120" begin="0s; 2s" dur="1s" id="b"/>
   </circle>
 </svg>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 <![CDATA[
 /** Test for adding and removing animations from a time container **/
 
 SimpleTest.waitForExplicitFinish();
 
 function main() {
   var svg = getElement("svg");
-  svg.pauseAnimations();
-  svg.setCurrentTime(0);
+  ok(svg.animationsPaused(), "should be paused by <svg> load handler");
+  is(svg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
 
   // Create animation and check initial state
   var anim = createAnim();
   anim.setAttribute('begin','b.begin+2s; 6s');
   ok(noStart(anim), "Animation has start time before attaching to document.");
 
   // Attach animation to container
   var circle = getElement("circle");
--- a/content/smil/test/test_smilCrossContainer.xhtml
+++ b/content/smil/test/test_smilCrossContainer.xhtml
@@ -4,39 +4,43 @@
   <title>Test for moving animations between time containers</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">
-<svg id="svga" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px">
+<svg id="svga" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px"
+     onload="this.pauseAnimations()">
   <circle cx="-20" cy="20" r="15" fill="blue" id="circlea"/>
 </svg>
-<svg id="svgb" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px">
+<svg id="svgb" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px"
+     onload="this.pauseAnimations()">
   <circle cx="-20" cy="20" r="15" fill="blue" id="circleb">
     <set attributeName="cy" to="120" begin="4s" dur="1s" id="syncb"/>
   </circle>
 </svg>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 <![CDATA[
 /** Test for moving animations between time containers **/
 
 SimpleTest.waitForExplicitFinish();
 
 function main() {
   var svga = getElement("svga");
-  svga.pauseAnimations();
+  ok(svga.animationsPaused(), "should be paused by <svg> load handler");
+  is(svga.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
   svga.setCurrentTime(1);
 
   var svgb = getElement("svgb");
-  svgb.pauseAnimations();
+  ok(svgb.animationsPaused(), "should be paused by <svg> load handler");
+  is(svgb.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
   svgb.setCurrentTime(1);
 
   // Create animation and check initial state
   var anim = createAnim();
   ok(noStart(anim), "Animation has start time before attaching to document");
 
   // Attach animation to first container
   var circlea = getElement("circlea");
--- a/content/smil/test/test_smilFillMode.xhtml
+++ b/content/smil/test/test_smilFillMode.xhtml
@@ -3,17 +3,18 @@
   <title>Test for SMIL fill modes</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">
-<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px">
+<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px"
+     onload="this.pauseAnimations()">
   <circle cx="-100" cy="20" r="15" fill="blue" id="circle"/>
 </svg>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 <![CDATA[
 /** Test for SMIL fill modes **/
 
@@ -29,17 +30,19 @@ function createAnim() {
   anim.setAttribute('attributeName','cx');
   anim.setAttribute('dur','4s');
   anim.setAttribute('begin','0s');
   anim.setAttribute('values', '10; 20');
   return circle.appendChild(anim);
 }
 
 function main() {
-  svg.pauseAnimations();
+  ok(svg.animationsPaused(), "should be paused by <svg> load handler");
+  is(svg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
+
   var tests =
     [ testSetLaterA,
       testSetLaterB,
       testRemoveLater ];
   for (var i = 0; i < tests.length; i++) {
     var anim = createAnim();
     svg.setCurrentTime(0);
     tests[i](anim);
--- a/content/smil/test/test_smilGetStartTime.xhtml
+++ b/content/smil/test/test_smilGetStartTime.xhtml
@@ -3,38 +3,37 @@
   <title>Test for getStartTime Behavior </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">
-<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px">
+<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px"
+     onload="this.pauseAnimations()">
   <circle cx="20" cy="20" r="15" fill="blue">
     <animate attributeName="cx" attributeType="XML" 
       from="20" to="100" begin="indefinite" dur="1s" id="anim"/>
   </circle>
 </svg>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 <![CDATA[
 /** Test for getStartTime Behavior  **/
 
-/* Global Variables */
-var svg = document.getElementById("svg");
-var anim = document.getElementById("anim");
-
 SimpleTest.waitForExplicitFinish();
 
 function main() {
-  svg.pauseAnimations();
-  svg.setCurrentTime(0);
+  var svg = document.getElementById("svg");
+  ok(svg.animationsPaused(), "should be paused by <svg> load handler");
+  is(svg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
 
+  var anim = document.getElementById("anim");
   // indefinite 
   var exceptionCaught = false;
   try {
     anim.getStartTime();
   } catch(e) {
     exceptionCaught = true;
     is(e.code, DOMException.INVALID_STATE_ERR,
        "Unexpected exception code from getStartTime.");
--- a/content/smil/test/test_smilKeySplines.xhtml
+++ b/content/smil/test/test_smilKeySplines.xhtml
@@ -3,17 +3,18 @@
   <title>Test for SMIL keySplines</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">
-<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px">
+<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px"
+     onload="this.pauseAnimations()">
   <circle cx="-100" cy="20" r="15" fill="blue" id="circle"/>
 </svg>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 <![CDATA[
 /** Test for SMIL keySplines **/
 
@@ -29,17 +30,19 @@ function createAnim() {
   anim.setAttribute('attributeName','cx');
   anim.setAttribute('dur','10s');
   anim.setAttribute('begin','0s');
   anim.setAttribute('fill', 'freeze');
   return circle.appendChild(anim);
 }
 
 function main() {
-  svg.pauseAnimations();
+  ok(svg.animationsPaused(), "should be paused by <svg> load handler");
+  is(svg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
+
   var tests =
     [ testSimpleA, // these first four are from SVG 1.1
       testSimpleB,
       testSimpleC,
       testSimpleD,
       testSimpleE, // bug 501569
       testMultipleIntervalsA,
       testMultipleIntervalsB,
--- a/content/smil/test/test_smilReset.xhtml
+++ b/content/smil/test/test_smilReset.xhtml
@@ -3,37 +3,37 @@
   <title>Tests for SMIL Reset Behavior </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">
-<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px">
+<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px"
+     onload="this.pauseAnimations()">
   <circle cx="20" cy="20" r="15" fill="blue">
     <animate attributeName="cx" from="20" to="100" begin="2s" dur="4s"
              id="anim1" attributeType="XML"/>
   </circle>
 </svg>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 <![CDATA[
 /** Tests for SMIL Reset Behavior  **/
 
-/* Global Variables */
-var svg = document.getElementById("svg");
-
 SimpleTest.waitForExplicitFinish();
 
 function main() {
-  var anim = document.getElementById("anim1");
+  var svg = document.getElementById("svg");
+  ok(svg.animationsPaused(), "should be paused by <svg> load handler");
+  is(svg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
 
-  svg.pauseAnimations();
+  var anim = document.getElementById("anim1");
   is(anim.getStartTime(), 2, "Unexpected initial start time");
 
   svg.setCurrentTime(1);
   anim.beginElementAt(2);
 
   // We now have two instance times: 2, 3
 
   // Restart (and reset) animation at t=1
--- a/content/smil/test/test_smilSetCurrentTime.xhtml
+++ b/content/smil/test/test_smilSetCurrentTime.xhtml
@@ -3,35 +3,35 @@
   <title>Test for setCurrentTime Behavior </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">
-<svg id="svg" xmlns="http://www.w3.org/2000/svg" />
+<svg id="svg" xmlns="http://www.w3.org/2000/svg"
+     onload="this.pauseAnimations()" />
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 <![CDATA[
 /** Test for basic setCurrentTime / getCurrentTime Behavior  **/
 
 /* Global Variables & Constants */
 const PRECISION_LEVEL = 0.0000001; // Allow small level of floating-point error
 const gTimes = [0, 1.5, 0.2, 0.99, -400.5, 10000000, -1];
 const gWaitTime = 20;
 var gSvg = document.getElementById("svg");
 
 SimpleTest.waitForExplicitFinish();
 
 function main() {
-  // Pause our document, so that the setCurrentTime calls are the only
-  // thing affecting document time
-  gSvg.pauseAnimations();
+  ok(gSvg.animationsPaused(), "should be paused by <svg> load handler");
+  is(gSvg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
 
   // Test that seeking takes effect immediately
   for (var i = 0; i < gTimes.length; i++) {
     gSvg.setCurrentTime(gTimes[i]);
     assertFloatsEqual(gSvg.getCurrentTime(), gTimes[i]);
   }
 
   // Test that seeking isn't messed up by timeouts
--- a/content/smil/test/test_smilSyncbaseTarget.xhtml
+++ b/content/smil/test/test_smilSyncbaseTarget.xhtml
@@ -4,17 +4,18 @@
   <title>Test for syncbase targetting</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">
-<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px">
+<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px"
+     onload="this.pauseAnimations()">
   <circle cx="-20" cy="20" r="15" fill="blue" id="circle">
     <set attributeName="cx" to="0" begin="2s" dur="1s" id="a"/>
     <set attributeName="cx" to="0" begin="2s" dur="1s" xml:id="b"/>
     <set attributeName="cx" to="0" begin="2s" dur="1s" id="あ"/>
     <set attributeName="cx" to="0" begin="2s" dur="1s" id="a.b"/>
     <set attributeName="cx" to="0" begin="2s" dur="1s" id="a-b"/>
     <set attributeName="cx" to="0" begin="2s" dur="1s" id="a:b"/>
     <set attributeName="cx" to="0" begin="2s" dur="1s" id="-a"/>
@@ -26,18 +27,18 @@
 <script class="testbody" type="text/javascript">
 <![CDATA[
 /** Test for syncbase targetting behavior  **/
 
 SimpleTest.waitForExplicitFinish();
 
 function main() {
   var svg = getElement("svg");
-  svg.pauseAnimations();
-  svg.setCurrentTime(0);
+  ok(svg.animationsPaused(), "should be paused by <svg> load handler");
+  is(svg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
 
   testSpecs();
   testChangeId();
   testRemoveTimebase();
 
   SimpleTest.finish();
 }
 
--- a/content/smil/test/test_smilTextZoom.xhtml
+++ b/content/smil/test/test_smilTextZoom.xhtml
@@ -4,17 +4,18 @@
   <script type="text/javascript" src="/MochiKit/packed.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript" src="smilTestUtils.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">
-  <svg xmlns="http://www.w3.org/2000/svg" width="300px" height="200px">
+  <svg xmlns="http://www.w3.org/2000/svg" width="300px" height="200px"
+       onload="this.pauseAnimations()">
     <text y="100px" x="0px" style="font-size: 5px">
       abc
       <animate attributeName="font-size" attributeType="CSS" fill="freeze"
                from="20px" to="40px" begin="1s" dur="1s"/>
     </text>
     <rect y="100px" x="50px" style="stroke-width: 5px">
       <animate attributeName="stroke-width" attributeType="CSS" fill="freeze"
                from="20px" to="40px" begin="1s" dur="1s"/>
@@ -36,20 +37,21 @@ function verifyStyle(aNode, aPropertyNam
 function main()
 {
   if (!SMILUtil.isSMILEnabled()) {
     ok(false, "SMIL dosn't seem to be enabled");
     SimpleTest.finish();
     return;
   }
 
-  // Start out paused
+  // Start out pause
   var svg = SMILUtil.getSVGRoot();
-  svg.pauseAnimations();
-
+  ok(svg.animationsPaused(), "should be paused by <svg> load handler");
+  is(svg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
+  
   // Get handle on nsIMarkupDocumentViewer
   netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
   const CI = Components.interfaces;
   var docshell = window.QueryInterface(CI.nsIInterfaceRequestor).getInterface(CI.nsIWebNavigation).QueryInterface(CI.nsIDocShell);
   var mudv = docshell.contentViewer.QueryInterface(CI.nsIMarkupDocumentViewer);
 
   // Set text zoom to 2x
   var origTextZoom = mudv.textZoom;
@@ -61,17 +63,16 @@ function main()
     // exactly twice as large as their corresponding specified values.
     // (Mozilla's SVG code divides out the textZoom factor from these computed
     // values when rendering, to obtain the correct font-size.)
     // * I also include tests for an identical animation of the "stroke-width"
     // property, which should _not_ be affected by textZoom.
     var text = document.getElementsByTagName("text")[0];
     var rect = document.getElementsByTagName("rect")[0];
 
-    svg.setCurrentTime(0);
     verifyStyle(text, "font-size",    "10px");
     verifyStyle(rect, "stroke-width", "5px");
     svg.setCurrentTime(1);
     verifyStyle(text, "font-size",    "40px");
     verifyStyle(rect, "stroke-width", "20px");
     svg.setCurrentTime(1.5);
     verifyStyle(text, "font-size",    "60px");
     verifyStyle(rect, "stroke-width", "30px");
--- a/content/smil/test/test_smilTiming.xhtml
+++ b/content/smil/test/test_smilTiming.xhtml
@@ -3,17 +3,18 @@
   <title>Test for SMIL timing</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">
-<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px">
+<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px"
+     onload="this.pauseAnimations()">
   <circle cx="-100" cy="20" r="15" fill="blue" id="circle"/>
 </svg>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 <![CDATA[
 /** Test for SMIL timing **/
 
@@ -34,17 +35,19 @@ function createAnim() {
   return circle.appendChild(anim);
 }
 
 function removeAnim(anim) {
   anim.parentNode.removeChild(anim);
 }
 
 function main() {
-  svg.pauseAnimations();
+  ok(svg.animationsPaused(), "should be paused by <svg> load handler");
+  is(svg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
+
   var tests =
     [ testOffsetStartup,
       testMultipleBegins,
       testNegativeBegins,
       testSorting
     ];
   for (var i = 0; i < tests.length; i++) {
     var anim = createAnim();
--- a/content/smil/test/test_smilTimingZeroIntervals.xhtml
+++ b/content/smil/test/test_smilTimingZeroIntervals.xhtml
@@ -3,17 +3,18 @@
   <title>Test for SMIL timing with zero-duration intervals</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">
-<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px">
+<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px"
+     onload="this.pauseAnimations()">
   <circle cx="-100" cy="20" r="15" fill="blue" id="circle"/>
 </svg>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 <![CDATA[
 /** Test for SMIL timing with zero-duration intervals **/
 
@@ -34,17 +35,19 @@ function createAnim() {
   return circle.appendChild(anim);
 }
 
 function removeAnim(anim) {
   anim.parentNode.removeChild(anim);
 }
 
 function main() {
-  svg.pauseAnimations();
+  ok(svg.animationsPaused(), "should be paused by <svg> load handler");
+  is(svg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
+
   var tests =
     [ testZeroDurationIntervalsA,
       testZeroDurationIntervalsB,
       testZeroDurationIntervalsC,
       testZeroDurationIntervalsD,
       testZeroDurationIntervalsE,
       testZeroDurationIntervalsF,
       testZeroDurationIntervalsG,
--- a/content/smil/test/test_smilUpdatedInterval.xhtml
+++ b/content/smil/test/test_smilUpdatedInterval.xhtml
@@ -3,37 +3,38 @@
   <title>Tests updated intervals</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">
-<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px">
+<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px"
+     onload="this.pauseAnimations()">
   <circle cx="20" cy="20" r="15" fill="blue" id="circle">
     <animate attributeName="cx" from="0" to="100" begin="2s" dur="4s"
              id="anim1" attributeType="XML"/>
   </circle>
 </svg>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 <![CDATA[
 /** Tests for updated intervals  **/
 
 /* Global Variables */
-var svg = document.getElementById("svg");
-
 SimpleTest.waitForExplicitFinish();
 
 function main() {
-  var anim = document.getElementById("anim1");
+  var svg = document.getElementById("svg");
+  ok(svg.animationsPaused(), "should be paused by <svg> load handler");
+  is(svg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
 
-  svg.pauseAnimations();
+  var anim = document.getElementById("anim1");
 
   // Check regular operation
   svg.setCurrentTime(3);
   is(anim.getStartTime(), 2, "Unexpected initial start time");
 
   // Add an instance time before the current interval at t=1s
   anim.beginElementAt(-2);
 
--- a/content/svg/content/test/test_animLengthObjectIdentity.xhtml
+++ b/content/svg/content/test/test_animLengthObjectIdentity.xhtml
@@ -7,17 +7,18 @@ https://bugzilla.mozilla.org/show_bug.cg
   <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>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=506856">Mozilla Bug 508496</a>
 <p id="display"></p>
 <div id="content" style="display: none">
-<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px">
+<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px"
+     onload="this.pauseAnimations()">
   <circle cx="-100" cy="-100" r="15" fill="blue" id="circle">
     <animate attributeName="cx" from="0" to="100" dur="4s" begin="1s; 10s"
       fill="freeze" id="animate"/>
   </circle>
 </svg>
 </div>
 <pre id="test">
 <script class="testbody" type="text/javascript">
@@ -27,32 +28,34 @@ https://bugzilla.mozilla.org/show_bug.cg
 /* Global Variables */
 const svgns="http://www.w3.org/2000/svg";
 var svg = document.getElementById("svg");
 var circle = document.getElementById('circle');
 
 SimpleTest.waitForExplicitFinish();
 
 function main() {
+  ok(svg.animationsPaused(), "should be paused by <svg> load handler");
+  is(svg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
+
   var animLength = circle.cx;
   ok(animLength === circle.cx,
     "Got different SVGAnimatedLength objects at startup");
 
   var baseVal = circle.cx.baseVal;
   ok(baseVal === circle.cx.baseVal,
     "Got different baseVal SVGLength objects at startup");
 
   var animVal = circle.cx.animVal;
   ok(animVal === circle.cx.animVal,
     "Got different animVal SVGLength objects at startup");
 
   var animate = document.getElementById('animate');
   if (animate && animate.targetElement) {
     // Sample mid-way through the animation
-    svg.pauseAnimations();
     svg.setCurrentTime(5);
 
     ok(animLength === circle.cx,
       "Got different SVGAnimatedLength objects during animation");
     ok(baseVal === circle.cx.baseVal,
       "Got different baseVal SVGLength objects during animation");
     ok(animVal === circle.cx.animVal,
       "Got different animVal SVGLength objects during animation");
--- a/content/svg/content/test/test_animLengthReadonly.xhtml
+++ b/content/svg/content/test/test_animLengthReadonly.xhtml
@@ -8,17 +8,18 @@ https://bugzilla.mozilla.org/show_bug.cg
   <script type="text/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=506856">Mozilla Bug 506856</a>
 <p id="display"></p>
 <div id="content" style="display: none">
 <svg id="svg" xmlns="http://www.w3.org/2000/svg"
-     width="100px" height="100px" viewBox="0 0 100 100">
+     width="100px" height="100px" viewBox="0 0 100 100"
+     onload="this.pauseAnimations()">
   <!-- Note: Need a viewBox on the SVG element, or else our percent-length
        basis will be '0' (based off of the viewport width, which is 0 in this
        case since we're in a display:none iframe. We use viewport width because
        the lack of a viewbox forces us into the not-mViewBox::IsValid() case of
        nsSVGSVGElement::GetLength).
 
        And we don't want a percent-length basis of 0, because then when we call
        convertToSpecifiedUnits to convert out of percent units, we divide by 0
@@ -40,19 +41,18 @@ https://bugzilla.mozilla.org/show_bug.cg
 /* Global Variables */
 const svgns="http://www.w3.org/2000/svg";
 var svg = document.getElementById("svg");
 var circle = document.getElementById('circle');
 
 SimpleTest.waitForExplicitFinish();
 
 function main() {
-  // Start out paused at beginning of timeline
-  svg.pauseAnimations();
-  svg.setCurrentTime(0);
+  ok(svg.animationsPaused(), "should be paused by <svg> load handler");
+  is(svg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
 
   // Sanity check: check initial values
   is(circle.cx.baseVal.value, -100);
   is(circle.cx.animVal.value, -100);
   is(circle.cy.baseVal.value, -100);
   is(circle.cy.animVal.value, -100);
 
   // (1): Check before animation that animVal's are readonly
--- a/content/svg/content/test/test_animLengthRelativeUnits.xhtml
+++ b/content/svg/content/test/test_animLengthRelativeUnits.xhtml
@@ -10,17 +10,18 @@ https://bugzilla.mozilla.org/show_bug.cg
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=508206">Mozilla Bug 508206</a>
 <p id="display"></p>
 <!-- XXX The following should be display: none but that's broken by bug 413975
      where we don't handle percentage lengths when the whole fragment is
      display: none properly. -->
 <div id="content" style="visibility: hidden">
-<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="100px" height="100px">
+<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="100px" height="100px"
+     onload="this.pauseAnimations()">
   <g font-size="10px">
     <circle cx="0" cy="0" r="15" fill="blue" id="circle">
       <animate attributeName="cx" from="0" to="10em" dur="10s" begin="0s"
         fill="freeze" id="animate"/>
       <animate attributeName="cy" from="0" to="100%" dur="10s" begin="0s"
         fill="freeze"/>
     </circle>
   </g>
@@ -34,18 +35,20 @@ https://bugzilla.mozilla.org/show_bug.cg
 /* Global Variables */
 const svgns="http://www.w3.org/2000/svg";
 var svg = document.getElementById("svg");
 var circle = document.getElementById('circle');
 
 SimpleTest.waitForExplicitFinish();
 
 function main() {
+  ok(svg.animationsPaused(), "should be paused by <svg> load handler");
+  is(svg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
+
   // Sample mid-way through the animation
-  svg.pauseAnimations();
   svg.setCurrentTime(5);
 
   // (1) Check values mid-way
   is(circle.cx.animVal.value, 50,
     "(1) Unexpected animVal for cx before changing base length");
   is(circle.cy.animVal.value, 50,
     "(1) Unexpected animVal for cy before changing base length");
 
--- a/content/svg/content/test/test_animLengthUnits.xhtml
+++ b/content/svg/content/test/test_animLengthUnits.xhtml
@@ -7,17 +7,18 @@ https://bugzilla.mozilla.org/show_bug.cg
   <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>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=507067">Mozilla Bug 507067</a>
 <p id="display"></p>
 <div id="content" style="display: none">
-<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px">
+<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="120px" height="120px"
+     onload="this.pauseAnimations()">
   <g font-size="10px">
     <circle cx="-100" cy="20" r="15" fill="blue" id="circle">
       <animate attributeName="cx" from="0em" to="10em" dur="8s" begin="1s"
         fill="freeze" id="animate"/>
     </circle>
   </g>
 </svg>
 </div>
@@ -38,19 +39,18 @@ SimpleTest.waitForExplicitFinish();
 //
 //  Opera -- 10 beta 2
 //  WebKit -- July 09 trunk build
 //  Batik -- 1.7
 //  Firefox -- July 09 trunk build
 // 
 
 function main() {
-  // Initialise timeline
-  svg.pauseAnimations();
-  svg.setCurrentTime(0);
+  ok(svg.animationsPaused(), "should be paused by <svg> load handler");
+  is(svg.getCurrentTime(), 0, "should be paused at 0 in <svg> load handler");
 
   // Sanity check: check initial values
   is(circle.cx.baseVal.valueInSpecifiedUnits, -100,
     "Unexpected initial baseVal");
   is(circle.cx.baseVal.unitType, SVGLength.SVG_LENGTHTYPE_NUMBER,
     "Unexpected initial baseVal units");
   is(circle.cx.animVal.valueInSpecifiedUnits, -100,
     "Unexpected initial animVal");
--- a/content/xul/templates/src/nsXULContentUtils.h
+++ b/content/xul/templates/src/nsXULContentUtils.h
@@ -101,16 +101,28 @@ class nsICollation;
 #define ERROR_TEMPLATE_TRIPLE_UNBOUND                                   \
         "neither subject or object variables of <triple> has a value"
 #define ERROR_TEMPLATE_BAD_XPATH                                        \
         "XPath expression in query could not be parsed"
 #define ERROR_TEMPLATE_BAD_ASSIGN_XPATH                                 \
         "XPath expression in <assign> could not be parsed"
 #define ERROR_TEMPLATE_BAD_BINDING_XPATH                                \
         "XPath expression in <binding> could not be parsed"
+#define ERROR_TEMPLATE_STORAGE_BAD_URI                                  \
+        "only profile: or file URI are allowed"
+#define ERROR_TEMPLATE_STORAGE_CANNOT_OPEN_DATABASE                     \
+        "cannot open given database"
+#define ERROR_TEMPLATE_STORAGE_BAD_QUERY                                \
+        "syntax error in the SQL query"
+#define ERROR_TEMPLATE_STORAGE_UNKNOWN_QUERY_PARAMETER                   \
+        "the given named parameter is unknown in the SQL query"
+#define ERROR_TEMPLATE_STORAGE_WRONG_TYPE_QUERY_PARAMETER               \
+        "the type of a query parameter is wrong"
+#define ERROR_TEMPLATE_STORAGE_QUERY_PARAMETER_NOT_BOUND                \
+        "a query parameter cannot be bound to the SQL query"
 
 class nsXULContentUtils
 {
 protected:
     static nsIRDFService* gRDF;
     static nsIDateTimeFormat* gFormat;
     static nsICollation *gCollation;
 
--- a/content/xul/templates/src/nsXULTemplateQueryProcessorStorage.cpp
+++ b/content/xul/templates/src/nsXULTemplateQueryProcessorStorage.cpp
@@ -48,16 +48,17 @@
 #include "nsIIOService.h"
 #include "nsIFileChannel.h"
 #include "nsIFile.h"
 #include "nsGkAtoms.h"
 #include "nsContentUtils.h"
 
 #include "nsXULTemplateBuilder.h"
 #include "nsXULTemplateResultStorage.h"
+#include "nsXULContentUtils.h"
 
 #include "mozIStorageService.h"
 
 //----------------------------------------------------------------------
 //
 // nsXULTemplateResultSetStorage
 //
 
@@ -243,27 +244,33 @@ nsXULTemplateQueryProcessorStorage::GetD
         nsCOMPtr<nsIIOService> ioservice =
             do_GetService("@mozilla.org/network/io-service;1", &rv);
         NS_ENSURE_SUCCESS(rv, rv);
 
         rv = ioservice->NewChannelFromURI(uri, getter_AddRefs(channel));
         NS_ENSURE_SUCCESS(rv, rv);
 
         nsCOMPtr<nsIFileChannel> fileChannel = do_QueryInterface(channel, &rv);
-        NS_ENSURE_SUCCESS(rv, rv); // if it fails, not a file url
+        if (NS_FAILED(rv)) { // if it fails, not a file url
+            nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_STORAGE_BAD_URI);
+            return rv;
+        }
 
         nsCOMPtr<nsIFile> file;
         rv = fileChannel->GetFile(getter_AddRefs(databaseFile));
         NS_ENSURE_SUCCESS(rv, rv);
     }
 
     // ok now we have an URI of a sqlite file
     nsCOMPtr<mozIStorageConnection> connection;
     rv = storage->OpenDatabase(databaseFile, getter_AddRefs(connection));
-    NS_ENSURE_SUCCESS(rv, rv);
+    if (NS_FAILED(rv)) {
+        nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_STORAGE_CANNOT_OPEN_DATABASE);
+        return rv;
+    }
 
     NS_ADDREF(*aReturn = connection);
     return NS_OK;
 }
 
 
 
 NS_IMETHODIMP
@@ -309,17 +316,20 @@ nsXULTemplateQueryProcessorStorage::Comp
     nsCOMPtr<nsIContent> queryContent = do_QueryInterface(aQueryNode);
     nsAutoString sqlQuery;
 
     // Let's get all text nodes (which should be the query) 
     nsContentUtils::GetNodeTextContent(queryContent, PR_FALSE, sqlQuery);
 
     nsresult rv = mStorageConnection->CreateStatement(NS_ConvertUTF16toUTF8(sqlQuery),
                                                               getter_AddRefs(statement));
-    NS_ENSURE_SUCCESS(rv, rv);
+    if (NS_FAILED(rv)) {
+        nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_STORAGE_BAD_QUERY);
+        return rv;
+    }
 
     PRUint32 parameterCount = 0;
     PRUint32 count = queryContent->GetChildCount();
 
     for (PRUint32 i = 0; i < count; ++i) {
         nsIContent *child = queryContent->GetChildAt(i);
 
         if (child->NodeInfo()->Equals(nsGkAtoms::param, kNameSpaceID_XUL)) {
@@ -327,33 +337,37 @@ nsXULTemplateQueryProcessorStorage::Comp
             nsContentUtils::GetNodeTextContent(child, PR_FALSE, value);
 
             PRUint32 index = parameterCount;
             nsAutoString name, indexValue;
 
             if (child->GetAttr(kNameSpaceID_None, nsGkAtoms::name, name)) {
                 rv = statement->GetParameterIndex(NS_ConvertUTF16toUTF8(name),
                                                   &index);
-                NS_ENSURE_SUCCESS(rv, rv);
+                if (NS_FAILED(rv)) {
+                    nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_STORAGE_UNKNOWN_QUERY_PARAMETER);
+                    return rv;
+                }
                 parameterCount++;
             }
             else if (child->GetAttr(kNameSpaceID_None, nsGkAtoms::index, indexValue)) {
                 PR_sscanf(NS_ConvertUTF16toUTF8(indexValue).get(),"%d",&index);
                 if (index > 0)
                     index--;
             }
             else {
                 parameterCount++;
             }
 
             static nsIContent::AttrValuesArray sTypeValues[] =
                 { &nsGkAtoms::int32, &nsGkAtoms::integer, &nsGkAtoms::int64,
                   &nsGkAtoms::null, &nsGkAtoms::double_, &nsGkAtoms::string, nsnull };
 
-            PRInt32 typeError, typeValue = child->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::type,
+            PRInt32 typeError = 1;
+            PRInt32 typeValue = child->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::type,
                                                        sTypeValues, eCaseMatters);
             rv = NS_ERROR_ILLEGAL_VALUE;
             PRInt32 valInt32 = 0;
             PRInt64 valInt64 = 0;
             PRFloat64 valFloat = 0;
 
             switch (typeValue) {
               case 0:
@@ -374,18 +388,29 @@ nsXULTemplateQueryProcessorStorage::Comp
                 typeError = PR_sscanf(NS_ConvertUTF16toUTF8(value).get(),"%lf",&valFloat);
                 if (typeError > 0)
                     rv = statement->BindDoubleParameter(index, valFloat);
                 break;
               case 5:
               case nsIContent::ATTR_MISSING:
                 rv = statement->BindStringParameter(index, value);
                 break;
+              default:
+                typeError = 0;
             }
-            NS_ENSURE_SUCCESS(rv, rv);
+
+            if (typeError <= 0) {
+                nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_STORAGE_WRONG_TYPE_QUERY_PARAMETER);
+                return rv;
+            }
+
+            if (NS_FAILED(rv)) {
+                nsXULContentUtils::LogTemplateError(ERROR_TEMPLATE_STORAGE_QUERY_PARAMETER_NOT_BOUND);
+                return rv;
+            }
         }
     }
 
     *aReturn = statement;
     NS_IF_ADDREF(*aReturn);
 
     return NS_OK;
 }
--- a/content/xul/templates/tests/chrome/Makefile.in
+++ b/content/xul/templates/tests/chrome/Makefile.in
@@ -154,16 +154,19 @@ include $(topsrcdir)/config/rules.mk
 		test_tmpl_sorttwovariablesdescendingquerysyntax.xul \
 		test_tmpl_sortresource2descendingsimplesyntax.xul \
 		test_tmpl_sortascendingtworulesquerysyntax.xul \
 		test_tmpl_sortascendingtworuleswithcontainerquerysyntax.xul \
 		test_tmpl_sortascendingtworuleswithdifferentcontainerquerysyntax.xul \
 		test_tmpl_sortquerymemberandtwotriples.xul \
 		test_tmpl_storage_baddatasource.xul \
 		test_tmpl_storage_badquery.xul \
+		test_tmpl_storage_bad_parameters.xul \
+		test_tmpl_storage_bad_parameters_2.xul \
+		test_tmpl_storage_bad_parameters_3.xul \
 		test_tmpl_storage_dynamicparameters.xul \
 		test_tmpl_storage_listbox.xul \
 		test_tmpl_storage_multiqueries.xul \
 		test_tmpl_storage_parameters.xul \
 		test_tmpl_storage_rule.xul \
 		test_tmpl_storage_simple.xul \
 		test_tmpl_storage_sortintegerasc.xul \
 		test_tmpl_storage_sortintegerdesc.xul \
new file mode 100644
--- /dev/null
+++ b/content/xul/templates/tests/chrome/test_tmpl_storage_bad_parameters.xul
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+
+<!--
+    storage listbox with bad query parameters
+-->
+
+<window title="XUL Template Tests" width="500" height="600"
+        onload="test_template();"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <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>
+
+  <body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;"/>
+
+<script src="templates_shared.js"/>
+
+<script>
+<![CDATA[
+SimpleTest.waitForExplicitFinish();
+
+var testid ="storage listbox with bad query parameters";
+var queryType = "storage";
+var isTreeBuilder = false;
+var needsOpen = false;
+var notWorkingYet = false;
+var notWorkingYetDynamic = false;
+var expectedOutput = <output></output>;
+
+
+Components.classes["@mozilla.org/consoleservice;1"]
+          .getService(Components.interfaces.nsIConsoleService)
+          .reset();
+
+expectedConsoleMessages.push("Error parsing template: the given named parameter is unknown in the SQL query");
+
+var changes = [];
+]]>
+</script>
+
+<listbox  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" id="root" 
+              flex="1"  datasources="animals.sqlite" ref="." querytype="storage">
+    <template>
+        <query>
+            SELECT * FROM animals WHERE species_id = ? ORDER BY name
+            <param name="bar">2</param>
+        </query>
+        <action>
+            <listitem uri="?" label="?name"/>
+        </action>
+    </template>
+</listbox>
+
+</window>
new file mode 100644
--- /dev/null
+++ b/content/xul/templates/tests/chrome/test_tmpl_storage_bad_parameters_2.xul
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+
+<!--
+    storage listbox with bad query parameters
+-->
+
+<window title="XUL Template Tests" width="500" height="600"
+        onload="test_template();"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <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>
+
+  <body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;"/>
+
+<script src="templates_shared.js"/>
+
+<script>
+<![CDATA[
+SimpleTest.waitForExplicitFinish();
+
+var testid ="storage listbox with bad query parameters";
+var queryType = "storage";
+var isTreeBuilder = false;
+var needsOpen = false;
+var notWorkingYet = false;
+var notWorkingYetDynamic = false;
+var expectedOutput = <output></output>;
+
+
+Components.classes["@mozilla.org/consoleservice;1"]
+          .getService(Components.interfaces.nsIConsoleService)
+          .reset();
+
+expectedConsoleMessages.push("Error parsing template: the type of a query parameter is wrong");
+
+var changes = [];
+]]>
+</script>
+
+<listbox  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" id="root" 
+              flex="1"  datasources="animals.sqlite" ref="." querytype="storage">
+    <template>
+        <query>
+            SELECT * FROM animals WHERE species_id = ? ORDER BY name
+            <param type="mysupertype">2</param>
+        </query>
+        <action>
+            <listitem uri="?" label="?name"/>
+        </action>
+    </template>
+</listbox>
+
+</window>
new file mode 100644
--- /dev/null
+++ b/content/xul/templates/tests/chrome/test_tmpl_storage_bad_parameters_3.xul
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
+
+<!--
+    storage listbox with bad query parameters
+-->
+
+<window title="XUL Template Tests" width="500" height="600"
+        onload="test_template();"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <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>
+
+  <body xmlns="http://www.w3.org/1999/xhtml" style="height: 300px; overflow: auto;"/>
+
+<script src="templates_shared.js"/>
+
+<script>
+<![CDATA[
+SimpleTest.waitForExplicitFinish();
+
+var testid ="storage listbox with bad query parameters";
+var queryType = "storage";
+var isTreeBuilder = false;
+var needsOpen = false;
+var notWorkingYet = false;
+var notWorkingYetDynamic = false;
+var expectedOutput = <output></output>;
+
+
+Components.classes["@mozilla.org/consoleservice;1"]
+          .getService(Components.interfaces.nsIConsoleService)
+          .reset();
+
+expectedConsoleMessages.push("Error parsing template: a query parameter cannot be bound to the SQL query");
+
+var changes = [];
+]]>
+</script>
+
+<listbox  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" id="root" 
+              flex="1"  datasources="animals.sqlite" ref="." querytype="storage">
+    <template>
+        <query>
+                SELECT * FROM animals WHERE species_id = :spec ORDER BY name
+            <param name="spec" type="int32">5</param>
+            <param>L%</param>
+        </query>
+        <action>
+            <listitem uri="?" label="?name"/>
+        </action>
+    </template>
+</listbox>
+
+</window>
--- a/content/xul/templates/tests/chrome/test_tmpl_storage_baddatasource.xul
+++ b/content/xul/templates/tests/chrome/test_tmpl_storage_baddatasource.xul
@@ -25,23 +25,30 @@ SimpleTest.waitForExplicitFinish();
 var testid ="storage bad datasource";
 var queryType = "storage";
 var isTreeBuilder = false;
 var needsOpen = false;
 var notWorkingYet = false;
 var notWorkingYetDynamic = false;
 var expectedOutput =<output></output>;
 
+Components.classes["@mozilla.org/consoleservice;1"]
+          .getService(Components.interfaces.nsIConsoleService)
+          .reset();
+
+expectedConsoleMessages.push("Error parsing template: only profile: or file URI are allowed");
+
+
 var changes = [];
 ]]>
 </script>
 
 <listbox  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" id="root" 
               flex="1" rows="8"
-              datasources="animalsqsdqsdqsdq.sqlite" ref="." querytype="storage">
+              datasources="http://foo.local/animals.sqlite" ref="." querytype="storage">
     <template>
         <query>
             SELECT * FROM animals WHERE species_id = 2 ORDER BY name
         </query>
         <action>
             <listitem uri="?" label="?name"  />
         </action>
     </template>
--- a/content/xul/templates/tests/chrome/test_tmpl_storage_badquery.xul
+++ b/content/xul/templates/tests/chrome/test_tmpl_storage_badquery.xul
@@ -25,16 +25,23 @@ SimpleTest.waitForExplicitFinish();
 var testid ="storage bad query";
 var queryType = "storage";
 var isTreeBuilder = false;
 var needsOpen = false;
 var notWorkingYet = false;
 var notWorkingYetDynamic = false;
 var expectedOutput =<output></output>;
 
+Components.classes["@mozilla.org/consoleservice;1"]
+          .getService(Components.interfaces.nsIConsoleService)
+          .reset();
+
+expectedConsoleMessages.push("Error parsing template: syntax error in the SQL query");
+
+
 var changes = [];
 ]]>
 </script>
 
 <listbox  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" id="root" 
               flex="1" rows="8"
               datasources="animals.sqlite" ref="." querytype="storage">
     <template>
--- a/docshell/base/nsDefaultURIFixup.cpp
+++ b/docshell/base/nsDefaultURIFixup.cpp
@@ -795,34 +795,45 @@ nsresult nsDefaultURIFixup::KeywordURIFi
                                             nsIURI** aURI)
 {
     // These are keyword formatted strings
     // "what is mozilla"
     // "what is mozilla?"
     // "docshell site:mozilla.org" - has no dot/colon in the first space-separated substring
     // "?mozilla" - anything that begins with a question mark
     // "?site:mozilla.org docshell"
+    // Things that have a quote before the first dot/colon
 
     // These are not keyword formatted strings
     // "www.blah.com" - first space-separated substring contains a dot, doesn't start with "?"
     // "www.blah.com stuff"
     // "nonQualifiedHost:80" - first space-separated substring contains a colon, doesn't start with "?"
     // "nonQualifiedHost:80 args"
     // "nonQualifiedHost?"
     // "nonQualifiedHost?args"
     // "nonQualifiedHost?some args"
 
-    PRInt32 dotLoc   = aURIString.FindChar('.');
-    PRInt32 colonLoc = aURIString.FindChar(':');
-    PRInt32 spaceLoc = aURIString.FindChar(' ');
-    PRInt32 qMarkLoc = aURIString.FindChar('?');
+    // Note: PRUint32(kNotFound) is greater than any actual location
+    // in practice.  So if we cast all locations to PRUint32, then a <
+    // b guarantees that either b is kNotFound and a is found, or both
+    // are found and a found before b.
+    PRUint32 dotLoc   = PRUint32(aURIString.FindChar('.'));
+    PRUint32 colonLoc = PRUint32(aURIString.FindChar(':'));
+    PRUint32 spaceLoc = PRUint32(aURIString.FindChar(' '));
+    if (spaceLoc == 0) {
+        // Treat this as not found
+        spaceLoc = PRUint32(kNotFound);
+    }
+    PRUint32 qMarkLoc = PRUint32(aURIString.FindChar('?'));
+    PRUint32 quoteLoc = NS_MIN(PRUint32(aURIString.FindChar('"')),
+                               PRUint32(aURIString.FindChar('\'')));
 
-    if ((dotLoc == kNotFound || (spaceLoc > 0 && spaceLoc < dotLoc)) &&
-        (colonLoc == kNotFound || (spaceLoc > 0 && spaceLoc < colonLoc)) &&
-        (spaceLoc > 0 && (qMarkLoc == kNotFound || spaceLoc < qMarkLoc)) ||
+    if (((spaceLoc < dotLoc || quoteLoc < dotLoc) &&
+         (spaceLoc < colonLoc || quoteLoc < colonLoc) &&
+         (spaceLoc < qMarkLoc || quoteLoc < qMarkLoc)) ||
         qMarkLoc == 0)
     {
         KeywordToURI(aURIString, aURI);
     }
 
     if(*aURI)
         return NS_OK;
 
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -1957,19 +1957,16 @@ nsDocShell::GetAppType(PRUint32 * aAppTy
     *aAppType = mAppType;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::SetAppType(PRUint32 aAppType)
 {
     mAppType = aAppType;
-    if (mAppType == APP_TYPE_MAIL || mAppType == APP_TYPE_EDITOR) {
-        SetAllowDNSPrefetch(PR_FALSE);
-    }
     return NS_OK;
 }
 
 
 NS_IMETHODIMP
 nsDocShell::GetAllowAuth(PRBool * aAllowAuth)
 {
     *aAllowAuth = mAllowAuth;
@@ -7892,17 +7889,17 @@ nsDocShell::InternalLoad(nsIURI * aURI,
     if (aLoadType == LOAD_NORMAL ||
         aLoadType == LOAD_STOP_CONTENT ||
         LOAD_TYPE_HAS_FLAGS(aLoadType, LOAD_FLAGS_REPLACE_HISTORY) ||
         aLoadType == LOAD_HISTORY ||
         aLoadType == LOAD_LINK) {
 
         PRBool wasAnchor = PR_FALSE;
         PRBool doHashchange = PR_FALSE;
-        nscoord cx, cy;
+        nscoord cx = 0, cy = 0;
 
         if (allowScroll) {
             NS_ENSURE_SUCCESS(ScrollIfAnchor(aURI, &wasAnchor, aLoadType, &cx,
                                              &cy, &doHashchange),
                               NS_ERROR_FAILURE);
         }
 
         // If this is a history load, aSHEntry will have document identifier X
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -4537,16 +4537,23 @@ nsGlobalWindow::Print()
     nsCOMPtr<nsIPrintSettings> printSettings;
     if (printSettingsService) {
       PRBool printSettingsAreGlobal =
         nsContentUtils::GetBoolPref("print.use_global_printsettings", PR_FALSE);
 
       if (printSettingsAreGlobal) {
         printSettingsService->GetGlobalPrintSettings(getter_AddRefs(printSettings));
 
+        if (printSettings) {
+          // Call any code that requires a run of the event loop.
+          EnterModalState();
+          printSettings->SetupSilentPrinting();
+          LeaveModalState();
+        }
+
         nsXPIDLString printerName;
         printSettingsService->GetDefaultPrinterName(getter_Copies(printerName));
         if (printerName)
           printSettingsService->InitPrintSettingsFromPrinter(printerName, printSettings);
         printSettingsService->InitPrintSettingsFromPrefs(printSettings, 
                                                          PR_TRUE, 
                                                          nsIPrintSettings::kInitSaveAll);
       } else {
--- a/dom/dom-config.mk
+++ b/dom/dom-config.mk
@@ -1,59 +1,10 @@
 MODULE = dom
 
-REQUIRES += \
-  string \
-  xpcom \
-  webbrwsr \
-  commandhandler \
-  js \
-  widget \
-  gfx \
-  thebes \
-  layout \
-  content \
-  caps \
-  docshell \
-  xpconnect \
-  pref \
-  oji \
-  necko \
-  nkcache \
-  mimetype \
-  java \
-  locale \
-  prefetch \
-  xuldoc \
-  webshell \
-  view \
-  uconv \
-  shistory \
-  plugin \
-  windowwatcher \
-  chardet \
-  find \
-  appshell \
-  intl \
-  unicharutil \
-  rdf \
-  xultmpl \
-  jar \
-  storage \
-  htmlparser \
-  $(NULL)
-
-ifdef NS_TRACE_MALLOC
-REQUIRES += tracemalloc
-endif
-
-ifdef MOZ_JSDEBUGGER
-REQUIRES += jsdebug
-endif
-
 DOM_SRCDIRS = \
   dom/base \
   dom/src/events \
   dom/src/storage \
   dom/src/offline \
   dom/src/geolocation \
   dom/src/threads \
   content/xbl/src \
--- a/dom/locales/en-US/chrome/plugins.properties
+++ b/dom/locales/en-US/chrome/plugins.properties
@@ -1,14 +1,14 @@
 # LOCALIZATION NOTE (plugins.properties):
 #    Those strings are inserted into an HTML page, so you all HTML characters
 #    have to be escaped in a way that they show up correctly in HTML!
 
 title_label=About Plugins
-installedplugins_label=Installed plugins
+enabledplugins_label=Enabled plugins
 nopluginsareenabled_label=No enabled plugins found
 findmore_label=Find more information about browser plugins at
 findpluginupdates_label=Find updates for installed plugins at
 installhelp_label=Help for installing plugins is available from
 file_label=File:
 version_label=Version:
 mimetype_label=MIME Type
 description_label=Description
--- a/editor/libeditor/html/tests/Makefile.in
+++ b/editor/libeditor/html/tests/Makefile.in
@@ -54,9 +54,10 @@ include $(topsrcdir)/config/rules.mk
 		test_bug487524.html \
 		test_bug525389.html \
 		test_select_all_without_body.html \
 		file_select_all_without_body.html \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
+	(cd $(srcdir) && tar $(TAR_CREATE_FLAGS) - browserscope) | (cd $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir) && tar -xf -)
 
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/html/tests/browserscope/lib/browserscope/LICENSE
@@ -0,0 +1,202 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/html/tests/browserscope/lib/browserscope/README
@@ -0,0 +1,58 @@
+README FOR BROWSERSCOPE
+-----------------------
+
+Hey there - thanks for downloading the code. This file has instructions
+for getting setup so that you can run the codebase locally.
+
+This project is built on Google App Engine using the
+Django web application framework and written in Python.
+
+To get started, you'll need to first download the App Engine SDK at:
+http://code.google.com/appengine/downloads.html
+
+For local development, just startup the server:
+./pathto/google_appengine/dev_appserver.py --port=8080 browserscope
+
+You should then be able to access the local application at:
+http://localhost:8080/
+
+Note: the first time you hit the homepage it may take a little
+while - that's because it's trying to read out median times for all
+of the tests from a non-existent datastore and write to memcache.
+Just be a lil patient.
+
+You can run the unit tests at:
+  http://localhost:8080/test
+
+
+CONTRIBUTING
+------------------
+
+Most likely you are interested in adding new tests or creating
+a new test category. If you are interested in adding tests to an existing
+"category" you may want to get in touch with the maintainer for that
+branch of the tree. We are really looking forward to receiving your
+code in patch format. Currently the category maintainers are:
+Network: Steve Souders <souders@gmail.com>
+Reflow: Lindsey Simon <elsigh@gmail.com>
+Security: Adam Barth <adam@adambarth.com> and Collin Jackson <collin@collinjackson.com>
+
+
+To create a completely new test category:
+  * Copy one of the existing directories in categories/
+  * Edit your test_set.py, handlers.py
+  * Add your files in templates/ and static/
+  * Update urls.py and settings.CATEGORIES
+  * Follow the examples of other tests re:
+      * beaconing using/testdriver_base
+      * your GetScoreAndDisplayValue method
+      * your GetRowScoreAndDisplayValue method
+
+References:
+  * App Engine Docs - http://code.google.com/appengine/docs/python/overview.html
+  * App Engine Group - http://groups.google.com/group/google-appengine
+  * Python Docs - http://www.python.org/doc/
+  * Django - http://www.djangoproject.com/
+
+
+
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/html/tests/browserscope/lib/browserscope/README.Mozilla
@@ -0,0 +1,17 @@
+The BrowserScope project provides a set of cross-browser HTML editor tests,
+which we import in our test suite in order to run them as part of our
+continuous integration system.
+
+We pull tests occasionally from their Subversion repository using the pull
+script which can be found in this directory.  We also record the revision ID
+which we've used in the current_revision file inside this directory.
+
+Using the pull script is quite easy, just switch to this directory, and say:
+
+sh update_from_upstream
+
+There are tests which we're currently failing on, and there will probably be
+more of those in the future.  We should maintain a list of the failing tests
+manually in currentStatus.js (which can also be found in this directory), to
+make sure that the suite passes entirely, with failing tests marked as todo
+items.
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/html/tests/browserscope/lib/browserscope/currentStatus.js
@@ -0,0 +1,64 @@
+/**
+ * This file lists the tests in the BrowserScope suite which we are currently
+ * failing.  We mark them as todo items to keep track of them.
+ */
+
+var knownFailures = {
+  // Dummy result items.  There is one for each category.
+  'apply' : {
+    '0-undefined' : true
+  },
+  'unapply' : {
+    '0-undefined' : true
+  },
+  'change' : {
+    '0-undefined' : true
+  },
+  'query' : {
+    '0-undefined' : true
+  },
+  'a' : {
+    'backcolor-0' : true,
+    'backcolor-1' : true,
+    'createbookmark-0' : true,
+    'fontsize-1' : true,
+    'hilitecolor-0' : true,
+    'subscript-1' : true,
+    'superscript-1' : true,
+  },
+  'u': {
+    'bold-1' : true,
+    'italic-1' : true,
+    'removeformat-1' : true,
+    'removeformat-2' : true,
+    'strikethrough-1' : true,
+    'strikethrough-2' : true,
+    'subscript-1' : true,
+    'superscript-1' : true,
+    'unbookmark-0' : true,
+  },
+  'q': {
+    'backcolor-0' : true,
+    'backcolor-1' : true,
+    'backcolor-2' : true,
+    'fontsize-1' : true,
+    'fontsize-2' : true,
+    'underline-5' : true,
+  },
+  'c': {
+    'backcolor-0' : true,
+    'backcolor-1' : true,
+    'backcolor-2' : true,
+    'fontname-0' : true,
+    'fontname-2' : true,
+    'fontname-3' : true,
+    'fontsize-1' : true,
+    'fontsize-2' : true,
+    'forecolor-0' : true,
+    'forecolor-2' : true,
+  },
+};
+
+function isKnownFailure(type, test, param) {
+  return (type in knownFailures) && ((test + "-" + param) in knownFailures[type]);
+}
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/html/tests/browserscope/lib/browserscope/current_revision
@@ -0,0 +1,1 @@
+547
new file mode 100755
--- /dev/null
+++ b/editor/libeditor/html/tests/browserscope/lib/browserscope/richtext/editable.html
@@ -0,0 +1,11 @@
+<html>
+<head>
+  <script>
+    function load(){
+      window.document.designMode = "On";
+    }
+  </script>
+</head>
+<body contentEditable="true" onload="load()">
+</body>
+</html>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/html/tests/browserscope/lib/browserscope/richtext/js/range.js
@@ -0,0 +1,1069 @@
+var goog$global = this, goog$isString = function(val) {
+  return typeof val == "string"
+};
+Math.floor(Math.random() * 2147483648).toString(36);
+var goog$now = Date.now || function() {
+  return(new Date).getTime()
+}, goog$inherits = function(childCtor, parentCtor) {
+  function tempCtor() {
+  }
+  tempCtor.prototype = parentCtor.prototype;
+  childCtor.superClass_ = parentCtor.prototype;
+  childCtor.prototype = new tempCtor
+};var goog$array$peek = function(array) {
+  return array[array.length - 1]
+}, goog$array$indexOf = function(arr, obj, opt_fromIndex) {
+  if(arr.indexOf)return arr.indexOf(obj, opt_fromIndex);
+  if(Array.indexOf)return Array.indexOf(arr, obj, opt_fromIndex);
+  for(var fromIndex = opt_fromIndex == null ? 0 : opt_fromIndex < 0 ? Math.max(0, arr.length + opt_fromIndex) : opt_fromIndex, i = fromIndex;i < arr.length;i++)if(i in arr && arr[i] === obj)return i;
+  return-1
+}, goog$array$map = function(arr, f, opt_obj) {
+  if(arr.map)return arr.map(f, opt_obj);
+  if(Array.map)return Array.map(arr, f, opt_obj);
+  for(var l = arr.length, res = [], resLength = 0, arr2 = goog$isString(arr) ? arr.split("") : arr, i = 0;i < l;i++)if(i in arr2)res[resLength++] = f.call(opt_obj, arr2[i], i, arr);
+  return res
+}, goog$array$some = function(arr, f, opt_obj) {
+  if(arr.some)return arr.some(f, opt_obj);
+  if(Array.some)return Array.some(arr, f, opt_obj);
+  for(var l = arr.length, arr2 = goog$isString(arr) ? arr.split("") : arr, i = 0;i < l;i++)if(i in arr2 && f.call(opt_obj, arr2[i], i, arr))return true;
+  return false
+}, goog$array$every = function(arr, f, opt_obj) {
+  if(arr.every)return arr.every(f, opt_obj);
+  if(Array.every)return Array.every(arr, f, opt_obj);
+  for(var l = arr.length, arr2 = goog$isString(arr) ? arr.split("") : arr, i = 0;i < l;i++)if(i in arr2 && !f.call(opt_obj, arr2[i], i, arr))return false;
+  return true
+}, goog$array$find = function(arr, f, opt_obj) {
+  var i;
+  JSCompiler_inline_label_goog$array$findIndex_12: {
+    for(var JSCompiler_inline_l = arr.length, JSCompiler_inline_arr2 = goog$isString(arr) ? arr.split("") : arr, JSCompiler_inline_i = 0;JSCompiler_inline_i < JSCompiler_inline_l;JSCompiler_inline_i++)if(JSCompiler_inline_i in JSCompiler_inline_arr2 && f.call(opt_obj, JSCompiler_inline_arr2[JSCompiler_inline_i], JSCompiler_inline_i, arr)) {
+      i = JSCompiler_inline_i;
+      break JSCompiler_inline_label_goog$array$findIndex_12
+    }i = -1
+  }return i < 0 ? null : goog$isString(arr) ? arr.charAt(i) : arr[i]
+};var goog$string$trim = function(str) {
+  return str.replace(/^[\s\xa0]+|[\s\xa0]+$/g, "")
+}, goog$string$htmlEscape = function(str, opt_isLikelyToContainHtmlChars) {
+  if(opt_isLikelyToContainHtmlChars)return str.replace(goog$string$amperRe_, "&amp;").replace(goog$string$ltRe_, "&lt;").replace(goog$string$gtRe_, "&gt;").replace(goog$string$quotRe_, "&quot;");
+  else {
+    if(!goog$string$allRe_.test(str))return str;
+    if(str.indexOf("&") != -1)str = str.replace(goog$string$amperRe_, "&amp;");
+    if(str.indexOf("<") != -1)str = str.replace(goog$string$ltRe_, "&lt;");
+    if(str.indexOf(">") != -1)str = str.replace(goog$string$gtRe_, "&gt;");
+    if(str.indexOf('"') != -1)str = str.replace(goog$string$quotRe_, "&quot;");
+    return str
+  }
+}, goog$string$amperRe_ = /&/g, goog$string$ltRe_ = /</g, goog$string$gtRe_ = />/g, goog$string$quotRe_ = /\"/g, goog$string$allRe_ = /[&<>\"]/, goog$string$contains = function(s, ss) {
+  return s.indexOf(ss) != -1
+}, goog$string$compareVersions = function(version1, version2) {
+  for(var order = 0, v1Subs = goog$string$trim(String(version1)).split("."), v2Subs = goog$string$trim(String(version2)).split("."), subCount = Math.max(v1Subs.length, v2Subs.length), subIdx = 0;order == 0 && subIdx < subCount;subIdx++) {
+    var v1Sub = v1Subs[subIdx] || "", v2Sub = v2Subs[subIdx] || "", v1CompParser = new RegExp("(\\d*)(\\D*)", "g"), v2CompParser = new RegExp("(\\d*)(\\D*)", "g");
+    do {
+      var v1Comp = v1CompParser.exec(v1Sub) || ["", "", ""], v2Comp = v2CompParser.exec(v2Sub) || ["", "", ""];
+      if(v1Comp[0].length == 0 && v2Comp[0].length == 0)break;
+      var v1CompNum = v1Comp[1].length == 0 ? 0 : parseInt(v1Comp[1], 10), v2CompNum = v2Comp[1].length == 0 ? 0 : parseInt(v2Comp[1], 10);
+      order = goog$string$compareElements_(v1CompNum, v2CompNum) || goog$string$compareElements_(v1Comp[2].length == 0, v2Comp[2].length == 0) || goog$string$compareElements_(v1Comp[2], v2Comp[2])
+    }while(order == 0)
+  }return order
+}, goog$string$compareElements_ = function(left, right) {
+  if(left < right)return-1;
+  else if(left > right)return 1;
+  return 0
+};
+goog$now();var goog$userAgent$detectedOpera_, goog$userAgent$detectedIe_, goog$userAgent$detectedWebkit_, goog$userAgent$detectedMobile_, goog$userAgent$detectedGecko_, goog$userAgent$detectedCamino_, goog$userAgent$detectedMac_, goog$userAgent$detectedWindows_, goog$userAgent$detectedLinux_, goog$userAgent$detectedX11_, goog$userAgent$getUserAgentString = function() {
+  return goog$global.navigator ? goog$global.navigator.userAgent : null
+}, goog$userAgent$getNavigator = function() {
+  return goog$global.navigator
+};
+goog$userAgent$detectedCamino_ = goog$userAgent$detectedGecko_ = goog$userAgent$detectedMobile_ = goog$userAgent$detectedWebkit_ = goog$userAgent$detectedIe_ = goog$userAgent$detectedOpera_ = false;
+var JSCompiler_inline_ua_15;
+if(JSCompiler_inline_ua_15 = goog$userAgent$getUserAgentString()) {
+  var JSCompiler_inline_navigator$$1_16 = goog$userAgent$getNavigator();
+  goog$userAgent$detectedOpera_ = JSCompiler_inline_ua_15.indexOf("Opera") == 0;
+  goog$userAgent$detectedIe_ = !goog$userAgent$detectedOpera_ && JSCompiler_inline_ua_15.indexOf("MSIE") != -1;
+  goog$userAgent$detectedMobile_ = (goog$userAgent$detectedWebkit_ = !goog$userAgent$detectedOpera_ && JSCompiler_inline_ua_15.indexOf("WebKit") != -1) && JSCompiler_inline_ua_15.indexOf("Mobile") != -1;
+  goog$userAgent$detectedCamino_ = (goog$userAgent$detectedGecko_ = !goog$userAgent$detectedOpera_ && !goog$userAgent$detectedWebkit_ && JSCompiler_inline_navigator$$1_16.product == "Gecko") && JSCompiler_inline_navigator$$1_16.vendor == "Camino"
+}var goog$userAgent$OPERA = goog$userAgent$detectedOpera_, goog$userAgent$IE = goog$userAgent$detectedIe_, goog$userAgent$GECKO = goog$userAgent$detectedGecko_, goog$userAgent$WEBKIT = goog$userAgent$detectedWebkit_, goog$userAgent$MOBILE = goog$userAgent$detectedMobile_, goog$userAgent$PLATFORM, JSCompiler_inline_navigator$$2_19 = goog$userAgent$getNavigator();
+goog$userAgent$PLATFORM = JSCompiler_inline_navigator$$2_19 && JSCompiler_inline_navigator$$2_19.platform || "";
+goog$userAgent$detectedMac_ = goog$string$contains(goog$userAgent$PLATFORM, "Mac");
+goog$userAgent$detectedWindows_ = goog$string$contains(goog$userAgent$PLATFORM, "Win");
+goog$userAgent$detectedLinux_ = goog$string$contains(goog$userAgent$PLATFORM, "Linux");
+goog$userAgent$detectedX11_ = !!goog$userAgent$getNavigator() && goog$string$contains(goog$userAgent$getNavigator().appVersion || "", "X11");
+var goog$userAgent$VERSION, JSCompiler_inline_version$$6_26 = "", JSCompiler_inline_re$$2_27;
+if(goog$userAgent$OPERA && goog$global.opera) {
+  var JSCompiler_inline_operaVersion_28 = goog$global.opera.version;
+  JSCompiler_inline_version$$6_26 = typeof JSCompiler_inline_operaVersion_28 == "function" ? JSCompiler_inline_operaVersion_28() : JSCompiler_inline_operaVersion_28
+}else {
+  if(goog$userAgent$GECKO)JSCompiler_inline_re$$2_27 = /rv\:([^\);]+)(\)|;)/;
+  else if(goog$userAgent$IE)JSCompiler_inline_re$$2_27 = /MSIE\s+([^\);]+)(\)|;)/;
+  else if(goog$userAgent$WEBKIT)JSCompiler_inline_re$$2_27 = /WebKit\/(\S+)/;
+  if(JSCompiler_inline_re$$2_27) {
+    var JSCompiler_inline_arr$$41_29 = JSCompiler_inline_re$$2_27.exec(goog$userAgent$getUserAgentString());
+    JSCompiler_inline_version$$6_26 = JSCompiler_inline_arr$$41_29 ? JSCompiler_inline_arr$$41_29[1] : ""
+  }
+}goog$userAgent$VERSION = JSCompiler_inline_version$$6_26;
+var goog$userAgent$isVersionCache_ = {}, goog$userAgent$isVersion = function(version) {
+  return goog$userAgent$isVersionCache_[version] || (goog$userAgent$isVersionCache_[version] = goog$string$compareVersions(goog$userAgent$VERSION, version) >= 0)
+};var goog$dom$getWindow = function(opt_doc) {
+  return opt_doc ? goog$dom$getWindow_(opt_doc) : window
+}, goog$dom$getWindow_ = function(doc) {
+  if(doc.parentWindow)return doc.parentWindow;
+  if(goog$userAgent$WEBKIT && !goog$userAgent$isVersion("500") && !goog$userAgent$MOBILE) {
+    var scriptElement = doc.createElement("script");
+    scriptElement.innerHTML = "document.parentWindow=window";
+    var parentElement = doc.documentElement;
+    parentElement.appendChild(scriptElement);
+    parentElement.removeChild(scriptElement);
+    return doc.parentWindow
+  }return doc.defaultView
+}, goog$dom$appendChild = function(parent, child) {
+  parent.appendChild(child)
+}, goog$dom$BAD_CONTAINS_WEBKIT_ = goog$userAgent$WEBKIT && goog$userAgent$isVersion("522"), goog$dom$contains = function(parent, descendant) {
+  if(typeof parent.contains != "undefined" && !goog$dom$BAD_CONTAINS_WEBKIT_ && descendant.nodeType == 1)return parent == descendant || parent.contains(descendant);
+  if(typeof parent.compareDocumentPosition != "undefined")return parent == descendant || Boolean(parent.compareDocumentPosition(descendant) & 16);
+  for(;descendant && parent != descendant;)descendant = descendant.parentNode;
+  return descendant == parent
+}, goog$dom$compareNodeOrder = function(node1, node2) {
+  if(node1 == node2)return 0;
+  if(node1.compareDocumentPosition)return node1.compareDocumentPosition(node2) & 2 ? 1 : -1;
+  if("sourceIndex" in node1 || node1.parentNode && "sourceIndex" in node1.parentNode) {
+    var isElement1 = node1.nodeType == 1, isElement2 = node2.nodeType == 1;
+    if(isElement1 && isElement2)return node1.sourceIndex - node2.sourceIndex;
+    else {
+      var parent1 = node1.parentNode, parent2 = node2.parentNode;
+      if(parent1 == parent2)return goog$dom$compareSiblingOrder_(node1, node2);
+      if(!isElement1 && goog$dom$contains(parent1, node2))return-1 * goog$dom$compareParentsDescendantNodeIe_(node1, node2);
+      if(!isElement2 && goog$dom$contains(parent2, node1))return goog$dom$compareParentsDescendantNodeIe_(node2, node1);
+      return(isElement1 ? node1.sourceIndex : parent1.sourceIndex) - (isElement2 ? node2.sourceIndex : parent2.sourceIndex)
+    }
+  }var doc = goog$dom$getOwnerDocument(node1), range1, range2;
+  range1 = doc.createRange();
+  range1.selectNode(node1);
+  range1.collapse(true);
+  range2 = doc.createRange();
+  range2.selectNode(node2);
+  range2.collapse(true);
+  return range1.compareBoundaryPoints(goog$global.Range.START_TO_END, range2)
+}, goog$dom$compareParentsDescendantNodeIe_ = function(textNode, node) {
+  var parent = textNode.parentNode;
+  if(parent == node)return-1;
+  for(var sibling = node;sibling.parentNode != parent;)sibling = sibling.parentNode;
+  return goog$dom$compareSiblingOrder_(sibling, textNode)
+}, goog$dom$compareSiblingOrder_ = function(node1, node2) {
+  for(var s = node2;s = s.previousSibling;)if(s == node1)return-1;
+  return 1
+}, goog$dom$findCommonAncestor = function() {
+  var i, count = arguments.length;
+  if(count) {
+    if(count == 1)return arguments[0]
+  }else return null;
+  var paths = [], minLength = Infinity;
+  for(i = 0;i < count;i++) {
+    for(var ancestors = [], node = arguments[i];node;) {
+      ancestors.unshift(node);
+      node = node.parentNode
+    }paths.push(ancestors);
+    minLength = Math.min(minLength, ancestors.length)
+  }var output = null;
+  for(i = 0;i < minLength;i++) {
+    for(var first = paths[0][i], j = 1;j < count;j++)if(first != paths[j][i])return output;
+    output = first
+  }return output
+}, goog$dom$getOwnerDocument = function(node) {
+  // Added 'editorDoc' as hack for browsers that don't support node.ownerDocument
+  return node.nodeType == 9 ? node : node.ownerDocument || node.document || editorDoc
+}, goog$dom$DomHelper = function(opt_document) {
+  this.document_ = opt_document || goog$global.document || document
+};
+goog$dom$DomHelper.prototype.getDocument = function() {
+  return this.document_
+};
+goog$dom$DomHelper.prototype.createElement = function(name) {
+  return this.document_.createElement(name)
+};
+goog$dom$DomHelper.prototype.getWindow = function() {
+  return goog$dom$getWindow_(this.document_)
+};
+goog$dom$DomHelper.prototype.appendChild = goog$dom$appendChild;
+goog$dom$DomHelper.prototype.contains = goog$dom$contains;var goog$Disposable = function() {
+};if("StopIteration" in goog$global)var goog$iter$StopIteration = goog$global.StopIteration;
+else goog$iter$StopIteration = Error("StopIteration");
+var goog$iter$Iterator = function() {
+};
+goog$iter$Iterator.prototype.next = function() {
+  throw goog$iter$StopIteration;
+};
+goog$iter$Iterator.prototype.__iterator__ = function() {
+  return this
+};var goog$debug$exposeException = function(err, opt_fn) {
+  try {
+    var e, JSCompiler_inline_href_34;
+    JSCompiler_inline_label_goog$getObjectByName_61: {
+      for(var JSCompiler_inline_parts = "window.location.href".split("."), JSCompiler_inline_cur = goog$global, JSCompiler_inline_part;JSCompiler_inline_part = JSCompiler_inline_parts.shift();)if(JSCompiler_inline_cur[JSCompiler_inline_part])JSCompiler_inline_cur = JSCompiler_inline_cur[JSCompiler_inline_part];
+      else {
+        JSCompiler_inline_href_34 = null;
+        break JSCompiler_inline_label_goog$getObjectByName_61
+      }JSCompiler_inline_href_34 = JSCompiler_inline_cur
+    }e = typeof err == "string" ? {message:err, name:"Unknown error", lineNumber:"Not available", fileName:JSCompiler_inline_href_34, stack:"Not available"} : !err.lineNumber || !err.fileName || !err.stack ? {message:err.message, name:err.name, lineNumber:err.lineNumber || err.line || "Not available", fileName:err.fileName || err.filename || err.sourceURL || JSCompiler_inline_href_34, stack:err.stack || "Not available"} : err;
+    var error = "Message: " + goog$string$htmlEscape(e.message) + '\nUrl: <a href="view-source:' + e.fileName + '" target="_new">' + e.fileName + "</a>\nLine: " + e.lineNumber + "\n\nBrowser stack:\n" + goog$string$htmlEscape(e.stack + "-> ") + "[end]\n\nJS stack traversal:\n" + goog$string$htmlEscape(goog$debug$getStacktrace(opt_fn) + "-> ");
+    return error
+  }catch(e2) {
+    return"Exception trying to expose exception! You win, we lose. " + e2
+  }
+}, goog$debug$getStacktrace = function(opt_fn) {
+  return goog$debug$getStacktraceHelper_(opt_fn || arguments.callee.caller, [])
+}, goog$debug$getStacktraceHelper_ = function(fn, visited) {
+  var sb = [], JSCompiler_inline_result_36;
+  JSCompiler_inline_label_goog$array$contains_41:JSCompiler_inline_result_36 = visited.contains ? visited.contains(fn) : goog$array$indexOf(visited, fn) > -1;
+  if(JSCompiler_inline_result_36)sb.push("[...circular reference...]");
+  else if(fn && visited.length < 50) {
+    sb.push(goog$debug$getFunctionName(fn) + "(");
+    for(var args = fn.arguments, i = 0;i < args.length;i++) {
+      i > 0 && sb.push(", ");
+      var argDesc, arg = args[i];
+      switch(typeof arg) {
+        case "object":
+          argDesc = arg ? "object" : "null";
+          break;
+        case "string":
+          argDesc = arg;
+          break;
+        case "number":
+          argDesc = String(arg);
+          break;
+        case "boolean":
+          argDesc = arg ? "true" : "false";
+          break;
+        case "function":
+          argDesc = (argDesc = goog$debug$getFunctionName(arg)) ? argDesc : "[fn]";
+          break;
+        case "undefined":
+        ;
+        default:
+          argDesc = typeof arg;
+          break
+      }
+      if(argDesc.length > 40)argDesc = argDesc.substr(0, 40) + "...";
+      sb.push(argDesc)
+    }visited.push(fn);
+    sb.push(")\n");
+    try {
+      sb.push(goog$debug$getStacktraceHelper_(fn.caller, visited))
+    }catch(e) {
+      sb.push("[exception trying to get caller]\n")
+    }
+  }else fn ? sb.push("[...long stack...]") : sb.push("[end]");
+  return sb.join("")
+}, goog$debug$getFunctionName = function(fn) {
+  var functionSource = String(fn);
+  if(!goog$debug$fnNameCache_[functionSource]) {
+    var matches = /function ([^\(]+)/.exec(functionSource);
+    if(matches) {
+      var method = matches[1];
+      goog$debug$fnNameCache_[functionSource] = method
+    }else goog$debug$fnNameCache_[functionSource] = "[Anonymous]"
+  }return goog$debug$fnNameCache_[functionSource]
+}, goog$debug$fnNameCache_ = {};var goog$debug$LogRecord = function(level, msg, loggerName, opt_time, opt_sequenceNumber) {
+  this.sequenceNumber_ = typeof opt_sequenceNumber == "number" ? opt_sequenceNumber : goog$debug$LogRecord$nextSequenceNumber_++;
+  this.time_ = opt_time || goog$now();
+  this.level_ = level;
+  this.msg_ = msg;
+  this.loggerName_ = loggerName
+};
+goog$debug$LogRecord.prototype.exception_ = null;
+goog$debug$LogRecord.prototype.exceptionText_ = null;
+var goog$debug$LogRecord$nextSequenceNumber_ = 0;
+goog$debug$LogRecord.prototype.setException = function(exception) {
+  this.exception_ = exception
+};
+goog$debug$LogRecord.prototype.setExceptionText = function(text) {
+  this.exceptionText_ = text
+};
+goog$debug$LogRecord.prototype.setLevel = function(level) {
+  this.level_ = level
+};var goog$debug$Logger = function(name) {
+  this.name_ = name;
+  this.parent_ = null;
+  this.children_ = {};
+  this.handlers_ = []
+};
+goog$debug$Logger.prototype.level_ = null;
+var goog$debug$Logger$Level = function(name, value) {
+  this.name = name;
+  this.value = value
+};
+goog$debug$Logger$Level.prototype.toString = function() {
+  return this.name
+};
+new goog$debug$Logger$Level("OFF", Infinity);
+new goog$debug$Logger$Level("SHOUT", 1200);
+var goog$debug$Logger$Level$SEVERE = new goog$debug$Logger$Level("SEVERE", 1000), goog$debug$Logger$Level$WARNING = new goog$debug$Logger$Level("WARNING", 900);
+new goog$debug$Logger$Level("INFO", 800);
+var goog$debug$Logger$Level$CONFIG = new goog$debug$Logger$Level("CONFIG", 700);
+new goog$debug$Logger$Level("FINE", 500);
+new goog$debug$Logger$Level("FINER", 400);
+new goog$debug$Logger$Level("FINEST", 300);
+new goog$debug$Logger$Level("ALL", 0);
+goog$debug$Logger.prototype.setLevel = function(level) {
+  this.level_ = level
+};
+goog$debug$Logger.prototype.isLoggable = function(level) {
+  if(this.level_)return level.value >= this.level_.value;
+  if(this.parent_)return this.parent_.isLoggable(level);
+  return false
+};
+goog$debug$Logger.prototype.log = function(level, msg, opt_exception) {
+  this.isLoggable(level) && this.logRecord(this.getLogRecord(level, msg, opt_exception))
+};
+goog$debug$Logger.prototype.getLogRecord = function(level, msg, opt_exception) {
+  var logRecord = new goog$debug$LogRecord(level, String(msg), this.name_);
+  if(opt_exception) {
+    logRecord.setException(opt_exception);
+    logRecord.setExceptionText(goog$debug$exposeException(opt_exception, arguments.callee.caller))
+  }return logRecord
+};
+goog$debug$Logger.prototype.severe = function(msg, opt_exception) {
+  this.log(goog$debug$Logger$Level$SEVERE, msg, opt_exception)
+};
+goog$debug$Logger.prototype.warning = function(msg, opt_exception) {
+  this.log(goog$debug$Logger$Level$WARNING, msg, opt_exception)
+};
+goog$debug$Logger.prototype.logRecord = function(logRecord) {
+  if(this.isLoggable(logRecord.level_))for(var target = this;target;) {
+    target.callPublish_(logRecord);
+    target = target.parent_
+  }
+};
+goog$debug$Logger.prototype.callPublish_ = function(logRecord) {
+  for(var i = 0;i < this.handlers_.length;i++)this.handlers_[i](logRecord)
+};
+goog$debug$Logger.prototype.setParent_ = function(parent) {
+  this.parent_ = parent
+};
+goog$debug$Logger.prototype.addChild_ = function(name, logger) {
+  this.children_[name] = logger
+};
+var goog$debug$LogManager$loggers_ = {}, goog$debug$LogManager$rootLogger_ = null, goog$debug$LogManager$getLogger = function(name) {
+  if(!goog$debug$LogManager$rootLogger_) {
+    goog$debug$LogManager$rootLogger_ = new goog$debug$Logger("");
+    goog$debug$LogManager$loggers_[""] = goog$debug$LogManager$rootLogger_;
+    goog$debug$LogManager$rootLogger_.setLevel(goog$debug$Logger$Level$CONFIG)
+  }return name in goog$debug$LogManager$loggers_ ? goog$debug$LogManager$loggers_[name] : goog$debug$LogManager$createLogger_(name)
+}, goog$debug$LogManager$createLogger_ = function(name) {
+  var logger = new goog$debug$Logger(name), parts = name.split("."), leafName = parts[parts.length - 1];
+  parts.length = parts.length - 1;
+  var parentName = parts.join("."), parentLogger = goog$debug$LogManager$getLogger(parentName);
+  parentLogger.addChild_(leafName, logger);
+  logger.setParent_(parentLogger);
+  return goog$debug$LogManager$loggers_[name] = logger
+};var goog$dom$SavedRange = function() {
+  goog$Disposable.call(this)
+};
+goog$inherits(goog$dom$SavedRange, goog$Disposable);
+goog$debug$LogManager$getLogger("goog.dom.SavedRange");var goog$dom$TagIterator = function(opt_node, opt_reversed, opt_unconstrained, opt_tagType, opt_depth) {
+  this.reversed = !!opt_reversed;
+  opt_node && this.setPosition(opt_node, opt_tagType);
+  this.depth = opt_depth != undefined ? opt_depth : this.tagType || 0;
+  if(this.reversed)this.depth *= -1;
+  this.constrained = !opt_unconstrained
+};
+goog$inherits(goog$dom$TagIterator, goog$iter$Iterator);
+goog$dom$TagIterator.prototype.node = null;
+goog$dom$TagIterator.prototype.tagType = null;
+goog$dom$TagIterator.prototype.started_ = false;
+goog$dom$TagIterator.prototype.setPosition = function(node, opt_tagType, opt_depth) {
+  if(this.node = node)this.tagType = typeof opt_tagType == "number" ? opt_tagType : this.node.nodeType != 1 ? 0 : this.reversed ? -1 : 1;
+  if(typeof opt_depth == "number")this.depth = opt_depth
+};
+goog$dom$TagIterator.prototype.next = function() {
+  var node;
+  if(this.started_) {
+    if(!this.node || this.constrained && this.depth == 0)throw goog$iter$StopIteration;node = this.node;
+    var startType = this.reversed ? -1 : 1;
+    if(this.tagType == startType) {
+      var child = this.reversed ? node.lastChild : node.firstChild;
+      child ? this.setPosition(child) : this.setPosition(node, startType * -1)
+    }else {
+      var sibling = this.reversed ? node.previousSibling : node.nextSibling;
+      sibling ? this.setPosition(sibling) : this.setPosition(node.parentNode, startType * -1)
+    }this.depth += this.tagType * (this.reversed ? -1 : 1)
+  }else this.started_ = true;
+  node = this.node;
+  if(!this.node)throw goog$iter$StopIteration;return node
+};
+goog$dom$TagIterator.prototype.isStartTag = function() {
+  return this.tagType == 1
+};var goog$dom$AbstractRange = function() {
+};
+goog$dom$AbstractRange.prototype.getTextRanges = function() {
+  for(var output = [], i = 0, len = this.getTextRangeCount();i < len;i++)output.push(this.getTextRange(i));
+  return output
+};
+goog$dom$AbstractRange.prototype.getAnchorNode = function() {
+  return this.isReversed() ? this.getEndNode() : this.getStartNode()
+};
+goog$dom$AbstractRange.prototype.getAnchorOffset = function() {
+  return this.isReversed() ? this.getEndOffset() : this.getStartOffset()
+};
+goog$dom$AbstractRange.prototype.getFocusNode = function() {
+  return this.isReversed() ? this.getStartNode() : this.getEndNode()
+};
+goog$dom$AbstractRange.prototype.getFocusOffset = function() {
+  return this.isReversed() ? this.getStartOffset() : this.getEndOffset()
+};
+goog$dom$AbstractRange.prototype.isReversed = function() {
+  return false
+};
+goog$dom$AbstractRange.prototype.getDocument = function() {
+  return goog$dom$getOwnerDocument(goog$userAgent$IE ? this.getContainer() : this.getStartNode())
+};
+goog$dom$AbstractRange.prototype.getWindow = function() {
+  return goog$dom$getWindow(this.getDocument())
+};
+goog$dom$AbstractRange.prototype.containsNode = function(node, opt_allowPartial) {
+  return this.containsRange(goog$dom$TextRange$createFromNodeContents(node, undefined), opt_allowPartial)
+};
+var goog$dom$RangeIterator = function(node, opt_reverse) {
+  goog$dom$TagIterator.call(this, node, opt_reverse, true)
+};
+goog$inherits(goog$dom$RangeIterator, goog$dom$TagIterator);var goog$dom$AbstractMultiRange = function() {
+};
+goog$inherits(goog$dom$AbstractMultiRange, goog$dom$AbstractRange);
+goog$dom$AbstractMultiRange.prototype.containsRange = function(otherRange, opt_allowPartial) {
+  var ranges = this.getTextRanges(), otherRanges = otherRange.getTextRanges(), fn = opt_allowPartial ? goog$array$some : goog$array$every;
+  return fn(otherRanges, function(otherRange) {
+    return goog$array$some(ranges, function(range) {
+      return range.containsRange(otherRange, opt_allowPartial)
+    })
+  })
+};var goog$dom$TextRangeIterator = function(startNode, startOffset, endNode, endOffset, opt_reverse) {
+  var goNext;
+  if(startNode) {
+    this.startNode_ = startNode;
+    this.startOffset_ = startOffset;
+    this.endNode_ = endNode;
+    this.endOffset_ = endOffset;
+    if(startNode.nodeType == 1 && startNode.tagName != "BR") {
+      var startChildren = startNode.childNodes, candidate = startChildren[startOffset];
+      if(candidate) {
+        this.startNode_ = candidate;
+        this.startOffset_ = 0
+      }else {
+        if(startChildren.length)this.startNode_ = goog$array$peek(startChildren);
+        goNext = true
+      }
+    }if(endNode.nodeType == 1)if(this.endNode_ = endNode.childNodes[endOffset])this.endOffset_ = 0;
+    else this.endNode_ = endNode
+  }goog$dom$RangeIterator.call(this, opt_reverse ? this.endNode_ : this.startNode_, opt_reverse);
+  if(goNext)try {
+    this.next()
+  }catch(e) {
+    if(e != goog$iter$StopIteration)throw e;
+  }
+};
+goog$inherits(goog$dom$TextRangeIterator, goog$dom$RangeIterator);
+goog$dom$TextRangeIterator.prototype.startNode_ = null;
+goog$dom$TextRangeIterator.prototype.endNode_ = null;
+goog$dom$TextRangeIterator.prototype.startOffset_ = 0;
+goog$dom$TextRangeIterator.prototype.endOffset_ = 0;
+goog$dom$TextRangeIterator.prototype.getStartNode = function() {
+  return this.startNode_
+};
+goog$dom$TextRangeIterator.prototype.getEndNode = function() {
+  return this.endNode_
+};
+goog$dom$TextRangeIterator.prototype.isLast = function() {
+  return this.started_ && this.node == this.endNode_ && (!this.endOffset_ || !this.isStartTag())
+};
+goog$dom$TextRangeIterator.prototype.next = function() {
+  if(this.isLast())throw goog$iter$StopIteration;return goog$dom$TextRangeIterator.superClass_.next.call(this)
+};var goog$userAgent$jscript$DETECTED_HAS_JSCRIPT_, goog$userAgent$jscript$DETECTED_VERSION_, JSCompiler_inline_hasScriptEngine_44 = "ScriptEngine" in goog$global;
+goog$userAgent$jscript$DETECTED_VERSION_ = (goog$userAgent$jscript$DETECTED_HAS_JSCRIPT_ = JSCompiler_inline_hasScriptEngine_44 && goog$global.ScriptEngine() == "JScript") ? goog$global.ScriptEngineMajorVersion() + "." + goog$global.ScriptEngineMinorVersion() + "." + goog$global.ScriptEngineBuildVersion() : "0";var goog$dom$browserrange$AbstractRange = function() {
+};
+goog$dom$browserrange$AbstractRange.prototype.containsRange = function(range, opt_allowPartial) {
+  return this.containsBrowserRange(range.range_, opt_allowPartial)
+};
+goog$dom$browserrange$AbstractRange.prototype.containsBrowserRange = function(range, opt_allowPartial) {
+  try {
+    return opt_allowPartial ? this.compareBrowserRangeEndpoints(range, 0, 1) >= 0 && this.compareBrowserRangeEndpoints(range, 1, 0) <= 0 : this.compareBrowserRangeEndpoints(range, 0, 0) >= 0 && this.compareBrowserRangeEndpoints(range, 1, 1) <= 0
+  }catch(e) {
+    if(!goog$userAgent$IE)throw e;return false
+  }
+};
+goog$dom$browserrange$AbstractRange.prototype.containsNode = function(node, opt_allowPartial) {
+  return this.containsRange(goog$userAgent$IE ? goog$dom$browserrange$IeRange$createFromNodeContents(node) : goog$userAgent$WEBKIT ? new goog$dom$browserrange$WebKitRange(goog$dom$browserrange$W3cRange$getBrowserRangeForNode(node)) : goog$userAgent$GECKO ? new goog$dom$browserrange$GeckoRange(goog$dom$browserrange$W3cRange$getBrowserRangeForNode(node)) : new goog$dom$browserrange$W3cRange(goog$dom$browserrange$W3cRange$getBrowserRangeForNode(node)), opt_allowPartial)
+};
+goog$dom$browserrange$AbstractRange.prototype.__iterator__ = function() {
+  return new goog$dom$TextRangeIterator(this.getStartNode(), this.getStartOffset(), this.getEndNode(), this.getEndOffset())
+};var goog$dom$browserrange$W3cRange = function(range) {
+  this.range_ = range
+};
+goog$inherits(goog$dom$browserrange$W3cRange, goog$dom$browserrange$AbstractRange);
+var goog$dom$browserrange$W3cRange$getBrowserRangeForNode = function(node) {
+  var nodeRange = goog$dom$getOwnerDocument(node).createRange();
+  if(node.nodeType == 3) {
+    nodeRange.setStart(node, 0);
+    nodeRange.setEnd(node, node.length)
+  }else {
+    for(var tempNode, leaf = node;tempNode = leaf.firstChild;)leaf = tempNode;
+    nodeRange.setStart(leaf, 0);
+    for(leaf = node;tempNode = leaf.lastChild;)leaf = tempNode;
+    nodeRange.setEnd(leaf, leaf.nodeType == 1 ? leaf.childNodes.length : leaf.length)
+  }return nodeRange
+}, goog$dom$browserrange$W3cRange$getBrowserRangeForNodes_ = function(startNode, startOffset, endNode, endOffset) {
+  var nodeRange = goog$dom$getOwnerDocument(startNode).createRange();
+  nodeRange.setStart(startNode, startOffset);
+  nodeRange.setEnd(endNode, endOffset);
+  return nodeRange
+};
+goog$dom$browserrange$W3cRange.prototype.getContainer = function() {
+  return this.range_.commonAncestorContainer
+};
+goog$dom$browserrange$W3cRange.prototype.getStartNode = function() {
+  return this.range_.startContainer
+};
+goog$dom$browserrange$W3cRange.prototype.getStartOffset = function() {
+  return this.range_.startOffset
+};
+goog$dom$browserrange$W3cRange.prototype.getEndNode = function() {
+  return this.range_.endContainer
+};
+goog$dom$browserrange$W3cRange.prototype.getEndOffset = function() {
+  return this.range_.endOffset
+};
+goog$dom$browserrange$W3cRange.prototype.compareBrowserRangeEndpoints = function(range, thisEndpoint, otherEndpoint) {
+  return this.range_.compareBoundaryPoints(otherEndpoint == 1 ? thisEndpoint == 1 ? goog$global.Range.START_TO_START : goog$global.Range.START_TO_END : thisEndpoint == 1 ? goog$global.Range.END_TO_START : goog$global.Range.END_TO_END, range)
+};
+goog$dom$browserrange$W3cRange.prototype.isCollapsed = function() {
+  return this.range_.collapsed
+};
+goog$dom$browserrange$W3cRange.prototype.select = function(reverse) {
+  var win = goog$dom$getWindow(goog$dom$getOwnerDocument(this.getStartNode()));
+  this.selectInternal(win.getSelection(), reverse)
+};
+goog$dom$browserrange$W3cRange.prototype.selectInternal = function(selection) {
+  selection.addRange(this.range_)
+};
+goog$dom$browserrange$W3cRange.prototype.collapse = function(toStart) {
+  this.range_.collapse(toStart)
+};var goog$dom$browserrange$GeckoRange = function(range) {
+  goog$dom$browserrange$W3cRange.call(this, range)
+};
+goog$inherits(goog$dom$browserrange$GeckoRange, goog$dom$browserrange$W3cRange);
+goog$dom$browserrange$GeckoRange.prototype.selectInternal = function(selection, reversed) {
+  var anchorNode = reversed ? this.getEndNode() : this.getStartNode(), anchorOffset = reversed ? this.getEndOffset() : this.getStartOffset(), focusNode = reversed ? this.getStartNode() : this.getEndNode(), focusOffset = reversed ? this.getStartOffset() : this.getEndOffset();
+  selection.collapse(anchorNode, anchorOffset);
+  if(anchorNode != focusNode || anchorOffset != focusOffset)selection.extend(focusNode, focusOffset)
+};var goog$dom$browserrange$IeRange = function(range, doc) {
+  this.range_ = range;
+  this.doc_ = doc
+};
+goog$inherits(goog$dom$browserrange$IeRange, goog$dom$browserrange$AbstractRange);
+var goog$dom$browserrange$IeRange$logger_ = goog$debug$LogManager$getLogger("goog.dom.browserrange.IeRange"), goog$dom$browserrange$IeRange$getBrowserRangeForNode_ = function(node) {
+  var nodeRange = goog$dom$getOwnerDocument(node).body.createTextRange();
+  if(node.nodeType == 1)nodeRange.moveToElementText(node);
+  else {
+    for(var offset = 0, sibling = node;sibling = sibling.previousSibling;) {
+      var nodeType = sibling.nodeType;
+      if(nodeType == 3)offset += sibling.length;
+      else if(nodeType == 1) {
+        nodeRange.moveToElementText(sibling);
+        break
+      }
+    }sibling || nodeRange.moveToElementText(node.parentNode);
+    nodeRange.collapse(!sibling);
+    offset && nodeRange.move("character", offset);
+    nodeRange.moveEnd("character", node.length)
+  }return nodeRange
+}, goog$dom$browserrange$IeRange$getBrowserRangeForNodes_ = function(startNode, startOffset, endNode, endOffset) {
+  var child, collapse = false;
+  if(startNode.nodeType == 1) {
+    startOffset > startNode.childNodes.length && goog$dom$browserrange$IeRange$logger_.severe("Cannot have startOffset > startNode child count");
+    child = startNode.childNodes[startOffset];
+    collapse = !child;
+    startNode = child || startNode;
+    startOffset = 0
+  }var leftRange = goog$dom$browserrange$IeRange$getBrowserRangeForNode_(startNode);
+  startOffset && leftRange.move("character", startOffset);
+  collapse && leftRange.collapse(false);
+  collapse = false;
+  if(endNode.nodeType == 1) {
+    startOffset > startNode.childNodes.length && goog$dom$browserrange$IeRange$logger_.severe("Cannot have endOffset > endNode child count");
+    endNode = (child = endNode.childNodes[endOffset]) || endNode;
+    if(endNode.tagName == "BR")endOffset = 1;
+    else {
+      endOffset = 0;
+      collapse = !child
+    }
+  }var rightRange = goog$dom$browserrange$IeRange$getBrowserRangeForNode_(endNode);
+  rightRange.collapse(!collapse);
+  endOffset && rightRange.moveEnd("character", endOffset);
+  leftRange.setEndPoint("EndToEnd", rightRange);
+  return leftRange
+}, goog$dom$browserrange$IeRange$createFromNodeContents = function(node) {
+  var range = new goog$dom$browserrange$IeRange(goog$dom$browserrange$IeRange$getBrowserRangeForNode_(node), goog$dom$getOwnerDocument(node));
+  range.parentNode_ = node;
+  return range
+};
+goog$dom$browserrange$IeRange.prototype.parentNode_ = null;
+goog$dom$browserrange$IeRange.prototype.startNode_ = null;
+goog$dom$browserrange$IeRange.prototype.endNode_ = null;
+goog$dom$browserrange$IeRange.prototype.clearCachedValues_ = function() {
+  this.parentNode_ = this.startNode_ = this.endNode_ = null
+};
+goog$dom$browserrange$IeRange.prototype.getContainer = function() {
+  if(!this.parentNode_) {
+    for(var selectText = this.range_.text, i = 1;selectText.charAt(selectText.length - i) == " ";i++)this.range_.moveEnd("character", -1);
+    for(var parent = this.range_.parentElement(), htmlText = this.range_.htmlText.replace(/(\r\n|\r|\n)+/g, " ");htmlText.length > parent.outerHTML.replace(/(\r\n|\r|\n)+/g, " ").length;)parent = parent.parentNode;
+    for(;parent.childNodes.length == 1 && parent.innerText == (parent.firstChild.nodeType == 3 ? parent.firstChild.nodeValue : parent.firstChild.innerText);) {
+      if(parent.firstChild.tagName == "IMG")break;
+      parent = parent.firstChild
+    }if(selectText.length == 0)parent = this.findDeepestContainer_(parent);
+    this.parentNode_ = parent
+  }return this.parentNode_
+};
+goog$dom$browserrange$IeRange.prototype.findDeepestContainer_ = function(node) {
+  for(var childNodes = node.childNodes, i = 0, len = childNodes.length;i < len;i++) {
+    var child = childNodes[i];
+    if(child.nodeType == 1)if(this.range_.inRange(goog$dom$browserrange$IeRange$getBrowserRangeForNode_(child)))return this.findDeepestContainer_(child)
+  }return node
+};
+goog$dom$browserrange$IeRange.prototype.getStartNode = function() {
+  return this.startNode_ || (this.startNode_ = this.getEndpointNode_(1))
+};
+goog$dom$browserrange$IeRange.prototype.getStartOffset = function() {
+  return this.getOffset_(1)
+};
+goog$dom$browserrange$IeRange.prototype.getEndNode = function() {
+  return this.endNode_ || (this.endNode_ = this.getEndpointNode_(0))
+};
+goog$dom$browserrange$IeRange.prototype.getEndOffset = function() {
+  return this.getOffset_(0)
+};
+goog$dom$browserrange$IeRange.prototype.containsRange = function(range, opt_allowPartial) {
+  return this.containsBrowserRange(range.range_, opt_allowPartial)
+};
+goog$dom$browserrange$IeRange.prototype.compareBrowserRangeEndpoints = function(range, thisEndpoint, otherEndpoint) {
+  return this.range_.compareEndPoints((thisEndpoint == 1 ? "Start" : "End") + "To" + (otherEndpoint == 1 ? "Start" : "End"), range)
+};
+goog$dom$browserrange$IeRange.prototype.getEndpointNode_ = function(endpoint, opt_node) {
+  var node = opt_node || this.getContainer();
+  if(!node || !node.firstChild) {
+    if(endpoint == 0 && node.previousSibling && node.previousSibling.tagName == "BR" && this.getOffset_(endpoint, node) == 0)node = node.previousSibling;
+    return node.tagName == "BR" ? node.parentNode : node
+  }for(var child = endpoint == 1 ? node.firstChild : node.lastChild;child;) {
+    if(this.containsNode(child, true))return this.getEndpointNode_(endpoint, child);
+    child = endpoint == 1 ? child.nextSibling : child.previousSibling
+  }return node
+};
+goog$dom$browserrange$IeRange.prototype.getOffset_ = function(endpoint, opt_container) {
+  var container = opt_container || (endpoint == 1 ? this.getStartNode() : this.getEndNode());
+  if(container.nodeType == 1) {
+    for(var children = container.childNodes, len = children.length, i = endpoint == 1 ? 0 : len - 1;i >= 0 && i < len;) {
+      var child = children[i];
+      if(this.containsNode(child, true)) {
+        endpoint == 0 && child.previousSibling && child.previousSibling.tagName == "BR" && this.getOffset_(endpoint, child) == 0 && i--;
+        break
+      }i += endpoint == 1 ? 1 : -1
+    }return i == -1 ? 0 : i
+  }else {
+    var range = this.range_.duplicate(), nodeRange = goog$dom$browserrange$IeRange$getBrowserRangeForNode_(container);
+    range.setEndPoint(endpoint == 1 ? "EndToEnd" : "StartToStart", nodeRange);
+    var rangeLength = range.text.length;
+    return endpoint == 0 ? rangeLength : container.length - rangeLength
+  }
+};
+goog$dom$browserrange$IeRange.prototype.isCollapsed = function() {
+  return this.range_.text == ""
+};
+goog$dom$browserrange$IeRange.prototype.select = function() {
+  this.range_.select()
+};
+goog$dom$browserrange$IeRange.prototype.collapse = function(toStart) {
+  this.range_.collapse(toStart);
+  if(toStart)this.endNode_ = this.startNode_;
+  else this.startNode_ = this.endNode_
+};var goog$dom$browserrange$WebKitRange = function(range) {
+  goog$dom$browserrange$W3cRange.call(this, range)
+};
+goog$inherits(goog$dom$browserrange$WebKitRange, goog$dom$browserrange$W3cRange);
+goog$dom$browserrange$WebKitRange.prototype.compareBrowserRangeEndpoints = function(range, thisEndpoint, otherEndpoint) {
+  if(goog$userAgent$isVersion("528"))return goog$dom$browserrange$WebKitRange.superClass_.compareBrowserRangeEndpoints.call(this, range, thisEndpoint, otherEndpoint);
+  return this.range_.compareBoundaryPoints(otherEndpoint == 1 ? thisEndpoint == 1 ? goog$global.Range.START_TO_START : goog$global.Range.END_TO_START : thisEndpoint == 1 ? goog$global.Range.START_TO_END : goog$global.Range.END_TO_END, range)
+};
+goog$dom$browserrange$WebKitRange.prototype.selectInternal = function(selection, reversed) {
+  selection.removeAllRanges();
+  reversed ? selection.setBaseAndExtent(this.getEndNode(), this.getEndOffset(), this.getStartNode(), this.getStartOffset()) : selection.setBaseAndExtent(this.getStartNode(), this.getStartOffset(), this.getEndNode(), this.getEndOffset())
+};var goog$dom$browserrange$createRangeFromNodes = function(startNode, startOffset, endNode, endOffset) {
+  return goog$userAgent$IE ? new goog$dom$browserrange$IeRange(goog$dom$browserrange$IeRange$getBrowserRangeForNodes_(startNode, startOffset, endNode, endOffset), goog$dom$getOwnerDocument(startNode)) : goog$userAgent$WEBKIT ? new goog$dom$browserrange$WebKitRange(goog$dom$browserrange$W3cRange$getBrowserRangeForNodes_(startNode, startOffset, endNode, endOffset)) : goog$userAgent$GECKO ? new goog$dom$browserrange$GeckoRange(goog$dom$browserrange$W3cRange$getBrowserRangeForNodes_(startNode, startOffset, 
+  endNode, endOffset)) : new goog$dom$browserrange$W3cRange(goog$dom$browserrange$W3cRange$getBrowserRangeForNodes_(startNode, startOffset, endNode, endOffset))
+};var goog$dom$TextRange = function() {
+};
+goog$inherits(goog$dom$TextRange, goog$dom$AbstractRange);
+var goog$dom$TextRange$createFromBrowserRangeWrapper_ = function(browserRange, opt_isReversed) {
+  var range = new goog$dom$TextRange;
+  range.browserRangeWrapper_ = browserRange;
+  range.isReversed_ = !!opt_isReversed;
+  return range
+}, goog$dom$TextRange$createFromNodeContents = function(node, opt_isReversed) {
+  return goog$dom$TextRange$createFromBrowserRangeWrapper_(goog$userAgent$IE ? goog$dom$browserrange$IeRange$createFromNodeContents(node) : goog$userAgent$WEBKIT ? new goog$dom$browserrange$WebKitRange(goog$dom$browserrange$W3cRange$getBrowserRangeForNode(node)) : goog$userAgent$GECKO ? new goog$dom$browserrange$GeckoRange(goog$dom$browserrange$W3cRange$getBrowserRangeForNode(node)) : new goog$dom$browserrange$W3cRange(goog$dom$browserrange$W3cRange$getBrowserRangeForNode(node)), opt_isReversed)
+}, goog$dom$TextRange$createFromNodes = function(anchorNode, anchorOffset, focusNode, focusOffset) {
+  var range = new goog$dom$TextRange;
+  range.isReversed_ = goog$dom$Range$isReversed(anchorNode, anchorOffset, focusNode, focusOffset);
+  if(anchorNode.tagName == "BR") {
+    var parent = anchorNode.parentNode;
+    anchorOffset = goog$array$indexOf(parent.childNodes, anchorNode);
+    anchorNode = parent
+  }if(focusNode.tagName == "BR") {
+    parent = focusNode.parentNode;
+    focusOffset = goog$array$indexOf(parent.childNodes, focusNode);
+    focusNode = parent
+  }if(range.isReversed_) {
+    range.startNode_ = focusNode;
+    range.startOffset_ = focusOffset;
+    range.endNode_ = anchorNode;
+    range.endOffset_ = anchorOffset
+  }else {
+    range.startNode_ = anchorNode;
+    range.startOffset_ = anchorOffset;
+    range.endNode_ = focusNode;
+    range.endOffset_ = focusOffset
+  }return range
+};
+goog$dom$TextRange.prototype.browserRangeWrapper_ = null;
+goog$dom$TextRange.prototype.startNode_ = null;
+goog$dom$TextRange.prototype.startOffset_ = null;
+goog$dom$TextRange.prototype.endNode_ = null;
+goog$dom$TextRange.prototype.endOffset_ = null;
+goog$dom$TextRange.prototype.isReversed_ = false;
+goog$dom$TextRange.prototype.getType = function() {
+  return"text"
+};
+goog$dom$TextRange.prototype.getBrowserRangeObject = function() {
+  return this.getBrowserRangeWrapper_().range_
+};
+goog$dom$TextRange.prototype.clearCachedValues_ = function() {
+  this.startNode_ = this.startOffset_ = this.endNode_ = this.endOffset_ = null
+};
+goog$dom$TextRange.prototype.getTextRangeCount = function() {
+  return 1
+};
+goog$dom$TextRange.prototype.getTextRange = function() {
+  return this
+};
+goog$dom$TextRange.prototype.getBrowserRangeWrapper_ = function() {
+  return this.browserRangeWrapper_ || (this.browserRangeWrapper_ = goog$dom$browserrange$createRangeFromNodes(this.getStartNode(), this.getStartOffset(), this.getEndNode(), this.getEndOffset()))
+};
+goog$dom$TextRange.prototype.getContainer = function() {
+  return this.getBrowserRangeWrapper_().getContainer()
+};
+goog$dom$TextRange.prototype.getStartNode = function() {
+  return this.startNode_ || (this.startNode_ = this.getBrowserRangeWrapper_().getStartNode())
+};
+goog$dom$TextRange.prototype.getStartOffset = function() {
+  return this.startOffset_ != null ? this.startOffset_ : (this.startOffset_ = this.getBrowserRangeWrapper_().getStartOffset())
+};
+goog$dom$TextRange.prototype.getEndNode = function() {
+  return this.endNode_ || (this.endNode_ = this.getBrowserRangeWrapper_().getEndNode())
+};
+goog$dom$TextRange.prototype.getEndOffset = function() {
+  return this.endOffset_ != null ? this.endOffset_ : (this.endOffset_ = this.getBrowserRangeWrapper_().getEndOffset())
+};
+goog$dom$TextRange.prototype.isReversed = function() {
+  return this.isReversed_
+};
+goog$dom$TextRange.prototype.containsRange = function(otherRange, opt_allowPartial) {
+  var otherRangeType = otherRange.getType();
+  if(otherRangeType == "text")return this.getBrowserRangeWrapper_().containsRange(otherRange.getBrowserRangeWrapper_(), opt_allowPartial);
+  else if(otherRangeType == "control") {
+    var elements = otherRange.getElements(), fn = opt_allowPartial ? goog$array$some : goog$array$every;
+    return fn(elements, function(el) {
+      return this.containsNode(el, opt_allowPartial)
+    }, this)
+  }
+};
+goog$dom$TextRange.prototype.isCollapsed = function() {
+  return this.getBrowserRangeWrapper_().isCollapsed()
+};
+goog$dom$TextRange.prototype.__iterator__ = function() {
+  return new goog$dom$TextRangeIterator(this.getStartNode(), this.getStartOffset(), this.getEndNode(), this.getEndOffset())
+};
+goog$dom$TextRange.prototype.select = function() {
+  this.getBrowserRangeWrapper_().select(this.isReversed_)
+};
+goog$dom$TextRange.prototype.saveUsingDom = function() {
+  return new goog$dom$DomSavedTextRange_(this)
+};
+goog$dom$TextRange.prototype.collapse = function(toAnchor) {
+  var toStart = this.isReversed() ? !toAnchor : toAnchor;
+  this.browserRangeWrapper_ && this.browserRangeWrapper_.collapse(toStart);
+  if(toStart) {
+    this.endNode_ = this.startNode_;
+    this.endOffset_ = this.startOffset_
+  }else {
+    this.startNode_ = this.endNode_;
+    this.startOffset_ = this.endOffset_
+  }this.isReversed_ = false
+};
+var goog$dom$DomSavedTextRange_ = function(range) {
+  this.anchorNode_ = range.getAnchorNode();
+  this.anchorOffset_ = range.getAnchorOffset();
+  this.focusNode_ = range.getFocusNode();
+  this.focusOffset_ = range.getFocusOffset()
+};
+goog$inherits(goog$dom$DomSavedTextRange_, goog$dom$SavedRange);var goog$dom$ControlRange = function() {
+};
+goog$inherits(goog$dom$ControlRange, goog$dom$AbstractMultiRange);
+goog$dom$ControlRange.prototype.range_ = null;
+goog$dom$ControlRange.prototype.elements_ = null;
+goog$dom$ControlRange.prototype.sortedElements_ = null;
+goog$dom$ControlRange.prototype.clearCachedValues_ = function() {
+  this.sortedElements_ = this.elements_ = null
+};
+goog$dom$ControlRange.prototype.getType = function() {
+  return"control"
+};
+goog$dom$ControlRange.prototype.getBrowserRangeObject = function() {
+  return this.range_ || document.body.createControlRange()
+};
+goog$dom$ControlRange.prototype.getTextRangeCount = function() {
+  return this.range_ ? this.range_.length : 0
+};
+goog$dom$ControlRange.prototype.getTextRange = function(i) {
+  return goog$dom$TextRange$createFromNodeContents(this.range_.item(i))
+};
+goog$dom$ControlRange.prototype.getContainer = function() {
+  return goog$dom$findCommonAncestor.apply(null, this.getElements())
+};
+goog$dom$ControlRange.prototype.getStartNode = function() {
+  return this.getSortedElements()[0]
+};
+goog$dom$ControlRange.prototype.getStartOffset = function() {
+  return 0
+};
+goog$dom$ControlRange.prototype.getEndNode = function() {
+  var sorted = this.getSortedElements(), startsLast = goog$array$peek(sorted);
+  return goog$array$find(sorted, function(el) {
+    return goog$dom$contains(el, startsLast)
+  })
+};
+goog$dom$ControlRange.prototype.getEndOffset = function() {
+  return this.getEndNode().childNodes.length
+};
+goog$dom$ControlRange.prototype.getElements = function() {
+  if(!this.elements_) {
+    this.elements_ = [];
+    if(this.range_)for(var i = 0;i < this.range_.length;i++)this.elements_.push(this.range_.item(i))
+  }return this.elements_
+};
+goog$dom$ControlRange.prototype.getSortedElements = function() {
+  if(!this.sortedElements_) {
+    this.sortedElements_ = this.getElements().concat();
+    this.sortedElements_.sort(function(a, b) {
+      return a.sourceIndex - b.sourceIndex
+    })
+  }return this.sortedElements_
+};
+goog$dom$ControlRange.prototype.isCollapsed = function() {
+  return!this.range_ || !this.range_.length
+};
+goog$dom$ControlRange.prototype.__iterator__ = function() {
+  return new goog$dom$ControlRangeIterator(this)
+};
+goog$dom$ControlRange.prototype.select = function() {
+  this.range_ && this.range_.select()
+};
+goog$dom$ControlRange.prototype.saveUsingDom = function() {
+  return new goog$dom$DomSavedControlRange_(this)
+};
+goog$dom$ControlRange.prototype.collapse = function() {
+  this.range_ = null;
+  this.clearCachedValues_()
+};
+var goog$dom$DomSavedControlRange_ = function(range) {
+  this.elements_ = range.getElements()
+};
+goog$inherits(goog$dom$DomSavedControlRange_, goog$dom$SavedRange);
+var goog$dom$ControlRangeIterator = function(range) {
+  if(range) {
+    this.elements_ = range.getSortedElements();
+    this.startNode_ = this.elements_.shift();
+    this.endNode_ = goog$array$peek(this.elements_) || this.startNode_
+  }goog$dom$RangeIterator.call(this, this.startNode_, false)
+};
+goog$inherits(goog$dom$ControlRangeIterator, goog$dom$RangeIterator);
+goog$dom$ControlRangeIterator.prototype.startNode_ = null;
+goog$dom$ControlRangeIterator.prototype.endNode_ = null;
+goog$dom$ControlRangeIterator.prototype.elements_ = null;
+goog$dom$ControlRangeIterator.prototype.getStartNode = function() {
+  return this.startNode_
+};
+goog$dom$ControlRangeIterator.prototype.getEndNode = function() {
+  return this.endNode_
+};
+goog$dom$ControlRangeIterator.prototype.isLast = function() {
+  return!this.depth && !this.elements_.length
+};
+goog$dom$ControlRangeIterator.prototype.next = function() {
+  if(this.isLast())throw goog$iter$StopIteration;else if(!this.depth) {
+    var el = this.elements_.shift();
+    this.setPosition(el, 1, 1);
+    return el
+  }return goog$dom$ControlRangeIterator.superClass_.next.call(this)
+};var goog$dom$MultiRange = function() {
+  this.browserRanges_ = [];
+  this.ranges_ = [];
+  this.container_ = this.sortedRanges_ = null
+};
+goog$inherits(goog$dom$MultiRange, goog$dom$AbstractMultiRange);
+goog$dom$MultiRange.prototype.logger_ = goog$debug$LogManager$getLogger("goog.dom.MultiRange");
+goog$dom$MultiRange.prototype.clearCachedValues_ = function() {
+  this.ranges_ = [];
+  this.container_ = this.sortedRanges_ = null
+};
+goog$dom$MultiRange.prototype.getType = function() {
+  return"mutli"
+};
+goog$dom$MultiRange.prototype.getBrowserRangeObject = function() {
+  this.browserRanges_.length > 1 && this.logger_.warning("getBrowserRangeObject called on MultiRange with more than 1 range");
+  return this.browserRanges_[0]
+};
+goog$dom$MultiRange.prototype.getTextRangeCount = function() {
+  return this.browserRanges_.length
+};
+goog$dom$MultiRange.prototype.getTextRange = function(i) {
+  this.ranges_[i] || (this.ranges_[i] = goog$dom$TextRange$createFromBrowserRangeWrapper_(goog$userAgent$IE ? new goog$dom$browserrange$IeRange(this.browserRanges_[i], goog$dom$getOwnerDocument(this.browserRanges_[i].parentElement())) : goog$userAgent$WEBKIT ? new goog$dom$browserrange$WebKitRange(this.browserRanges_[i]) : goog$userAgent$GECKO ? new goog$dom$browserrange$GeckoRange(this.browserRanges_[i]) : new goog$dom$browserrange$W3cRange(this.browserRanges_[i]), undefined));
+  return this.ranges_[i]
+};
+goog$dom$MultiRange.prototype.getContainer = function() {
+  if(!this.container_) {
+    for(var nodes = [], i = 0, len = this.getTextRangeCount();i < len;i++)nodes.push(this.getTextRange(i).getContainer());
+    this.container_ = goog$dom$findCommonAncestor.apply(null, nodes)
+  }return this.container_
+};
+goog$dom$MultiRange.prototype.getSortedRanges = function() {
+  if(!this.sortedRanges_) {
+    this.sortedRanges_ = this.getTextRanges();
+    this.sortedRanges_.sort(function(a, b) {
+      var aStartNode = a.getStartNode(), aStartOffset = a.getStartOffset(), bStartNode = b.getStartNode(), bStartOffset = b.getStartOffset();
+      if(aStartNode == bStartNode && aStartOffset == bStartOffset)return 0;
+      return goog$dom$Range$isReversed(aStartNode, aStartOffset, bStartNode, bStartOffset) ? 1 : -1
+    })
+  }return this.sortedRanges_
+};
+goog$dom$MultiRange.prototype.getStartNode = function() {
+  return this.getSortedRanges()[0].getStartNode()
+};
+goog$dom$MultiRange.prototype.getStartOffset = function() {
+  return this.getSortedRanges()[0].getStartOffset()
+};
+goog$dom$MultiRange.prototype.getEndNode = function() {
+  return goog$array$peek(this.getSortedRanges()).getEndNode()
+};
+goog$dom$MultiRange.prototype.getEndOffset = function() {
+  return goog$array$peek(this.getSortedRanges()).getEndOffset()
+};
+goog$dom$MultiRange.prototype.isCollapsed = function() {
+  return this.browserRanges_.length == 0 || this.browserRanges_.length == 1 && this.getTextRange(0).isCollapsed()
+};
+goog$dom$MultiRange.prototype.__iterator__ = function() {
+  return new goog$dom$MultiRangeIterator(this)
+};
+goog$dom$MultiRange.prototype.select = function() {
+  var selection;
+  JSCompiler_inline_label_goog$dom$AbstractRange$getBrowserSelectionForWindow_50: {
+    var JSCompiler_inline_win = this.getWindow();
+    if(JSCompiler_inline_win.getSelection)selection = JSCompiler_inline_win.getSelection();
+    else {
+      var JSCompiler_inline_doc = JSCompiler_inline_win.document;
+      selection = JSCompiler_inline_doc.selection || JSCompiler_inline_doc.getSelection && JSCompiler_inline_doc.getSelection()
+    }
+  }selection.removeAllRanges();
+  for(var i = 0, len = this.getTextRangeCount();i < len;i++)selection.addRange(this.getTextRange(i).getBrowserRangeObject())
+};
+goog$dom$MultiRange.prototype.saveUsingDom = function() {
+  return new goog$dom$DomSavedMultiRange_(this)
+};
+goog$dom$MultiRange.prototype.collapse = function(toAnchor) {
+  if(!this.isCollapsed()) {
+    var range = toAnchor ? this.getTextRange(0) : this.getTextRange(this.getTextRangeCount() - 1);
+    this.clearCachedValues_();
+    range.collapse(toAnchor);
+    this.ranges_ = [range];
+    this.sortedRanges_ = [range];
+    this.browserRanges_ = [range.getBrowserRangeObject()]
+  }
+};
+var goog$dom$DomSavedMultiRange_ = function(range) {
+  this.savedRanges_ = goog$array$map(range.getTextRanges(), function(range) {
+    return range.saveUsingDom()
+  })
+};
+goog$inherits(goog$dom$DomSavedMultiRange_, goog$dom$SavedRange);
+var goog$dom$MultiRangeIterator = function(range) {
+  if(range) {
+    this.ranges_ = range.getSortedRanges();
+    if(this.ranges_.length) {
+      this.startNode_ = this.ranges_[0].getStartNode();
+      this.endNode_ = goog$array$peek(this.ranges_).getEndNode()
+    }
+  }goog$dom$RangeIterator.call(this, this.startNode_, false)
+};
+goog$inherits(goog$dom$MultiRangeIterator, goog$dom$RangeIterator);
+goog$dom$MultiRangeIterator.prototype.startNode_ = null;
+goog$dom$MultiRangeIterator.prototype.endNode_ = null;
+goog$dom$MultiRangeIterator.prototype.ranges_ = null;
+goog$dom$MultiRangeIterator.prototype.getStartNode = function() {
+  return this.startNode_
+};
+goog$dom$MultiRangeIterator.prototype.getEndNode = function() {
+  return this.endNode_
+};
+goog$dom$MultiRangeIterator.prototype.isLast = function() {
+  return this.ranges_.length == 1 && this.ranges_[0].isLast()
+};
+goog$dom$MultiRangeIterator.prototype.next = function() {
+  do try {
+    this.ranges_[0].next();
+    break
+  }catch(ex) {
+    if(ex != goog$iter$StopIteration)throw ex;this.ranges_.shift()
+  }while(this.ranges_.length);
+  if(this.ranges_.length) {
+    var range = this.ranges_[0];
+    this.setPosition(range.node, range.tagType, range.depth);
+    return range.node
+  }else throw goog$iter$StopIteration;
+};var goog$dom$Range$createCaret = function(node, offset) {
+  return goog$dom$TextRange$createFromNodes(node, offset, node, offset)
+}, goog$dom$Range$createFromNodes = function(startNode, startOffset, endNode, endOffset) {
+  return goog$dom$TextRange$createFromNodes(startNode, startOffset, endNode, endOffset)
+}, goog$dom$Range$isReversed = function(anchorNode, anchorOffset, focusNode, focusOffset) {
+  if(anchorNode == focusNode)return focusOffset < anchorOffset;
+  var child;
+  if(anchorNode.nodeType == 1 && anchorOffset)if(child = anchorNode.childNodes[anchorOffset]) {
+    anchorNode = child;
+    anchorOffset = 0
+  }else if(goog$dom$contains(anchorNode, focusNode))return true;
+  if(focusNode.nodeType == 1 && focusOffset)if(child = focusNode.childNodes[focusOffset]) {
+    focusNode = child;
+    focusOffset = 0
+  }else if(goog$dom$contains(focusNode, anchorNode))return false;
+  return(goog$dom$compareNodeOrder(anchorNode, focusNode) || anchorOffset - focusOffset) > 0
+};window.createCaret = goog$dom$Range$createCaret;
+window.createFromNodes = goog$dom$Range$createFromNodes;
+try {
+  goog$dom$Range$createCaret(document.body, 0).select()
+}catch(e$$13) {
+};
+
+/**************************************************
+  Trace:
+      56.427 Start        Handling request
+    0 56.427 Start        Building cUnit
+    1 56.428 Done    1 ms Building cUnit
+    0 56.428 Start        Checking memcacheg
+    0 56.428 Start        Connecting to memcacheg
+    8 56.436 Done    8 ms Connecting to memcacheg
+    1 56.437 Done    9 ms Checking memcacheg
+    0 56.437 Done   10 ms Handling request
+**************************************************/
new file mode 100755
--- /dev/null
+++ b/editor/libeditor/html/tests/browserscope/lib/browserscope/richtext/richtext.html
@@ -0,0 +1,1079 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+  <title>Rich Text Tests</title>
+  <script src="js/range.js"></script>
+  <script>
+    /**
+     * Color class allows cross-browser comparison of values, which can
+     * be returned from queryCommandValue in several formats:
+     *   0xff00ff
+     *   rgb(255, 0, 0)
+     *   Number containing the hex value
+     */
+    function Color(value) {
+      this.compare = function(other) {
+        if (!this.valid || !other.valid) {
+          return false;
+        }
+        return this.red == other.red && this.green == other.green && this.blue == other.blue;
+      }
+      this.parse = function(value) {
+        var hexMatch = String(value).match(/#([0-9a-f]{6})/i);
+        if (hexMatch) {
+          this.red = parseInt(hexMatch[1].substring(0, 2), 16);
+          this.green = parseInt(hexMatch[1].substring(2, 4), 16);
+          this.blue = parseInt(hexMatch[1].substring(4, 6), 16);
+          return true;
+        }
+        var rgbMatch = String(value).match(/rgb\(([0-9]{1,3}),\s*([0-9]{1,3}),\s*([0-9]{1,3})\)/i);
+        if (rgbMatch) {
+          this.red = Number(rgbMatch[1]);
+          this.green = Number(rgbMatch[2]);
+          this.blue = Number(rgbMatch[3]);
+          return true;
+        }
+        if (Number(value)) {
+          this.red = value & 0xFF;
+          this.green = (value & 0xFF00) >> 8;
+          this.blue = (value & 0xFF0000) >> 16;
+          return true;
+        }
+        return false;
+      }
+      this.toString = function() {
+        return this.red + ',' + this.green + ',' + this.blue;
+      }
+      this.valid = this.parse(value);
+    }
+
+    /**
+     * Utility class for converting font sizes to the size
+     * attribute in a font tag. Currently only converts px because
+     * only the sizes and px ever come from queryCommandValue.
+     */
+    function Size(value) {
+      var pxMatch = String(value).match(/([0-9]+)px/);
+      if (pxMatch) {
+        var px = Number(pxMatch[1]);
+        if (px <= 10) {
+          this.size = 1;
+        } else if (px <= 13) {
+          this.size = 2;
+        } else if (px <= 16) {
+          this.size = 3;
+        } else if (px <= 18) {
+          this.size = 4;
+        } else if (px <= 24) {
+          this.size = 5;
+        } else if (px <= 32) {
+          this.size = 6;
+        } else if (px <= 47) {
+          this.size = 7;
+        } else {
+          this.size = NaN;
+        }
+      } else if (Number(value)) {
+           this.size = Number(value);
+      } else {
+        switch (value) {
+          case 'x-small':
+            this.size = 1;
+            break;
+          case 'small':
+            this.size = 2;
+            break;
+          case 'medium':
+            this.size = 3;
+            break;
+          case 'large':
+            this.size = 4;
+            break;
+          case 'x-large':
+            this.size = 5;
+            break;
+          case 'xx-large':
+            this.size = 6;
+            break;
+          case 'xxx-large':
+          case '-webkit-xxx-large':
+            this.size = 7;
+            break;
+          default:
+            this.size = null;
+        }
+      }
+      this.compare = function(other) {
+        return this.size == other.size;
+      }
+      this.toString = function() {
+        return String(this.size);
+      }
+    }
+
+    var APPLY_TESTS = {
+      'backcolor' : {
+        opt_arg: '#FF0000',
+        styleWithCSS: 'background-color'},
+      'bold' : {
+        opt_arg: null,
+        styleWithCSS: 'font-weight'},
+      'createbookmark' : {
+        opt_arg: 'bookmark_name'},
+      'createlink' : {
+        opt_arg: 'http://www.openweb.org'},
+      'decreasefontsize' : {
+        opt_arg: null},
+      'fontname' : {
+        opt_arg: 'Arial',
+        styleWithCSS: 'font-family'},
+      'fontsize' : {
+        opt_arg: 4,
+        styleWithCSS: 'font-size'},
+      'forecolor' : {
+        opt_arg: '#FF0000',
+        styleWithCSS: 'color'},
+      'formatblock' : {
+        opt_arg: 'h1',
+        wholeline: true},
+      'hilitecolor' : {
+        opt_arg: '#FF0000',
+        styleWithCSS: 'background-color'},
+      'indent' : {
+        opt_arg: null,
+        wholeline: true,
+        styleWithCSS: 'margin'},
+      'inserthorizontalrule' : {
+        opt_arg: null,
+        collapse: true},
+      'inserthtml': {
+        opt_arg: '<br>',
+        collapse: true},
+      'insertimage': {
+        opt_arg: 'http://www.google.com/intl/en_ALL/images/logo.gif',
+        collapse: true},
+      'insertorderedlist' : {
+        opt_arg: null,
+        wholeline: true},
+      'insertunorderedlist' : {
+        opt_arg: null,
+        wholeline: true},
+      'italic' : {
+        opt_arg: null,
+        styleWithCSS: 'font-style'},
+      'justifycenter' : {
+        opt_arg: null,
+        wholeline: true,
+        styleWithCSS: 'text-align'},
+      'justifyfull' : {
+        opt_arg: null,
+        wholeline: true,
+        styleWithCSS: 'text-align'},
+      'justifyleft' : {
+        opt_arg: null,
+        wholeline: true,
+        styleWithCSS: 'text-align'},
+      'justifyright' : {
+        opt_arg: null,
+        wholeline: true,
+        styleWithCSS: 'text-align'},
+      'strikethrough' : {
+        opt_arg: null,
+        styleWithCSS: 'text-decoration'},
+      'subscript' : {
+        opt_arg: null,
+        styleWithCSS: 'vertical-align'},
+      'superscript' : {
+        opt_arg: null,
+        styleWithCSS: 'vertical-align'},
+      'underline' : {
+        opt_arg: null,
+        styleWithCSS: 'text-decoration'}};
+
+    var UNAPPLY_TESTS = {
+      'bold' : {
+        tags: [
+          ['<b>', '</b>'],
+          ['<STRONG>', '</STRONG>'],
+          ['<span style="font-weight: bold;">', '</span>']]},
+      'italic' : {
+        tags: [
+          ['<i>', '</i>'],
+          ['<EM>', '</EM>'],
+          ['<span style="font-style: italic;">', '</span>']]},
+      'outdent' : {
+        unapply: 'indent',
+        block: true,
+        tags: [
+          ['<blockquote>', '</blockquote>'],
+          ['<blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;">', '</blockquote>'],
+          ['<ul><li>', '</li></ul>'],
+          ['<ol><li>', '</li></ol>'],
+          ['<div style="margin-left: 40px;">', '</div>']]},
+      'removeformat' : {
+        unapply: '*',
+        block: true,
+        tags: [
+          ['<b>', '</b>'],
+          ['<a href="http://www.foo.com">', '</a>'],
+          ['<table><tr><td>', '</td></tr></table>']]},
+      'strikethrough' : {
+        tags: [
+          ['<strike>', '</strike>'],
+          ['<s>', '</s>'],
+          ['<del>', '</del>'],
+          ['<span style="text-decoration: line-through;">', '</span>']]},
+      'subscript' : {
+        tags: [
+          ['<sub>', '</sub>'],
+          ['<span style="vertical-align: sub;">', '</span>']]},
+      'superscript' : {
+        tags: [
+          ['<sup>', '</sup>'],
+          ['<span style="vertical-align: super;">', '</span>']]},
+      'unbookmark' : {
+        unapply: 'createbookmark',
+        tags: [
+          ['<a name="bookmark">', '</a>']]},
+      'underline' : {
+        tags: [
+          ['<u>', '</u>'],
+          ['<span style="text-decoration: underline;">', '</span>']]},
+      'unlink' : {
+        unapply: 'createbookmark',
+        tags: [
+          ['<a href="http://www.foo.com">', '</a>']]}};
+
+    var QUERY_TESTS = {
+      'backcolor' : {
+        type: 'value',
+        tests: [
+          {html: '<FONT style="BACKGROUND-COLOR: #ffccaa">foo bar baz</FONT>', expected: new Color('#ffccaa')},
+          {html: '<span class="Apple-style-span" style="background-color: rgb(255, 0, 0);">foo bar baz</span>', expected: new Color('#ff0000')},
+          {html: '<span style="background-color: #ff0000">foo bar baz</span>', expected: new Color('#ff0000')}
+        ]
+      },
+      'bold' : {
+        type: 'state',
+        tests: [
+          {html: 'foo bar baz', expected: false},
+          {html: '<b>foo bar baz</b>', expected: true},
+          {html: '<STRONG>foo bar baz</STRONG>', expected: true},
+          {html: '<span style="font-weight:bold">foo bar baz</span>', expected: true},
+          {html: '<b style="font-weight:normal">foo bar baz</b>', expected: false},
+          {html: '<b><span style="font-weight:normal;">foo bar baz</span>', expected: false}
+         ]
+      },
+      'fontname' : {
+        type: 'value',
+        tests: [
+          {html: '<font face="Arial">foo bar baz</font>', expected: 'Arial'},
+          {html: '<span style="font-family:Arial">foo bar baz</span>', expected: 'Arial'},
+          {html: '<font face="Arial" style="font-family:Courier">foo bar baz</font>', expected: 'Courier'},
+          {html: '<font face="Courier"><font face="Arial">foo bar baz</font></font>', expected: 'Arial'},
+          {html: '<span style="font-family:Courier"><font face="Arial">foo bar baz</font></span>', expected: 'Arial'}
+        ]
+      },
+      'fontsize' : {
+        type: 'value',
+        tests: [
+          {html: '<font size=4>foo bar baz</font>', expected: new Size(4)},
+          // IE adds +1 to font size from font-size style attributes.
+          // This is hard to correct for since it does NOT add +1 to size attribute from font tag.
+          {html: '<span class="Apple-style-span" style="font-size: large;">foo bar baz</span>', expected: new Size(4)},
+          {html: '<font size=1 style="font-size:x-large;">foo bar baz</font>', expected: new Size(5)}
+        ]
+      },
+      'forecolor' : {
+        type: 'value',
+        tests: [
+          {html: '<font color="#ff0000">foo bar baz</font>', expected: new Color('#ff0000')},
+          {html: '<span style="color:#ff0000">foo bar baz</span>', expected: new Color('#ff0000')},
+          {html: '<font color="#0000ff" style="color:#ff0000">foo bar baz</span>', expected: new Color('#ff0000')}
+        ]
+      },
+      'hilitecolor' : {
+        type: 'value',
+        tests: [
+          {html: '<FONT style="BACKGROUND-COLOR: #ffccaa">foo bar baz</FONT>', expected: new Color('#ffccaa')},
+          {html: '<span class="Apple-style-span" style="background-color: rgb(255, 0, 0);">foo bar baz</span>', expected: new Color('#ff0000')},
+          {html: '<span style="background-color: #ff0000">foo bar baz</span>', expected: new Color('#ff0000')}
+        ]
+      },
+      'insertorderedlist' : {
+        type: 'state',
+        tests: [
+          {html: 'foo bar baz', expected: false},
+          {html: '<ol><li>foo bar baz</li></ol>', expected: true},
+          {html: '<ul><li>foo bar baz</li></ul>', expected: false}
+        ]
+      },
+      'insertunorderedlist' : {
+        type: 'state',
+        tests: [
+          {html: 'foo bar baz', expected: false},
+          {html: '<ol><li>foo bar baz</li></ol>', expected: false},
+          {html: '<ul><li>foo bar baz</li></ul>', expected: true}
+        ]
+      },
+      'italic' : {
+        type: 'state',
+        tests: [
+          {html: 'foo bar baz', expected: false},
+          {html: '<i>foo bar baz</i>', expected: true},
+          {html: '<EM>foo bar baz</EM>', expected: true},
+          {html: '<span style="font-style:italic">foo bar baz</span>', expected: true},
+          {html: '<i><span style="font-style:normal">foo bar baz</span></i>', expected: false}
+        ]
+      },
+      'justifycenter' : {
+        type: 'state',
+        tests: [
+          {html: 'foo bar baz', expected: false},
+          {html: '<div align="center">foo bar baz</div>', expected: true},
+          {html: '<p align="center">foo bar baz</p>', expected: true},
+          {html: '<div style="text-align: center;">foo bar baz</div>', expected: true}
+        ]
+      },
+      'justifyfull' : {
+        type: 'state',
+        tests: [
+          {html: 'foo bar baz', expected: false},
+          {html: '<div align="justify">foo bar baz</div>', expected: true},
+          {html: '<p align="justify">foo bar baz</p>', expected: true},
+          {html: '<div style="text-align: justify;">foo bar baz</div>', expected: true}
+        ]
+      },
+      'justifyleft' : {
+        type: 'state',
+        tests: [
+          {html: '<div align="left">foo bar baz</div>', expected: true},
+          {html: '<p align="left">foo bar baz</p>', expected: true},
+          {html: '<div style="text-align: left;">foo bar baz</div>', expected: true}
+        ]
+      },
+      'justifyright' : {
+        type: 'state',
+        tests: [
+          {html: 'foo bar baz', expected: false},
+          {html: '<div align="right">foo bar baz</div>', expected: true},
+          {html: '<p align="right">foo bar baz</p>', expected: true},
+          {html: '<div style="text-align: right;">foo bar baz</div>', expected: true}
+        ]
+      },
+      'strikethrough' : {
+        type: 'state',
+        tests: [
+          {html: 'foo bar baz', expected: false},
+          {html: '<strike>foo bar baz</strike>', expected: true},
+          {html: '<strike style="text-decoration: none">foo bar baz</strike>', expected: false},
+          {html: '<s>foo bar baz</s>', expected: true},
+          {html: '<del>foo bar baz</del>', expected: true},
+          {html: '<span style="text-decoration:line-through">foo bar baz</span>', expected: true}
+        ]
+      },
+      'subscript' : {
+        type: 'state',
+        tests: [
+          {html: 'foo bar baz', expected: false},
+          {html: '<sub>foo bar baz</sub>', expected: true}
+        ]
+      },
+      'superscript' : {
+        type: 'state',
+        tests: [
+          {html: 'foo bar baz', expected: false},
+          {html: '<sup>foo bar baz</sup>', expected: true}
+        ]
+      },
+      'underline' : {
+        type: 'state',
+        tests: [
+          {html: 'foo bar baz', expected: false},
+          {html: '<u>foo bar baz</u>', expected: true},
+          {html: '<a href="http://www.foo.com">foo bar baz</a>', expected: true},
+          {html: '<span style="text-decoration:underline">foo bar baz</span>', expected: true},
+          {html: '<u style="text-decoration:none">foo bar baz</u>', expected: false},
+          {html: '<a style="text-decoration:none" href="http://www.foo.com">foo bar baz</a>', expected: false}
+        ]
+      }
+    };
+
+    var CHANGE_TESTS = {
+      'backcolor' : {
+        type: 'value',
+        tests: [
+          {html: '<FONT style="BACKGROUND-COLOR: #ffccaa">foo bar baz</FONT>', opt_arg: '#884422'},
+          {html: '<span class="Apple-style-span" style="background-color: rgb(255, 0, 0);">foo bar baz</span>', opt_arg: '#0000ff'},
+          {html: '<span style="background-color: #ff0000">foo bar baz</span>', opt_arg: '#0000ff'}
+        ]
+      },
+      'fontname' : {
+        type: 'value',
+        tests: [
+          {html: '<font face="Arial">foo bar baz</font>', opt_arg: 'Courier'},
+          {html: '<span style="font-family:Arial">foo bar baz</span>', opt_arg: 'Courier'},
+          {html: '<font face="Arial" style="font-family:Verdana">foo bar baz</font>', opt_arg: 'Courier'},
+          {html: '<font face="Verdana"><font face="Arial">foo bar baz</font></font>', opt_arg: 'Courier'},
+          {html: '<span style="font-family:Verdana"><font face="Arial">foo bar baz</font></span>', opt_arg: 'Courier'}
+        ]
+      },
+      'fontsize' : {
+        type: 'value',
+        tests: [
+          {html: '<font size=4>foo bar baz</font>', opt_arg: 1},
+          {html: '<span class="Apple-style-span" style="font-size: large;">foo bar baz</span>', opt_arg: 1},
+          {html: '<font size=1 style="font-size:x-small;">foo bar baz</font>', opt_arg: 5}
+        ]
+      },
+      'forecolor' : {
+        type: 'value',
+        tests: [
+          {html: '<font color="#ff0000">foo bar baz</font>', opt_arg: '#00ff00'},
+          {html: '<span style="color:#ff0000">foo bar baz</span>', opt_arg: '#00ff00'},
+          {html: '<font color="#0000ff" style="color:#ff0000">foo bar baz</span>', opt_arg: '#00ff00'}
+        ]
+      },
+      'hilitecolor' : {
+        type: 'value',
+        tests: [
+          {html: '<FONT style="BACKGROUND-COLOR: #ffccaa">foo bar baz</FONT>', opt_arg: '#884422'},
+          {html: '<span class="Apple-style-span" style="background-color: rgb(255, 0, 0);">foo bar baz</span>', opt_arg: '#00ff00'},
+          {html: '<span style="background-color: #ff0000">foo bar baz</span>', opt_arg: '#00ff00'}
+        ]
+      }
+    };
+
+    /** The document of the editable iframe */
+    var editorDoc = null;
+    /** Dummy text to apply and unapply formatting to */
+    var TEST_CONTENT = 'foo bar baz';
+    /**
+     * Word in dummy text that should change. Formatting is sometimes applied
+     * to a single word instead of the entire text node because sometimes a
+     * style might get applied to the body node instead of wrapped around
+     * the text, and that's not what's being tested.
+     */
+    var TEST_WORD = 'bar';
+    /** Constant for indicating an action is unsupported (threw exception) */
+    var UNSUPPORTED = 'UNSUPPORTED';
+    /** <br> and <p> are acceptable HTML to be left over from block elements */
+    var BLOCK_REMOVE_TAGS = [/\s*<br>\s*/i, /\s*<p>\s*/i];
+    /** Array used to accumulate test results */
+    // Tack on the actual display tests with bogus data
+    // otherwise the beacon will fail.
+    var results = ['apply=0', 'unapply=0', 'change=0', 'query=0'];
+
+    /**
+     *
+     */
+    function resetIframe(newHtml) {
+      // These attributes can get set on the iframe by some errant execCommands
+      editorDoc.body.setAttribute('style', '');
+      editorDoc.body.setAttribute('bgcolor', '');
+      editorDoc.body.innerHTML = newHtml;
+    }
+
+    /**
+     * Finds the text node in the given node containing the given word.
+     * Returns null if not found.
+     */
+    function findTextNode(word, node) {
+      if (node.nodeType == 3) {
+        // Text node, check value.
+        if (node.data.indexOf(word) != -1) {
+          return node;
+        }
+      } else if (node.nodeType == 1) {
+        // Element node, check children.
+        for (var i = 0; i < node.childNodes.length; i++) {
+          var result = findTextNode(word, node.childNodes[i]);
+          if (result) {
+            return result;
+          }
+        }
+      }
+      return null;
+    }
+
+    /**
+     * Sets the selection to be collapsed at the start of the word,
+     * or the start of the editor if no word is passed in.
+     */
+     function selectStart(word) {
+       var textNode = findTextNode(word || '', editorDoc.body);
+       var startOffset = 0;
+       if (word) {
+         startOffset = textNode.data.indexOf(word);
+       }
+       var range = createCaret(textNode, startOffset);
+       range.select();
+     }
+
+    /**
+     * Selects the given word in the editor iframe.
+     */
+    function selectWord(word) {
+      var textNode = findTextNode(word, editorDoc.body);
+      if (!textNode) {
+        return;
+      }
+      var start = textNode.data.indexOf(word);
+      var range = createFromNodes(textNode, start, textNode, start + word.length);
+      range.select();
+    }
+
+    /**
+     * Gets the HTML before the text, so that we know how the browser
+     * applied a style
+     */
+    function getSurroundingTags(text) {
+      var html = editorDoc.body.innerHTML;
+      var tagStart = html.indexOf('<');
+      var index = editorDoc.body.innerHTML.indexOf(text);
+      if (tagStart == -1 || index == -1) {
+        return '';
+      }
+      return editorDoc.body.innerHTML.substring(tagStart, index);
+    }
+
+    /**
+     * Does the test for an apply execCommand.
+     */
+    function doApplyTest(command, styleWithCSS) {
+      try {
+        // Set styleWithCSS
+        try {
+          editorDoc.execCommand('styleWithCSS', false, styleWithCSS);
+        } catch (ex) {
+          // Ignore errors
+        }
+        resetIframe(TEST_CONTENT);
+        if (APPLY_TESTS[command].collapse) {
+          selectStart(TEST_WORD);
+        } else {
+          selectWord(TEST_WORD);
+        }
+        try {
+          editorDoc.execCommand(command, false, APPLY_TESTS[command].opt_arg);
+        } catch (ex) {
+          return UNSUPPORTED;
+        }
+        return getSurroundingTags(APPLY_TESTS[command].wholeline? TEST_CONTENT : TEST_WORD);
+      } catch (ex) {
+        return UNSUPPORTED;
+      }
+    }
+
+    /**
+     * Outputs the result of the apply command to a table.
+     * @return {boolean} success
+     */
+    function outputApplyResult(command, result, styleWithCSS) {
+      // The apply command "succeeded" if HTML was generated.
+      var success = (result != UNSUPPORTED) && result;
+      // Except for styleWithCSS commands, which only succeed if the
+      // expected style was applied.
+      if (styleWithCSS) {
+        success = result && result.toLowerCase().indexOf(APPLY_TESTS[command].styleWithCSS) != -1;
+      }
+      results.push('a-' + command + '-' + (styleWithCSS ? 1 : 0) + '=' + (success ? '1' : '0'));
+
+      // Each command is displayed as a table row with 3 columns
+      var tr = document.createElement('TR');
+      tr.className = success ? 'success' : 'fail';
+
+      // Column 1: command name
+      var td = document.createElement('TD');
+      td.innerHTML = command;
+      tr.appendChild(td);
+
+      // Column 2: styleWithCSS
+      var td = document.createElement('TD');
+      td.innerHTML = styleWithCSS ? 'true' : 'false';
+      tr.appendChild(td);
+
+      // Column 3: pass/fail
+      td = document.createElement('TD');
+      td.innerHTML = success ? 'PASS' : 'FAIL';
+      tr.appendChild(td);
+
+      // Column 4: generated HTML (for passing commands)
+      td = document.createElement('TD');
+      // Escape the HTML in the result for printing.
+      result = result.replace(/\</g, '&lt;').replace(/\>/g, '&gt;');
+      td.innerHTML = result;
+      tr.appendChild(td);
+      var table = document.getElementById('apply_output');
+      table.appendChild(tr);
+      return success;
+    }
+
+    /**
+     * Does the test for an unapply execCommand.
+     */
+    function doUnapplyTest(command, index) {
+      try {
+        var wordStart = TEST_CONTENT.indexOf(TEST_WORD);
+        resetIframe(
+            TEST_CONTENT.substring(0, wordStart) +
+            UNAPPLY_TESTS[command].tags[index][0] +
+            TEST_WORD +
+            UNAPPLY_TESTS[command].tags[index][1] +
+            TEST_CONTENT.substring(wordStart + TEST_WORD.length));
+        selectWord(TEST_WORD);
+        try {
+          editorDoc.execCommand(command, false, UNAPPLY_TESTS[command].opt_arg || null);
+        } catch (ex) {
+          return UNSUPPORTED;
+        }
+        return getSurroundingTags(TEST_WORD);
+      } catch (ex) {
+        return UNSUPPORTED;
+      }
+    }
+
+    /**
+     * Check if the given unapply execCommand succeeded. It succeeded if
+     * the following conditions are true:
+     *   - The execCommand did not throw an exception
+     *   - One of the following:
+     *     - The html was removed after the execCommand
+     *     - The html was block and the html was replaced with <p> or <br>
+     */
+    function unapplyCommandSucceeded(command, result) {
+      if (result != UNSUPPORTED) {
+        if (!result) {
+          return true;
+        } else if (UNAPPLY_TESTS[command].block) {
+          for (var i = 0; i < BLOCK_REMOVE_TAGS.length; i++) {
+            if (result.match(BLOCK_REMOVE_TAGS[i])) {
+              return true;
+            }
+          }
+        }
+      }
+      return false;
+    }
+
+    /**
+     * Outputs the result of the unapply command to a table.
+     * @return {boolean} success
+     */
+    function outputUnapplyResult(command, result, index) {
+      // The apply command "succeeded" if HTML was removed.
+      var success = unapplyCommandSucceeded(command, result);
+      results.push('u-' + command + '-' + index + '=' + (success ? '1' : '0'));
+
+      // Each command is displayed as a table row with 5 columns
+      var tr = document.createElement('TR');
+      tr.className = success ? 'success' : 'fail';
+
+      // Column 1: command name
+      var td = document.createElement('TD');
+      td.innerHTML = command;
+      tr.appendChild(td);
+
+      // Column 2: command name being unapplied
+      var td = document.createElement('TD');
+      td.innerHTML = UNAPPLY_TESTS[command].unapply || command;
+      tr.appendChild(td);
+
+      // Column 3: pass/fail
+      td = document.createElement('TD');
+      td.innerHTML = success ? 'PASS' : 'FAIL';
+      tr.appendChild(td);
+
+      // Column 4: html being removed
+      td = document.createElement('TD');
+      // Escape the html for printing.
+      var htmlToRemove = UNAPPLY_TESTS[command].tags[index][0].replace(/\</g, '&lt;').replace(/\>/g, '&gt;');
+      td.innerHTML = htmlToRemove;
+      tr.appendChild(td);
+
+      // Column 5: resulting html
+      td = document.createElement('TD');
+      // Escape the HTML in the result for printing.
+      result = result.replace(/\</g, '&lt;').replace(/\>/g, '&gt;');
+      td.innerHTML = success ? '&nbsp;' : result;
+      tr.appendChild(td);
+      var table = document.getElementById('unapply_output');
+      table.appendChild(tr);
+      return success;
+    }
+
+    /**
+     * Does a queryCommandState or queryCommandValue test for an execCommand.
+     */
+    function doQueryTest(command, index) {
+      try {
+        resetIframe(QUERY_TESTS[command].tests[index].html);
+        selectWord(TEST_WORD);
+        // Dummy val that won't match any expected vals, including false.
+        var result = UNSUPPORTED;
+        if (QUERY_TESTS[command].type == 'state') {
+          try {
+            result = editorDoc.queryCommandState(command);
+          } catch (ex) {
+            result = UNSUPPORTED;
+          }
+        } else {
+          try {
+            // A return value of false indicates the command is not supported.
+            result = editorDoc.queryCommandValue(command) || UNSUPPORTED;
+          } catch (ex) {
+            result = UNSUPPORTED;
+          }
+        }
+        return result;
+      } catch (ex) {
+        return UNSUPPORTED;
+      }
+    }
+
+    /**
+     * Check if the given queryCommandState or queryCommandValue succeeded.
+     */
+    function queryCommandSucceeded(command, index, result) {
+      var expected = QUERY_TESTS[command].tests[index].expected;
+      if (expected instanceof Color) {
+        return expected.compare(new Color(result));
+      } else if (expected instanceof Size) {
+        return expected.compare(new Size(result));
+      } else {
+        return (result == expected);
+      }
+    }
+
+    /**
+     * @return {boolean} success
+     */
+    function outputQueryResult(command, index, result) {
+      // Create table row for results.
+      var tr = document.createElement('TR');
+      var success = queryCommandSucceeded(command, index, result);
+      tr.className = success ? 'success' : 'fail';
+      results.push('q-' + command + '-' + index + '=' + (success ? '1' : '0'));
+
+      // Column 1: command name
+      var td = document.createElement('TD');
+      td.innerHTML = command;
+      tr.appendChild(td);
+
+      // Column 2: pass/fail
+      td = document.createElement('TD');
+      td.innerHTML = success ? 'PASS' : 'FAIL';
+      tr.appendChild(td);
+
+      // Column 3: test HTML
+      td = document.createElement('TD');
+      var testHtml = QUERY_TESTS[command].tests[index].html.replace(/</g, '&lt;').replace(/>/g, '&gt;');
+      td.innerHTML = testHtml.substring(0, testHtml.indexOf(TEST_CONTENT));
+      tr.appendChild(td);
+
+      // Column 4: Expected result
+      td = document.createElement('TD');
+      td.innerHTML = QUERY_TESTS[command].tests[index].expected;
+      tr.appendChild(td);
+
+      // Column 5: Actual result
+      td = document.createElement('TD');
+      td.innerHTML = result;
+      tr.appendChild(td);
+
+      // Append result to the state or value table, depending on what
+      // type of command this is.
+      var table = document.getElementById(
+      QUERY_TESTS[command].type == 'state' ? 'querystate_output' : 'queryvalue_output');
+      table.appendChild(tr);
+      return success;
+    }
+
+    function doChangeTest(command, index) {
+      try {
+        resetIframe(CHANGE_TESTS[command].tests[index].html);
+        selectWord(TEST_CONTENT);
+        try {
+          editorDoc.execCommand(command, false, CHANGE_TESTS[command].tests[index].opt_arg);
+        } catch (ex) {
+          return UNSUPPORTED;
+        }
+      } catch (ex) {
+        return UNSUPPORTED;
+      }
+    }
+
+    function checkChangeSuccess(command, index) {
+      var textNode = findTextNode(TEST_CONTENT, editorDoc.body);
+      if (!textNode) {
+        // The text has been removed from the document, or split up for no reason.
+        return false;
+      }
+      var expected = null, attributeName = null, styleName = null;
+      switch (command) {
+        case 'backcolor':
+        case 'hilitecolor':
+          expected = new Color(CHANGE_TESTS[command].tests[index].opt_arg);
+          styleName = 'backgroundColor';
+          break;
+        case 'fontname':
+          expected = CHANGE_TESTS[command].tests[index].opt_arg;
+          attributeName = 'face';
+          styleName = 'fontFamily';
+          break;
+        case 'fontsize':
+          expected = new Size(CHANGE_TESTS[command].tests[index].opt_arg);
+          attributeName = 'size';
+          styleName = 'fontSize';
+          break;
+        case 'forecolor':
+          expected = new Color(CHANGE_TESTS[command].tests[index].opt_arg);
+          attributeName = 'color';
+          styleName = 'color';
+      }
+      var foundExpected = false;
+
+      // Loop through all the parent nodes that format the text node,
+      // checking that there is exactly one font attribute or
+      // style, and that it's set correctly.
+      var currentNode = textNode.parentNode;
+      while(currentNode && currentNode.nodeName != 'BODY') {
+        // Check font attribute.
+        if (attributeName && currentNode.nodeName == 'FONT' && currentNode.getAttribute(attributeName)) {
+          var foundAttribute = false;
+          switch(command) {
+            case 'backcolor':
+            case 'forecolor':
+            case 'hilitecolor':
+              foundAttribute = new Color(currentNode.getAttribute(attributeName)).compare(expected);
+              break;
+            case 'fontsize':
+              foundAttribute = new Size(currentNode.getAttribute(attributeName)).compare(expected);
+              break;
+            case 'fontname':
+              foundAttribute = (currentNode.getAttribute(attributeName).toLowerCase() == expected.toLowerCase());
+          }
+          if (foundAttribute && foundExpected) {
+            // This is the correct attribute, but the style has been applied
+            // twice. This makes it hard for other browsers to remove the
+            // style.
+            return false;
+          } else if (!foundAttribute) {
+            // This node has an incorrect font attribute.
+            return false;
+          }
+          // The expected font attribute was found.
+          foundExpected = true;
+        }
+        // Check node style.
+        if (currentNode.style[styleName]) {
+          var foundStyle = false;
+          switch(command) {
+            case 'backcolor':
+            case 'forecolor':
+            case 'hilitecolor':
+              foundStyle = new Color(currentNode.style[styleName]).compare(expected);
+              break;
+            case 'fontsize':
+              foundStyle = new Size(currentNode.style[styleName]).compare(expected);
+              break;
+            case 'fontname':
+              foundStyle = (currentNode.style[styleName].toLowerCase() == expected.toLowerCase());
+          }
+          if (foundStyle && foundExpected) {
+            // This is the correct style, but the style has been
+            // applied twice. This makes it hard for other browsers to
+            // remove the style.
+            return false;
+          } else if (!foundStyle) {
+            // This node has an incorrect font style.
+            return false;
+          }
+          foundExpected = true;
+        }
+        currentNode = currentNode.parentNode;
+      }
+      return foundExpected;
+    }
+
+    /**
+     * @return {boolean} success
+     */
+    function outputChangeResult(command, index) {
+      // Each command is displayed as a table row with 4 columns
+      var tr = document.createElement('TR');
+      var success = checkChangeSuccess(command, index);
+      tr.className = success ? 'success' : 'fail';
+      results.push('c-' + command + '-' + index + '=' + (success ? '1' : '0'));
+
+      // Column 1: command name
+      var td = document.createElement('TD');
+      td.innerHTML = command;
+      tr.appendChild(td);
+
+      // Column 2: status
+      td = document.createElement('TD');
+      td.innerHTML = (success == null) ? '?' : (success == true ? 'PASS' : 'FAIL');
+      tr.appendChild(td);
+
+      // Column 3: opt_arg
+      td = document.createElement('TD');
+      td.innerHTML = CHANGE_TESTS[command].tests[index].opt_arg;
+      tr.appendChild(td);
+
+      // Column 4: original html
+      td = document.createElement('TD');
+      td.innerHTML = CHANGE_TESTS[command].tests[index].html.replace(/\</g, '&lt;').replace(/\>/g, '&gt;');;
+      tr.appendChild(td);
+
+      // Column 5: resulting html
+      td = document.createElement('TD');
+      td.innerHTML = editorDoc.body.innerHTML.replace(/\</g, '&lt;').replace(/\>/g, '&gt;');;
+      tr.appendChild(td);
+
+      var table = document.getElementById('change_output');
+      table.appendChild(tr);
+      return success;
+    }
+
+    function runTests() {
+      // Wrap initialization code in a try/catch so we can fail gracefully
+      // on older browsers.
+      try {
+        editorDoc = document.getElementById('editor').contentWindow.document;
+        // Default styleWithCSS to false, since it's not supported by IE.
+        try {
+          editorDoc.execCommand('styleWithCSS', false, false);
+        } catch (ex) {
+          // Not supported by IE.
+        }
+      } catch (ex) {}
+
+      // Apply tests
+      var apply_score = 0;
+      var apply_count = 0;
+      var unapply_score= 0;
+      var unapply_count = 0;
+      var change_score = 0;
+      var change_count = 0;
+      var query_score = 0;
+      var query_count = 0;
+      for (var command in APPLY_TESTS) {
+        try {
+          var result = doApplyTest(command, false);
+          var success = outputApplyResult(command, result, false);
+          apply_score += success ? 1 : 0;
+        } catch (ex) {
+          // An exception is counted as a failed test, don't increment success.
+        }
+        apply_count++;
+        if (APPLY_TESTS[command].styleWithCSS) {
+          try {
+            var result = doApplyTest(command, true);
+            var success = outputApplyResult(command, result, true);
+            apply_score += success ? 1 : 0;
+          } catch (ex) {
+            // An exception is counted as a failed test, don't increment success.
+          }
+          apply_count++;
+        }
+      }
+
+      // Unapply tests
+      for (var command in UNAPPLY_TESTS) {
+        for (var i = 0; i < UNAPPLY_TESTS[command].tags.length; i++) {
+          try {
+            var result = doUnapplyTest(command, i);
+            var success = outputUnapplyResult(command, result, i);
+            unapply_score += success ? 1 : 0;
+          } catch (ex) {
+            // An exception is counted as a failed test, don't increment success.
+          }
+          unapply_count++;
+        }
+      }
+
+      // Query tests
+      for (var command in QUERY_TESTS) {
+        for (var i = 0; i < QUERY_TESTS[command].tests.length; i++) {
+          try {
+            var result = doQueryTest(command, i);
+            var success = outputQueryResult(command, i, result);
+            query_score += success ? 1 : 0;
+          } catch (ex) {
+            // An exception is counted as a failed test, don't increment success.
+          }
+          query_count++;
+        }
+      }
+
+      // Change tests
+      for (var command in CHANGE_TESTS) {
+        for (var i = 0; i < CHANGE_TESTS[command].tests.length; i++) {
+          try {
+            doChangeTest(command, i);
+            var success = outputChangeResult(command, i);
+            change_score += success ? 1 : 0;
+          } catch (ex) {
+            // An exception is counted as a failed test, don't increment success.
+          }
+          change_count++;
+        }
+      }
+
+      // Beacon all test results.
+      // and construct a shorter version for the results page.
+      try {
+        document.getElementById('apply-score').innerHTML =
+            apply_score + '/' + apply_count;
+        document.getElementById('unapply-score').innerHTML =
+            unapply_score + '/' + unapply_count;
+        document.getElementById('query-score').innerHTML =
+            query_score + '/' + query_count;
+        document.getElementById('change-score').innerHTML =
+            change_score + '/' + change_count;
+      } catch (ex) {}
+      var continueParams = [
+        'apply=' + apply_score,
+        'unapply=' + unapply_score,
+        'query=' + query_score,
+        'change=' + change_score
+      ];
+      parent.sendScore(results, continueParams);
+    }
+  </script>
+  <style>
+    .success {
+      background-color: #93c47d;
+    }
+    .fail {
+      background-color: #ea9999;
+    }
+    .score {
+      color: #666;
+    }
+  </style>
+</head>
+<body onload="runTests()">
+  <h1>Apply Formatting <span id="apply-score" class="score"></span></h1>
+  <table id="apply"><tbody id="apply_output"><tr><th>Command</th><th>styleWithCSS</th><th>Status</th><th>Output</th></tr></tbody></table>
+  <h1>Unapply Formatting <span id="unapply-score" class="score"></span></h1>
+  <table id="unapply">
+    <thead><tr><th>Command</th><th>Command unapplied</th><th>Status</th><th>HTML Attempted to Unapply</th><th>Resulting HTML</th></tr></thead>
+    <tbody id="unapply_output"></tbody></table>
+  <h1>Query Formatting State <span id="query-score" class="score"></span></h1>
+  <table id="querystate">
+    <thead><tr><th>Command</th><th>Status</th><th>HTML</th><th>Expected</th><th>Actual</th></tr></thead>
+    <tbody id="querystate_output"></tbody></table>
+  <h1>Query Formatting Value </h1>
+  <table id="queryvalue">
+    <thead><tr><th>Command</th><th>Status</th><th>HTML</th><th>Expected</th><th>Actual</th></tr></thead>
+    <tbody id="queryvalue_output"></tbody></table>
+  <h1>Change Formatting <span id="change-score" class="score"></span></h1>
+  <table id="change">
+    <thead><tr><th>Command</th><th>Status</th><th>Argument</th><th>Original HTML</th><th>Resulting HTML</th></tr></thead>
+    <tbody id="change_output"></tbody></table>
+  <iframe name="editor" id="editor" src="editable.html"></iframe>
+</body>
+</html>
new file mode 100755
--- /dev/null
+++ b/editor/libeditor/html/tests/browserscope/lib/browserscope/update_from_upstream
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+set -x
+
+if test -d richtext; then
+  rm -drf richtext;
+fi
+
+svn checkout http://browserscope.googlecode.com/svn/trunk/categories/richtext/static richtext | tail -1 | sed 's/[^0-9]//g' > current_revision
+
+find richtext -type d -name .svn -exec rm -drf \{\} \; 2> /dev/null
+
+hg add current_revision richtext
+
+hg stat .
+
new file mode 100644
--- /dev/null
+++ b/editor/libeditor/html/tests/browserscope/test_browserscope.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+BrowserScope richtext category tests
+-->
+<head>
+  <title>BrowserScope Richtext Tests</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"/>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>  
+  <script type="text/javascript" src="lib/browserscope/currentStatus.js"></script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=550569">Mozilla Bug 550569</a>
+<p id="display"></p>
+<div id="content">
+  <iframe src="lib/browserscope/richtext/richtext.html"></iframe>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+// Running all of the tests can take a long time, try to account for it
+SimpleTest.requestLongerTimeout(5);
+
+function sendScore(results, continueParams) {
+  ok(results.length > 1, "At least one test should have been run");
+  for (var i = 1; i < results.length; ++i) {
+    var result = results[i];
+    [type, command, param, success] = result.split(/[\-=]/);
+    var comp = is;
+    if (isKnownFailure(type, command, param)) {
+      comp = todo_is;
+    }
+    comp(success, "1", "Browserscope category=" + type +
+         " test=" + command +
+         " param=" + param);
+  }
+}
+
+document.getElementsByTagName("iframe")[0].addEventListener("load", function() {
+  SimpleTest.finish();
+}, false);
+
+</script>
+</pre>
+</body>
+</html>
--- a/editor/txmgr/tests/TestTXMgr.cpp
+++ b/editor/txmgr/tests/TestTXMgr.cpp
@@ -1061,17 +1061,17 @@ quick_test(TestTransactionFactory *facto
    *
    *******************************************************************/
 
   printf("Test coalescing of transactions ... ");
 
   result = mgr->SetMaxTransactionCount(10);
 
   if (NS_FAILED(result)) {
-    printf("ERROR: SetMaxTransactionCount(0) failed. (%d)\n", result);
+    printf("ERROR: SetMaxTransactionCount(10) failed. (%d)\n", result);
     return result;
   }
 
 
   tximpl = factory->create(mgr, MERGE_FLAG);
 
   if (!tximpl) {
     printf("ERROR: Failed to allocate initial transaction.\n");
@@ -1416,17 +1416,17 @@ quick_test(TestTransactionFactory *facto
     printf("ERROR: GetNumberOfUndoItems() expected 6 got %d. (%d)\n",
            numitems, result);
     return NS_ERROR_FAILURE;
   }
 
   result = mgr->GetNumberOfRedoItems(&numitems);
 
   if (NS_FAILED(result)) {
-    printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
+    printf("ERROR: GetNumberOfRedoItems() on redo stack with 4 items failed. (%d)\n",
            result);
     return result;
   }
 
   if (numitems != 4) {
     printf("ERROR: GetNumberOfRedoItems() expected 4 got %d. (%d)\n",
            numitems, result);
     return NS_ERROR_FAILURE;
@@ -1525,17 +1525,17 @@ quick_test(TestTransactionFactory *facto
     printf("ERROR: GetNumberOfUndoItems() expected 9 got %d. (%d)\n",
            numitems, result);
     return NS_ERROR_FAILURE;
   }
 
   result = mgr->GetNumberOfRedoItems(&numitems);
 
   if (NS_FAILED(result)) {
-    printf("ERROR: GetNumberOfRedoItems() on redo stack with 0 items failed. (%d)\n",
+    printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
            result);
     return result;
   }
 
   if (numitems != 0) {
     printf("ERROR: GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
            numitems, result);
     return NS_ERROR_FAILURE;
@@ -1606,17 +1606,17 @@ quick_test(TestTransactionFactory *facto
     printf("ERROR: GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
            numitems, result);
     return NS_ERROR_FAILURE;
   }
 
   result = mgr->GetNumberOfRedoItems(&numitems);
 
   if (NS_FAILED(result)) {
-    printf("ERROR: GetNumberOfRedoItems() on empty cleared stack failed. (%d)\n",
+    printf("ERROR: GetNumberOfRedoItems() on cleared redo stack failed. (%d)\n",
            result);
     return result;
   }
 
   if (numitems != 0) {
     printf("ERROR: GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
            numitems, result);
     return NS_ERROR_FAILURE;
@@ -2062,17 +2062,17 @@ quick_test(TestTransactionFactory *facto
     printf("ERROR: GetNumberOfUndoItems() expected 6 got %d. (%d)\n",
            numitems, result);
     return NS_ERROR_FAILURE;
   }
 
   result = mgr->GetNumberOfRedoItems(&numitems);
 
   if (NS_FAILED(result)) {
-    printf("ERROR: GetNumberOfRedoItems() on empty redo stack. (%d)\n",
+    printf("ERROR: GetNumberOfRedoItems() on redo stack with 2 items failed. (%d)\n",
            result);
     return result;
   }
 
   if (numitems != 2) {
     printf("ERROR: GetNumberOfRedoItems() expected 2 got %d. (%d)\n",
            numitems, result);
     return NS_ERROR_FAILURE;
@@ -2101,17 +2101,17 @@ quick_test(TestTransactionFactory *facto
 
   if (NS_FAILED(result)) {
     printf("ERROR: GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
            result);
     return result;
   }
 
   if (numitems != 0) {
-    printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
+    printf("ERROR: GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
            numitems, result);
     return NS_ERROR_FAILURE;
   }
 
   result = mgr->GetNumberOfRedoItems(&numitems);
 
   if (NS_FAILED(result)) {
     printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
@@ -2153,17 +2153,17 @@ quick_test(TestTransactionFactory *facto
 
     if (NS_FAILED(result)) {
       printf("ERROR: GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
              result);
       return result;
     }
 
     if (numitems != 0) {
-      printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
+      printf("ERROR: GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
              numitems, result);
       return NS_ERROR_FAILURE;
     }
 
     result = mgr->GetNumberOfRedoItems(&numitems);
 
     if (NS_FAILED(result)) {
       printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
@@ -2188,17 +2188,17 @@ quick_test(TestTransactionFactory *facto
    *
    *******************************************************************/
 
   printf("Test SetMaxTransactionCount() greater than num stack items ... ");
 
   result = mgr->SetMaxTransactionCount(-1);
 
   if (NS_FAILED(result)) {
-    printf("ERROR: SetMaxTransactionCount(0) failed. (%d)\n", result);
+    printf("ERROR: SetMaxTransactionCount(-1) failed. (%d)\n", result);
     return result;
   }
 
   // Push 20 transactions on the undo stack:
 
   for (i = 1; i <= 20; i++) {
     tximpl = factory->create(mgr, NONE_FLAG);
 
@@ -2221,24 +2221,24 @@ quick_test(TestTransactionFactory *facto
       return result;
     }
 
     tx->Release();
 
     result = mgr->GetNumberOfUndoItems(&numitems);
 
     if (NS_FAILED(result)) {
-      printf("ERROR: GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
-             result);
+      printf("ERROR: GetNumberOfUndoItems() on undo stack with %d items failed. (%d)\n",
+             i, result);
       return result;
     }
 
     if (numitems != i) {
-      printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
-             numitems, result);
+      printf("ERROR: GetNumberOfUndoItems() expected %d got %d. (%d)\n",
+             i, numitems, result);
       return NS_ERROR_FAILURE;
     }
 
     result = mgr->GetNumberOfRedoItems(&numitems);
 
     if (NS_FAILED(result)) {
       printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
              result);
@@ -2401,17 +2401,17 @@ quick_test(TestTransactionFactory *facto
   if (NS_FAILED(result)) {
     printf("ERROR: Initial PeekRedoStack() failed. (%d)\n", result);
     return result;
   }
 
   result = mgr->SetMaxTransactionCount(15);
 
   if (NS_FAILED(result)) {
-    printf("ERROR: SetMaxTransactionCount(25) failed. (%d)\n", result);
+    printf("ERROR: SetMaxTransactionCount(15) failed. (%d)\n", result);
     return result;
   }
 
   result = mgr->PeekUndoStack(&u2);
 
   TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
 
   if (NS_FAILED(result)) {
@@ -2436,23 +2436,23 @@ quick_test(TestTransactionFactory *facto
   if (r1 != r2) {
     printf("ERROR: Top of redo stack changed. (%d)\n", result);
     return NS_ERROR_FAILURE;
   }
 
   result = mgr->GetNumberOfUndoItems(&numitems);
 
   if (NS_FAILED(result)) {
-    printf("ERROR: GetNumberOfUndoItems() on undo stack with 10 items failed. (%d)\n",
+    printf("ERROR: GetNumberOfUndoItems() on undo stack with 5 items failed. (%d)\n",
            result);
     return result;
   }
 
   if (numitems != 5) {
-    printf("ERROR: GetNumberOfUndoItems() expected 10 got %d. (%d)\n",
+    printf("ERROR: GetNumberOfUndoItems() expected 5 got %d. (%d)\n",
            numitems, result);
     return NS_ERROR_FAILURE;
   }
 
   result = mgr->GetNumberOfRedoItems(&numitems);
 
   if (NS_FAILED(result)) {
     printf("ERROR: GetNumberOfRedoItems() on redo stack with 10 items failed. (%d)\n",
@@ -2496,17 +2496,17 @@ quick_test(TestTransactionFactory *facto
   if (NS_FAILED(result)) {
     printf("ERROR: Initial PeekRedoStack() failed. (%d)\n", result);
     return result;
   }
 
   result = mgr->SetMaxTransactionCount(5);
 
   if (NS_FAILED(result)) {
-    printf("ERROR: SetMaxTransactionCount(25) failed. (%d)\n", result);
+    printf("ERROR: SetMaxTransactionCount(5) failed. (%d)\n", result);
     return result;
   }
 
   result = mgr->PeekUndoStack(&u2);
 
   TEST_TXMGR_IF_RELEASE(u2); // Don't hold onto any references!
 
   if (NS_FAILED(result)) {
@@ -2570,17 +2570,17 @@ quick_test(TestTransactionFactory *facto
    *
    *******************************************************************/
 
   printf("Release the transaction manager ... ");
 
   result = mgr->SetMaxTransactionCount(-1);
 
   if (NS_FAILED(result)) {
-    printf("ERROR: SetMaxTransactionCount(0) failed. (%d)\n", result);
+    printf("ERROR: SetMaxTransactionCount(-1) failed. (%d)\n", result);
     return result;
   }
 
   // Push 20 transactions on the undo stack:
 
   for (i = 1; i <= 20; i++) {
     tximpl = factory->create(mgr, NONE_FLAG);
 
@@ -2603,24 +2603,24 @@ quick_test(TestTransactionFactory *facto
       return result;
     }
 
     tx->Release();
 
     result = mgr->GetNumberOfUndoItems(&numitems);
 
     if (NS_FAILED(result)) {
-      printf("ERROR: GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
-             result);
+      printf("ERROR: GetNumberOfUndoItems() on undo stack with %d items failed. (%d)\n",
+             i, result);
       return result;
     }
 
     if (numitems != i) {
-      printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
-             numitems, result);
+      printf("ERROR: GetNumberOfUndoItems() expected %d got %d. (%d)\n",
+             i, numitems, result);
       return NS_ERROR_FAILURE;
     }
 
     result = mgr->GetNumberOfRedoItems(&numitems);
 
     if (NS_FAILED(result)) {
       printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
              result);
@@ -2640,17 +2640,17 @@ quick_test(TestTransactionFactory *facto
     if (NS_FAILED(result)) {
       printf("ERROR: Failed to undo transaction %d. (%d)\n", i, result);
       return result;
     }
   }
   result = mgr->GetNumberOfUndoItems(&numitems);
 
   if (NS_FAILED(result)) {
-    printf("ERROR: GetNumberOfUndoItems() on empty undo stack with 10 items failed. (%d)\n",
+    printf("ERROR: GetNumberOfUndoItems() on undo stack with 10 items failed. (%d)\n",
            result);
     return result;
   }
 
   if (numitems != 10) {
     printf("ERROR: GetNumberOfUndoItems() expected 10 got %d. (%d)\n",
            numitems, result);
     return NS_ERROR_FAILURE;
@@ -2714,22 +2714,22 @@ simple_test()
   sRedoOrderArr       = sSimpleTestRedoOrderArr;
 
   /*******************************************************************
    *
    * Run the quick test.
    *
    *******************************************************************/
 
-  SimpleTransactionFactory factory;
-
   printf("\n-----------------------------------------------------\n");
   printf("- Begin Simple Transaction Test:\n");
   printf("-----------------------------------------------------\n");
 
+  SimpleTransactionFactory factory;
+
   return quick_test(&factory);
 }
 
 nsresult
 aggregation_test()
 {
   /*******************************************************************
    *
@@ -2744,22 +2744,22 @@ aggregation_test()
   sRedoOrderArr       = sAggregateTestRedoOrderArr;
 
   /*******************************************************************
    *
    * Run the quick test.
    *
    *******************************************************************/
 
-  AggregateTransactionFactory factory(3,2);
-
   printf("\n-----------------------------------------------------\n");
   printf("- Begin Aggregate Transaction Test:\n");
   printf("-----------------------------------------------------\n");
 
+  AggregateTransactionFactory factory(3, 2);
+
   return quick_test(&factory);
 }
 
 /**
  * Test behaviors in batch mode.
  **/
 nsresult
 quick_batch_test(TestTransactionFactory *factory)
@@ -3269,17 +3269,17 @@ quick_batch_test(TestTransactionFactory 
 
   if (NS_FAILED(result)) {
     printf("ERROR: GetNumberOfUndoItems() on undo stack with 2 items failed. (%d)\n",
            result);
     return result;
   }
 
   if (numitems != 2) {
-    printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
+    printf("ERROR: GetNumberOfUndoItems() expected 2 got %d. (%d)\n",
            numitems, result);
     return NS_ERROR_FAILURE;
   }
 
   printf("passed\n");
 
   /*******************************************************************
    *
@@ -3364,17 +3364,17 @@ quick_batch_test(TestTransactionFactory 
 
   if (NS_FAILED(result)) {
     printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
            result);
     return result;
   }
 
   if (numitems != 0) {
-    printf("ERROR: GetNumberOfRedoItems() expected 2 got %d. (%d)\n",
+    printf("ERROR: GetNumberOfRedoItems() expected 0 got %d. (%d)\n",
            numitems, result);
     return NS_ERROR_FAILURE;
   }
 
   printf("passed\n");
 
   /*******************************************************************
    *
@@ -3604,17 +3604,17 @@ quick_batch_test(TestTransactionFactory 
     printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
            numitems, result);
     return NS_ERROR_FAILURE;
   }
 
   result = mgr->GetNumberOfRedoItems(&numitems);
 
   if (NS_FAILED(result)) {
-    printf("ERROR: GetNumberOfRedoItems() on redo stack with 1 items failed. (%d)\n",
+    printf("ERROR: GetNumberOfRedoItems() on redo stack with 1 item failed. (%d)\n",
            result);
     return result;
   }
 
   if (numitems != 1) {
     printf("ERROR: GetNumberOfRedoItems() expected 1 got %d. (%d)\n",
            numitems, result);
     return NS_ERROR_FAILURE;
@@ -3687,17 +3687,17 @@ quick_batch_test(TestTransactionFactory 
     printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
            numitems, result);
     return NS_ERROR_FAILURE;
   }
 
   result = mgr->GetNumberOfRedoItems(&numitems);
 
   if (NS_FAILED(result)) {
-    printf("ERROR: GetNumberOfRedoItems() on redo stack with 1 items failed. (%d)\n",
+    printf("ERROR: GetNumberOfRedoItems() on redo stack with 1 item failed. (%d)\n",
            result);
     return result;
   }
 
   if (numitems != 1) {
     printf("ERROR: GetNumberOfRedoItems() expected 1 got %d. (%d)\n",
            numitems, result);
     return NS_ERROR_FAILURE;
@@ -3799,31 +3799,31 @@ quick_batch_test(TestTransactionFactory 
   if (r1 != r2) {
     printf("ERROR: Top of redo stack changed. (%d)\n", result);
     return NS_ERROR_FAILURE;
   }
 
   result = mgr->GetNumberOfUndoItems(&numitems);
 
   if (NS_FAILED(result)) {
-    printf("ERROR: GetNumberOfUndoItems() on undo stack with 5 items failed. (%d)\n",
+    printf("ERROR: GetNumberOfUndoItems() on undo stack with 1 item failed. (%d)\n",
            result);
     return result;
   }
 
   if (numitems != 1) {
-    printf("ERROR: GetNumberOfUndoItems() expected 5 got %d. (%d)\n",
+    printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
            numitems, result);
     return NS_ERROR_FAILURE;
   }
 
   result = mgr->GetNumberOfRedoItems(&numitems);
 
   if (NS_FAILED(result)) {
-    printf("ERROR: GetNumberOfRedoItems() on empty redo stack. (%d)\n",
+    printf("ERROR: GetNumberOfRedoItems() on redo stack with 1 item failed. (%d)\n",
            result);
     return result;
   }
 
   if (numitems != 1) {
     printf("ERROR: GetNumberOfRedoItems() expected 1 got %d. (%d)\n",
            numitems, result);
     return NS_ERROR_FAILURE;
@@ -4123,17 +4123,17 @@ quick_batch_test(TestTransactionFactory 
     printf("ERROR: GetNumberOfUndoItems() expected 2 got %d. (%d)\n",
            numitems, result);
     return NS_ERROR_FAILURE;
   }
 
   result = mgr->GetNumberOfRedoItems(&numitems);
 
   if (NS_FAILED(result)) {
-    printf("ERROR: GetNumberOfRedoItems() on empty redo stack. (%d)\n",
+    printf("ERROR: GetNumberOfRedoItems() on redo stack with 2 items failed. (%d)\n",
            result);
     return result;
   }
 
   if (numitems != 2) {
     printf("ERROR: GetNumberOfRedoItems() expected 2 got %d. (%d)\n",
            numitems, result);
     return NS_ERROR_FAILURE;
@@ -4162,17 +4162,17 @@ quick_batch_test(TestTransactionFactory 
 
   if (NS_FAILED(result)) {
     printf("ERROR: GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
            result);
     return result;
   }
 
   if (numitems != 0) {
-    printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
+    printf("ERROR: GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
            numitems, result);
     return NS_ERROR_FAILURE;
   }
 
   result = mgr->GetNumberOfRedoItems(&numitems);
 
   if (NS_FAILED(result)) {
     printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
@@ -4228,17 +4228,17 @@ quick_batch_test(TestTransactionFactory 
 
     if (NS_FAILED(result)) {
       printf("ERROR: GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
              result);
       return result;
     }
 
     if (numitems != 0) {
-      printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
+      printf("ERROR: GetNumberOfUndoItems() expected 0 got %d. (%d)\n",
              numitems, result);
       return NS_ERROR_FAILURE;
     }
 
     result = mgr->GetNumberOfRedoItems(&numitems);
 
     if (NS_FAILED(result)) {
       printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
@@ -4309,24 +4309,24 @@ quick_batch_test(TestTransactionFactory 
     if (NS_FAILED(result)) {
       printf("ERROR: EndBatch() failed. (%d)\n", result);
       return result;
     }
 
     result = mgr->GetNumberOfUndoItems(&numitems);
 
     if (NS_FAILED(result)) {
-      printf("ERROR: GetNumberOfUndoItems() on empty undo stack failed. (%d)\n",
-             result);
+      printf("ERROR: GetNumberOfUndoItems() on undo stack with %d items failed. (%d)\n",
+             i, result);
       return result;
     }
 
     if (numitems != i) {
-      printf("ERROR: GetNumberOfUndoItems() expected 1 got %d. (%d)\n",
-             numitems, result);
+      printf("ERROR: GetNumberOfUndoItems() expected %d got %d. (%d)\n",
+             i, numitems, result);
       return NS_ERROR_FAILURE;
     }
 
     result = mgr->GetNumberOfRedoItems(&numitems);
 
     if (NS_FAILED(result)) {
       printf("ERROR: GetNumberOfRedoItems() on empty redo stack failed. (%d)\n",
              result);
@@ -4421,22 +4421,22 @@ simple_batch_test()
   sRedoOrderArr       = sSimpleBatchTestRedoOrderArr;
 
   /*******************************************************************
    *
    * Run the quick batch test.
    *
    *******************************************************************/
 
-  SimpleTransactionFactory factory;
-
   printf("\n-----------------------------------------------------\n");
   printf("- Begin Batch Transaction Test:\n");
   printf("-----------------------------------------------------\n");
 
+  SimpleTransactionFactory factory;
+
   return quick_batch_test(&factory);
 }
 
 nsresult
 aggregation_batch_test()
 {
   /*******************************************************************
    *
@@ -4451,41 +4451,41 @@ aggregation_batch_test()
   sRedoOrderArr       = sAggregateBatchTestRedoOrderArr;
 
   /*******************************************************************
    *
    * Run the quick batch test.
    *
    *******************************************************************/
 
-  AggregateTransactionFactory factory(3,2,BATCH_FLAG);
-
   printf("\n-----------------------------------------------------\n");
   printf("- Begin Batch Aggregate Transaction Test:\n");
   printf("-----------------------------------------------------\n");
 
+  AggregateTransactionFactory factory(3, 2, BATCH_FLAG);
+
   return quick_batch_test(&factory);
 }
 
 /**
  * Create 'iterations * (iterations + 1) / 2' transactions;
  * do/undo/redo/undo them.
  **/
 nsresult
 stress_test(TestTransactionFactory *factory, PRInt32 iterations)
 {
+  printf("Stress test (may take a while) ... ");
+  fflush(stdout);
+
   /*******************************************************************
    *
    * Create a transaction manager:
    *
    *******************************************************************/
 
-  printf("Stress test (may take a while) ... ");
-  fflush(stdout);
-
   PRInt32 i, j;
   nsCOMPtr<nsITransactionManager> mgr;
   nsITransaction *tx          = 0;
   nsresult result;
 
   mgr = do_CreateInstance(NS_TRANSACTIONMANAGER_CONTRACTID, &result);
   if (NS_FAILED(result) || !mgr) {
     printf("ERROR: Failed to create Transaction Manager instance.\n");
@@ -4498,31 +4498,32 @@ stress_test(TestTransactionFactory *fact
      * Create and execute a bunch of transactions:
      *
      *******************************************************************/
 
     for (j = 1; j <= i; j++) {
       TestTransaction *tximpl = factory->create(mgr, NONE_FLAG);
 
       if (!tximpl) {
-        printf("ERROR: Failed to allocate transaction %d.\n", j);
+        printf("ERROR: Failed to allocate transaction %d-%d.\n", i, j);
         return NS_ERROR_OUT_OF_MEMORY;
       }
 
       tx = 0;
       result = tximpl->QueryInterface(NS_GET_IID(nsITransaction), (void **)&tx);
       if (NS_FAILED(result)) {
-        printf("ERROR: QueryInterface() failed for transaction %d. (%d)\n",
-               i, result);
+        printf("ERROR: QueryInterface() failed for transaction %d-%d. (%d)\n",
+               i, j, result);
         return result;
       }
 
       result = mgr->DoTransaction(tx);
       if (NS_FAILED(result)) {
-        printf("ERROR: Failed to execute transaction %d. (%d)\n", i, result);
+        printf("ERROR: Failed to execute transaction %d-%d. (%d)\n",
+               i, j, result);
         return result;
       }
 
       tx->Release();
     }
 
     /*******************************************************************
      *
@@ -4600,22 +4601,22 @@ simple_stress_test()
   reset_globals();
 
   /*******************************************************************
    *
    * Do the stress test:
    *
    *******************************************************************/
 
-  SimpleTransactionFactory factory;
-
   printf("\n-----------------------------------------------------\n");
   printf("- Simple Transaction Stress Test:\n");
   printf("-----------------------------------------------------\n");
 
+  SimpleTransactionFactory factory;
+
   //
   // 1500 iterations sends 1,125,750 transactions through the system!!
   //
   return stress_test(&factory, 1500);
 }
 
 nsresult
 aggregation_stress_test()
@@ -4629,22 +4630,22 @@ aggregation_stress_test()
   reset_globals();
 
   /*******************************************************************
    *
    * Do the stress test:
    *
    *******************************************************************/
 
-  AggregateTransactionFactory factory(3,4);
-
   printf("\n-----------------------------------------------------\n");
   printf("- Aggregate Transaction Stress Test:\n");
   printf("-----------------------------------------------------\n");
 
+  AggregateTransactionFactory factory(3, 4);
+
   //
   // 500 iterations sends 2,630,250 transactions through the system!!
   //
   return stress_test(&factory, 500);
 }
 
 nsresult
 aggregation_batch_stress_test()
@@ -4658,22 +4659,22 @@ aggregation_batch_stress_test()
   reset_globals();
 
   /*******************************************************************
    *
    * Do the stress test:
    *
    *******************************************************************/
 
-  AggregateTransactionFactory factory(3,4,BATCH_FLAG);
-
   printf("\n-----------------------------------------------------\n");
   printf("- Aggregate Batch Transaction Stress Test:\n");
   printf("-----------------------------------------------------\n");
 
+  AggregateTransactionFactory factory(3, 4, BATCH_FLAG);
+
   //
   // 500 iterations sends 2,630,250 transactions through the system!!
   //
   return stress_test(&factory, 500);
 }
 
 int
 main (int argc, char *argv[])
--- a/embedding/components/Makefile.in
+++ b/embedding/components/Makefile.in
@@ -40,17 +40,17 @@ topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 # You'd think we could skip building ui if XUL is disabled,
 # but we need to export interface headers from those directories.
 
-DIRS = windowwatcher appstartup find webbrowserpersist commandhandler ui
+DIRS = windowwatcher appstartup find webbrowserpersist commandhandler
 
 ifdef MOZ_XUL
 ifdef NS_PRINTING
 ifndef WINCE
 DIRS += printingui
 endif
 endif
 endif
deleted file mode 100644
--- a/embedding/components/ui/Makefile.in
+++ /dev/null
@@ -1,47 +0,0 @@
-# 
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications, Inc.
-# Portions created by the Initial Developer are Copyright (C) 2001
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either the GNU General Public License Version 2 or later (the "GPL"), or
-# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-
-DEPTH		= ../../..
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-DIRS = helperAppDlg progressDlg
-
-include $(topsrcdir)/config/rules.mk
deleted file mode 100644
--- a/embedding/components/ui/helperAppDlg/Makefile.in
+++ /dev/null
@@ -1,52 +0,0 @@
-# 
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications, Inc.
-# Portions created by the Initial Developer are Copyright (C) 2001
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either the GNU General Public License Version 2 or later (the "GPL"), or
-# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-# in which case the provisions of the GPL or the LGPL are applicable instead
-# of those above. If you wish to allow use of your version of this file only
-# under the terms of either the GPL or the LGPL, and not to allow others to
-# use your version of this file under the terms of the MPL, indicate your
-# decision by deleting the provisions above and replace them with the notice
-# and other provisions required by the GPL or the LGPL. If you do not delete
-# the provisions above, a recipient may use your version of this file under
-# the terms of any one of the MPL, the GPL or the LGPL.
-#
-# ***** END LICENSE BLOCK *****
-
-DEPTH		= ../../../..
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-MODULE=helperAppDlg
-
-include $(DEPTH)/config/autoconf.mk
-
-EXTRA_COMPONENTS = \
-	nsHelperAppDlg.js \
-	$(NULL)
-
-include $(topsrcdir)/config/rules.mk
-
deleted file mode 100644
--- a/embedding/components/ui/helperAppDlg/nsHelperAppDlg.js
+++ /dev/null
@@ -1,894 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** 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 the Mozilla browser.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2001
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Bill Law    <law@netscape.com>
- *   Scott MacGregor <mscott@netscape.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 ***** */
-
-/* This file implements the nsIHelperAppLauncherDialog interface.
- *
- * The implementation consists of a JavaScript "class" named nsHelperAppDialog,
- * comprised of:
- *   - a JS constructor function
- *   - a prototype providing all the interface methods and implementation stuff
- *
- * In addition, this file implements an nsIModule object that registers the
- * nsHelperAppDialog component.
- */
-
-const nsIHelperAppLauncherDialog = Components.interfaces.nsIHelperAppLauncherDialog;
-const REASON_CANTHANDLE = nsIHelperAppLauncherDialog.REASON_CANTHANDLE;
-const REASON_SERVERREQUEST = nsIHelperAppLauncherDialog.REASON_SERVERREQUEST;
-const REASON_TYPESNIFFED = nsIHelperAppLauncherDialog.REASON_TYPESNIFFED;
-
-
-/* ctor
- */
-function nsHelperAppDialog() {
-    // Initialize data properties.
-    this.mLauncher = null;
-    this.mContext  = null;
-    this.mSourcePath = null;
-    this.chosenApp = null;
-    this.givenDefaultApp = false;
-    this.strings   = new Array;
-    this.elements  = new Array;
-    this.updateSelf = true;
-    this.mTitle    = "";
-    this.mIsMac    = false;
-}
-
-nsHelperAppDialog.prototype = {
-    // Turn this on to get debugging messages.
-    debug: false,
-
-    nsIMIMEInfo  : Components.interfaces.nsIMIMEInfo,
-
-    // Dump text (if debug is on).
-    dump: function( text ) {
-        if ( this.debug ) {
-            dump( text );
-        }
-    },
-
-    // This "class" supports nsIHelperAppLauncherDialog, and nsISupports.
-    QueryInterface: function (iid) {
-        if (iid.equals(Components.interfaces.nsIHelperAppLauncherDialog) ||
-            iid.equals(Components.interfaces.nsISupports))
-            return this;
-
-        throw Components.results.NS_ERROR_NO_INTERFACE;
-    },
-
-    // ---------- nsIHelperAppLauncherDialog methods ----------
-
-    // show: Open XUL dialog using window watcher.  Since the dialog is not
-    //       modal, it needs to be a top level window and the way to open
-    //       one of those is via that route).
-    show: function(aLauncher, aContext, aReason)  {
-         this.mLauncher = aLauncher;
-         this.mContext  = aContext;
-         this.mReason   = aReason;
-         // Display the dialog using the Window Watcher interface.
-         var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
-                    .getService( Components.interfaces.nsIWindowWatcher );
-         this.mDialog = ww.openWindow( null, // no parent
-                                       "chrome://global/content/nsHelperAppDlg.xul",
-                                       null,
-                                       "chrome,titlebar,dialog=yes",
-                                       null );
-         // Hook this object to the dialog.
-         this.mDialog.dialog = this;
-         // Watch for error notifications.
-         this.mIsMac = (this.mDialog.navigator.platform.indexOf( "Mac" ) != -1);
-         this.progressListener.helperAppDlg = this;
-         this.mLauncher.setWebProgressListener( this.progressListener );
-    },
-
-    // promptForSaveToFile:  Display file picker dialog and return selected file.
-    promptForSaveToFile: function(aLauncher, aContext, aDefaultFile, aSuggestedFileExtension, aForcePrompt) {
-        var result = "";
-
-        const prefSvcContractID = "@mozilla.org/preferences-service;1";
-        const prefSvcIID = Components.interfaces.nsIPrefService;
-        var branch = Components.classes[prefSvcContractID].getService(prefSvcIID)
-                                                          .getBranch("browser.download.");
-        var dir = null;
-
-        const nsILocalFile = Components.interfaces.nsILocalFile;
-        const kDownloadDirPref = "dir";
-
-        // Try and pull in download directory pref
-        try {
-            dir = branch.getComplexValue(kDownloadDirPref, nsILocalFile);
-        } catch (e) { }
-
-        var bundle = Components.classes["@mozilla.org/intl/stringbundle;1"]
-                               .getService(Components.interfaces.nsIStringBundleService)
-                               .createBundle("chrome://global/locale/nsHelperAppDlg.properties");
-
-        var autoDownload = branch.getBoolPref("autoDownload");
-        // If the autoDownload pref is set then just download to default download directory
-        if (!aForcePrompt && autoDownload && dir && dir.exists()) {
-            if (aDefaultFile == "")
-                aDefaultFile = bundle.GetStringFromName("noDefaultFile") + (aSuggestedFileExtension || "");
-            dir.append(aDefaultFile);
-            return uniqueFile(dir);
-        }
-
-        // Use file picker to show dialog.
-        var nsIFilePicker = Components.interfaces.nsIFilePicker;
-        var picker = Components.classes[ "@mozilla.org/filepicker;1" ]
-                       .createInstance( nsIFilePicker );
-
-        var windowTitle = bundle.GetStringFromName( "saveDialogTitle" );
-
-        var parent = aContext
-                        .QueryInterface( Components.interfaces.nsIInterfaceRequestor )
-                        .getInterface( Components.interfaces.nsIDOMWindowInternal );
-        picker.init( parent, windowTitle, nsIFilePicker.modeSave );
-        picker.defaultString = aDefaultFile;
-        if (aSuggestedFileExtension) {
-            // aSuggestedFileExtension includes the period, so strip it
-            picker.defaultExtension = aSuggestedFileExtension.substring(1);
-        } else {
-            try {
-                picker.defaultExtension = this.mLauncher.MIMEInfo.primaryExtension;
-            } catch (ex) {
-            }
-        }
-
-        var wildCardExtension = "*";
-        if ( aSuggestedFileExtension ) {
-            wildCardExtension += aSuggestedFileExtension;
-            picker.appendFilter( wildCardExtension, wildCardExtension );
-        }
-
-        picker.appendFilters( nsIFilePicker.filterAll );
-
-        try {
-            if (dir.exists())
-                picker.displayDirectory = dir;
-        } catch (e) { }
-
-        if (picker.show() == nsIFilePicker.returnCancel || !picker.file) {
-            // Null result means user cancelled.
-            return null;
-        }
-
-        // If not using specified location save the user's choice of directory
-        if (branch.getBoolPref("lastLocation") || autoDownload) {
-            var directory = picker.file.parent.QueryInterface(nsILocalFile);
-            branch.setComplexValue(kDownloadDirPref, nsILocalFile, directory);
-        }
-
-        return picker.file;
-    },
-
-    // ---------- implementation methods ----------
-
-    // Web progress listener so we can detect errors while mLauncher is
-    // streaming the data to a temporary file.
-    progressListener: {
-        // Implementation properties.
-        helperAppDlg: null,
-
-        // nsIWebProgressListener methods.
-        // Look for error notifications and display alert to user.
-        onStatusChange: function( aWebProgress, aRequest, aStatus, aMessage ) {
-            if ( aStatus != Components.results.NS_OK ) {
-                // Get prompt service.
-                var prompter = Components.classes[ "@mozilla.org/embedcomp/prompt-service;1" ]
-                                   .getService( Components.interfaces.nsIPromptService );
-                // Display error alert (using text supplied by back-end).
-                prompter.alert( this.dialog, this.helperAppDlg.mTitle, aMessage );
-
-                // Close the dialog.
-                this.helperAppDlg.onCancel();
-                if ( this.helperAppDlg.mDialog ) {
-                    this.helperAppDlg.mDialog.close();
-                }
-            }
-        },
-
-        // Ignore onProgressChange, onProgressChange64, onStateChange, onLocationChange, onSecurityChange, and onRefreshAttempted notifications.
-        onProgressChange: function( aWebProgress,
-                                    aRequest,
-                                    aCurSelfProgress,
-                                    aMaxSelfProgress,
-                                    aCurTotalProgress,
-                                    aMaxTotalProgress ) {
-        },
-
-        onProgressChange64: function( aWebProgress,
-                                      aRequest,
-                                      aCurSelfProgress,
-                                      aMaxSelfProgress,
-                                      aCurTotalProgress,
-                                      aMaxTotalProgress ) {
-        },
-
-        onStateChange: function( aWebProgress, aRequest, aStateFlags, aStatus ) {
-        },
-
-        onLocationChange: function( aWebProgress, aRequest, aLocation ) {
-        },
-
-        onSecurityChange: function( aWebProgress, aRequest, state ) {
-        },
-
-        onRefreshAttempted: function( aWebProgress, aURI, aDelay, aSameURI ) {
-            return true;
-        }
-    },
-
-    // initDialog:  Fill various dialog fields with initial content.
-    initDialog : function() {
-         // Put product brand short name in prompt.
-         var prompt = this.dialogElement( "prompt" );
-         var modified = this.replaceInsert( prompt.firstChild.nodeValue, 1, this.getString( "brandShortName" ) );
-         prompt.firstChild.nodeValue = modified;
-
-         // Put file name in window title.
-         var suggestedFileName = this.mLauncher.suggestedFileName;
-
-         // Some URIs do not implement nsIURL, so we can't just QI.
-         var url = this.mLauncher.source.clone();
-         try {
-           url.userPass = "";
-         } catch (ex) {}
-         var fname = "";
-         this.mSourcePath = url.prePath;
-         try {
-             url = url.QueryInterface( Components.interfaces.nsIURL );
-             // A url, use file name from it.
-             fname = url.fileName;
-             this.mSourcePath += url.directory;
-         } catch (ex) {
-             // A generic uri, use path.
-             fname = url.path;
-             this.mSourcePath += url.path;
-         }
-
-         if (suggestedFileName)
-           fname = suggestedFileName;
-
-         this.mTitle = this.replaceInsert( this.mDialog.document.title, 1, fname);
-         this.mDialog.document.title = this.mTitle;
-
-         // Put content type, filename and location into intro.
-         this.initIntro(url, fname);
-
-         var iconString = "moz-icon://" + fname + "?size=32&contentType=" + this.mLauncher.MIMEInfo.MIMEType;
-
-         this.dialogElement("contentTypeImage").setAttribute("src", iconString);
-
-         this.initAppAndSaveToDiskValues();
-
-         // Initialize "always ask me" box. This should always be disabled
-         // and set to true for the ambiguous type application/octet-stream.
-         // Same if this dialog was forced due to a server request or type
-         // sniffing
-         var alwaysHandleCheckbox = this.dialogElement( "alwaysHandle" );
-         if (this.mReason != REASON_CANTHANDLE ||
-             this.mLauncher.MIMEInfo.MIMEType == "application/octet-stream"){
-            alwaysHandleCheckbox.checked = false;
-            alwaysHandleCheckbox.disabled = true;
-         }
-         else {
-            alwaysHandleCheckbox.checked = !this.mLauncher.MIMEInfo.alwaysAskBeforeHandling;
-         }
-
-         // Position it.
-         if ( this.mDialog.opener ) {
-             this.mDialog.moveToAlertPosition();
-         } else {
-             this.mDialog.sizeToContent();
-             this.mDialog.centerWindowOnScreen();
-         }
-
-         // Set initial focus
-         this.dialogElement( "mode" ).focus();
-
-         this.mDialog.document.documentElement.getButton("accept").disabled = true;
-         const nsITimer = Components.interfaces.nsITimer;
-         this._timer = Components.classes["@mozilla.org/timer;1"]
-                                 .createInstance(nsITimer);
-         this._timer.initWithCallback(this, 250, nsITimer.TYPE_ONE_SHOT);
-    },
-
-    // initIntro:
-    initIntro: function(url, filename) {
-        var intro = this.dialogElement( "intro" );
-        var desc = this.mLauncher.MIMEInfo.description;
-
-        var text;
-        if ( this.mReason == REASON_CANTHANDLE )
-          text = "intro.";
-        else if (this.mReason == REASON_SERVERREQUEST )
-          text = "intro.attachment.";
-        else if (this.mReason == REASON_TYPESNIFFED )
-          text = "intro.sniffed.";
-
-        var modified;
-        if (desc)
-          modified = this.replaceInsert( this.getString( text + "label" ), 1, desc );
-        else
-          modified = this.getString( text + "noDesc.label" );
-
-        modified = this.replaceInsert( modified, 2, this.mLauncher.MIMEInfo.MIMEType );
-        modified = this.replaceInsert( modified, 3, filename);
-        modified = this.replaceInsert( modified, 4, this.getString( "brandShortName" ));
-
-        // if mSourcePath is a local file, then let's use the pretty path name instead of an ugly
-        // url...
-        var pathString = url.prePath;
-        try
-        {
-          var fileURL = url.QueryInterface(Components.interfaces.nsIFileURL);
-          if (fileURL)
-          {
-            var fileObject = fileURL.file;
-            if (fileObject)
-            {
-              var parentObject = fileObject.parent;
-              if (parentObject)
-              {
-                pathString = parentObject.path;
-              }
-            }
-          }
-        } catch(ex) {}
-
-
-        intro.firstChild.nodeValue = "";
-        intro.firstChild.nodeValue = modified;
-
-        // Set the location text, which is separate from the intro text so it can be cropped
-        var location = this.dialogElement( "location" );
-        location.value = pathString;
-        location.setAttribute( "tooltiptext", this.mSourcePath );
-    },
-
-    _timer: null,
-    notify: function (aTimer) {
-        try { // The user may have already canceled the dialog.
-          if (!this._blurred)
-            this.mDialog.document.documentElement.getButton('accept').disabled = false;
-        } catch (ex) {}
-        this._timer = null;
-    },
-
-    _blurred: false,
-    onBlur: function(aEvent) {
-        if (aEvent.target != this.mDialog.document)
-          return;
-
-        this._blurred = true;
-        this.mDialog.document.documentElement.getButton("accept").disabled = true;
-    },
-
-    onFocus: function(aEvent) {
-        if (aEvent.target != this.mDialog.document)
-          return;
-
-        this._blurred = false;
-        if (!this._timer) {
-          // Don't enable the button if the initial timer is running
-          var script = "document.documentElement.getButton('accept').disabled = false";
-          this.mDialog.setTimeout(script, 250);
-        }
-    },
-
-    // Returns true iff opening the default application makes sense.
-    openWithDefaultOK: function() {
-        var result;
-
-        // The checking is different on Windows...
-        if ( this.mDialog.navigator.platform.indexOf( "Win" ) != -1 ) {
-            // Windows presents some special cases.
-            // We need to prevent use of "system default" when the file is
-            // executable (so the user doesn't launch nasty programs downloaded
-            // from the web), and, enable use of "system default" if it isn't
-            // executable (because we will prompt the user for the default app
-            // in that case).
-
-            // Need to get temporary file and check for executable-ness.
-            var tmpFile = this.mLauncher.targetFile;
-
-            //  Default is Ok if the file isn't executable (and vice-versa).
-            result = !tmpFile.isExecutable();
-        } else {
-            // On other platforms, default is Ok if there is a default app.
-            // Note that nsIMIMEInfo providers need to ensure that this holds true
-            // on each platform.
-            result = this.mLauncher.MIMEInfo.hasDefaultHandler;
-        }
-        return result;
-    },
-
-    // Set "default" application description field.
-    initDefaultApp: function() {
-        // Use description, if we can get one.
-        var desc = this.mLauncher.MIMEInfo.defaultDescription;
-        if ( desc ) {
-            this.dialogElement( "useSystemDefault" ).label = this.replaceInsert( this.getString( "defaultApp" ), 1, desc );
-        }
-    },
-
-    // getPath:
-    getPath: function(file) {
-        if (this.mIsMac) {
-            return file.leafName || file.path;
-        }
-
-        return file.path;
-    },
-
-    // initAppAndSaveToDiskValues:
-    initAppAndSaveToDiskValues: function() {
-        // Fill in helper app info, if there is any.
-        try {
-            this.chosenApp =
-              this.mLauncher.MIMEInfo.preferredApplicationHandler
-                  .QueryInterface(Components.interfaces.nsILocalHandlerApp);
-        } catch (e) {
-            this.chosenApp = null;
-        }
-        // Initialize "default application" field.
-        this.initDefaultApp();
-
-        // Fill application name textbox.
-        if (this.chosenApp && this.chosenApp.executable &&
-            this.chosenApp.executable.path) {
-            this.dialogElement( "appPath" ).value = 
-              this.getPath(this.chosenApp.executable);
-        }
-
-        var useDefault = this.dialogElement( "useSystemDefault" );
-        if (this.mLauncher.MIMEInfo.preferredAction == this.nsIMIMEInfo.useSystemDefault &&
-            this.mReason != REASON_SERVERREQUEST) {
-            // Open (using system default).
-            useDefault.radioGroup.selectedItem = useDefault;
-        } else if (this.mLauncher.MIMEInfo.preferredAction == this.nsIMIMEInfo.useHelperApp &&
-                   this.mReason != REASON_SERVERREQUEST) {
-            // Open with given helper app.