Merge cvs-trunk-mirror -> mozilla-central
authorbenjamin@smedbergs.us
Mon, 10 Mar 2008 17:07:41 -0400
changeset 12851 eb6c4014c87751b4f48b0f52e5ae41b7427a253d
parent 12602 02bc7f0e0862d09a6e06967abf734b6b38c18324 (current diff)
parent 12850 1e10d63bcf39fefc58fb9ff1b8d71b7d0594dc69 (diff)
child 12886 8ea3defc129b1945fe111b0e7651f2c0aae7c11f
push idunknown
push userunknown
push dateunknown
milestone2.0a1pre
Merge cvs-trunk-mirror -> mozilla-central
client.mk
config/autoconf.mk.in
config/config.mk
configure.in
js/src/js.cpp
js/src/jsapi.cpp
js/src/jsarray.cpp
js/src/jsatom.cpp
js/src/jsdate.cpp
js/src/jsemit.cpp
js/src/jsexn.cpp
js/src/jsfun.cpp
js/src/jsgc.cpp
js/src/jsinterp.cpp
js/src/jsiter.cpp
js/src/jslock.cpp
js/src/jsmath.cpp
js/src/jsnum.cpp
js/src/jsobj.cpp
js/src/jsopcode.cpp
js/src/jsparse.cpp
js/src/jsregexp.cpp
js/src/jsscan.cpp
js/src/jsscript.cpp
js/src/jsstr.cpp
js/src/jsxml.cpp
toolkit/toolkit-makefiles.sh
--- a/Makefile.in
+++ b/Makefile.in
@@ -213,14 +213,19 @@ ifneq (,$(wildcard $(DIST)/bin/applicati
 BUILDID = $(shell $(PYTHON) $(srcdir)/config/printconfigsetting.py $(DIST)/bin/application.ini App BuildID)
 else
 BUILDID = $(shell $(PYTHON) $(srcdir)/config/printconfigsetting.py $(DIST)/bin/platform.ini Build BuildID)
 endif
 
 #XXX: this is a hack, since we don't want to clobber for MSVC
 # PGO support, but we can't do this test in client.mk
 ifneq ($(OS_ARCH)_$(GNU_CC), WINNT_)
+# No point in clobbering if PGO has been explicitly disabled.
+ifndef NO_PROFILE_GUIDED_OPTIMIZE
 maybe_clobber_profiledbuild: clobber_all
 else
 maybe_clobber_profiledbuild:
 endif
+else
+maybe_clobber_profiledbuild:
+endif
 
 .PHONY: maybe_clobber_profiledbuild
--- a/accessible/src/base/nsAccessibilityAtomList.h
+++ b/accessible/src/base/nsAccessibilityAtomList.h
@@ -111,16 +111,18 @@ ACCESSIBILITY_ATOM(h6, "h6")
 ACCESSIBILITY_ATOM(item, "item") // XForms
 ACCESSIBILITY_ATOM(itemset, "itemset") // XForms
 ACCESSIBILITY_ATOM(img, "img")
 ACCESSIBILITY_ATOM(input, "input")
 ACCESSIBILITY_ATOM(label, "label")
 ACCESSIBILITY_ATOM(legend, "legend")
 ACCESSIBILITY_ATOM(li, "li")
 ACCESSIBILITY_ATOM(link, "link")
+ACCESSIBILITY_ATOM(listcols, "listcols") // XUL
+ACCESSIBILITY_ATOM(listcol, "listcol") // XUL
 ACCESSIBILITY_ATOM(listhead, "listhead") // XUL
 ACCESSIBILITY_ATOM(listheader, "listheader") // XUL
 ACCESSIBILITY_ATOM(map, "map")
 ACCESSIBILITY_ATOM(math, "math")
 ACCESSIBILITY_ATOM(menu, "menu")    // XUL
 ACCESSIBILITY_ATOM(menupopup, "menupopup")     // XUL
 ACCESSIBILITY_ATOM(object, "object")
 ACCESSIBILITY_ATOM(ol, "ol")
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -67,16 +67,17 @@
 #include "nsIForm.h"
 #include "nsIFormControl.h"
 
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsIFrame.h"
 #include "nsIViewManager.h"
 #include "nsIDocShellTreeItem.h"
+#include "nsIScrollableFrame.h"
 
 #include "nsXPIDLString.h"
 #include "nsUnicharUtils.h"
 #include "nsReadableUtils.h"
 #include "prdtoa.h"
 #include "nsIAtom.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
@@ -2666,16 +2667,31 @@ NS_IMETHODIMP nsAccessible::GetAccessibl
     {
       relatedNode =
         do_QueryInterface(nsAccUtils::FindNeighbourPointingToNode(content, nsAccessibilityAtoms::aria_owns));
       if (!relatedNode && mRoleMapEntry && mRoleMapEntry->role == nsIAccessibleRole::ROLE_OUTLINEITEM) {
         // This is an ARIA tree that doesn't use owns, so we need to get the parent the hard way
         nsAccUtils::GetARIATreeItemParent(this, content, aRelated);
         return NS_OK;
       }
+      // If accessible is in its own Window then we should provide NODE_CHILD_OF relation
+      // so that MSAA clients can easily get to true parent instead of getting to oleacc's
+      // ROLE_WINDOW accessible which will prevent us from going up further (because it is
+      // system generated and has no idea about the hierarchy above it).
+      nsIFrame *frame = GetFrame();
+      if (frame) {
+        nsIView *view = frame->GetViewExternal();
+        if (view) {
+          nsIScrollableFrame *scrollFrame = nsnull;
+          CallQueryInterface(frame, &scrollFrame);
+          if (scrollFrame || view->GetWidget()) {
+            return GetParent(aRelated);
+          }
+        }
+      }
       break;
     }
   case nsIAccessibleRelation::RELATION_CONTROLLED_BY:
     {
       relatedNode =
         do_QueryInterface(nsAccUtils::FindNeighbourPointingToNode(content, nsAccessibilityAtoms::aria_controls));
       break;
     }
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -137,18 +137,18 @@ public:
    */
   PRUint32 GetARIAState();
 
 #ifdef DEBUG_A11Y
   static PRBool IsTextInterfaceSupportCorrect(nsIAccessible *aAccessible);
 #endif
 
   static PRBool IsCorrectFrameType(nsIFrame* aFrame, nsIAtom* aAtom);
-  static PRUint32 State(nsIAccessible *aAcc) { PRUint32 state; aAcc->GetFinalState(&state, nsnull); return state; }
-  static PRUint32 Role(nsIAccessible *aAcc) { PRUint32 role; aAcc->GetFinalRole(&role); return role; }
+  static PRUint32 State(nsIAccessible *aAcc) { PRUint32 state = 0; if (aAcc) aAcc->GetFinalState(&state, nsnull); return state; }
+  static PRUint32 Role(nsIAccessible *aAcc) { PRUint32 role = nsIAccessibleRole::ROLE_NOTHING; if (aAcc) aAcc->GetFinalRole(&role); return role; }
   static PRBool IsText(nsIAccessible *aAcc) { PRUint32 role = Role(aAcc); return role == nsIAccessibleRole::ROLE_TEXT_LEAF || role == nsIAccessibleRole::ROLE_STATICTEXT; }
   static PRBool IsEmbeddedObject(nsIAccessible *aAcc) { PRUint32 role = Role(aAcc); return role != nsIAccessibleRole::ROLE_TEXT_LEAF && role != nsIAccessibleRole::ROLE_WHITESPACE && role != nsIAccessibleRole::ROLE_STATICTEXT; }
   static PRInt32 TextLength(nsIAccessible *aAccessible); // Returns -1 on failure
   static PRBool IsLeaf(nsIAccessible *aAcc) { PRInt32 numChildren; aAcc->GetChildCount(&numChildren); return numChildren > 0; }
   static PRBool IsNodeRelevant(nsIDOMNode *aNode); // Is node something that could have an attached accessible
   /**
    * When exposing to platform accessibility APIs, should the children be pruned off?
    */
--- a/accessible/src/base/nsRootAccessible.cpp
+++ b/accessible/src/base/nsRootAccessible.cpp
@@ -458,31 +458,35 @@ PRBool nsRootAccessible::FireAccessibleF
         return PR_FALSE;
       }
       nsCOMPtr<nsIDOMElement> relatedEl;
       domDoc->GetElementById(id, getter_AddRefs(relatedEl));
       finalFocusNode = do_QueryInterface(relatedEl);
       if (!finalFocusNode) {
         return PR_FALSE;
       }
-      GetAccService()->GetAccessibleFor(finalFocusNode, getter_AddRefs(finalFocusAccessible));      
-      // For activedescendant, the ARIA spec does not require that the user agent
-      // checks whether finalFocusNode is actually a descendant of the element with
-      // the activedescendant attribute.
-      if (!finalFocusAccessible) {
-        return PR_FALSE;
-      }
+      finalFocusAccessible = nsnull;
     }
   }
 
   // Fire focus only if it changes, but always fire focus events when aForceEvent == PR_TRUE
   if (gLastFocusedNode == finalFocusNode && !aForceEvent) {
     return PR_FALSE;
   }
 
+  if (!finalFocusAccessible) {
+    GetAccService()->GetAccessibleFor(finalFocusNode, getter_AddRefs(finalFocusAccessible));      
+    // For activedescendant, the ARIA spec does not require that the user agent
+    // checks whether finalFocusNode is actually a descendant of the element with
+    // the activedescendant attribute.
+    if (!finalFocusAccessible) {
+      return PR_FALSE;
+    }
+  }
+
   gLastFocusedAccessiblesState = State(finalFocusAccessible);
   PRUint32 role = Role(finalFocusAccessible);
   if (role == nsIAccessibleRole::ROLE_MENUITEM) {
     if (!mCurrentARIAMenubar) {  // Entering menus
       PRUint32 naturalRole; // The natural role is the role that this type of element normally has
       finalFocusAccessible->GetRole(&naturalRole);
       if (role != naturalRole) { // Must be a DHTML menuitem
         nsCOMPtr<nsIAccessible> menuBarAccessible =
@@ -840,45 +844,45 @@ nsresult nsRootAccessible::HandleEventWi
   }
   else if (eventType.EqualsLiteral("DOMMenuInactive")) {
     if (Role(accessible) == nsIAccessibleRole::ROLE_MENUPOPUP) {
       nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END,
                                accessible);
     }
   }
   else if (eventType.EqualsLiteral("DOMMenuItemActive")) {
-    PRBool fireFocus = PR_FALSE;
+    PRBool fireFocus = PR_FALSE;
     if (!treeItemAccessible) {
 #ifdef MOZ_XUL
       if (isTree) {
         return NS_OK; // Tree with nothing selected
       }
 #endif
       nsCOMPtr<nsPIAccessNode> menuAccessNode = do_QueryInterface(accessible);
       NS_ENSURE_TRUE(menuAccessNode, NS_ERROR_FAILURE);
       nsIFrame* menuFrame = menuAccessNode->GetFrame();
       NS_ENSURE_TRUE(menuFrame, NS_ERROR_FAILURE);
       nsIMenuFrame* imenuFrame;
       CallQueryInterface(menuFrame, &imenuFrame);
-      if (imenuFrame)
-        fireFocus = PR_TRUE;
+      if (imenuFrame)
+        fireFocus = PR_TRUE;
       // QI failed for nsIMenuFrame means it's not on menu bar
       if (imenuFrame && imenuFrame->IsOnMenuBar() &&
                        !imenuFrame->IsOnActiveMenuBar()) {
         // It is a top level menuitem. Only fire a focus event when the menu bar
         // is active.
         return NS_OK;
       } else {
         nsCOMPtr<nsIAccessible> containerAccessible;
         accessible->GetParent(getter_AddRefs(containerAccessible));
         NS_ENSURE_TRUE(containerAccessible, NS_ERROR_FAILURE);
         // It is not top level menuitem
         // Only fire focus event if it is not inside collapsed popup
         // and not a listitem of a combo box
-        if (State(containerAccessible) & nsIAccessibleStates::STATE_COLLAPSED) {
+        if (State(containerAccessible) & nsIAccessibleStates::STATE_COLLAPSED) {
           nsCOMPtr<nsIAccessible> containerParent;
           containerAccessible->GetParent(getter_AddRefs(containerParent));
           NS_ENSURE_TRUE(containerParent, NS_ERROR_FAILURE);
           if (Role(containerParent) != nsIAccessibleRole::ROLE_COMBOBOX) {
             return NS_OK;
           }
         }
       }
@@ -888,26 +892,26 @@ nsresult nsRootAccessible::HandleEventWi
       nsCOMPtr<nsIContent> realFocusedContent = do_QueryInterface(realFocusedNode);
       nsCOMPtr<nsIContent> targetContent = do_QueryInterface(aTargetNode);
       nsIContent *containerContent = targetContent;
       while (containerContent) {
         nsCOMPtr<nsIDOMXULPopupElement> popup = do_QueryInterface(containerContent);
         if (popup || containerContent == realFocusedContent) { 
           // If we're inside the focus or a popup we can fire focus events
           // for the changed active item
-          fireFocus = PR_TRUE;
-          break;
+          fireFocus = PR_TRUE;
+          break;
         }
         containerContent = containerContent->GetParent();
       }
     }
-    if (fireFocus) {
-      nsAccEvent::PrepareForEvent(aTargetNode, PR_TRUE);  // Always asynch, always from user input
-      FireAccessibleFocusEvent(accessible, aTargetNode, aEvent, PR_TRUE, PR_TRUE);
-    }
+    if (fireFocus) {
+      nsAccEvent::PrepareForEvent(aTargetNode, PR_TRUE);  // Always asynch, always from user input
+      FireAccessibleFocusEvent(accessible, aTargetNode, aEvent, PR_TRUE, PR_TRUE);
+    }
   }
   else if (eventType.EqualsLiteral("DOMMenuBarActive")) {  // Always asynch, always from user input
     nsAccEvent::PrepareForEvent(aTargetNode, PR_TRUE);
     nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENU_START, accessible, PR_TRUE);
   }
   else if (eventType.EqualsLiteral("DOMMenuBarInactive")) {  // Always asynch, always from user input
     nsAccEvent::PrepareForEvent(aTargetNode, PR_TRUE);
     nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_MENU_END, accessible, PR_TRUE);
--- a/accessible/src/html/nsHTMLAreaAccessible.cpp
+++ b/accessible/src/html/nsHTMLAreaAccessible.cpp
@@ -48,16 +48,20 @@
 
 // --- area -----
 
 nsHTMLAreaAccessible::nsHTMLAreaAccessible(nsIDOMNode *aDomNode, nsIAccessible *aParent, nsIWeakReference* aShell):
 nsLinkableAccessible(aDomNode, aShell)
 { 
 }
 
+// Expose nsIAccessibleHyperLink unconditionally
+NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLAreaAccessible, nsLinkableAccessible,
+                             nsIAccessibleHyperLink)
+
 /* wstring getName (); */
 NS_IMETHODIMP nsHTMLAreaAccessible::GetName(nsAString & aName)
 {
   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
   if (!content) {
     return NS_ERROR_FAILURE;
   }
 
--- a/accessible/src/html/nsHTMLAreaAccessible.h
+++ b/accessible/src/html/nsHTMLAreaAccessible.h
@@ -43,17 +43,22 @@
 
 /* Accessible for image map areas - must be child of image
  */
 
 class nsHTMLAreaAccessible : public nsLinkableAccessible
 {
 
 public:
-  nsHTMLAreaAccessible(nsIDOMNode *domNode, nsIAccessible *accParent, nsIWeakReference* aShell);
+  nsHTMLAreaAccessible(nsIDOMNode *domNode, nsIAccessible *accParent,
+                       nsIWeakReference* aShell);
+
+  NS_DECL_ISUPPORTS_INHERITED
+
+  // nsIAccessible
   NS_IMETHOD GetName(nsAString & _retval); 
   NS_IMETHOD GetRole(PRUint32 *_retval); 
   NS_IMETHOD GetFirstChild(nsIAccessible **_retval);
   NS_IMETHOD GetLastChild(nsIAccessible **_retval);
   NS_IMETHOD GetChildCount(PRInt32 *_retval);
   NS_IMETHOD GetDescription(nsAString& _retval);
   NS_IMETHOD GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height);
   NS_IMETHOD GetChildAtPoint(PRInt32 aX, PRInt32 aY, nsIAccessible **aAccessible)
--- a/accessible/src/html/nsHTMLImageAccessible.cpp
+++ b/accessible/src/html/nsHTMLImageAccessible.cpp
@@ -42,26 +42,30 @@
 #include "nsHTMLImageAccessible.h"
 #include "nsAccessibilityAtoms.h"
 #include "nsHTMLAreaAccessible.h"
 
 #include "nsIDOMHTMLCollection.h"
 #include "nsIDocument.h"
 #include "nsIHTMLDocument.h"
 #include "nsIImageLoadingContent.h"
+#include "nsILink.h"
 #include "nsIPresShell.h"
 #include "nsIServiceManager.h"
 #include "nsIDOMHTMLImageElement.h"
 #include "nsIDOMDocument.h"
 #include "nsPIDOMWindow.h"
 
 // --- image -----
 
 const PRUint32 kDefaultImageCacheSize = 256;
 
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLImageAccessible
+
 nsHTMLImageAccessible::nsHTMLImageAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell):
 nsLinkableAccessible(aDOMNode, aShell), mAccessNodeCache(nsnull)
 { 
   nsCOMPtr<nsIDOMElement> element(do_QueryInterface(aDOMNode));
   nsCOMPtr<nsIPresShell> shell(do_QueryReferent(mWeakShell));
   if (!shell)
     return;
 
@@ -79,17 +83,21 @@ nsLinkableAccessible(aDOMNode, aShell), 
   }
 
   if (mMapElement) {
     mAccessNodeCache = new nsAccessNodeHashtable();
     mAccessNodeCache->Init(kDefaultImageCacheSize);
   }
 }
 
-NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLImageAccessible, nsAccessible, nsIAccessibleImage)
+NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLImageAccessible, nsAccessible,
+                             nsIAccessibleImage)
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIAccessible
 
 NS_IMETHODIMP
 nsHTMLImageAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
 {
   // The state is a bitfield, get our inherited state, then logically OR it with
   // STATE_ANIMATED if this is an animated image.
 
   nsresult rv = nsLinkableAccessible::GetState(aState, aExtraState);
@@ -146,89 +154,41 @@ NS_IMETHODIMP nsHTMLImageAccessible::Get
 /* wstring getRole (); */
 NS_IMETHODIMP nsHTMLImageAccessible::GetRole(PRUint32 *_retval)
 {
   *_retval = mMapElement ? nsIAccessibleRole::ROLE_IMAGE_MAP :
                            nsIAccessibleRole::ROLE_GRAPHIC;
   return NS_OK;
 }
 
-
-already_AddRefed<nsIAccessible>
-nsHTMLImageAccessible::GetAreaAccessible(PRInt32 aAreaNum)
-{
-  if (!mMapElement)
-    return nsnull;
-
-  nsCOMPtr<nsIDOMHTMLCollection> mapAreas;
-  mMapElement->GetAreas(getter_AddRefs(mapAreas));
-  if (!mapAreas)
-    return nsnull;
-
-  nsCOMPtr<nsIDOMNode> domNode;
-  mapAreas->Item(aAreaNum,getter_AddRefs(domNode));
-  if (!domNode)
-    return nsnull;
-
-  nsCOMPtr<nsIAccessNode> accessNode;
-  GetCacheEntry(*mAccessNodeCache, (void*)(aAreaNum),
-                getter_AddRefs(accessNode));
-
-  if (!accessNode) {
-    accessNode = new nsHTMLAreaAccessible(domNode, this, mWeakShell);
-    if (!accessNode)
-      return nsnull;
-
-    nsCOMPtr<nsPIAccessNode> privateAccessNode(do_QueryInterface(accessNode));
-    NS_ASSERTION(privateAccessNode,
-                 "Accessible doesn't implement nsPIAccessNode");
-
-    nsresult rv = privateAccessNode->Init();
-    if (NS_FAILED(rv))
-      return nsnull;
-
-    PutCacheEntry(*mAccessNodeCache, (void*)(aAreaNum), accessNode);
-  }
-
-  nsCOMPtr<nsIAccessible> accessible(do_QueryInterface(accessNode));
-  nsIAccessible *accPtr;
-  NS_IF_ADDREF(accPtr = accessible);
-  return accPtr;
-}
-
-
 void nsHTMLImageAccessible::CacheChildren()
 {
   if (!mWeakShell) {
     // This node has been shut down
     mAccChildCount = eChildCountUninitialized;
     return;
   }
 
   if (mAccChildCount != eChildCountUninitialized) {
     return;
   }
 
   mAccChildCount = 0;
-  nsCOMPtr<nsIDOMHTMLCollection> mapAreas;
-  if (mMapElement) {
-    mMapElement->GetAreas(getter_AddRefs(mapAreas));
-  }
-  if (!mapAreas) {
+  nsCOMPtr<nsIDOMHTMLCollection> mapAreas = GetAreaCollection();
+  if (!mapAreas)
     return;
-  }
 
   PRUint32 numMapAreas;
   mapAreas->GetLength(&numMapAreas);
   PRInt32 childCount = 0;
   
   nsCOMPtr<nsIAccessible> areaAccessible;
   nsCOMPtr<nsPIAccessible> privatePrevAccessible;
   while (childCount < (PRInt32)numMapAreas && 
-         (areaAccessible = GetAreaAccessible(childCount)) != nsnull) {
+         (areaAccessible = GetAreaAccessible(mapAreas, childCount)) != nsnull) {
     if (privatePrevAccessible) {
       privatePrevAccessible->SetNextSibling(areaAccessible);
     }
     else {
       SetFirstChild(areaAccessible);
     }
 
     ++ childCount;
@@ -258,16 +218,76 @@ NS_IMETHODIMP nsHTMLImageAccessible::DoA
     NS_ENSURE_TRUE(win, NS_ERROR_FAILURE);
     nsCOMPtr<nsIDOMWindow> tmp;
     return win->Open(longDesc, NS_LITERAL_STRING(""), NS_LITERAL_STRING(""),
                      getter_AddRefs(tmp));
   }
   return nsLinkableAccessible::DoAction(index);
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// nsIAccessibleHyperLink
+NS_IMETHODIMP
+nsHTMLImageAccessible::GetAnchors(PRInt32 *aAnchors)
+{
+  NS_ENSURE_ARG_POINTER(aAnchors);
+
+  if (!mMapElement)
+    return nsLinkableAccessible::GetAnchors(aAnchors);
+
+  return GetChildCount(aAnchors);
+}
+
+NS_IMETHODIMP
+nsHTMLImageAccessible::GetURI(PRInt32 aIndex, nsIURI **aURI)
+{
+  NS_ENSURE_ARG_POINTER(aURI);
+  *aURI = nsnull;
+
+  if (!mMapElement)
+    return nsLinkableAccessible::GetURI(aIndex, aURI);
+
+  nsCOMPtr<nsIDOMHTMLCollection> mapAreas = GetAreaCollection();
+  if (!mapAreas)
+    return NS_OK;
+  
+  nsCOMPtr<nsIDOMNode> domNode;
+  mapAreas->Item(aIndex, getter_AddRefs(domNode));
+  if (!domNode)
+    return NS_ERROR_INVALID_ARG;
+
+  nsCOMPtr<nsILink> link(do_QueryInterface(domNode));
+  if (link)
+    link->GetHrefURI(aURI);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHTMLImageAccessible::GetObject(PRInt32 aIndex, nsIAccessible **aAccessible)
+{
+  NS_ENSURE_ARG_POINTER(aAccessible);
+  *aAccessible = nsnull;
+
+  if (!mMapElement)
+    return nsLinkableAccessible::GetObject(aIndex, aAccessible);
+
+  nsCOMPtr<nsIDOMHTMLCollection> mapAreas = GetAreaCollection();
+  if (mapAreas) {
+    nsCOMPtr<nsIAccessible> accessible;
+    accessible = GetAreaAccessible(mapAreas, aIndex);
+    NS_IF_ADDREF(*aAccessible = accessible);
+  }
+
+  return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// nsIAccessibleImage
+
 NS_IMETHODIMP
 nsHTMLImageAccessible::GetImagePosition(PRUint32 aCoordType,
                                         PRInt32 *aX, PRInt32 *aY)
 {
   PRInt32 width, height;
   nsresult rv = GetBounds(aX, aY, &width, &height);
   if (NS_FAILED(rv))
     return rv;
@@ -277,22 +297,79 @@ nsHTMLImageAccessible::GetImagePosition(
 
 NS_IMETHODIMP
 nsHTMLImageAccessible::GetImageSize(PRInt32 *aWidth, PRInt32 *aHeight)
 {
   PRInt32 x, y;
   return GetBounds(&x, &y, aWidth, aHeight);
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// nsPIAccessNode
+
 NS_IMETHODIMP
 nsHTMLImageAccessible::Shutdown()
 {
   nsLinkableAccessible::Shutdown();
 
   if (mAccessNodeCache) {
     ClearCache(*mAccessNodeCache);
     delete mAccessNodeCache;
     mAccessNodeCache = nsnull;
   }
 
   return NS_OK;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// nsHTMLImageAccessible
+
+already_AddRefed<nsIDOMHTMLCollection>
+nsHTMLImageAccessible::GetAreaCollection()
+{
+  if (!mMapElement)
+    return nsnull;
+
+  nsIDOMHTMLCollection *mapAreas = nsnull;
+  nsresult rv = mMapElement->GetAreas(&mapAreas);
+  if (NS_FAILED(rv))
+    return nsnull;
+
+  return mapAreas;
+}
+
+already_AddRefed<nsIAccessible>
+nsHTMLImageAccessible::GetAreaAccessible(nsIDOMHTMLCollection *aAreaCollection,
+                                         PRInt32 aAreaNum)
+{
+  if (!aAreaCollection)
+    return nsnull;
+
+  nsCOMPtr<nsIDOMNode> domNode;
+  aAreaCollection->Item(aAreaNum,getter_AddRefs(domNode));
+  if (!domNode)
+    return nsnull;
+  
+  nsCOMPtr<nsIAccessNode> accessNode;
+  GetCacheEntry(*mAccessNodeCache, (void*)(aAreaNum),
+                getter_AddRefs(accessNode));
+  
+  if (!accessNode) {
+    accessNode = new nsHTMLAreaAccessible(domNode, this, mWeakShell);
+    if (!accessNode)
+      return nsnull;
+    
+    nsCOMPtr<nsPIAccessNode> privateAccessNode(do_QueryInterface(accessNode));
+    NS_ASSERTION(privateAccessNode,
+                 "Accessible doesn't implement nsPIAccessNode");
+    
+    nsresult rv = privateAccessNode->Init();
+    if (NS_FAILED(rv))
+      return nsnull;
+    
+    PutCacheEntry(*mAccessNodeCache, (void*)(aAreaNum), accessNode);
+  }
+
+  nsIAccessible *accessible = nsnull;
+  CallQueryInterface(accessNode, &accessible);
+
+  return accessible;
+}
--- a/accessible/src/html/nsHTMLImageAccessible.h
+++ b/accessible/src/html/nsHTMLImageAccessible.h
@@ -61,25 +61,36 @@ public:
   nsHTMLImageAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
 
   // nsIAccessible
   NS_IMETHOD GetName(nsAString& _retval); 
   NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetRole(PRUint32 *_retval);
   NS_IMETHOD DoAction(PRUint8 index);
 
+  // nsIAccessibleHyperLink
+  NS_IMETHOD GetAnchors(PRInt32 *aAnchors);
+  NS_IMETHOD GetURI(PRInt32 aIndex, nsIURI **aURI);
+  NS_IMETHOD GetObject(PRInt32 aIndex, nsIAccessible **aAccessible);
+
   // nsPIAccessNode
   NS_IMETHOD Shutdown();
 
   // nsIAccessibleImage
   NS_DECL_NSIACCESSIBLEIMAGE
 
 protected:
+  // nsAccessible
   virtual void CacheChildren();
-  already_AddRefed<nsIAccessible> GetAreaAccessible(PRInt32 aAreaNum);
+
+  already_AddRefed<nsIDOMHTMLCollection> GetAreaCollection();
+  already_AddRefed<nsIAccessible>
+    GetAreaAccessible(nsIDOMHTMLCollection* aAreaNodes, PRInt32 aAreaNum);
+
+  // Reference on linked map element if any.
   nsCOMPtr<nsIDOMHTMLMapElement> mMapElement;
 
   // Cache of area accessibles. We do not use common cache because images can
   // share area elements but we need to have separate area accessibles for
   // each image accessible.
   nsAccessNodeHashtable *mAccessNodeCache;
 };
 
--- a/accessible/src/html/nsHTMLTableAccessible.cpp
+++ b/accessible/src/html/nsHTMLTableAccessible.cpp
@@ -53,16 +53,17 @@
 #include "nsIDOMHTMLTableElement.h"
 #include "nsIDOMHTMLTableRowElement.h"
 #include "nsIDOMHTMLTableSectionElem.h"
 #include "nsIDocument.h"
 #include "nsIPresShell.h"
 #include "nsIServiceManager.h"
 #include "nsITableLayout.h"
 #include "nsITableCellLayout.h"
+#include "nsLayoutErrors.h"
 
 
 NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLTableCellAccessible, nsHyperTextAccessible)
 
 nsHTMLTableCellAccessible::nsHTMLTableCellAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell):
 nsHyperTextAccessibleWrap(aDomNode, aShell)
 { 
 }
@@ -657,33 +658,40 @@ nsHTMLTableAccessible::IsRowSelected(PRI
     }
   }
 
   return rv;
 }
 
 NS_IMETHODIMP
 nsHTMLTableAccessible::IsCellSelected(PRInt32 aRow, PRInt32 aColumn,
-                                      PRBool *_retval)
+                                      PRBool *aIsSelected)
 {
-  NS_ENSURE_TRUE(IsValidRow(aRow) && IsValidColumn(aColumn), NS_ERROR_INVALID_ARG);
+  NS_ENSURE_ARG_POINTER(aIsSelected);
+  *aIsSelected = PR_FALSE;
 
-  nsITableLayout *tableLayout;
+  NS_ENSURE_TRUE(IsValidRow(aRow) && IsValidColumn(aColumn),
+                 NS_ERROR_INVALID_ARG);
+
+  nsITableLayout *tableLayout = nsnull;
   nsresult rv = GetTableLayout(&tableLayout);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIDOMElement> domElement;
   PRInt32 startRowIndex = 0, startColIndex = 0,
           rowSpan, colSpan, actualRowSpan, actualColSpan;
 
-  return tableLayout->GetCellDataAt(aRow, aColumn,
-                                    *getter_AddRefs(domElement),
-                                    startRowIndex, startColIndex, rowSpan,
-                                    colSpan, actualRowSpan, actualColSpan,
-                                    *_retval);
+  rv = tableLayout->GetCellDataAt(aRow, aColumn, *getter_AddRefs(domElement),
+                                  startRowIndex, startColIndex,
+                                  rowSpan, colSpan,
+                                  actualRowSpan, actualColSpan, *aIsSelected);
+
+  if (rv == NS_TABLELAYOUT_CELL_NOT_FOUND)
+    return NS_ERROR_INVALID_ARG;
+  return rv;
 }
 
 PRBool
 nsHTMLTableAccessible::IsValidColumn(PRInt32 aColumn)
 {
   PRInt32 colCount = 0;
   nsresult rv = GetColumns(&colCount);
   return NS_SUCCEEDED(rv) && (aColumn >= 0) && (aColumn < colCount);
@@ -862,25 +870,28 @@ nsresult
 nsHTMLTableAccessible::GetCellAt(PRInt32        aRowIndex,
                                  PRInt32        aColIndex,
                                  nsIDOMElement* &aCell)
 {
   PRInt32 startRowIndex = 0, startColIndex = 0,
           rowSpan, colSpan, actualRowSpan, actualColSpan;
   PRBool isSelected;
 
-  nsITableLayout *tableLayout;
+  nsITableLayout *tableLayout = nsnull;
   nsresult rv = GetTableLayout(&tableLayout);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  return tableLayout->GetCellDataAt(aRowIndex, aColIndex, aCell,
-                                    startRowIndex, startColIndex,
-                                    rowSpan, colSpan,
-                                    actualRowSpan, actualColSpan,
-                                    isSelected);
+  rv = tableLayout->GetCellDataAt(aRowIndex, aColIndex, aCell,
+                                  startRowIndex, startColIndex,
+                                  rowSpan, colSpan,
+                                  actualRowSpan, actualColSpan, isSelected);
+
+  if (rv == NS_TABLELAYOUT_CELL_NOT_FOUND)
+    return NS_ERROR_INVALID_ARG;
+  return rv;
 }
 
 NS_IMETHODIMP nsHTMLTableAccessible::GetDescription(nsAString& aDescription)
 {
   // Helpful for debugging layout vs. data tables
   aDescription.Truncate();
   nsAccessible::GetDescription(aDescription);
   if (!aDescription.IsEmpty()) {
@@ -1025,17 +1036,19 @@ NS_IMETHODIMP nsHTMLTableAccessible::IsP
   if (columns >= 5) {
     RETURN_LAYOUT_ANSWER(PR_FALSE, ">=5 columns");
   }
   
   // Now we know there are 2-4 columns and 2 or more rows
   // Check to see if there are visible borders on the cells
   // XXX currently, we just check the first cell -- do we really need to do more?
   nsCOMPtr<nsIDOMElement> cellElement;
-  GetCellAt(0, 0, *getter_AddRefs(cellElement));
+  nsresult rv = GetCellAt(0, 0, *getter_AddRefs(cellElement));
+  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
+
   nsCOMPtr<nsIContent> cellContent(do_QueryInterface(cellElement));
   NS_ENSURE_TRUE(cellContent, NS_ERROR_FAILURE);
   nsCOMPtr<nsIPresShell> shell(GetPresShell());
   nsIFrame *cellFrame = shell->GetPrimaryFrameFor(cellContent);
   if (!cellFrame) {
     return NS_OK;
   }
   nsMargin border;
--- a/accessible/src/msaa/CAccessibleAction.cpp
+++ b/accessible/src/msaa/CAccessibleAction.cpp
@@ -172,35 +172,33 @@ CAccessibleAction::get_keyBinding(long a
 
   return S_OK;
 }
 
 STDMETHODIMP
 CAccessibleAction::get_name(long aActionIndex, BSTR *aName)
 {
 __try {
-  *aName = NULL;
-
   nsCOMPtr<nsIAccessible> acc(do_QueryInterface(this));
   if (!acc)
     return E_FAIL;
 
   nsAutoString name;
   PRUint8 index = static_cast<PRUint8>(aActionIndex);
   if (NS_FAILED(acc->GetActionName(index, name)))
     return E_FAIL;
 
-  if (!name.IsVoid()) {
-    INT result = ::SysReAllocStringLen(aName, name.get(), name.Length());
-    if (!result)
-      return E_OUTOFMEMORY;
-  }
+  INT result = ::SysReAllocStringLen(aName, name.get(), name.Length());
+  if (!result)
+    return E_OUTOFMEMORY;
+
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
 
   return S_OK;
 }
 
 STDMETHODIMP
 CAccessibleAction::get_localizedName(long aActionIndex, BSTR *aLocalizedName)
 {
+  ::SysFreeString(*aLocalizedName);
   return E_NOTIMPL;
 }
 
--- a/accessible/src/msaa/CAccessibleTable.cpp
+++ b/accessible/src/msaa/CAccessibleTable.cpp
@@ -155,30 +155,29 @@ CAccessibleTable::get_childIndex(long aR
 
   return E_FAIL;
 }
 
 STDMETHODIMP
 CAccessibleTable::get_columnDescription(long aColumn, BSTR *aDescription)
 {
 __try {
-  *aDescription = NULL;
-
   nsCOMPtr<nsIAccessibleTable> tableAcc(do_QueryInterface(this));
   NS_ASSERTION(tableAcc, CANT_QUERY_ASSERTION_MSG);
   if (!tableAcc)
     return E_FAIL;
 
   nsAutoString descr;
   nsresult rv = tableAcc->GetColumnDescription (aColumn, descr);
   if (NS_FAILED(rv))
     return E_FAIL;
 
   if (!::SysReAllocStringLen(aDescription, descr.get(), descr.Length()))
     return E_OUTOFMEMORY;
+
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 STDMETHODIMP
 CAccessibleTable::get_columnExtentAt(long aRow, long aColumn,
                                      long *nColumnsSpanned)
 {
@@ -366,30 +365,29 @@ CAccessibleTable::get_nSelectedRows(long
 
   return E_FAIL;
 }
 
 STDMETHODIMP
 CAccessibleTable::get_rowDescription(long aRow, BSTR *aDescription)
 {
 __try {
-  *aDescription = NULL;
-
   nsCOMPtr<nsIAccessibleTable> tableAcc(do_QueryInterface(this));
   NS_ASSERTION(tableAcc, CANT_QUERY_ASSERTION_MSG);
   if (!tableAcc)
     return E_FAIL;
 
   nsAutoString descr;
   nsresult rv = tableAcc->GetRowDescription (aRow, descr);
   if (NS_FAILED(rv))
     return E_FAIL;
 
   if (!::SysReAllocStringLen(aDescription, descr.get(), descr.Length()))
     return E_OUTOFMEMORY;
+
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 STDMETHODIMP
 CAccessibleTable::get_rowExtentAt(long aRow, long aColumn, long *aNRowsSpanned)
 {
 __try {
@@ -731,18 +729,22 @@ CAccessibleTable::GetSelectedItems(long 
   }
 
   if (NS_FAILED(rv))
     return E_FAIL;
 
   if (size == 0 || !items)
     return S_OK;
 
-  PRUint32 maxSize = size < (PRUint32)aMaxItems ? size : aMaxItems;
+  PRUint32 maxSize = size < static_cast<PRUint32>(aMaxItems) ? size : aMaxItems;
   *aItemsCount = maxSize;
 
+  *aItems = static_cast<long*>(nsMemory::Alloc((maxSize) * sizeof(long)));
+  if (!*aItems)
+    return E_OUTOFMEMORY;
+
   for (PRUint32 index = 0; index < maxSize; ++index)
     (*aItems)[index] = items[index];
 
   nsMemory::Free(items);
   return S_OK;
 }
 
--- a/accessible/src/msaa/nsAccessibleRelationWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleRelationWrap.cpp
@@ -81,83 +81,84 @@ nsAccessibleRelationWrap::QueryInterface
 }
 
 // IAccessibleRelation
 
 STDMETHODIMP
 nsAccessibleRelationWrap::get_relationType(BSTR *aRelationType)
 {
 __try {
-  *aRelationType = NULL;
-
   PRUint32 type = 0;
   nsresult rv = GetRelationType(&type);
   if (NS_FAILED(rv))
     return E_FAIL;
 
+  INT res;
   switch (type) {
     case RELATION_CONTROLLED_BY:
-      *aRelationType = ::SysAllocString(IA2_RELATION_CONTROLLED_BY);
+      res = ::SysReAllocString(aRelationType, IA2_RELATION_CONTROLLED_BY);
       break;
     case RELATION_CONTROLLER_FOR:
-      *aRelationType = ::SysAllocString(IA2_RELATION_CONTROLLER_FOR);
+      res = ::SysReAllocString(aRelationType, IA2_RELATION_CONTROLLER_FOR);
       break;
     case RELATION_DESCRIBED_BY:
-      *aRelationType = ::SysAllocString(IA2_RELATION_DESCRIBED_BY);
+      res = ::SysReAllocString(aRelationType, IA2_RELATION_DESCRIBED_BY);
       break;
     case RELATION_DESCRIPTION_FOR:
-      *aRelationType = ::SysAllocString(IA2_RELATION_DESCRIPTION_FOR);
+      res = ::SysReAllocString(aRelationType, IA2_RELATION_DESCRIPTION_FOR);
       break;
     case RELATION_EMBEDDED_BY:
-      *aRelationType = ::SysAllocString(IA2_RELATION_EMBEDDED_BY);
+      res = ::SysReAllocString(aRelationType, IA2_RELATION_EMBEDDED_BY);
       break;
     case RELATION_EMBEDS:
-      *aRelationType = ::SysAllocString(IA2_RELATION_EMBEDS);
+      res = ::SysReAllocString(aRelationType, IA2_RELATION_EMBEDS);
       break;
     case RELATION_FLOWS_FROM:
-      *aRelationType = ::SysAllocString(IA2_RELATION_FLOWS_FROM);
+      res = ::SysReAllocString(aRelationType, IA2_RELATION_FLOWS_FROM);
       break;
     case RELATION_FLOWS_TO:
-      *aRelationType = ::SysAllocString(IA2_RELATION_FLOWS_TO);
+      res = ::SysReAllocString(aRelationType, IA2_RELATION_FLOWS_TO);
       break;
     case RELATION_LABEL_FOR:
-      *aRelationType = ::SysAllocString(IA2_RELATION_LABEL_FOR);
+      res = ::SysReAllocString(aRelationType, IA2_RELATION_LABEL_FOR);
       break;
     case RELATION_LABELLED_BY:
-      *aRelationType = ::SysAllocString(IA2_RELATION_LABELED_BY);
+      res = ::SysReAllocString(aRelationType, IA2_RELATION_LABELED_BY);
       break;
     case RELATION_MEMBER_OF:
-      *aRelationType = ::SysAllocString(IA2_RELATION_MEMBER_OF);
+      res = ::SysReAllocString(aRelationType, IA2_RELATION_MEMBER_OF);
       break;
     case RELATION_NODE_CHILD_OF:
-      *aRelationType = ::SysAllocString(IA2_RELATION_NODE_CHILD_OF);
+      res = ::SysReAllocString(aRelationType, IA2_RELATION_NODE_CHILD_OF);
       break;
     case RELATION_PARENT_WINDOW_OF:
-      *aRelationType = ::SysAllocString(IA2_RELATION_PARENT_WINDOW_OF);
+      res = ::SysReAllocString(aRelationType, IA2_RELATION_PARENT_WINDOW_OF);
       break;
     case RELATION_POPUP_FOR:
-      *aRelationType = ::SysAllocString(IA2_RELATION_POPUP_FOR);
+      res = ::SysReAllocString(aRelationType, IA2_RELATION_POPUP_FOR);
       break;
     case RELATION_SUBWINDOW_OF:
-      *aRelationType = ::SysAllocString(IA2_RELATION_SUBWINDOW_OF);
+      res = ::SysReAllocString(aRelationType, IA2_RELATION_SUBWINDOW_OF);
       break;
     default:
       return E_FAIL;
   }
 
-  if (!aRelationType)
+  if (!res)
     return E_OUTOFMEMORY;
+
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   
   return S_OK;
 }
 
 STDMETHODIMP
 nsAccessibleRelationWrap::get_localizedRelationType(BSTR *aLocalizedRelationType)
 {
+  ::SysFreeString(*aLocalizedRelationType);
   return E_NOTIMPL;
 }
 
 STDMETHODIMP
 nsAccessibleRelationWrap::get_nTargets(long *aNTargets)
 {
 __try {
   PRUint32 count = 0;
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -1376,17 +1376,17 @@ nsAccessibleWrap::get_localizedExtendedS
   *nLocalizedExtendedStates = 0;
   return E_NOTIMPL;
 }
 
 STDMETHODIMP
 nsAccessibleWrap::get_uniqueID(long *uniqueID)
 {
 __try {
-  void *id;
+  void *id = nsnull;
   if (NS_SUCCEEDED(GetUniqueID(&id))) {
     *uniqueID = - reinterpret_cast<long>(id);
     return S_OK;
   }
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return E_FAIL;
 }
 
@@ -1518,17 +1518,20 @@ nsAccessibleWrap::get_attributes(BSTR *a
     }
 
     AppendUTF8toUTF16(name, strAttrs);
     strAttrs.Append(':');
     strAttrs.Append(value);
     strAttrs.Append(';');
   }
 
-  *aAttributes = ::SysAllocString(strAttrs.get());
+  *aAttributes = ::SysAllocString(strAttrs.get()); 
+  if (!*aAttributes)
+    return E_OUTOFMEMORY;
+
 } __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
   return S_OK;
 }
 
 STDMETHODIMP
 nsAccessibleWrap::Clone(IEnumVARIANT FAR* FAR* ppenum)
 {
 __try {
@@ -1667,17 +1670,17 @@ nsAccessibleWrap::FireAccessibleEvent(ns
 //------- Helper methods ---------
 
 PRInt32 nsAccessibleWrap::GetChildIDFor(nsIAccessible* aAccessible)
 {
   // A child ID of the window is required, when we use NotifyWinEvent,
   // so that the 3rd party application can call back and get the IAccessible
   // the event occured on.
 
-  void *uniqueID;
+  void *uniqueID = nsnull;
   nsCOMPtr<nsIAccessNode> accessNode(do_QueryInterface(aAccessible));
   if (!accessNode) {
     return 0;
   }
   accessNode->GetUniqueID(&uniqueID);
 
   // Yes, this means we're only compatibible with 32 bit
   // MSAA is only available for 32 bit windows, so it's okay
@@ -1736,17 +1739,17 @@ IDispatch *nsAccessibleWrap::NativeAcces
 {
   if (!aXPAccessible) {
    NS_WARNING("Not passing in an aXPAccessible");
    return NULL;
   }
 
   nsCOMPtr<nsIAccessibleWin32Object> accObject(do_QueryInterface(aXPAccessible));
   if (accObject) {
-    void* hwnd;
+    void* hwnd = nsnull;
     accObject->GetHwnd(&hwnd);
     if (hwnd) {
       IDispatch *retval = nsnull;
       AccessibleObjectFromWindow(reinterpret_cast<HWND>(hwnd),
         OBJID_WINDOW, IID_IAccessible, (void **) &retval);
       return retval;
     }
   }
--- a/accessible/src/xul/nsXULSelectAccessible.cpp
+++ b/accessible/src/xul/nsXULSelectAccessible.cpp
@@ -37,18 +37,18 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsXULSelectAccessible.h"
 #include "nsAccessibilityService.h"
 #include "nsIContent.h"
 #include "nsIDOMXULMenuListElement.h"
 #include "nsIDOMXULPopupElement.h"
+#include "nsIDOMXULMultSelectCntrlEl.h"
 #include "nsIDOMXULSelectCntrlItemEl.h"
-#include "nsIDOMXULSelectCntrlEl.h"
 #include "nsIDOMXULTextboxElement.h"
 #include "nsIPresShell.h"
 #include "nsIServiceManager.h"
 #include "nsCaseTreatment.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsXULColumnsAccessible
 
@@ -253,25 +253,25 @@ NS_IMETHODIMP nsXULListboxAccessible::Ge
 // nsXULListboxAccessible. nsIAccessibleTable
 
 NS_IMETHODIMP
 nsXULListboxAccessible::GetCaption(nsIAccessible **aCaption)
 {
   NS_ENSURE_ARG_POINTER(aCaption);
   *aCaption = nsnull;
 
-  return NS_ERROR_NOT_IMPLEMENTED;
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULListboxAccessible::GetSummary(nsAString &aSummary)
 {
   aSummary.Truncate();
 
-  return NS_ERROR_NOT_IMPLEMENTED;
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULListboxAccessible::GetColumns(PRInt32 *aNumColumns)
 {
   NS_ENSURE_ARG_POINTER(aNumColumns);
   *aNumColumns = 0;
 
@@ -282,33 +282,33 @@ nsXULListboxAccessible::GetColumns(PRInt
 
   nsCOMPtr<nsIContent> headContent;
   PRUint32 count = content->GetChildCount();
 
   for (PRUint32 index = 0; index < count; ++index) {
     nsCOMPtr<nsIContent> childContent(content->GetChildAt(index));
     NS_ENSURE_STATE(childContent);
 
-    if (childContent->NodeInfo()->Equals(nsAccessibilityAtoms::listhead,
+    if (childContent->NodeInfo()->Equals(nsAccessibilityAtoms::listcols,
                                          kNameSpaceID_XUL)) {
       headContent = childContent;
     }
   }
 
   if (!headContent)
     return NS_OK;
 
   PRUint32 columnCount = 0;
   count = headContent->GetChildCount();
 
   for (PRUint32 index = 0; index < count; ++index) {
     nsCOMPtr<nsIContent> childContent(headContent->GetChildAt(index));
     NS_ENSURE_STATE(childContent);
 
-    if (childContent->NodeInfo()->Equals(nsAccessibilityAtoms::listheader,
+    if (childContent->NodeInfo()->Equals(nsAccessibilityAtoms::listcol,
                                          kNameSpaceID_XUL)) {
       columnCount++;
     }
   }
 
   *aNumColumns = columnCount;
   return NS_OK;
 }
@@ -447,124 +447,360 @@ nsXULListboxAccessible::GetRowExtentAt(P
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULListboxAccessible::GetColumnDescription(PRInt32 aColumn,
                                              nsAString& aDescription)
 {
-  return NS_ERROR_NOT_IMPLEMENTED;
+  aDescription.Truncate();
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULListboxAccessible::GetRowDescription(PRInt32 aRow, nsAString& aDescription)
 {
-  return NS_ERROR_NOT_IMPLEMENTED;
+  aDescription.Truncate();
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULListboxAccessible::IsColumnSelected(PRInt32 aColumn, PRBool *aIsSelected)
 {
   NS_ENSURE_ARG_POINTER(aIsSelected);
+  *aIsSelected = PR_FALSE;
 
-  return NS_ERROR_NOT_IMPLEMENTED;
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
+    do_QueryInterface(mDOMNode);
+  NS_ASSERTION(control,
+               "Doesn't implement nsIDOMXULMultiSelectControlElement.");
+
+  PRInt32 selectedRowsCount = 0;
+  nsresult rv = control->GetSelectedCount(&selectedRowsCount);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRInt32 rowsCount = 0;
+  rv = GetRows(&rowsCount);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  *aIsSelected = (selectedRowsCount == rowsCount);
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULListboxAccessible::IsRowSelected(PRInt32 aRow, PRBool *aIsSelected)
 {
   NS_ENSURE_ARG_POINTER(aIsSelected);
+  *aIsSelected = PR_FALSE;
 
-  return NS_ERROR_NOT_IMPLEMENTED;
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsCOMPtr<nsIDOMXULSelectControlElement> control =
+    do_QueryInterface(mDOMNode);
+  NS_ASSERTION(control,
+               "Doesn't implement nsIDOMXULSelectControlElement.");
+  
+  nsCOMPtr<nsIDOMXULSelectControlItemElement> item;
+  control->GetItemAtIndex(aRow, getter_AddRefs(item));
+  NS_ENSURE_TRUE(item, NS_ERROR_INVALID_ARG);
+
+  return item->GetSelected(aIsSelected);
 }
 
 NS_IMETHODIMP
 nsXULListboxAccessible::IsCellSelected(PRInt32 aRow, PRInt32 aColumn,
                                        PRBool *aIsSelected)
 {
-  NS_ENSURE_ARG_POINTER(aIsSelected);
-
-  return NS_ERROR_NOT_IMPLEMENTED;
+  return IsRowSelected(aRow, aIsSelected);
 }
 
 NS_IMETHODIMP
 nsXULListboxAccessible::GetSelectedCellsCount(PRUint32* aCount)
 {
   NS_ENSURE_ARG_POINTER(aCount);
+  *aCount = 0;
 
-  return NS_ERROR_NOT_IMPLEMENTED;
+  nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
+    do_QueryInterface(mDOMNode);
+  NS_ASSERTION(control,
+               "Doesn't implement nsIDOMXULMultiSelectControlElement.");
+
+  nsCOMPtr<nsIDOMNodeList> selectedItems;
+  control->GetSelectedItems(getter_AddRefs(selectedItems));
+  if (!selectedItems)
+    return NS_OK;
+
+  PRUint32 selectedItemsCount = 0;
+  nsresult rv = selectedItems->GetLength(&selectedItemsCount);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (!selectedItemsCount)
+    return NS_OK;
+
+  PRInt32 columnsCount = 0;
+  rv = GetColumns(&columnsCount);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  *aCount = selectedItemsCount * columnsCount;
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULListboxAccessible::GetSelectedColumnsCount(PRUint32* aCount)
 {
   NS_ENSURE_ARG_POINTER(aCount);
+  *aCount = 0;
 
-  return NS_ERROR_NOT_IMPLEMENTED;
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
+  do_QueryInterface(mDOMNode);
+  NS_ASSERTION(control,
+               "Doesn't implement nsIDOMXULMultiSelectControlElement.");
+
+  PRInt32 selectedRowsCount = 0;
+  nsresult rv = control->GetSelectedCount(&selectedRowsCount);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRInt32 rowsCount = 0;
+  rv = GetRows(&rowsCount);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (selectedRowsCount != rowsCount)
+    return NS_OK;
+
+  PRInt32 columnsCount = 0;
+  rv = GetColumns(&columnsCount);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  *aCount = columnsCount;
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULListboxAccessible::GetSelectedRowsCount(PRUint32* aCount)
 {
   NS_ENSURE_ARG_POINTER(aCount);
+  *aCount = 0;
 
-  return NS_ERROR_NOT_IMPLEMENTED;
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
+    do_QueryInterface(mDOMNode);
+  NS_ASSERTION(control,
+               "Doesn't implement nsIDOMXULMultiSelectControlElement.");
+
+  PRInt32 selectedRowsCount = 0;
+  nsresult rv = control->GetSelectedCount(&selectedRowsCount);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  *aCount = selectedRowsCount;
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULListboxAccessible::GetSelectedCells(PRUint32 *aNumCells, PRInt32 **aCells)
 {
   NS_ENSURE_ARG_POINTER(aNumCells);
+  *aNumCells = 0;
   NS_ENSURE_ARG_POINTER(aCells);
+  *aCells = nsnull;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+  
+  nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
+    do_QueryInterface(mDOMNode);
+  NS_ASSERTION(control,
+               "Doesn't implement nsIDOMXULMultiSelectControlElement.");
+
+  nsCOMPtr<nsIDOMNodeList> selectedItems;
+  control->GetSelectedItems(getter_AddRefs(selectedItems));
+  if (!selectedItems)
+    return NS_OK;
+
+  PRUint32 selectedItemsCount = 0;
+  nsresult rv = selectedItems->GetLength(&selectedItemsCount);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRInt32 columnsCount = 0;
+  rv = GetColumns(&columnsCount);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PRUint32 cellsCount = selectedItemsCount * columnsCount;
 
-  return NS_ERROR_NOT_IMPLEMENTED;
+  PRInt32 *cellsIdxArray =
+    static_cast<PRInt32*>(nsMemory::Alloc((cellsCount) * sizeof(PRInt32)));
+  NS_ENSURE_TRUE(cellsIdxArray, NS_ERROR_OUT_OF_MEMORY);
+
+  PRUint32 index = 0, cellsIdx = 0;
+  for (; index < selectedItemsCount; index++) {
+    nsCOMPtr<nsIDOMNode> itemNode;
+    selectedItems->Item(index, getter_AddRefs(itemNode));
+    nsCOMPtr<nsIDOMXULSelectControlItemElement> item =
+      do_QueryInterface(itemNode);
+
+    if (item) {
+      PRInt32 itemIdx = -1;
+      control->GetIndexOfItem(item, &itemIdx);
+      if (itemIdx != -1) {
+        PRInt32 colIdx = 0;
+        for (; colIdx < columnsCount; colIdx++)
+          cellsIdxArray[cellsIdx++] = itemIdx * columnsCount + colIdx;
+      }
+    }
+  }
+
+  *aNumCells = cellsCount;
+  *aCells = cellsIdxArray;
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULListboxAccessible::GetSelectedColumns(PRUint32 *aNumColumns,
                                            PRInt32 **aColumns)
 {
   NS_ENSURE_ARG_POINTER(aNumColumns);
+  *aNumColumns = 0;
   NS_ENSURE_ARG_POINTER(aColumns);
+  *aColumns = nsnull;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  PRUint32 columnsCount = 0;
+  nsresult rv = GetSelectedColumnsCount(&columnsCount);
+  NS_ENSURE_SUCCESS(rv, rv);
 
-  return NS_ERROR_NOT_IMPLEMENTED;
+  if (!columnsCount)
+    return NS_OK;
+
+  PRInt32 *colsIdxArray =
+    static_cast<PRInt32*>(nsMemory::Alloc((columnsCount) * sizeof(PRInt32)));
+  NS_ENSURE_TRUE(colsIdxArray, NS_ERROR_OUT_OF_MEMORY);
+
+  PRUint32 colIdx = 0;
+  for (; colIdx < columnsCount; colIdx++)
+    colsIdxArray[colIdx] = colIdx;
+
+  *aNumColumns = columnsCount;
+  *aColumns = colsIdxArray;
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULListboxAccessible::GetSelectedRows(PRUint32 *aNumRows, PRInt32 **aRows)
 {
   NS_ENSURE_ARG_POINTER(aNumRows);
+  *aNumRows = 0;
   NS_ENSURE_ARG_POINTER(aRows);
+  *aRows = nsnull;
+
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+
+  nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
+    do_QueryInterface(mDOMNode);
+  NS_ASSERTION(control,
+               "Doesn't implement nsIDOMXULMultiSelectControlElement.");
+  
+  nsCOMPtr<nsIDOMNodeList> selectedItems;
+  control->GetSelectedItems(getter_AddRefs(selectedItems));
+  if (!selectedItems)
+    return NS_OK;
+  
+  PRUint32 selectedItemsCount = 0;
+  nsresult rv = selectedItems->GetLength(&selectedItemsCount);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (!selectedItemsCount)
+    return NS_OK;
 
-  return NS_ERROR_NOT_IMPLEMENTED;
+  PRInt32 *rowsIdxArray =
+    static_cast<PRInt32*>(nsMemory::Alloc((selectedItemsCount) * sizeof(PRInt32)));
+  NS_ENSURE_TRUE(rowsIdxArray, NS_ERROR_OUT_OF_MEMORY);
+
+  PRUint32 index = 0;
+  for (; index < selectedItemsCount; index++) {
+    nsCOMPtr<nsIDOMNode> itemNode;
+    selectedItems->Item(index, getter_AddRefs(itemNode));
+    nsCOMPtr<nsIDOMXULSelectControlItemElement> item =
+      do_QueryInterface(itemNode);
+    
+    if (item) {
+      PRInt32 itemIdx = -1;
+      control->GetIndexOfItem(item, &itemIdx);
+      if (itemIdx != -1)
+        rowsIdxArray[index] = itemIdx;
+    }
+  }
+
+  *aNumRows = selectedItemsCount;
+  *aRows = rowsIdxArray;
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULListboxAccessible::SelectRow(PRInt32 aRow)
 {
-  return NS_ERROR_NOT_IMPLEMENTED;
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+  
+  nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
+  do_QueryInterface(mDOMNode);
+  NS_ASSERTION(control,
+               "Doesn't implement nsIDOMXULMultiSelectControlElement.");
+
+  nsCOMPtr<nsIDOMXULSelectControlItemElement> item;
+  control->GetItemAtIndex(aRow, getter_AddRefs(item));
+  NS_ENSURE_TRUE(item, NS_ERROR_INVALID_ARG);
+
+  return control->SelectItem(item);
 }
 
 NS_IMETHODIMP
 nsXULListboxAccessible::SelectColumn(PRInt32 aColumn)
 {
-  return NS_ERROR_NOT_IMPLEMENTED;
+  // xul:listbox and xul:richlistbox support row selection only.
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULListboxAccessible::UnselectRow(PRInt32 aRow)
 {
-  return NS_ERROR_NOT_IMPLEMENTED;
+  if (IsDefunct())
+    return NS_ERROR_FAILURE;
+  
+  nsCOMPtr<nsIDOMXULMultiSelectControlElement> control =
+    do_QueryInterface(mDOMNode);
+  NS_ASSERTION(control,
+               "Doesn't implement nsIDOMXULMultiSelectControlElement.");
+
+  nsCOMPtr<nsIDOMXULSelectControlItemElement> item;
+  control->GetItemAtIndex(aRow, getter_AddRefs(item));
+  NS_ENSURE_TRUE(item, NS_ERROR_INVALID_ARG);
+
+  return control->RemoveItemFromSelection(item);
 }
 
 NS_IMETHODIMP
 nsXULListboxAccessible::UnselectColumn(PRInt32 aColumn)
 {
-  return NS_ERROR_NOT_IMPLEMENTED;
+  // xul:listbox and xul:richlistbox support row selection only.
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULListboxAccessible::IsProbablyForLayout(PRBool *aIsProbablyForLayout)
 {
   NS_ENSURE_ARG_POINTER(aIsProbablyForLayout);
   *aIsProbablyForLayout = PR_FALSE;
 
--- a/accessible/tests/mochitest/Makefile.in
+++ b/accessible/tests/mochitest/Makefile.in
@@ -43,15 +43,17 @@ VPATH		= @srcdir@
 relativesrcdir  = accessible
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES =\
 		test_bug368835.xul \
 		test_groupattrs.xul \
+		test_table_indexes.html \
 		test_nsIAccessibleTable_1.html \
 		test_nsIAccessibleTable_2.html \
 		test_nsIAccessibleTable_3.html \
+		test_nsIAccessibleTable_listboxes.xul \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/a11y/$(relativesrcdir)
--- a/accessible/tests/mochitest/test_bug368835.xul
+++ b/accessible/tests/mochitest/test_bug368835.xul
@@ -1,15 +1,16 @@
 <?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"?>
 
 <!--
   Bug 368835 - fire TreeViewChanged/TreeRowCountChanged events.
+  Bug 308564 - no accessibility events when data in a tree row changes.
 -->
 
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         title="Mozilla Bug 368835">
 
   <script type="application/javascript" 
           src="chrome://mochikit/content/MochiKit/packed.js"></script>
   <script type="application/javascript"
@@ -60,16 +61,19 @@
       performActionOnRow: function(aAction, aRow) {},
       performActionOnCell: function(aAction, aRow, aCol) {}
     };
 
     var gTreeViewChanged = false;
     function TreeViewChangedHandler(aEvent)
     {
       gTreeViewChanged = true;
+
+      // Tree view has been setted. We can continue tests for the tree.
+      window.setTimeout(doTest2, 0);
     }
 
     var gTreeRowCountChanged = false;
     function TreeRowCountChangedHandler(aEvent)
     {
       gTreeRowCountChanged = true;
 
       var index = aEvent.getData("index");
@@ -78,44 +82,41 @@
       var count = aEvent.getData("count");
       is(count, 1, "Wrong 'count' data of 'treeRowCountChanged' event.");
     }
 
     var gTreeInvalidatedCount = 0;
     function TreeInvalidatedHandler(aEvent)
     {
       gTreeInvalidatedCount++;
-      switch (gTreeInvalidatedCount) {
-        case 2:
-          TreeColumnInvalidatedHandler(aEvent);
-          break;
-        case 3:
-          TreeRowInvalidatedHandler(aEvent);
-          break;
-      }
+
+      if (gTreeInvalidatedCount == 2)
+        TreeColumnInvalidatedHandler(aEvent);
+      else if (gTreeInvalidatedCount == 5)
+        TreeRowInvalidatedHandler(aEvent);
     }
 
     var gTreeColumnInvalidated = false;
     function TreeColumnInvalidatedHandler(aEvent)
     {
       var startRow = aEvent.getData("startrow");
       is(startRow, null,
-         "Wrong 'startrow' of 'treeInvalidated' event on InvalidateColumn().");
+         "Wrong 'startrow' of 'treeInvalidated' event on InvalidateRow().");
 
       var endRow = aEvent.getData("endrow");
       is(endRow, null,
-         "Wrong 'endrow' of 'treeInvalidated' event on InvalidateColumn().");
+         "Wrong 'endrow' of 'treeInvalidated' event on InvalidateRow().");
 
       var startCol = aEvent.getData("startcolumn");
       is(startCol, 0,
-         "Wrong 'startcolumn' of 'treeInvalidated' event on InvalidateColumn().");
+         "Wrong 'startcolumn' of 'treeInvalidated' event on InvalidateRow().");
 
       var endCol = aEvent.getData("endcolumn");
       is(endCol, 0,
-         "Wrong 'endcolumn' of 'treeInvalidated' event on InvalidateColumn().");
+         "Wrong 'endcolumn' of 'treeInvalidated' event on InvalidateRow().");
 
       gTreeColumnInvalidated = true;
     }
 
     var gTreeRowInvalidated = false;
     function TreeRowInvalidatedHandler(aEvent)
     {
       var startRow = aEvent.getData("startrow");
@@ -132,122 +133,189 @@
 
       var endCol = aEvent.getData("endcolumn");
       is(endCol, null,
          "Wrong 'endcolumn' of 'treeInvalidated' event on InvalidateColumn().");
 
       gTreeRowInvalidated = true;
     }
 
+    var gNameChangedOnTreeRowInvalidated = false;
+    var gNameChangedOnTreeColumnInvalidated = false;
+
+    var gA11yEventObserver = {
+      observe: function observe(aSubject, aTopic, aData)
+      {
+        if (aTopic != "accessible-event")
+          return;
+
+        const nsIAccessibleEvent = Components.interfaces.nsIAccessibleEvent;
+        var event = aSubject.QueryInterface(nsIAccessibleEvent);
+
+        if (event.eventType != nsIAccessibleEvent.EVENT_NAME_CHANGE)
+          return;
+
+        ++this.mCount;
+
+        if (this.mCount == 6) {
+          gNameChangedOnTreeColumnInvalidated = true;
+
+          // Make sure 'name change' events have been fired on
+          // InvalidateColumn() before continue the test.
+          window.setTimeout(doTest3, 0);
+        }
+        else if (this.mCount == 7)
+          gNameChangedOnTreeRowInvalidated = true;
+      },
+
+      mCount: 0,
+      mType: ""
+    };
+
     function CheckEvents()
     {
       // If these fail then it doesn't mean actually events are not fired,
-      // possibly setTimeout was executed earlier than events have beenS fired.
+      // possibly setTimeout was executed earlier than events have been fired.
 
+      // DOM events
       ok(gTreeViewChanged,
          "TreeViewChanged event should have been fired.");
       ok(gTreeRowCountChanged,
          "TreeRowCountChanged event should have been fired.");
       ok(gTreeColumnInvalidated,
          "TreeInvalidated event should have been fired for InvalidateColumn().");
       ok(gTreeRowInvalidated,
          "TreeInvalidated event should have been fired for InvalidateRow().");
 
+      // A11y events
+      ok(gNameChangedOnTreeRowInvalidated,
+         "Wrong NameChanged events number on tree row invalidation.");
+      ok(gNameChangedOnTreeColumnInvalidated,
+         "Wrong NameChanged events number on tree column invalidation.");
+
+      // Remove DOM event listeners
       document.removeEventListener("TreeViewChanged",
                                    TreeViewChangedHandler, true);
 
       document.removeEventListener("TreeRowCountChanged",
                                    TreeRowCountChangedHandler, true);
 
       document.removeEventListener("TreeInvalidated",
                                    TreeInvalidatedHandler, true);
 
+      // Remove a11y events listener
+      gObserverService.removeObserver(gA11yEventObserver, "accessible-event");
+
       SimpleTest.finish();
     }
 
     var gAccService = null;
+    var gObserverService = null;
+
+    var gTree = null;
+    var gTreeBox = null;
+    var gTreeView = null;
 
     function doTest()
     {
-      // Check whether accessibility support is enabled.
-      if (!("@mozilla.org/accessibleRetrieval;1" in Components.classes)) {
-        SimpleTest.finish();
-        return;
-      }
-
       // Activate accessibility, otherwise events aren't fired.
       gAccService = Components.classes["@mozilla.org/accessibleRetrieval;1"].
                     getService(Components.interfaces.nsIAccessibleRetrieval);
 
-      // Add event listeners
+      // Add accessibility event listeners
+      gObserverService = Components.classes["@mozilla.org/observer-service;1"].
+                         getService(Components.interfaces.nsIObserverService);
+      gObserverService.addObserver(gA11yEventObserver, "accessible-event",
+                                   false);
+
+      // Add DOM event listeners
       document.addEventListener("TreeViewChanged",
                                 TreeViewChangedHandler, true);
       document.addEventListener("TreeRowCountChanged",
                                 TreeRowCountChangedHandler, true);
       document.addEventListener("TreeInvalidated",
                                 TreeInvalidatedHandler, true);
 
       // Initialize the tree
-      var tree = document.getElementById("tree");
-      var treeBox = tree.treeBoxObject;
+      gTree = document.getElementById("tree");
+      gTreeBox = gTree.treeBoxObject;
 
-      var view = new inTreeView();
-      view.mRowCount = 5;
+      gView = new inTreeView();
+      gView.mRowCount = 5;
 
       // Fire 'TreeViewChanged' event
-      treeBox.view = view;
+      gTreeBox.view = gView;
 
       // Fire 'TreeRowCountChanged' changed
-      ++view.mRowCount;
-      treeBox.rowCountChanged(0, 1);
+      ++gView.mRowCount;
+      gTreeBox.rowCountChanged(0, 1);
+
+      // Wait for events.
+      window.setTimeout(CheckEvents, 1000);
+    }
+
+    function doTest2()
+    {
+      // Make sure accessibles for the tree is created because it makes
+      // sure accessible events will be fired.
+      var treeAcc = gAccService.getAccessibleFor(gTree);
+
+      // Makes sure tree children accessibles are created otherwise they won't
+      // be a couse of name changed events.
+      var children = treeAcc.children;
 
       // Fire 'TreeInvalidated' event by InvalidateColumn()
-      var firstCol = treeBox.columns.getFirstColumn();
-      for (var i = 0; i < view.mRowCount; i++) {
+      var firstCol = gTree.columns.getFirstColumn();
+      for (var i = 0; i < gView.mRowCount; i++) {
         var key = String(i) + firstCol.id;
-        view.mData[key] = key + "_col";
+        gView.mData[key] = key + "_col";
       }
 
-      treeBox.invalidateColumn(firstCol);
+      gTreeBox.invalidateColumn(firstCol);
+    }
 
+    function doTest3()
+    {
       // Fire 'TreeInvalidated' event by InvalidateRow()
-      var colCount = tree.columns.count;
+      var colCount = gTree.columns.count;
       for (var i = 0; i < colCount; i++) {
-        var key = "1" + tree.columns.getColumnAt(i).id;
-        view.mData[key] = key + "_row";
+        var key = "1" + gTree.columns.getColumnAt(i).id;
+        gView.mData[key] = key + "_row";
       }
 
-      treeBox.invalidateRow(1);
-
-      // Wait for events.
-      if (gTreeViewChanged && gTreeRowCountChanged &&
-          gTreeColumnInvalidated)
-        CheckEvents();
-      else
-        window.setTimeout(CheckEvents, 1000);
+      gTreeBox.invalidateRow(1);
     }
 
     SimpleTest.waitForExplicitFinish();
     addLoadEvent(doTest);
   ]]>
   </script>
 
-  <body xmlns="http://www.w3.org/1999/xhtml">
-    <a target="_blank"
-       href="https://bugzilla.mozilla.org/show_bug.cgi?id=368835">
-      Mozilla Bug 368835
-    </a>
-    <p id="display"></p>
-    <div id="content" style="display: none">
-    </div>
-    <pre id="test">
-    </pre>
-  </body>
+  <hbox flex="1" style="overflow: auto;">
+    <body xmlns="http://www.w3.org/1999/xhtml">
+      <a target="_blank"
+         href="https://bugzilla.mozilla.org/show_bug.cgi?id=368835"
+         title="Fire TreeViewChanged/TreeRowCountChanged events.">
+        Mozilla Bug 368835
+      </a><br/>
+      <a target="_blank"
+         href="https://bugzilla.mozilla.org/show_bug.cgi?id=308564"
+         title="No accessibility events when data in a tree row changes.">
+        Mozilla Bug 308564
+      </a>
+      <p id="display"></p>
+      <div id="content" style="display: none">
+      </div>
+      <pre id="test">
+      </pre>
+    </body>
 
-  <tree id="tree" flex="1">
-    <treecols>
-      <treecol id="col" flex="1" primary="true" label="column"/>
-      <treecol id="scol" flex="1" label="column 2"/>
-    </treecols>
-    <treechildren id="treechildren"/>
-  </tree>
+    <tree id="tree" flex="1">
+      <treecols>
+        <treecol id="col" flex="1" primary="true" label="column"/>
+        <treecol id="scol" flex="1" label="column 2"/>
+      </treecols>
+      <treechildren id="treechildren"/>
+    </tree>
+  </hbox>
+
 </window>
 
--- a/accessible/tests/mochitest/test_nsIAccessibleTable_2.html
+++ b/accessible/tests/mochitest/test_nsIAccessibleTable_2.html
@@ -7,42 +7,73 @@
   <script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
   <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript">
 
 function doTest()
 {
   netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
 
-  var table = document.getElementById("table");
   var accService = Components.classes["@mozilla.org/accessibleRetrieval;1"].
                    getService(Components.interfaces.nsIAccessibleRetrieval);
 
+  // bug 410052
+  var table = document.getElementById("table");
   var accTable = accService.getAccessibleFor(table).
                  QueryInterface(Components.interfaces.nsIAccessibleTable);
 
   is(accTable.getIndexAt(2,4), 17, "wrong index returned");
   is(accTable.getColumnAtIndex(18), 5,"got wrong column");
   is(accTable.getRowAtIndex(10), 1, "wrong row");
   is(accTable.getColumnExtentAt(2,2), 2, "colspan wrong");
   is(accTable.getColumnExtentAt(0,3), 2, "colspan wrong");
   is(accTable.getColumnExtentAt(3,5), 1, "colspan");
   is(accTable.getRowExtentAt(0,7), 4, "rowspan wrong");
   is(accTable.getRowExtentAt(2,7), 4,"rowspan wrong");
   is(accTable.getColumnExtentAt(2,3), 1, "colspan wrong");
   is(accTable.cellRefAt(2,1).firstChild.name, "c1", "wrong cell");
+
+  // bug 417912
+  var table2 = document.getElementById("table2");
+  var accTable2 = accService.getAccessibleFor(table2).
+                  QueryInterface(Components.interfaces.nsIAccessibleTable);
+  testCellAt(accTable2, 0, 0, true);
+  testCellAt(accTable2, 0, 1, true);
+  testCellAt(accTable2, 0, 2, true);
+  testCellAt(accTable2, 1, 0, true);
+  testCellAt(accTable2, 1, 1, false);
+  testCellAt(accTable2, 1, 2, true);
+  testCellAt(accTable2, 2, 0, true);
+  testCellAt(accTable2, 2, 1, true);
+  testCellAt(accTable2, 2, 2, true);
+
   SimpleTest.finish();
 }
 
+function testCellAt(aTable, aRow, aColumn, aSucceeded)
+{
+  try {
+    aTable.cellRefAt(aRow, aColumn);
+    ok(aSucceeded, "cell is available at (" + aRow + ", " + aColumn + ").");
+  } catch (e) {
+    ok(!aSucceeded, "cell is not available at (" + aRow + ", " + aColumn + ").");
+  }
+}
+
 SimpleTest.waitForExplicitFinish();
 addLoadEvent(doTest);
   </script>
  </head>
  <body>
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=410052">Mozilla Bug 410052</a>
+  <br>
+  <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=417912"
+                     title="GetCellDataAt callers that expect an error if no cell is found are wrong">
+    Mozilla Bug 417912
+  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <!-- Test Table -->
   <br><br><b> Testing Table:</b><br><br>
   <center>
@@ -78,10 +109,19 @@ addLoadEvent(doTest);
       <td><br></td>
       <td><br></td>
       <td><br></td>
       <td><br></td>
      </tr>
     </tbody>
    </table>
   </center>
+
+  <br><br><b>Testing Table 2:</b><br><br>
+  <center>
+    <table cellpadding="2" cellspacing="2" border="1" width="50%" id="table2">
+      <tr><td>1</td><td>2</td><td rowspan=3>3</td>
+      <tr><td>4</td>
+      <tr><td>5</td><td>6</td>
+    </table>
+  </center>
  </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/test_nsIAccessibleTable_listboxes.xul
@@ -0,0 +1,343 @@
+<?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"?>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        title="nsIAccessibleTable interface on xul:listbox test.">
+
+  <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 type="application/javascript">
+  <![CDATA[
+    var gAccService = null;
+    var Ci = Components.interfaces;
+
+    function doTest()
+    {
+      gAccService = Components.classes["@mozilla.org/accessibleRetrieval;1"].
+                    getService(Components.interfaces.nsIAccessibleRetrieval);
+      var id = "";
+      var listbox = null, acc = null;
+
+      //////////////////////////////////////////////////////////////////////////
+      // Simple listbox. There is no nsIAccessibleTable interface.
+
+      id = "listbox1";
+      listbox = document.getElementById(id);
+      acc = gAccService.getAccessibleFor(listbox);
+
+      // query nsIAccessibleTable
+      try {
+        acc.QueryInterface(Ci.nsIAccessibleTable);
+        ok(false,
+           id + " shouldn't implement nsIAccessibleTable interface.");
+      } catch(e) {
+        ok(true, id + " doesn't implement nsIAccessibleTable interface.");
+      }
+
+      // role
+      is(acc.role, Ci.nsIAccessibleRole.ROLE_LISTBOX,
+         id + " has wrong role.");
+
+      //////////////////////////////////////////////////////////////////////////
+      // Multicolumn listbox.
+
+      id = "listbox2";
+      listbox = document.getElementById(id);
+      acc = gAccService.getAccessibleFor(listbox);
+
+      // role
+      is(acc.role, Ci.nsIAccessibleRole.ROLE_TABLE,
+         id + " has wrong role.");
+
+      // query nsIAccessibleTable
+      try {
+        acc.QueryInterface(Ci.nsIAccessibleTable);
+        ok(true,
+           id + " implements nsIAccessibleTable interface.");
+      } catch(e) {
+        ok(false, id + " doesn't implement nsIAccessibleTable interface.");
+      }
+
+      // rows count
+      var rowsCount = acc.rows;
+      is (rowsCount, 2, id + " has wrong number of rows.");
+
+      // columns count
+      var colsCount = acc.columns;
+      is (colsCount, 2, id + " has wrong number of columns.");
+
+      //////////////////////////////////////////////////////////////////////////
+      // Multicolumn listbox with header.
+
+      id = "listbox3";
+      listbox = document.getElementById(id);
+      acc = gAccService.getAccessibleFor(listbox);
+
+      // role
+      is(acc.role, Ci.nsIAccessibleRole.ROLE_TABLE,
+         id + " has wrong role.");
+
+      // query nsIAccessibleTable
+      try {
+        acc.QueryInterface(Ci.nsIAccessibleTable);
+        ok(true,
+           id + " implements nsIAccessibleTable interface.");
+      } catch(e) {
+        ok(false, id + " doesn't implement nsIAccessibleTable interface.");
+      }
+
+      // rows count
+      var rowsCount = acc.rows;
+      is (rowsCount, 3, id + " has wrong number of rows.");
+
+      // columns count
+      var colsCount = acc.columns;
+      is (colsCount, 3, id + " has wrong number of columns.");
+
+      // getCellRefAt, getIndexAt, getRowAtIndex, getColumnAtIndex,
+      // getColumnExtentAt, getRowExtentAt.
+      for (var row = 0; row < rowsCount; row++) {
+        for (var col = 0; col < colsCount; col++) {
+          var index = row * colsCount + col;
+
+          is(acc.cellRefAt(row, col).name, "cell" + index,
+             id + ": wrong cell returned for (" + row + ", " + col + ")");
+
+          is(acc.getIndexAt(row, col), index,
+             id + ": wrong index returned for (" + row + ", " + col + ")");
+          is(acc.getRowAtIndex(index), row,
+             id + ": wrong row at the index " + index);
+          is(acc.getColumnAtIndex(index), col,
+             id + ": wrong column at the index " + index);
+
+          is(acc.getColumnExtentAt(row, col), 1,
+             id + ": colspan wrong for (" + row + ", " + col + ")");
+          is(acc.getRowExtentAt(row, col), 1,
+             id + ": rowspan wrong for (" + row + ", " + col + ")");
+        }
+      }
+
+      // columns selection
+      testColumnSelection(id, acc, colsCount, 0, null);
+      acc.selectColumn(0);
+      testColumnSelection(id, acc, colsCount, 0, null);
+
+      // rows selection
+      testRowSelection(id, acc, rowsCount, 0, null);
+      acc.selectRow(0);
+      testRowSelection(id, acc, rowsCount, 1, [0]);
+      acc.selectRow(1);
+      testRowSelection(id, acc, rowsCount, 1, [1]);
+      acc.unselectRow(1);
+      testRowSelection(id, acc, rowsCount, 0, null);
+
+      // cells selection
+      testCellSelection(id, acc, rowsCount, colsCount, 0, null);
+      acc.selectRow(2);
+      testCellSelection(id, acc, rowsCount, colsCount, 3, [6, 7, 8]);
+      acc.unselectRow(2);
+      testCellSelection(id, acc, rowsCount, colsCount, 0, null);
+
+      SimpleTest.finish();
+    }
+
+    /**
+     * Helper function to test isColumnSelected(), selectedColumnCount() and
+     * getSelectedColumn() methods.
+     */
+    function testColumnSelection(aId, aAcc, aCount, aSelCount, aSelIndexesArray)
+    {
+      // isColumnSelected
+      for (var col = 0; col < aCount; col++) {
+        if (aSelIndexesArray && aSelIndexesArray.indexOf(col) != -1) {
+          is(aAcc.isColumnSelected(col), true,
+             aId + ": column " + col + " should be selected");
+        } else {
+          is(aAcc.isColumnSelected(col), false,
+             aId + ": column " + col + " shouldn't be selected");
+        }
+      }
+
+      // selectedColumnsCount
+      is(aAcc.selectedColumnsCount, aSelCount,
+         aId + ": wrong number of selected columns");
+
+      // getSelectedColumns
+      var selColsCount = {}, selCols = {};
+      aAcc.getSelectedColumns(selColsCount, selCols);
+
+      is(selColsCount.value, aSelCount,
+         aId + ": wrong number of selected columns");
+
+      if (!aSelIndexesArray) {
+        is(selCols.value, null,
+           aId + ": no columns should be selected");
+      } else {
+        for (var i = 0; i < selCols.length; i++) {
+          is(selCols[i], aSelIndexesArray[i],
+             aId + ": wrong selected column index " + i);
+        }
+      }
+    }
+
+    /**
+     * Helper function to test isRowSelected(), selectedRowCount() and
+     * getSelectedRow() methods.
+     */
+    function testRowSelection(aId, aAcc, aCount, aSelCount, aSelIndexesArray)
+    {
+      // isRowSelected
+      for (var row = 0; row < aCount; row++) {
+        if (aSelIndexesArray && aSelIndexesArray.indexOf(row) != -1) {
+          is(aAcc.isRowSelected(row), true,
+             aId + ": row " + row + " should be selected");
+        } else {
+          is(aAcc.isRowSelected(row), false,
+             aId + ": row " + row + " shouldn't be selected");
+        }
+      }
+
+      // selectedRowsCount
+      is(aAcc.selectedRowsCount, aSelCount,
+         aId + ": wrong number of selected rows");
+
+      // getSelectedRows
+      var selColsCount = {}, selCols = {};
+      aAcc.getSelectedRows(selColsCount, selCols);
+
+      is(selColsCount.value, aSelCount,
+         aId + ": wrong number of selected rows");
+
+      if (!aSelIndexesArray) {
+        is(selCols.value, null,
+           aId + ": no row should be selected");
+      } else {
+        for (var i = 0; i < selCols.length; i++) {
+          is(selCols[i], aSelIndexesArray[i],
+             aId + ": wrong selected row index " + i);
+        }
+      }
+    }
+
+    /**
+     * Helper function to test isCellSelected(), selectedCellCount() and
+     * getSelectedCells() methods.
+     */
+    function testCellSelection(aId, aAcc, aRowCount, aColCount,
+                               aSelCount, aSelIndexesArray)
+    {
+      // isCellSelected
+      for (var row = 0; row < aRowCount; row++) {
+        for (var col = 0; col < aColCount; col++) {
+          var index = aAcc.getIndexAt(row, col);
+          if (aSelIndexesArray && aSelIndexesArray.indexOf(index) != -1) {
+            is(aAcc.isCellSelected(row, col), true,
+               aId + ": cell (" + row + ", " + col + ") should be selected");
+          } else {
+            is(aAcc.isCellSelected(row, col), false,
+               aId + ": cell (" + row + ", " + col + ") shouldn't be selected");
+          }
+        }
+      }
+
+      // selectedCellCount
+      is(aAcc.selectedCellsCount, aSelCount,
+         aId + ": wrong number of selected cells");
+
+      // getSelectedCells
+      var selColsCount = {}, selCols = {};
+      aAcc.getSelectedCells(selColsCount, selCols);
+
+      is(selColsCount.value, aSelCount,
+         aId + ": wrong number of selected cells");
+
+      if (!aSelIndexesArray) {
+        is(selCols.value, null,
+           aId + ": no cells should be selected");
+      } else {
+        for (var i = 0; i < selCols.length; i++) {
+          is(selCols[i], aSelIndexesArray[i],
+             aId + ": wrong selected cell index " + i);
+        }
+      }
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addLoadEvent(doTest);
+  ]]>
+  </script>
+
+  <hbox style="overflow: auto;">
+  <body xmlns="http://www.w3.org/1999/xhtml">
+    <a target="_blank"
+       href="https://bugzilla.mozilla.org/show_bug.cgi?id=418371"
+       title="implement the rest of methods of nsIAccessibleTable on xul:listbox">
+      Mozilla Bug 418371
+    </a>
+    <p id="display"></p>
+    <div id="content" style="display: none">
+    </div>
+    <pre id="test">
+    </pre>
+  </body>
+
+  <vbox flex="1">
+    <label control="listbox1" value="listbox: "/>
+    <listbox id="listbox1">
+      <listitem label="item1" id="item1"/>
+      <listitem label="item2" id="item2"/>
+    </listbox>
+
+    <label control="listbox2" value="multicolumn listbox: "/>
+    <listbox id="listbox2">
+      <listcols>
+        <listcol flex="1"/>
+        <listcol flex="1"/>
+      </listcols>
+      <listitem>
+        <listcell label="cell1"/>
+        <listcell label="cell2"/>
+      </listitem>
+      <listitem>
+        <listcell label="cell1"/>
+        <listcell label="cell2"/>
+      </listitem>
+    </listbox>
+
+    <label control="listbox3" value="multicolumn listbox with header"/>
+    <listbox id="listbox3">
+      <listhead>
+        <listheader label="header1"/>
+        <listheader label="header2"/>
+        <listheader label="header3"/>
+      </listhead>
+      <listcols>
+        <listcol flex="1"/>
+        <listcol flex="1"/>
+        <listcol flex="1"/>
+      </listcols>
+      <listitem>
+        <listcell label="cell0"/>
+        <listcell label="cell1"/>
+        <listcell label="cell2"/>
+      </listitem>
+      <listitem>
+        <listcell label="cell3"/>
+        <listcell label="cell4"/>
+        <listcell label="cell5"/>
+      </listitem>
+      <listitem>
+        <listcell label="cell6"/>
+        <listcell label="cell7"/>
+        <listcell label="cell8"/>
+      </listitem>
+    </listbox>
+  </vbox>
+  </hbox>
+
+</window>
+
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/test_table_indexes.html
@@ -0,0 +1,294 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=410052
+-->
+<head>
+  <title>Table indexes chrome tests</title>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+  <script type="application/javascript">
+    function doTest()
+    {
+      const nsIAccessibleRetrieval =
+        Components.interfaces.nsIAccessibleRetrieval;
+      const nsIAccessibleTable = Components.interfaces.nsIAccessibleTable;
+
+      var accService = Components.classes["@mozilla.org/accessibleRetrieval;1"].
+                       getService(nsIAccessibleRetrieval);
+
+      //////////////////////////////////////////////////////////////////////////
+      // table
+      var table = document.getElementById("table");
+      var tableAcc = accService.getAccessibleFor(table).
+        QueryInterface(nsIAccessibleTable);
+
+      var row, column, index;
+      var tRow = new Array(0,0,0,1,1,1,2,2,3,3);
+      var tCol = new Array(0,1,2,0,1,2,0,1,1,2);
+
+      for (var i = 0; i < 10; i++) {
+        row = tableAcc.getRowAtIndex(i);
+        column = tableAcc.getColumnAtIndex(i);
+        index = tableAcc.getIndexAt(tRow[i], tCol[i]);
+        is(row, tRow[i], "table: row  for index " + i +" is nor correct");
+        is(column, tCol[i], "table: column  for index " + i +"is nor correct");
+        is(index, i,
+           "table: row " + row + " /column " + column + " and index " + index + " aren't inconsistent.");
+      }
+
+      //////////////////////////////////////////////////////////////////////////
+      // tableinsane1
+      table = document.getElementById("tableinsane1");
+      tableAcc = accService.getAccessibleFor(table).
+        QueryInterface(nsIAccessibleTable);
+
+      tRow = [0,0,0,1,1,1,2,2,3,3];
+      tCol = [0,1,2,0,1,2,0,1,1,2];
+
+      for (var i = 0; i < 10; i++) {
+        row = tableAcc.getRowAtIndex(i);
+        column = tableAcc.getColumnAtIndex(i);
+        index = tableAcc.getIndexAt(tRow[i], tCol[i]);
+        is(row, tRow[i],
+           "tableinsane1: row  for index " + i +" is nor correct");
+        is(column, tCol[i],
+           "tableinsane1: column  for index " + i +"is nor correct");
+        is(index, i,
+           "tableinsane1: row " + row + " /column " + column + " and index " + index + " aren't inconsistent.");
+      }
+
+      //////////////////////////////////////////////////////////////////////////
+      // tableinsane2
+      table = document.getElementById("tableinsane2");
+      tableAcc = accService.getAccessibleFor(table).
+        QueryInterface(nsIAccessibleTable);
+    
+      tRow = [0,0,0,1,1,1,2,2,3,3,4,4,4];
+      tCol = [0,1,2,0,1,2,0,1,1,2,1,3,4];
+
+      for (var i = 0; i < 13; i++) {
+        row = tableAcc.getRowAtIndex(i);
+        column = tableAcc.getColumnAtIndex(i);
+        index = tableAcc.getIndexAt(tRow[i], tCol[i]);
+        is(row, tRow[i],
+           "tableinsane2: row  for index " + i +" is nor correct");
+        is(column, tCol[i],
+           "tableinsane2: column  for index " + i +"is nor correct");
+        is(index, i,
+           "tableinsane2: row " + row + " /column " + column + " and index " + index + " aren't inconsistent.");
+      }
+
+      //////////////////////////////////////////////////////////////////////////
+      // tableinsane4
+      table = document.getElementById("tableinsane4");
+      tableAcc = accService.getAccessibleFor(table).
+        QueryInterface(Components.interfaces.nsIAccessibleTable);
+
+      tRow = [0,0,0,1,1,1,2,2,3,4];
+      tCol = [0,1,2,0,1,2,0,2,0,0];
+
+      for (var i = 0; i < 10; i++) {
+        row = tableAcc.getRowAtIndex(i);
+        column = tableAcc.getColumnAtIndex(i);
+        index = tableAcc.getIndexAt(tRow[i], tCol[i]);
+        is(row, tRow[i],
+           "tableinsane4: row  for index " + i +" is nor correct");
+        is(column, tCol[i],
+           "tableinsane4: column  for index " + i +"is nor correct");
+        is(index, i,
+           "tableinsane4: row " + row + " /column " + column + " and index " + index + " aren't inconsistent.");
+      }
+
+      //////////////////////////////////////////////////////////////////////////
+      // tableborder
+      var table = document.getElementById("tableborder");
+      var tableAcc = accService.getAccessibleFor(table).
+        QueryInterface(nsIAccessibleTable);
+
+      tRow = [0,0,0,1,1,1,2,2,3,3];
+      tCol = [0,1,2,0,1,2,0,1,1,2];
+
+      for (var i = 0; i < 10; i++) {
+        row = tableAcc.getRowAtIndex(i);
+        column = tableAcc.getColumnAtIndex(i);
+        index = tableAcc.getIndexAt(tRow[i], tCol[i]);
+        is(row, tRow[i],
+           "tableborder: row  for index " + i +" is nor correct");
+        is(column, tCol[i],
+           "tableborder: column  for index " + i +"is nor correct");
+        is(index, i,
+           "tableborder: row " + row + " /column " + column + " and index " + index + " aren't inconsistent.");
+      }
+
+      SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addLoadEvent(doTest);
+  </script>
+</head>
+<body>
+
+  <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=410052">Mozilla Bug 410052</a>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+
+  <!--
+    If you change the structure of the table please make sure to change
+    the indexes count in 'for' statement in the script above.
+  -->
+  <table border="1" id="table">
+    <caption><strong><b><font size="29">this is a caption for this table</font></b></strong></caption>
+    <thead>
+      <tr>
+        <th>col1</th>
+        <th>col2</th>
+        <th>col3</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>1</td>
+        <td>2</td>
+        <td>3</td>
+      </tr>
+      <tr>
+        <td rowspan="0">4</td>
+        <td colspan="2">5</td>
+      </tr>
+      <tr>
+        <td>6</td>
+        <td>7</td>
+      </tr>
+    </tbody>
+  </table>
+
+  <table border="1" id="tableborder" style="border-collapse:collapse">
+    <caption><strong><b><font size="29">this is a caption for this bc table</font></b></strong></caption>
+    <thead>
+      <tr>
+        <th>col1</th>
+        <th>col2</th>
+        <th>col3</th>
+      </tr>
+    </thead>
+    <tbody>
+      <tr>
+        <td>1</td>
+        <td>2</td>
+        <td>3</td>
+      </tr>
+      <tr>
+        <td rowspan="2">4</td>
+        <td colspan="2">5</td>
+      </tr>
+      <tr>
+        <td>6</td>
+        <td>7</td>
+      </tr>
+    </tbody>
+  </table>
+
+  <table border="1" id="tableinsane1">
+    <caption>test empty row groups</caption>
+    <thead>
+      <tr>
+        <th>col1</th>
+        <th>col2</th>
+        <th>col3</th>
+      </tr>
+    </thead>
+    <tbody></tbody>
+    <tbody></tbody>
+    <tbody></tbody>
+    <tbody>
+      <tr>
+        <td>1</td>
+        <td>2</td>
+        <td>3</td>
+      </tr>
+      <tr>
+        <td rowspan="2">4</td>
+        <td colspan="2">5</td>
+      </tr>
+      <tr>
+        <td>6</td>
+        <td>7</td>
+      </tr>
+    </tbody>
+  </table>
+
+  <table border="1" id="tableinsane2" >
+    <caption>empty rowgroup + empty rows</caption>
+    <thead>
+      <tr>
+        <th>col1</th>
+        <th>col2</th>
+        <th>col3</th>
+      </tr>
+    </thead>
+    <tbody><tr></tr></tbody>
+    <tbody></tbody>
+    <tbody></tbody>
+    <tbody>
+      <tr>
+        <td>1</td>
+        <td>2</td>
+        <td>3</td>
+      </tr>
+      <tr>
+        <td rowspan="0">4</td>
+        <td colspan="0">5</td>
+      </tr>
+      <tr>
+        <td>6</td>
+        <td  rowspan="0">7</td>
+      </tr>
+      <tr>
+        <td>8</td>
+        <td>9</td>
+        <td>10</td>
+      </tr>
+
+    </tbody>
+
+  <table border="1" id="tableinsane4" >
+    <caption>test cellmap holes</caption>
+    <thead>
+      <tr>
+        <th>col1</th>
+        <th>col2</th>
+        <th>col3</th>
+      </tr>
+    </thead>
+    <tbody><tr></tr></tbody>
+    <tbody></tbody>
+    <tbody></tbody>
+    <tbody>
+      <tr>
+        <td>1</td>
+        <td>2</td>
+        <td>3</td>
+      </tr>
+      <tr>
+         <td colspan="2">4</td>
+        <td rowspan="2">5</td>
+        </tr>
+      <tr>
+        <td>6</td>
+      </tr>
+      <tr>
+        <td colspan="3">7</td>       
+      </tr>
+
+    </tbody>
+  </table>
+
+</body>
+</html>
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -193,16 +193,18 @@ pref("browser.startup.homepage",        
 
 pref("browser.cache.disk.capacity",         50000);
 pref("browser.enable_automatic_image_resizing", true);
 pref("browser.chrome.site_icons", true);
 pref("browser.chrome.favicons", true);
 pref("browser.formfill.enable", true);
 pref("browser.warnOnQuit", true);
 pref("browser.warnOnRestart", true);
+pref("browser.fullscreen.autohide", true);
+pref("browser.fullscreen.animateUp", 1);
 
 #ifdef UNIX_BUT_NOT_MAC
 pref("browser.urlbar.clickSelectsAll", false);
 #else
 pref("browser.urlbar.clickSelectsAll", true);
 #endif
 #ifdef UNIX_BUT_NOT_MAC
 pref("browser.urlbar.doubleClickSelectsAll", true);
@@ -598,16 +600,20 @@ pref("browser.safebrowsing.provider.0.re
 pref("browser.safebrowsing.warning.infoURL", "http://%LOCALE%.www.mozilla.com/%LOCALE%/firefox/phishing-protection/");
 
 // Name of the about: page contributed by safebrowsing to handle display of error
 // pages on phishing/malware hits.  (bug 399233)
 pref("urlclassifier.alternate_error_page", "blocked");
 
 // The number of random entries to send with a gethash request.
 pref("urlclassifier.gethashnoise", 4);
+
+// URL for checking the reason for a malware warning.
+pref("browser.safebrowsing.malware.reportURL", "http://www.stopbadware.org/reports/container?source=@APP_UA_NAME@&version=@APP_VERSION@&reportname=");
+
 #endif
 
 // defaults to true
 pref("browser.EULA.2.accepted", true);
 
 // if we rev the EULA again, we should bump this so users agree to the new EULA
 pref("browser.EULA.version", 2);
 
new file mode 100644
--- /dev/null
+++ b/browser/base/content/aboutRobots.xhtml
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License
+# Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is netError.xhtml.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Adam Lock <adamlock@netscape.com>
+#   William R. Price <wrprice@alumni.rice.edu>
+#   Henrik Skupin <mozilla@hskupin.info>
+#   Jeff Walden <jwalden+code@mit.edu>
+#   Johnathan Nightingale <johnath@mozilla.com>
+#   Justin Dolske <dolske@mozilla.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK ***** -->
+
+<!DOCTYPE html [
+  <!ENTITY % htmlDTD
+    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+    "DTD/xhtml1-strict.dtd">
+  %htmlDTD;
+  <!ENTITY % netErrorDTD
+    SYSTEM "chrome://global/locale/netError.dtd">
+  %netErrorDTD;
+  <!ENTITY % globalDTD
+    SYSTEM "chrome://global/locale/global.dtd">
+  %globalDTD;
+  <!ENTITY % aboutrobotsDTD
+    SYSTEM "chrome://browser/locale/aboutRobots.dtd">
+  %aboutrobotsDTD;
+]>
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <title>&robots.pagetitle;</title>
+    <link rel="stylesheet" href="chrome://global/skin/netError.css" type="text/css" media="all" />
+    <link rel="icon" type="image/png" id="favicon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8%2F9hAAAACGFjVEwAAAASAAAAAJNtBPIAAAAaZmNUTAAAAAAAAAAQAAAAEAAAAAAAAAAALuAD6AABhIDeugAAALhJREFUOI2Nk8sNxCAMRDlGohauXFOMpfTiAlxICqAELltHLqlgctg1InzMRhpFAc%2BLGWTnmoeZYamt78zXdZmaQtQMADlnU0OIAlbmJUBEcO4bRKQY2rUXIPmAGnDuG%2FBx3%2FfvOPVaDUg%2BoAPUf1PArIMCSD5glMEsUGaG%2BkyAFWIBaCsKuA%2BHGCNijLgP133XgOEtaPFMy2vUolEGJoCIzBmoRUR9%2B7rxj16DZaW%2FmgtmxnJ8V3oAnApQwNS5zpcAAAAaZmNUTAAAAAEAAAAQAAAAEAAAAAAAAAAAAB4D6AIB52fclgAAACpmZEFUAAAAAjiNY2AYBVhBc3Pzf2LEcGreqcbwH1kDNjHauWAUjAJyAADymxf9WF%2Bu8QAAABpmY1RMAAAAAwAAABAAAAAQAAAAAAAAAAAAHgPoAgEK8Q9%2FAAAAFmZkQVQAAAAEOI1jYBgFo2AUjAIIAAAEEAAB0xIn4wAAABpmY1RMAAAABQAAABAAAAAQAAAAAAAAAAAAHgPoAgHnO30FAAAAQGZkQVQAAAAGOI1jYBieYKcaw39ixHCC%2F6cwFWMTw2rz%2F1MM%2F6Vu%2Ff%2F%2F%2FxTD%2F51qEIwuRjsXILuEGLFRMApgAADhNCsVfozYcAAAABpmY1RMAAAABwAAABAAAAAQAAAAAAAAAAAAHgPoAgEKra7sAAAAFmZkQVQAAAAIOI1jYBgFo2AUjAIIAAAEEAABM9s3hAAAABpmY1RMAAAACQAAABAAAAAQAAAAAAAAAAAAHgPoAgHn3p%2BwAAAAKmZkQVQAAAAKOI1jYBgFWEFzc%2FN%2FYsRwat6pxvAfWQM2Mdq5YBSMAnIAAPKbF%2F1BhPl6AAAAGmZjVEwAAAALAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAQpITFkAAAAWZmRBVAAAAAw4jWNgGAWjYBSMAggAAAQQAAHaszpmAAAAGmZjVEwAAAANAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAeeCPiMAAABAZmRBVAAAAA44jWNgGJ5gpxrDf2LEcIL%2FpzAVYxPDavP%2FUwz%2FpW79%2F%2F%2F%2FFMP%2FnWoQjC5GOxcgu4QYsVEwCmAAAOE0KxUmBL0KAAAAGmZjVEwAAAAPAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAQoU7coAAAAWZmRBVAAAABA4jWNgGAWjYBSMAggAAAQQAAEpOBELAAAAGmZjVEwAAAARAAAAEAAAABAAAAAAAAAAAAAeA%2BgCAeYVWtoAAAAqZmRBVAAAABI4jWNgGAVYQXNz839ixHBq3qnG8B9ZAzYx2rlgFIwCcgAA8psX%2FWvpAecAAAAaZmNUTAAAABMAAAAQAAAAEAAAAAAAAAAAAB4D6AIBC4OJMwAAABZmZEFUAAAAFDiNY2AYBaNgFIwCCAAABBAAAcBQHOkAAAAaZmNUTAAAABUAAAAQAAAAEAAAAAAAAAAAAB4D6AIB5kn7SQAAAEBmZEFUAAAAFjiNY2AYnmCnGsN%2FYsRwgv%2BnMBVjE8Nq8%2F9TDP%2Blbv3%2F%2F%2F8Uw%2F%2BdahCMLkY7FyC7hBixUTAKYAAA4TQrFc%2BcEoQAAAAaZmNUTAAAABcAAAAQAAAAEAAAAAAAAAAAAB4D6AIBC98ooAAAABZmZEFUAAAAGDiNY2AYBaNgFIwCCAAABBAAASCZDI4AAAAaZmNUTAAAABkAAAAQAAAAEAAAAAAAAAAAAB4D6AIB5qwZ%2FAAAACpmZEFUAAAAGjiNY2AYBVhBc3Pzf2LEcGreqcbwH1kDNjHauWAUjAJyAADymxf9cjJWbAAAABpmY1RMAAAAGwAAABAAAAAQAAAAAAAAAAAAHgPoAgELOsoVAAAAFmZkQVQAAAAcOI1jYBgFo2AUjAIIAAAEEAAByfEBbAAAABpmY1RMAAAAHQAAABAAAAAQAAAAAAAAAAAAHgPoAgHm8LhvAAAAQGZkQVQAAAAeOI1jYBieYKcaw39ixHCC%2F6cwFWMTw2rz%2F1MM%2F6Vu%2Ff%2F%2F%2FxTD%2F51qEIwuRjsXILuEGLFRMApgAADhNCsVlxR3%2FgAAABpmY1RMAAAAHwAAABAAAAAQAAAAAAAAAAAAHgPoAgELZmuGAAAAFmZkQVQAAAAgOI1jYBgFo2AUjAIIAAAEEAABHP5cFQAAABpmY1RMAAAAIQAAABAAAAAQAAAAAAAAAAAAHgPoAgHlgtAOAAAAKmZkQVQAAAAiOI1jYBgFWEFzc%2FN%2FYsRwat6pxvAfWQM2Mdq5YBSMAnIAAPKbF%2F0%2FMvDdAAAAAElFTkSuQmCC"/>
+
+    <script type="application/x-javascript"><![CDATA[
+      var buttonClicked = false;
+      function robotButton()
+      {
+        var button = document.getElementById('errorTryAgain');
+        if (buttonClicked) {
+          button.style.visibility = "hidden";
+        } else {
+          var newLabel = button.getAttribute("label2");
+          button.setAttribute("label", newLabel);
+          buttonClicked = true;
+        }
+      }
+    ]]></script>
+  </head>
+
+  <body dir="&locale.dir;">
+
+    <!-- PAGE CONTAINER (for styling purposes only) -->
+    <div id="errorPageContainer">
+    
+      <!-- Error Title -->
+      <div id="errorTitle">
+        <h1 id="errorTitleText">&robots.errorTitleText;</h1>
+      </div>
+      
+      <!-- LONG CONTENT (the section most likely to require scrolling) -->
+      <div id="errorLongContent">
+      
+        <!-- Short Description -->
+        <div id="errorShortDesc">
+          <p id="errorShortDescText">&robots.errorShortDescText;</p>
+        </div>
+
+        <!-- Long Description (Note: See netError.dtd for used XHTML tags) -->
+        <div id="errorLongDesc">
+          <ul>
+            <li>&robots.errorLongDesc1;</li>
+            <li>&robots.errorLongDesc2;</li>
+            <li>&robots.errorLongDesc3;</li>
+            <li>&robots.errorLongDesc4;</li>
+          </ul>
+        </div>
+
+        <!-- Short Description -->
+        <div id="errorTrailerDesc">
+          <p id="errorTrailerDescText" style="float: right;">&robots.errorTrailerDescText;</p>
+        </div>
+
+      </div>
+
+      <!-- Button -->
+      <xul:button xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+                  id="errorTryAgain"
+                  label="&retry.label;"
+                  label2="&robots.dontpress;"
+                  oncommand="robotButton();" />
+
+    </div>
+
+  </body>
+</html>
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -71,23 +71,25 @@
                           type="checkbox" oncommand="BrowserOffline.toggleOfflineStatus();"/>
                 <menuitem id="menu_FileQuitItem" 
 #ifdef XP_WIN
         label="&quitApplicationCmdWin.label;"
         accesskey="&quitApplicationCmdWin.accesskey;"
 #else
 #ifdef XP_MACOSX
         label="&quitApplicationCmdMac.label;"
-        key="key_quitApplicationCmdMac"
 #else
         label="&quitApplicationCmd.label;"
         accesskey="&quitApplicationCmd.accesskey;"
 #endif
+#ifdef XP_UNIX
+        key="key_quitApplication"
 #endif
-        oncommand="goQuitApplication();"/>
+#endif
+        command="cmd_quitApplication"/>
               </menupopup>
             </menu>
   
             <menu id="edit-menu" label="&editMenu.label;"
                   accesskey="&editMenu.accesskey;">
               <menupopup id="menu_EditPopup"
                          onpopupshowing="updateEditUIVisibility()"
                          onpopuphidden="updateEditUIVisibility()">
@@ -332,44 +334,46 @@
                   oncommand="var url = event.target.getAttribute('statustext'); if (url) { PlacesUtils.markPageAsTyped(url); openUILink(url, event, false, true); }"
                   onclick="checkForMiddleClick(this, event);"
                   label="&historyMenu.label;"
                   accesskey="&historyMenu.accesskey;">
               <menupopup id="goPopup"
                          type="places"
                          onpopupshowing="HistoryMenu.onPopupShowing(this);"
                          place="place:type=0&amp;sort=4&amp;maxResults=10">
-                <menuitem label="&backCmd.label;"
+                <menuitem id="historyMenuBack"
+                          label="&backCmd.label;"
 #ifdef XP_MACOSX
                           key="goBackKb2"
 #else
                           key="goBackKb"
 #endif
                           chromedir="&locale.dir;"
                           oncommand="BrowserBack(event, true)"
                           onclick="checkForMiddleClick(this, event);">
                   <observes element="Browser:Back" attribute="disabled" />
                 </menuitem>
-                <menuitem label="&forwardCmd.label;" 
+                <menuitem id="historyMenuForward"
+                          label="&forwardCmd.label;"
 #ifdef XP_MACOSX
                           key="goForwardKb2"
 #else
                           key="goForwardKb"
 #endif
                           chromedir="&locale.dir;"
                           oncommand="BrowserForward(event, true)"
                           onclick="checkForMiddleClick(this, event);">
                   <observes element="Browser:Forward" attribute="disabled" />
                 </menuitem>
 
                 <menuitem label="&historyHomeCmd.label;"
                           oncommand="BrowserGoHome(event);"
                           onclick="checkForMiddleClick(this, event);"
                           key="goHome"/>
-                <menuitem label="&showAllHistoryCmd.label;"
+                <menuitem label="&showAllHistoryCmd2.label;"
 #ifndef XP_MACOSX
                           key="showAllHistoryKb"
 #endif
                           command="Browser:ShowAllHistory"/>
                 <menuseparator id="startHistorySeparator" builder="start"/>
                 <menuseparator id="endHistorySeparator" builder="end"/>
                 <menu id="historyUndoMenu" label="&historyUndoMenu.label;" disabled="true">
                   <menupopup id="historyUndoPopup" onpopupshowing="HistoryMenu.populateUndoSubmenu();"/>
@@ -402,17 +406,17 @@
             hidden="true">
         <menupopup id="subscribeToPageSubmenuMenupopup" 
                    onpopupshowing="return FeedHandler.buildFeedList(event.target);" 
                    oncommand="return FeedHandler.subscribeToFeed(null, event);"
                    onclick="checkForMiddleClick(this, event);"/>
       </menu>
       <menuitem label="&addCurPagesCmd.label;" 
                 command="Browser:BookmarkAllTabs" key="bookmarkAllTabsKb"/>
-      <menuitem label="&showAllBookmarksCmd.label;" 
+      <menuitem label="&showAllBookmarksCmd2.label;" 
                 command="Browser:ShowAllBookmarks" key="manBookmarkKb"/>
       <menuseparator builder="start"/>
     </menupopup>
   </menu>
         
             <menu id="tools-menu" label="&toolsMenu.label;" accesskey="&toolsMenu.accesskey;">
               <menupopup id="menu_ToolsPopup">
               <menuitem label="&search.label;" accesskey="&search.accesskey;" 
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -748,23 +748,19 @@ var BookmarksMenuDropHandler = {
   },
 
   /**
    * Advertises the set of data types that can be dropped on the Bookmarks
    * Menu
    * @returns a FlavourSet object per nsDragAndDrop parlance.
    */
   getSupportedFlavours: function BMDH_getSupportedFlavours() {
-    var flavorSet = new FlavourSet();
     var view = document.getElementById("bookmarksMenuPopup");
-    var types = PlacesUtils.GENERIC_VIEW_DROP_TYPES
-    for (var i = 0; i < types.length; ++i)
-      flavorSet.appendFlavour(types[i]);
-    return flavorSet;
-  }, 
+    return view.getSupportedFlavours();
+  },
 
   /**
    * Determine whether or not the user can drop on the Bookmarks Menu.
    * @param   event
    *          A dragover event
    * @param   session
    *          The active DragSession
    * @returns true if the user can drop onto the Bookmarks Menu item, false 
@@ -779,21 +775,19 @@ var BookmarksMenuDropHandler = {
    * @param   event
    *          A drop event
    * @param   data
    *          Data that was dropped
    * @param   session
    *          The active DragSession
    */
   onDrop: function BMDH_onDrop(event, data, session) {
-    var view = document.getElementById("bookmarksMenuPopup");
     // Put the item at the end of bookmark menu
     var ip = new InsertionPoint(PlacesUtils.bookmarksMenuFolderId, -1);
     PlacesControllerDragHelper.onDrop(ip);
-    view._rebuild();
   }
 };
 
 /**
  * Handles special drag and drop functionality for menus on the Bookmarks 
  * Toolbar and Bookmarks Menu.
  */
 var PlacesMenuDNDController = {
--- a/browser/base/content/browser-sets.inc
+++ b/browser/base/content/browser-sets.inc
@@ -66,16 +66,17 @@
 
     <command id="cmd_pageSetup" oncommand="PrintUtils.showPageSetup();"/>
     <command id="cmd_print" oncommand="PrintUtils.print();"/>
     <command id="cmd_printPreview" oncommand="PrintUtils.printPreview(onEnterPrintPreview, onExitPrintPreview);"/>
     <command id="cmd_close" oncommand="BrowserCloseTabOrWindow()"/>
     <command id="cmd_closeWindow" oncommand="BrowserTryToCloseWindow()"/>
     <command id="cmd_toggleTaskbar" oncommand="goToggleToolbar('status-bar','toggle_taskbar');"/>
     <command id="cmd_CustomizeToolbars" oncommand="BrowserCustomizeToolbar()"/>
+    <command id="cmd_quitApplication" oncommand="goQuitApplication()"/>
 
 
     <commandset id="editMenuCommands"/>
 
     <command id="View:PageSource" oncommand="BrowserViewSourceOfDocument(content.document);" observes="isImage"/>
     <command id="View:PageInfo" oncommand="BrowserPageInfo();"/>
     <command id="View:FullScreen" oncommand="BrowserFullScreen();"/>
     <command id="cmd_find"
@@ -297,18 +298,21 @@
     <key                          key="&fullZoomEnlargeCmd.commandkey2;" command="cmd_fullZoomEnlarge" modifiers="accel"/>
     <key id="key_fullZoomReset"   key="&fullZoomResetCmd.commandkey;"    command="cmd_fullZoomReset"   modifiers="accel"/>
     
     <key id="key_switchTextDirection" key="&bidiSwitchTextDirectionItem.commandkey;" command="cmd_switchTextDirection" modifiers="accel,shift" />
 
     <key id="key_sanitize" command="Tools:Sanitize" keycode="VK_DELETE" modifiers="accel,shift"/>
 #ifdef XP_MACOSX
     <key id="key_sanitize_mac" command="Tools:Sanitize" keycode="VK_BACK" modifiers="accel,shift"/>
-    <key id="key_quitApplicationCmdMac" key="&quitApplicationCmdMac.key;" modifiers="accel"/>
 #endif
+#ifdef XP_UNIX
+    <key id="key_quitApplication" key="&quitApplicationCmdMac.key;" command="cmd_quitApplication" modifiers="accel"/>
+#endif
+
     <key id="key_undoCloseTab" command="History:UndoCloseTab" key="&tabCmd.commandkey;" modifiers="accel,shift"/>
   </keyset>
 
 # Used by baseMenuOverlay
 #ifdef XP_MACOSX
   <commandset id="baseMenuCommandSet" />
 #endif
   <keyset id="baseMenuKeyset" />
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -70,8 +70,19 @@ window[chromehidden~="toolbar"] toolbar:
 #identity-popup-content-box.unknownIdentity > #identity-popup-connectedToLabel ,
 #identity-popup-content-box.unknownIdentity > #identity-popup-runByLabel ,
 #identity-popup-content-box.unknownIdentity > #identity-popup-content-host ,
 #identity-popup-content-box.unknownIdentity > #identity-popup-content-owner ,
 #identity-popup-content-box.verifiedIdentity > #identity-popup-connectedToLabel2 ,
 #identity-popup-content-box.verifiedDomain > #identity-popup-connectedToLabel2 {
   display: none;
 }
+
+/* ::::: Fullscreen pseudo-toolbar ::::: */
+#fullscr-toggler {
+  display: none;
+  min-height: 5px;
+  height: 5px;
+}
+
+#navigator-toolbox[inFullscreen="true"] #fullscr-toggler {
+  display: -moz-box;
+}
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1526,16 +1526,19 @@ function focusAndSelectUrlBar()
     gURLBar.select();
     return true;
   }
   return false;
 }
 
 function openLocation()
 {
+  if (window.fullScreen)
+    FullScreen.mouseoverToggle(true);
+
   if (focusAndSelectUrlBar())
     return;
 #ifdef XP_MACOSX
   if (window.location.href != getBrowserURL()) {
     var win = getTopWin();
     if (win) {
       // If there's an open browser window, it should handle this command
       win.focus()
@@ -1630,18 +1633,34 @@ function BrowserCloseTabOrWindow()
   }
 #endif
 
   closeWindow(true);
 }
 
 function BrowserTryToCloseWindow()
 {
-  if (WindowIsClosing())
+  if (WindowIsClosing()) {
+    if (window.fullScreen) {
+      gBrowser.mPanelContainer.removeEventListener("mousemove",
+                                                   FullScreen._collapseCallback, false);
+      document.removeEventListener("keypress", FullScreen._keyToggleCallback, false);
+      document.removeEventListener("popupshown", FullScreen._setPopupOpen, false);
+      document.removeEventListener("popuphidden", FullScreen._setPopupOpen, false);
+      gPrefService.removeObserver("browser.fullscreen", FullScreen);
+
+      var fullScrToggler = document.getElementById("fullscr-toggler");
+      if (fullScrToggler) {
+        fullScrToggler.removeEventListener("mouseover", FullScreen._expandCallback, false);
+        fullScrToggler.removeEventListener("dragenter", FullScreen._expandCallback, false);
+      }
+    }
+
     window.close();     // WindowIsClosing does all the necessary checks
+  }
 }
 
 function loadURI(uri, referrer, postData, allowThirdPartyFixup)
 {
   try {
     if (postData === undefined)
       postData = null;
     var flags = nsIWebNavigation.LOAD_FLAGS_NONE;
@@ -1731,19 +1750,24 @@ function getShortcutOrURI(aURL, aPostDat
       encodedParam = encodeURIComponent(param);
 
     shortcutURL = shortcutURL.replace(/%s/g, encodedParam).replace(/%S/g, param);
 
     if (/%s/i.test(postData)) // POST keyword
       aPostDataRef.value = getPostDataStream(postData, param, encodedParam,
                                              "application/x-www-form-urlencoded");
   }
-  else
+  else if (param) {
+    // This keyword doesn't take a parameter, but one was provided. Just return
+    // the original URL.
     aPostDataRef.value = null;
 
+    return aURL;
+  }
+
   return shortcutURL;
 }
  
 function getPostDataStream(aStringData, aKeyword, aEncKeyword, aType) {
   var dataStream = Cc["@mozilla.org/io/string-input-stream;1"].
                    createInstance(Ci.nsIStringInputStream);
   aStringData = aStringData.replace(/%s/g, aEncKeyword).replace(/%S/g, aKeyword);
   dataStream.data = aStringData;
@@ -2227,22 +2251,22 @@ function BrowserImport()
 /**
  * Handle command events bubbling up from error page content
  */
 function BrowserOnCommand(event) {
     // Don't trust synthetic events
     if (!event.isTrusted)
       return;
 
+    var ot = event.originalTarget;
+    var errorDoc = ot.ownerDocument;
+
     // If the event came from an ssl error page, it is probably either the "Add
     // Exception…" or "Get me out of here!" button
-    if (/^about:neterror\?e=nssBadCert/.test(event.originalTarget.ownerDocument.documentURI)) {
-      var ot = event.originalTarget;
-      var errorDoc = ot.ownerDocument;
-      
+    if (/^about:neterror\?e=nssBadCert/.test(errorDoc.documentURI)) {
       if (ot == errorDoc.getElementById('exceptionDialogButton')) {
         var params = { exceptionAdded : false };
         
         try {
           switch (gPrefService.getIntPref("browser.ssl_override_behavior")) {
             case 2 : // Pre-fetch & pre-populate
               params.prefetchCert = true;
             case 1 : // Pre-populate
@@ -2255,33 +2279,76 @@ function BrowserOnCommand(event) {
         window.openDialog('chrome://pippki/content/exceptionDialog.xul',
                           '','chrome,centerscreen,modal', params);
         
         // If the user added the exception cert, attempt to reload the page
         if (params.exceptionAdded)
           errorDoc.location.reload();
       }
       else if (ot == errorDoc.getElementById('getMeOutOfHereButton')) {
-        // Redirect them to a known-functioning page, default start page
-        var prefs = Cc["@mozilla.org/preferences-service;1"]
-                    .getService(Ci.nsIPrefService).getDefaultBranch(null);
-        var url = "about:blank";
-        try {
-          url = prefs.getComplexValue("browser.startup.homepage",
-                                      Ci.nsIPrefLocalizedString).data;
-          // If url is a pipe-delimited set of pages, just take the first one.
-          if (url.indexOf("|") != -1)
-            url = url.split("|")[0];
-        } catch(e) {
-          Components.utils.reportError("Couldn't get homepage pref: " + e);
+        getMeOutOfHere();
+      }
+    }
+    else if (/^about:blocked/.test(errorDoc.documentURI)) {
+      // The event came from a button on a malware/phishing block page
+      
+      if (ot == errorDoc.getElementById('getMeOutButton')) {
+        getMeOutOfHere();
+      }
+      else if (ot == errorDoc.getElementById('reportButton')) {
+        // This is the "Why is this site blocked" button.  For malware,
+        // we can fetch a site-specific report, for phishing, we redirect
+        // to the generic page describing phishing protection.
+        if (/e=malwareBlocked/.test(errorDoc.documentURI)) {
+          // Get the stop badware "why is this blocked" report url,
+          // append the current url, and go there.
+          try {
+            var reportURL = gPrefService.getCharPref("browser.safebrowsing.malware.reportURL");
+            reportURL += content.location.href;
+            content.location = reportURL;
+          } catch (e) {
+            Components.utils.reportError("Couldn't get malware report URL: " + e);
+          }
         }
-        content.location = url;
+        else if (/e=phishingBlocked/.test(errorDoc.documentURI)) {
+          try {
+            content.location = Cc["@mozilla.org/toolkit/URLFormatterService;1"]
+                              .getService(Components.interfaces.nsIURLFormatter)
+                              .formatURLPref("browser.safebrowsing.warning.infoURL");
+          } catch (e) {
+            Components.utils.reportError("Couldn't get phishing info URL: " + e);
+          }
+        }
       }
     }
+}
+
+/**
+ * Re-direct the browser to a known-safe page.  This function is
+ * used when, for example, the user browses to a known malware page
+ * and is presented with about:blocked.  The "Get me out of here!"
+ * button should take the user to the default start page so that even
+ * when their own homepage is infected, we can get them somewhere safe.
+ */
+function getMeOutOfHere() {
+  // Get the start page from the *default* pref branch, not the user's
+  var prefs = Cc["@mozilla.org/preferences-service;1"]
+             .getService(Ci.nsIPrefService).getDefaultBranch(null);
+  var url = "about:blank";
+  try {
+    url = prefs.getComplexValue("browser.startup.homepage",
+                                Ci.nsIPrefLocalizedString).data;
+    // If url is a pipe-delimited set of pages, just take the first one.
+    if (url.indexOf("|") != -1)
+      url = url.split("|")[0];
+  } catch(e) {
+    Components.utils.reportError("Couldn't get homepage pref: " + e);
   }
+  content.location = url;
+}
 
 function BrowserFullScreen()
 {
   window.fullScreen = !window.fullScreen;
 }
 
 function onFullScreen()
 {
@@ -2732,18 +2799,20 @@ const DOMLinkHandler = {
             var uri = ios.newURI(link.href, targetDoc.characterSet, null);
 
             if (gBrowser.isFailedIcon(uri))
               break;
 
             // Verify that the load of this icon is legal.
             // error pages can load their favicon, to be on the safe side,
             // only allow chrome:// favicons
-            const aboutNeterr = "about:neterror?";
-            if (targetDoc.documentURI.substr(0, aboutNeterr.length) != aboutNeterr ||
+            const aboutNeterr = /^about:neterror\?/;
+            const aboutBlocked = /^about:blocked\?/;
+            if (!(aboutNeterr.test(targetDoc.documentURI) ||
+                  aboutBlocked.test(targetDoc.documentURI)) ||
                 !uri.schemeIs("chrome")) {
               var ssm = Cc["@mozilla.org/scriptsecuritymanager;1"].
                         getService(Ci.nsIScriptSecurityManager);
               try {
                 ssm.checkLoadURIWithPrincipal(targetDoc.nodePrincipal, uri,
                                               Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
               } catch(e) {
                 break;
@@ -2875,16 +2944,19 @@ const BrowserSearch = {
 
         win = window.openDialog("chrome://browser/content/", "_blank",
                                 "chrome,all,dialog=no", "about:blank");
         win.addEventListener("load", webSearchCallback, false);
       }
       return;
     }
 #endif
+    if (window.fullScreen)
+      FullScreen.mouseoverToggle(true);
+
     var searchBar = this.searchBar;
     if (isElementVisible(searchBar)) {
       searchBar.select();
       searchBar.focus();
     } else {
       var ss = Cc["@mozilla.org/browser/search-service;1"].
                getService(Ci.nsIBrowserSearchService);
       var searchForm = ss.defaultEngine.searchForm;
@@ -3267,67 +3339,285 @@ function updateEditUIVisibility()
     goSetCommandEnabled("cmd_delete", true);
     goSetCommandEnabled("cmd_switchTextDirection", true);
   }
 #endif
 }
 
 var FullScreen =
 {
+  _XULNS: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
   toggle: function()
   {
     // show/hide all menubars, toolbars, and statusbars (except the full screen toolbar)
     this.showXULChrome("toolbar", window.fullScreen);
     this.showXULChrome("statusbar", window.fullScreen);
     document.getElementById("fullScreenItem").setAttribute("checked", !window.fullScreen);
+
+    var fullScrToggler = document.getElementById("fullscr-toggler");
+    if (!window.fullScreen) {
+      // Add a tiny toolbar to receive mouseover and dragenter events, and provide affordance.
+      // This will help simulate the "collapse" metaphor while also requiring less code and
+      // events than raw listening of mouse coords.
+      if (!fullScrToggler) {
+        fullScrToggler = document.createElement("toolbar");
+        fullScrToggler.id = "fullscr-toggler";
+        fullScrToggler.setAttribute("customizable", "false");
+        fullScrToggler.setAttribute("moz-collapsed", "true");
+        var navBar = document.getElementById("nav-bar");
+        navBar.parentNode.insertBefore(fullScrToggler, navBar);
+      }
+      fullScrToggler.addEventListener("mouseover", this._expandCallback, false);
+      fullScrToggler.addEventListener("dragenter", this._expandCallback, false);
+
+      if (gPrefService.getBoolPref("browser.fullscreen.autohide"))
+        gBrowser.mPanelContainer.addEventListener("mousemove",
+                                                  this._collapseCallback, false);
+
+      document.addEventListener("keypress", this._keyToggleCallback, false);
+      document.addEventListener("popupshown", this._setPopupOpen, false);
+      document.addEventListener("popuphidden", this._setPopupOpen, false);
+      this._shouldAnimate = true;
+      this.mouseoverToggle(false);
+
+      // Autohide prefs
+      gPrefService.addObserver("browser.fullscreen", this, false);
+    }
+    else {
+      document.removeEventListener("keypress", this._keyToggleCallback, false);
+      document.removeEventListener("popupshown", this._setPopupOpen, false);
+      document.removeEventListener("popuphidden", this._setPopupOpen, false);
+      gPrefService.removeObserver("browser.fullscreen", this);
+
+      if (fullScrToggler) {
+        fullScrToggler.removeEventListener("mouseover", this._expandCallback, false);
+        fullScrToggler.removeEventListener("dragenter", this._expandCallback, false);
+      }
+
+      // The user may quit fullscreen during an animation
+      clearInterval(this._animationInterval);
+      getNavToolbox().style.marginTop = "0px";
+      if (this._isChromeCollapsed)
+        this.mouseoverToggle(true);
+      this._isAnimating = false;
+      // This is needed if they use the context menu to quit fullscreen
+      this._isPopupOpen = false;
+
+      gBrowser.mPanelContainer.removeEventListener("mousemove",
+                                                   this._collapseCallback, false);
+    }
+  },
+
+  observe: function(aSubject, aTopic, aData)
+  {
+    if (aData == "browser.fullscreen.autohide") {
+      if (gPrefService.getBoolPref("browser.fullscreen.autohide")) {
+        gBrowser.mPanelContainer.addEventListener("mousemove",
+                                                  this._collapseCallback, false);
+      }
+      else {
+        gBrowser.mPanelContainer.removeEventListener("mousemove",
+                                                     this._collapseCallback, false);
+      }
+    }
+  },
+
+  // Event callbacks
+  _expandCallback: function()
+  {
+    FullScreen.mouseoverToggle(true);
+  },
+  _collapseCallback: function()
+  {
+    FullScreen.mouseoverToggle(false);
+  },
+  _keyToggleCallback: function(aEvent)
+  {
+    // if we can use the keyboard (eg Ctrl+L or Ctrl+E) to open the toolbars, we
+    // should provide a way to collapse them too.
+    if (aEvent.keyCode == aEvent.DOM_VK_ESCAPE) {
+      FullScreen._shouldAnimate = false;
+      FullScreen.mouseoverToggle(false, true);
+    }
+    // F6 is another shortcut to the address bar, but its not covered in OpenLocation()
+    else if (aEvent.keyCode == aEvent.DOM_VK_F6)
+      FullScreen.mouseoverToggle(true);
+  },
+
+  // Checks whether we are allowed to collapse the chrome
+  _isPopupOpen: false,
+  _isChromeCollapsed: false,
+  _safeToCollapse: function(forceHide)
+  {
+    if (!gPrefService.getBoolPref("browser.fullscreen.autohide"))
+      return false;
+
+    // a popup menu is open in chrome: don't collapse chrome
+    if (!forceHide && this._isPopupOpen)
+      return false;
+
+    // a textbox in chrome is focused (location bar anyone?): don't collapse chrome
+    if (document.commandDispatcher.focusedElement &&
+        document.commandDispatcher.focusedElement.ownerDocument == document &&
+        document.commandDispatcher.focusedElement.localName == "input") {
+      if (forceHide)
+        // hidden textboxes that still have focus are bad bad bad
+        document.commandDispatcher.focusedElement.blur();
+      else
+        return false;
+    }
+    return true;
+  },
+
+  _setPopupOpen: function(aEvent)
+  {
+    // Popups should only veto chrome collapsing if they were opened when the chrome was not collapsed.
+    // Otherwise, they would not affect chrome and the user would expect the chrome to go away.
+    // e.g. we wouldn't want the autoscroll icon firing this event, so when the user
+    // toggles chrome when moving mouse to the top, it doesn't go away again.
+    if (aEvent.type == "popupshown" && !FullScreen._isChromeCollapsed &&
+        aEvent.target.localName != "tooltip" && aEvent.target.localName != "window")
+      FullScreen._isPopupOpen = true;
+    else if (aEvent.type == "popuphidden" && aEvent.target.localName != "tooltip" &&
+             aEvent.target.localName != "window")
+      FullScreen._isPopupOpen = false;
+  },
+
+  // Autohide helpers for the context menu item
+  getAutohide: function(aItem)
+  {
+    aItem.setAttribute("checked", gPrefService.getBoolPref("browser.fullscreen.autohide"));
+  },
+  setAutohide: function()
+  {
+    gPrefService.setBoolPref("browser.fullscreen.autohide", !gPrefService.getBoolPref("browser.fullscreen.autohide"));
+  },
+
+  // Animate the toolbars disappearing
+  _shouldAnimate: true,
+  _isAnimating: false,
+  _animationInterval: null,
+  _animateUp: function()
+  {
+    // check again, the user may have done something before the animation was due to start
+    if (!window.fullScreen || !FullScreen._safeToCollapse(false)) {
+      FullScreen._isAnimating = false;
+      FullScreen._shouldAnimate = true;
+      return;
+    }
+
+    var navToolbox = getNavToolbox();
+    var animateFrameAmount = 2;
+    function animateUpFrame() {
+      animateFrameAmount *= 2;
+      if (animateFrameAmount >=
+          (navToolbox.boxObject.height + gBrowser.mStrip.boxObject.height)) {
+        // We've animated enough
+        clearInterval(FullScreen._animationInterval);
+        navToolbox.style.marginTop = "0px";
+        FullScreen._isAnimating = false;
+        FullScreen._shouldAnimate = false; // Just to make sure
+        FullScreen.mouseoverToggle(false);
+        return;
+      }
+      navToolbox.style.marginTop = (animateFrameAmount * -1) + "px";
+    }
+
+    FullScreen._animationInterval = setInterval(animateUpFrame, 70);
+  },
+
+  mouseoverToggle: function(aShow, forceHide)
+  {
+    // Don't do anything if:
+    // a) we're already in the state we want,
+    // b) we're animating and will become collapsed soon, or
+    // c) we can't collapse because it would be undesirable right now
+    if (aShow != this._isChromeCollapsed || (!aShow && this._isAnimating) ||
+        (!aShow && !this._safeToCollapse(forceHide)))
+      return;
+
+    // browser.fullscreen.animateUp
+    // 0 - never animate up
+    // 1 - animate only for first collapse after entering fullscreen (default for perf's sake)
+    // 2 - animate every time it collapses
+    if (gPrefService.getIntPref("browser.fullscreen.animateUp") == 0)
+      this._shouldAnimate = false;
+
+    if (!aShow && this._shouldAnimate) {
+      this._isAnimating = true;
+      this._shouldAnimate = false;
+      setTimeout(this._animateUp, 800);
+      return;
+    }
+
+    // The chrome is collapsed so don't spam needless mousemove events
+    if (aShow) {
+      gBrowser.mPanelContainer.addEventListener("mousemove",
+                                                this._collapseCallback, false);
+    }
+    else {
+      gBrowser.mPanelContainer.removeEventListener("mousemove",
+                                                   this._collapseCallback, false);
+    }
+
+    gBrowser.mStrip.setAttribute("moz-collapsed", !aShow);
+    var allFSToolbars = document.getElementsByTagNameNS(this._XULNS, "toolbar");
+    for (var i = 0; i < allFSToolbars.length; i++) {
+      if (allFSToolbars[i].getAttribute("fullscreentoolbar") == "true")
+        allFSToolbars[i].setAttribute("moz-collapsed", !aShow);
+    }
+    document.getElementById("fullscr-toggler").setAttribute("moz-collapsed", aShow);
+    this._isChromeCollapsed = !aShow;
+    if (gPrefService.getIntPref("browser.fullscreen.animateUp") == 2)
+      this._shouldAnimate = true;
   },
 
   showXULChrome: function(aTag, aShow)
   {
-    var XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-    var els = document.getElementsByTagNameNS(XULNS, aTag);
+    var els = document.getElementsByTagNameNS(this._XULNS, aTag);
 
     for (var i = 0; i < els.length; ++i) {
       // XXX don't interfere with previously collapsed toolbars
       if (els[i].getAttribute("fullscreentoolbar") == "true") {
         if (!aShow) {
 
           var toolbarMode = els[i].getAttribute("mode");
           if (toolbarMode != "text") {
             els[i].setAttribute("saved-mode", toolbarMode);
             els[i].setAttribute("saved-iconsize",
                                 els[i].getAttribute("iconsize"));
             els[i].setAttribute("mode", "icons");
             els[i].setAttribute("iconsize", "small");
           }
 
-          // XXX See bug 202978: we disable the context menu
-          // to prevent customization while in fullscreen, which
-          // causes menu breakage.
+          // Give the main nav bar the fullscreen context menu, otherwise remove it
+          // to prevent breakage
           els[i].setAttribute("saved-context",
                               els[i].getAttribute("context"));
-          els[i].removeAttribute("context");
+          if (els[i].id == "nav-bar")
+            els[i].setAttribute("context", "autohide-context");
+          else
+            els[i].removeAttribute("context");
 
           // Set the inFullscreen attribute to allow specific styling
           // in fullscreen mode
           els[i].setAttribute("inFullscreen", true);
         }
         else {
           function restoreAttr(attrName) {
             var savedAttr = "saved-" + attrName;
             if (els[i].hasAttribute(savedAttr)) {
-              var savedValue = els[i].getAttribute(savedAttr);
-              els[i].setAttribute(attrName, savedValue);
+              els[i].setAttribute(attrName, els[i].getAttribute(savedAttr));
               els[i].removeAttribute(savedAttr);
             }
           }
 
           restoreAttr("mode");
           restoreAttr("iconsize");
-          restoreAttr("context"); // XXX see above
+          restoreAttr("context");
 
           els[i].removeAttribute("inFullscreen");
         }
       } else {
         // use moz-collapsed so it doesn't persist hidden/collapsed,
         // so that new windows don't have missing toolbars
         if (aShow)
           els[i].removeAttribute("moz-collapsed");
@@ -3350,21 +3640,25 @@ var FullScreen =
   }
 };
 
 /**
  * Returns true if |aMimeType| is text-based, false otherwise.
  *
  * @param aMimeType
  *        The MIME type to check.
+ *
+ * If adding types to this function, please also check the similar 
+ * function in findbar.xml
  */
 function mimeTypeIsTextBased(aMimeType)
 {
   return /^text\/|\+xml$/.test(aMimeType) ||
          aMimeType == "application/x-javascript" ||
+         aMimeType == "application/javascript" ||
          aMimeType == "application/xml" ||
          aMimeType == "mozilla.application/cached-xul";
 }
 
 function nsBrowserStatusHandler()
 {
   this.init();
 }
@@ -3860,17 +4154,17 @@ nsBrowserStatusHandler.prototype =
     }
 
     if (setHost && this._host)
       this.securityButton.setAttribute("label", this._host);
     else
       this.securityButton.removeAttribute("label");
 
     this.securityButton.setAttribute("tooltiptext", this._tooltipText);
-    getIdentityHandler().checkIdentity(this._state, this._host);
+    getIdentityHandler().checkIdentity(this._state, gBrowser.contentWindow.location);
   },
 
   // simulate all change notifications after switching tabs
   onUpdateCurrentBrowser : function(aStateFlags, aStatus, aMessage, aTotalProgress)
   {
     var nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
     var loadingDone = aStateFlags & nsIWebProgressListener.STATE_STOP;
     // use a pseudo-object instead of a (potentially non-existing) channel for getting
@@ -5970,19 +6264,19 @@ function IdentityHandler() {
 
 IdentityHandler.prototype = {
 
   // Mode strings used to control CSS display
   IDENTITY_MODE_IDENTIFIED       : "verifiedIdentity", // High-quality identity information
   IDENTITY_MODE_DOMAIN_VERIFIED  : "verifiedDomain",   // Minimal SSL CA-signed domain verification
   IDENTITY_MODE_UNKNOWN          : "unknownIdentity",  // No trusted identity information
 
-  // Cache the most recently seen SSLStatus and URI to prevent unnecessary updates
+  // Cache the most recent SSLStatus and Location seen in checkIdentity
   _lastStatus : null,
-  _lastHost : null,
+  _lastLocation : null,
 
   /**
    * Build out a cache of the elements that we need frequently.
    */
   _cacheElements : function() {
     this._identityPopup = document.getElementById("identity-popup");
     this._identityBox = document.getElementById("identity-box");
     this._identityPopupContentBox = document.getElementById("identity-popup-content-box");
@@ -6037,34 +6331,51 @@ IdentityHandler.prototype = {
   },
   
   /**
    * Determine the identity of the page being displayed by examining its SSL cert
    * (if available) and, if necessary, update the UI to reflect this.  Intended to
    * be called by onSecurityChange
    * 
    * @param PRUint32 state
-   * @param AUTF8String host
+   * @param Location location
    */
-  checkIdentity : function(state, host) {
+  checkIdentity : function(state, location) {
     var currentStatus = gBrowser.securityUI
                                 .QueryInterface(Components.interfaces.nsISSLStatusProvider)
                                 .SSLStatus;
     this._lastStatus = currentStatus;
-    this._lastHost = host;
+    this._lastLocation = location;
     
     if (state & Components.interfaces.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL)
       this.setMode(this.IDENTITY_MODE_IDENTIFIED);
     else if (state & Components.interfaces.nsIWebProgressListener.STATE_SECURE_HIGH)
       this.setMode(this.IDENTITY_MODE_DOMAIN_VERIFIED);
     else
       this.setMode(this.IDENTITY_MODE_UNKNOWN);
   },
   
   /**
+   * Return the eTLD+1 version of the current hostname
+   */
+  getEffectiveHost : function() {
+    // Cache the eTLDService if this is our first time through
+    if (!this._eTLDService)
+      this._eTLDService = Cc["@mozilla.org/network/effective-tld-service;1"]
+                         .getService(Ci.nsIEffectiveTLDService);
+    try {
+      return this._eTLDService.getBaseDomainFromHost(this._lastLocation.hostname);
+    } catch (e) {
+      // If something goes wrong (e.g. hostname is an IP address) just fail back
+      // to the full domain.
+      return this._lastLocation.hostname;
+    }
+  },
+  
+  /**
    * Update the UI to reflect the specified mode, which should be one of the
    * IDENTITY_MODE_* constants.
    */
   setMode : function(newMode) {
     if (!this._identityBox) {
       // No identity box means the identity box is not visible, in which
       // case there's nothing to do.
       return;
@@ -6092,34 +6403,25 @@ IdentityHandler.prototype = {
       // typically what we want here, but thanks to x509 certs being extensible,
       // it's not the only place you have to check, there can be more than one domain,
       // et cetera, ad nauseum.  We know the cert is valid for location.host, so
       // let's just use that. Check the pref to determine how much of the verified
       // hostname to show
       var icon_label = "";
       switch (gPrefService.getIntPref("browser.identity.ssl_domain_display")) {
         case 2 : // Show full domain
-          icon_label = this._lastHost;
+          icon_label = this._lastLocation.hostname;
           break;
-        case 1 : // Show eTLD.  Cache eTLD service the first time we need it.
-          if (!this._eTLDService)
-            this._eTLDService = Cc["@mozilla.org/network/effective-tld-service;1"]
-                                .getService(Ci.nsIEffectiveTLDService);
-          try {
-            icon_label = this._eTLDService.getBaseDomainFromHost(this._lastHost);
-          } catch (e) {
-            // If something goes wrong (e.g. _lastHost is an IP address) just fail back
-            // to the full domain.
-            icon_label = this._lastHost;
-          }
+        case 1 : // Show eTLD.
+          icon_label = this.getEffectiveHost();
       }
       
       // We need a port number for all lookups.  If one hasn't been specified, use
       // the https default
-      var lookupHost = this._lastHost;
+      var lookupHost = this._lastLocation.host;
       if (lookupHost.indexOf(':') < 0)
         lookupHost += ":443";
 
       // Cache the override service the first time we need to check it
       if (!this._overrideService)
         this._overrideService = Components.classes["@mozilla.org/security/certoverride;1"]
                                           .getService(Components.interfaces.nsICertOverrideService);
 
@@ -6164,45 +6466,28 @@ IdentityHandler.prototype = {
     this._identityPopupContentBox.className = newMode;
     
     // Set the static strings up front
     this._identityPopupEncLabel.textContent = this._staticStrings[newMode].encryption_label;
     
     // Initialize the optional strings to empty values
     var supplemental = "";
     var verifier = "";
-      
-    // Cache eTLD service if we haven't yet
-    if (!this._eTLDService)
-      this._eTLDService = Cc["@mozilla.org/network/effective-tld-service;1"]
-                          .getService(Ci.nsIEffectiveTLDService);
     
     if (newMode == this.IDENTITY_MODE_DOMAIN_VERIFIED) {
       var iData = this.getIdentityData();
-
-      try {
-        var host = this._eTLDService.getBaseDomainFromHost(this._lastHost);
-      } catch (e) {
-        // Fail back to the full domain.
-        host = this._lastHost;
-      }
-      var owner = this._stringBundle.getString("identity.ownerUnknown");
+      var host = this.getEffectiveHost();
+      var owner = this._stringBundle.getString("identity.ownerUnknown2");
       verifier = this._identityBox.tooltipText;
       supplemental = "";
     }
     else if (newMode == this.IDENTITY_MODE_IDENTIFIED) {
       // If it's identified, then we can populate the dialog with credentials
       iData = this.getIdentityData();
-
-      try {
-        host = this._eTLDService.getBaseDomainFromHost(this._lastHost);
-      } catch (e) {
-        // Fail back to the full domain.
-        host = this._lastHost;
-      }
+      host = this.getEffectiveHost();
       owner = iData.subjectOrg; 
       verifier = this._identityBox.tooltipText;
 
       // Build an appropriate supplemental block out of whatever location data we have
       if (iData.city)
         supplemental += iData.city + "\n";        
       if (iData.state && iData.country)
         supplemental += this._stringBundle.getFormattedString("identity.identified.state_and_country",
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -154,16 +154,27 @@
     <popup id="blockedPopupOptions" 
            onpopupshowing="gPopupBlockerObserver.fillPopupList(event);">
       <menuitem observes="blockedPopupAllowSite"/>
       <menuitem observes="blockedPopupEditSettings"/>
       <menuitem observes="blockedPopupDontShowMessage"/>
       <menuseparator observes="blockedPopupsSeparator"/>
     </popup>
 
+    <menupopup id="autohide-context"
+           onpopupshowing="FullScreen.getAutohide(this.firstChild);">
+      <menuitem type="checkbox" label="&fullScreenAutohide.label;"
+                accesskey="&fullScreenAutohide.accesskey;"
+                oncommand="FullScreen.setAutohide();"/>
+      <menuseparator/>
+      <menuitem label="&fullScreenExit.label;"
+                accesskey="&fullScreenExit.accesskey;"
+                oncommand="BrowserFullScreen();"/>
+    </menupopup>
+
     <popup id="contentAreaContextMenu"
            onpopupshowing="if (event.target != this) return true; updateEditUIVisibility(); gContextMenu = new nsContextMenu(this, window.getBrowser()); return gContextMenu.shouldDisplay;"
            onpopuphiding="if (event.target == this) { gContextMenu = null; updateEditUIVisibility(); }">
 #include browser-context.inc
     </popup>
 
     <popup id="placesContext"/>
 
@@ -171,17 +182,17 @@
     <panel id="identity-popup" position="after_start" hidden="true" noautofocus="true"
            onpopupshown="document.getElementById('identity-popup-more-info-button').focus();"
            onpopuphidden="focusAndSelectUrlBar();" norestorefocus="true">
       <hbox id="identity-popup-container" align="top">
         <image id="identity-popup-icon"/>
         <vbox id="identity-popup-content-box">
           <label id="identity-popup-connectedToLabel" value="&identity.connectedTo;"/>
           <label id="identity-popup-connectedToLabel2"
-                 value="&identity.unverifiedsite;"/>
+                 value="&identity.unverifiedsite2;"/>
           <description id="identity-popup-content-host"/>
           <label id="identity-popup-runByLabel" value="&identity.runBy;"/>
           <description id="identity-popup-content-owner"/>
           <description id="identity-popup-content-supplemental"/>
           <description id="identity-popup-content-verifier"/>
           <hbox id="identity-popup-encryption" flex="1">
             <vbox>
               <image id="identity-popup-encryption-icon"/>
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -292,19 +292,24 @@
             onProgressChange : function (aWebProgress, aRequest,
                                          aCurSelfProgress, aMaxSelfProgress,
                                          aCurTotalProgress, aMaxTotalProgress)
             {
               if (!this.mBlank && this.mTabBrowser.mCurrentTab == this.mTab) {
                 for (var i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
                   var p = this.mTabBrowser.mProgressListeners[i];
                   if (p)
-                    p.onProgressChange(aWebProgress, aRequest,
-                                       aCurSelfProgress, aMaxSelfProgress,
-                                       aCurTotalProgress, aMaxTotalProgress);
+                    try {
+                      p.onProgressChange(aWebProgress, aRequest,
+                                         aCurSelfProgress, aMaxSelfProgress,
+                                         aCurTotalProgress, aMaxTotalProgress);
+                    } catch (e) {
+                      // don't inhibit other listeners or following code
+                      Components.utils.reportError(e);
+                    }
                 }
               }
 
               this.mTotalProgress = aMaxTotalProgress ? aCurTotalProgress / aMaxTotalProgress : 0;
             },
 
             onProgressChange64 : function (aWebProgress, aRequest,
                                          aCurSelfProgress, aMaxSelfProgress,
@@ -393,21 +398,27 @@
 
                 if (this.mTabBrowser.mCurrentTab == this.mTab)
                   this.mTabBrowser.mIsBusy = false;
               }
 
               if (this.mTabBrowser.mCurrentTab == this.mTab) {
                 for (var i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
                   var p = this.mTabBrowser.mProgressListeners[i];
-                  if (p && !oldBlank)
-                    p.onStateChange(aWebProgress, aRequest, aStateFlags, aStatus);
-                  // make sure that the visible status of new blank tabs is correctly set
-                  else if (p && "onUpdateCurrentBrowser" in p)
-                    p.onUpdateCurrentBrowser(aStateFlags, aStatus, "", 0);
+                  if (p)
+                    try {
+                      if (!oldBlank)
+                        p.onStateChange(aWebProgress, aRequest, aStateFlags, aStatus);
+                      // make sure that the visible status of new blank tabs is correctly set
+                      else if ("onUpdateCurrentBrowser" in p)
+                        p.onUpdateCurrentBrowser(aStateFlags, aStatus, "", 0);
+                    } catch (e) {
+                      // don't inhibit other listeners or following code
+                      Components.utils.reportError(e);
+                    }
                 }
               }
 
               if (aStateFlags & (nsIWebProgressListener.STATE_START |
                                  nsIWebProgressListener.STATE_STOP)) {
                 // reset cached temporary values at beginning and end
                 this.mMessage = "";
                 this.mTotalProgress = 0;
@@ -428,56 +439,76 @@
 
               // changing location, clear out the missing plugins list
               this.mBrowser.missingPlugins = null;
 
               if (!this.mBlank && this.mTabBrowser.mCurrentTab == this.mTab) {
                 for (var i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
                   var p = this.mTabBrowser.mProgressListeners[i];
                   if (p)
-                    p.onLocationChange(aWebProgress, aRequest, aLocation);
+                    try {
+                      p.onLocationChange(aWebProgress, aRequest, aLocation);
+                    } catch (e) {
+                      // don't inhibit other listeners
+                      Components.utils.reportError(e);
+                    }
                 }
               }
             },
 
             onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage)
             {
               if (this.mBlank)
                 return;
 
               if (this.mTabBrowser.mCurrentTab == this.mTab) {
                 for (var i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
                   var p = this.mTabBrowser.mProgressListeners[i];
                   if (p)
-                    p.onStatusChange(aWebProgress, aRequest, aStatus, aMessage);
+                    try {
+                      p.onStatusChange(aWebProgress, aRequest, aStatus, aMessage);
+                    } catch (e) {
+                      // don't inhibit other listeners or following code
+                      Components.utils.reportError(e);
+                    }
                 }
               }
 
               this.mMessage = aMessage;
             },
 
             onSecurityChange : function(aWebProgress, aRequest, aState)
             {
               if (this.mTabBrowser.mCurrentTab == this.mTab) {
                 for (var i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
                   var p = this.mTabBrowser.mProgressListeners[i];
                   if (p)
-                    p.onSecurityChange(aWebProgress, aRequest, aState);
+                    try {
+                      p.onSecurityChange(aWebProgress, aRequest, aState);
+                    } catch (e) {
+                      // don't inhibit other listeners
+                      Components.utils.reportError(e);
+                    }
                 }
               }
             },
 
              onRefreshAttempted : function(aWebProgress, aURI, aDelay, aSameURI)
              {
                var allowRefresh = true;
                for (var i = 0; i < this.mTabBrowser.mProgressListeners.length; i++) {
                  var p = this.mTabBrowser.mProgressListeners[i];
                  if (p && "onRefreshAttempted" in p) {
-                   if (!p.onRefreshAttempted(aWebProgress, aURI, aDelay, aSameURI))
-                     allowRefresh = false;
+                   try {
+                     if (!p.onRefreshAttempted(aWebProgress, aURI, aDelay, aSameURI))
+                       allowRefresh = false;
+                    } catch (e) {
+                      // don't inhibit other listeners or following code
+                      Components.utils.reportError(e);
+                    }
                  }
                }
                return allowRefresh;
              },
  
             QueryInterface : function(aIID)
             {
               if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
@@ -510,17 +541,22 @@
                                                             aURI, false);
             }
 
             this.updateIcon(aTab);
 
             for (var i = 0; i < this.mProgressListeners.length; i++) {
               var p = this.mProgressListeners[i];
               if ('onLinkIconAvailable' in p)
-                p.onLinkIconAvailable(browser);
+                try {
+                  p.onLinkIconAvailable(browser);
+                } catch (e) {
+                  // don't inhibit other listeners
+                  Components.utils.reportError(e);
+                }
             }
           ]]>
         </body>
       </method>
 
       <method name="updateIcon">
         <parameter name="aTab"/>
         <body>
@@ -732,58 +768,72 @@
             var loc = this.mCurrentBrowser.currentURI;
 
             var webProgress = this.mCurrentBrowser.webProgress;
             var securityUI = this.mCurrentBrowser.securityUI;
 
             var i, p;
             for (i = 0; i < this.mProgressListeners.length; i++) {
               p = this.mProgressListeners[i];
-              if (p) {
-                p.onLocationChange(webProgress, null, loc);
-                if (securityUI)
-                  p.onSecurityChange(webProgress, null, securityUI.state);
-
-                // make sure that all status indicators are properly updated
-                if ("onUpdateCurrentBrowser" in p) {
-                  var listener = this.mTabListeners[this.mTabContainer.selectedIndex] || null;
-                  if (listener && listener.mStateFlags)
-                    p.onUpdateCurrentBrowser(listener.mStateFlags, listener.mStatus,
-                                             listener.mMessage, listener.mTotalProgress);
+              if (p)
+                try {
+                  p.onLocationChange(webProgress, null, loc);
+                  if (securityUI)
+                    p.onSecurityChange(webProgress, null, securityUI.state);
+
+                  // make sure that all status indicators are properly updated
+                  if ("onUpdateCurrentBrowser" in p) {
+                    var listener = this.mTabListeners[this.mTabContainer.selectedIndex] || null;
+                    if (listener && listener.mStateFlags)
+                      p.onUpdateCurrentBrowser(listener.mStateFlags, listener.mStatus,
+                                               listener.mMessage, listener.mTotalProgress);
+                  }
+                } catch (e) {
+                  // don't inhibit other listeners or following code
+                  Components.utils.reportError(e);
                 }
-              }
             }
 
             this._fastFind.setDocShell(this.mCurrentBrowser.docShell);
 
             // Update the window title.
             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;
               webProgress = this.mCurrentBrowser.webProgress;
               for (i = 0; i < this.mProgressListeners.length; i++) {
                 p = this.mProgressListeners[i];
                 if (p)
-                  p.onStateChange(webProgress, null, nsIWebProgressListener.STATE_START | nsIWebProgressListener.STATE_IS_NETWORK, 0);
+                  try {
+                    p.onStateChange(webProgress, null, nsIWebProgressListener.STATE_START | nsIWebProgressListener.STATE_IS_NETWORK, 0);
+                  } catch (e) {
+                    // don't inhibit other listeners or following code
+                    Components.utils.reportError(e);
+                  }
               }
             }
 
             // If the new tab is not busy, and our current state is busy, then
             // we need to fire a stop to all progress listeners.
             if (!this.mCurrentTab.hasAttribute("busy") && this.mIsBusy) {
               this.mIsBusy = false;
               webProgress = this.mCurrentBrowser.webProgress;
               for (i = 0; i < this.mProgressListeners.length; i++) {
                 p = this.mProgressListeners[i];
                 if (p)
-                  p.onStateChange(webProgress, null, nsIWebProgressListener.STATE_STOP | nsIWebProgressListener.STATE_IS_NETWORK, 0);
+                  try {
+                    p.onStateChange(webProgress, null, nsIWebProgressListener.STATE_STOP | nsIWebProgressListener.STATE_IS_NETWORK, 0);
+                  } catch (e) {
+                    // don't inhibit other listeners or following code
+                    Components.utils.reportError(e);
+                  }
               }
             }
 
             // We've selected the new tab, so go ahead and notify listeners.
             var event = document.createEvent("Events");
             event.initEvent("TabSelect", true, false);
             this.mCurrentTab.dispatchEvent(event);
 
@@ -2533,51 +2583,48 @@
   <binding id="tabbrowser-tabs"
            extends="chrome://global/content/bindings/tabbox.xml#tabs">
     <content>
       <xul:stack flex="1" class="tabs-stack">
         <xul:vbox>
           <xul:spacer flex="1"/>
           <xul:hbox class="tabs-bottom" align="center"/>
         </xul:vbox>
-        <xul:vbox>
-          <xul:hbox xbl:inherits="overflow" class="tabs-container">
+        <xul:hbox xbl:inherits="overflow" class="tabs-container">
 #ifdef XP_MACOSX
-            <xul:stack>
-              <xul:spacer class="tabs-left"/>
-            </xul:stack>
+          <xul:stack>
+            <xul:spacer class="tabs-left"/>
+          </xul:stack>
 #endif
-            <xul:arrowscrollbox anonid="arrowscrollbox" orient="horizontal" flex="1"
-                                style="min-width: 1px;" chromedir="&locale.dir;"
+          <xul:arrowscrollbox anonid="arrowscrollbox" orient="horizontal" flex="1"
+                              style="min-width: 1px;" chromedir="&locale.dir;"
 #ifndef XP_MACOSX
-                                clicktoscroll="true"
+                              clicktoscroll="true"
 #endif
-                                class="tabbrowser-arrowscrollbox">
-              <children/>
-            </xul:arrowscrollbox>
-            <xul:stack align="center" pack="end" chromedir="&locale.dir;">
-              <xul:hbox flex="1" class="tabs-alltabs-box" anonid="alltabs-box"/>
-              <xul:hbox flex="1" class="tabs-alltabs-box-animate" anonid="alltabs-box-animate"/>
-              <xul:toolbarbutton class="tabs-alltabs-button" type="menu" anonid="alltabs-button"
-                                 tooltipstring="&listAllTabs.label;">
-                <xul:menupopup class="tabs-alltabs-popup" anonid="alltabs-popup"
-                               position="after_end"/>
-              </xul:toolbarbutton>
-            </xul:stack>
+                              class="tabbrowser-arrowscrollbox">
+            <children/>
+          </xul:arrowscrollbox>
+          <xul:stack align="center" pack="end" chromedir="&locale.dir;">
+            <xul:hbox flex="1" class="tabs-alltabs-box" anonid="alltabs-box"/>
+            <xul:hbox flex="1" class="tabs-alltabs-box-animate" anonid="alltabs-box-animate"/>
+            <xul:toolbarbutton class="tabs-alltabs-button" type="menu" anonid="alltabs-button"
+                               tooltipstring="&listAllTabs.label;">
+              <xul:menupopup class="tabs-alltabs-popup" anonid="alltabs-popup"
+                             position="after_end"/>
+            </xul:toolbarbutton>
+          </xul:stack>
 #ifdef XP_MACOSX
-            <xul:hbox anonid="tabstrip-closebutton" class="tabs-closebutton-box" align="center" pack="end" chromedir="&locale.dir;">
+          <xul:hbox anonid="tabstrip-closebutton" class="tabs-closebutton-box" align="center" pack="end" chromedir="&locale.dir;">
 #endif
-            <xul:toolbarbutton anonid="tabs-closebutton"
-                               class="close-button tabs-closebutton" chromedir="&locale.dir;"/>
+          <xul:toolbarbutton anonid="tabs-closebutton"
+                             class="close-button tabs-closebutton" chromedir="&locale.dir;"/>
 #ifdef XP_MACOSX
-            </xul:hbox>
+          </xul:hbox>
 #endif
-          </xul:hbox>
-          <xul:spacer class="tabs-bottom-spacer"/>
-        </xul:vbox>
+        </xul:hbox>
       </xul:stack>
     </content>
     <implementation implements="nsITimerCallback, nsIDOMEventListener">
       <constructor>
         <![CDATA[
           var pb2 =
               Components.classes['@mozilla.org/preferences-service;1'].
               getService(Components.interfaces.nsIPrefBranch2);
@@ -3113,19 +3160,28 @@
              * after the first click (i.e. the first click event was dispatched
              * on the tab). This happens when we show the close button only on
              * the active tab. (bug 352021)
              * The only sequence in which a third click event can be dispatched
              * on an in-tab close button is when the tab was opened with a
              * double click on the tabbar. (bug 378344)
              * In both cases, it is most likely that the close button area has
              * been accidentally clicked, therefore we do not close the tab.
+             *
+             * We don't want to ignore processing of more than one click event,
+             * though, since the user might actually be repeatedly clicking to
+             * close many tabs at once.
              */
-            if (event.detail > 1)
+            if (event.detail > 1 && !this._ignoredClick) {
+              this._ignoredClick = true;
               return;
+            }
+
+            // Reset the "ignored click" flag
+            this._ignoredClick = false;
 
             tabbedBrowser.removeTab(bindingParent);
             tabbedBrowser._blockDblClick = true;
 
             /* XXXmano hack (see bug 343628):
              * Since we're removing the event target, if the user
              * double-clicks this button, the dblclick event will be dispatched
              * with the tabbar as its event target (and explicit/originalTarget),
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -48,17 +48,19 @@ include $(topsrcdir)/config/rules.mk
 		test_bug395533.html \
 		bug395533-data.txt \
 		$(NULL)
 
 _BROWSER_FILES = browser_bug321000.js \
                  browser_bug405137.js \
                  browser_bug409481.js \
                  browser_autodiscovery.js \
+                 browser_bug420160.js \
                  autodiscovery.html \
                  moz.png \
+                 browser_getshortcutoruri.js \
     $(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
 
 libs::	$(_BROWSER_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_bug420160.js
@@ -0,0 +1,50 @@
+var listener = {
+  testFunction : null,
+  
+  handleEvent : function (e) {
+    this.testFunction();
+  }
+}
+
+var newBrowser;
+
+/* Tests for correct behaviour of getEffectiveHost on identity handler */
+function test() {
+  
+  waitForExplicitFinish();
+  
+  ok(getIdentityHandler(), "getIdentityHandler should return a result");
+  ok(gIdentityHandler, "gIdentityHandler should exist");
+  
+  var newTab = gBrowser.addTab();
+  gBrowser.selectedTab = newTab;
+  newBrowser = gBrowser.getBrowserForTab(newTab);
+  
+  newBrowser.addEventListener("load", listener, true);
+  listener.testFunction = testNormalDomain;  
+  newBrowser.contentWindow.location = 'http://test1.example.org/';
+}
+
+function testNormalDomain() {
+  is(gIdentityHandler._lastLocation.host, 'test1.example.org', "Identity handler is getting the full location");
+  is(gIdentityHandler.getEffectiveHost(), 'example.org', "getEffectiveHost should return example.org for test1.example.org");
+  
+  listener.testFunction = testNormalDomainWithPort;
+  newBrowser.contentWindow.location = 'http://sub1.test1.example.org:8000/';
+}
+
+function testNormalDomainWithPort() {
+
+  is(gIdentityHandler._lastLocation.host, 'sub1.test1.example.org:8000', "Identity handler is getting port information");
+  is(gIdentityHandler.getEffectiveHost(), 'example.org', "getEffectiveHost should return example.org for sub1.test1.example.org:8000");
+  
+  listener.testFunction = testIPWithPort;
+  newBrowser.contentWindow.location = 'http://127.0.0.1:8888/';
+}
+
+function testIPWithPort() {
+  is(gIdentityHandler.getEffectiveHost(), '127.0.0.1', "getEffectiveHost should return 127.0.0.1 for 127.0.0.1:8888");
+  newBrowser.removeEventListener("load", listener, true);
+  gBrowser.removeCurrentTab();
+  finish();
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_getshortcutoruri.js
@@ -0,0 +1,139 @@
+function makeURI(aURL, aOriginCharset, aBaseURI) {
+  var ioService = Components.classes["@mozilla.org/network/io-service;1"]
+                            .getService(Components.interfaces.nsIIOService);
+  return ioService.newURI(aURL, aOriginCharset, aBaseURI);
+}
+
+function getPostDataString(aIS) {
+  if (!aIS)
+    return null;
+
+  var sis = Cc["@mozilla.org/scriptableinputstream;1"].
+            createInstance(Ci.nsIScriptableInputStream);
+  sis.init(aIS);
+  var dataLines = sis.read(aIS.available()).split("\n");
+
+  // only want the last line
+  return dataLines[dataLines.length-1];
+}
+
+function keywordResult(aURL, aPostData) {
+  this.url = aURL;
+  this.postData = aPostData;
+}
+
+function keyWordData() {}
+keyWordData.prototype = {
+  init: function(aKeyWord, aURL, aPostData, aSearchWord) {
+    this.keyword = aKeyWord;
+    this.uri = makeURI(aURL);
+    this.postData = aPostData;
+    this.searchWord = aSearchWord;
+
+    this.method = (this.postData ? "POST" : "GET");
+  }
+}
+
+function bmKeywordData(aKeyWord, aURL, aPostData, aSearchWord) {
+  this.init(aKeyWord, aURL, aPostData, aSearchWord);
+}
+bmKeywordData.prototype = new keyWordData();
+
+function searchKeywordData(aKeyWord, aURL, aPostData, aSearchWord) {
+  this.init(aKeyWord, aURL, aPostData, aSearchWord);
+}
+searchKeywordData.prototype = new keyWordData();
+
+var testData = [
+  [new bmKeywordData("bmget", "http://bmget/search=%s", null, "foo"),
+   new keywordResult("http://bmget/search=foo", null)],
+
+  [new bmKeywordData("bmpost", "http://bmpost/", "search=%s", "foo2"),
+   new keywordResult("http://bmpost/", "search=foo2")],
+
+  [new bmKeywordData("bmpostget", "http://bmpostget/search1=%s", "search2=%s", "foo3"),
+   new keywordResult("http://bmpostget/search1=foo3", "search2=foo3")],
+
+  [new bmKeywordData("bmget-nosearch", "http://bmget-nosearch/", null, ""),
+   new keywordResult("http://bmget-nosearch/", null)],
+
+  [new searchKeywordData("searchget", "http://searchget/?search={searchTerms}", null, "foo4"),
+   new keywordResult("http://searchget/?search=foo4", null)],
+
+  [new searchKeywordData("searchpost", "http://searchpost/", "search={searchTerms}", "foo5"),
+   new keywordResult("http://searchpost/", "search=foo5")],
+
+  [new searchKeywordData("searchpostget", "http://searchpostget/?search1={searchTerms}", "search2={searchTerms}", "foo6"),
+   new keywordResult("http://searchpostget/?search1=foo6", "search2=foo6")],
+
+  // Bookmark keywords that don't take parameters should not be activated if a
+  // parameter is passed (bug 420328).
+  [new bmKeywordData("bmget-noparam", "http://bmget-noparam/", null, "foo7"),
+   new keywordResult(null, null)],
+  [new bmKeywordData("bmpost-noparam", "http://bmpost-noparam/", "not_a=param", "foo8"),
+   new keywordResult(null, null)],
+  
+  // Test escaping (%s = escaped, %S = raw)
+  // UTF-8 default
+  [new bmKeywordData("bmget-escaping", "http://bmget/?esc=%s&raw=%S", null, "foé"),
+   new keywordResult("http://bmget/?esc=fo%C3%A9&raw=foé", null)],
+  // Explicitly-defined ISO-8859-1
+  [new bmKeywordData("bmget-escaping2", "http://bmget/?esc=%s&raw=%S&mozcharset=ISO-8859-1", null, "foé"),
+   new keywordResult("http://bmget/?esc=fo%E9&raw=foé", null)],
+];
+
+function test() {
+  setupKeywords();
+
+  for each (var item in testData) {
+    var [data, result] = item;
+
+    var postData = {};
+    var query = data.keyword;
+    if (data.searchWord)
+      query += " " + data.searchWord;
+    var url = getShortcutOrURI(query, postData);
+
+    // null result.url means we should expect the same query we sent in
+    var expected = result.url || query;
+    is(url, expected, "got correct URL for " + data.keyword);
+    is(getPostDataString(postData.value), result.postData, "got correct postData for " + data.keyword);
+  }
+
+  cleanupKeywords();
+}
+
+var gBMFolder = null;
+var gAddedEngines = [];
+function setupKeywords() {
+  var searchService = Cc["@mozilla.org/browser/search-service;1"].
+                      getService(Ci.nsIBrowserSearchService);
+  gBMFolder = Application.bookmarks.addFolder("keyword-test");
+  for each (var item in testData) {
+    var data = item[0];
+    if (data instanceof bmKeywordData) {
+      var bm = gBMFolder.addBookmark(data.keyword, data.uri);
+      bm.keyword = data.keyword;
+      if (data.postData)
+        bm.annotations.set("bookmarkProperties/POSTData", data.postData, Ci.nsIAnnotationService.EXPIRE_SESSION);
+    }
+    
+    if (data instanceof searchKeywordData) {
+      searchService.addEngineWithDetails(data.keyword, "", data.keyword, "", data.method, data.uri.spec);
+      var addedEngine = searchService.getEngineByName(data.keyword);
+      if (data.postData) {
+        var [paramName, paramValue] = data.postData.split("=");
+        addedEngine.addParam(paramName, paramValue, null);
+      }
+
+      gAddedEngines.push(addedEngine);
+    }
+  }
+}
+
+function cleanupKeywords() {
+  var searchService = Cc["@mozilla.org/browser/search-service;1"].
+                      getService(Ci.nsIBrowserSearchService);
+  gBMFolder.remove();
+  gAddedEngines.map(searchService.removeEngine);
+}
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -8,16 +8,17 @@ browser.jar:
 #endif
 %  overlay chrome://global/content/viewSource.xul chrome://browser/content/viewSourceOverlay.xul
 %  overlay chrome://global/content/viewPartialSource.xul chrome://browser/content/viewSourceOverlay.xul
 %  style chrome://global/content/customizeToolbar.xul chrome://browser/content/browser.css
 %  style chrome://global/content/customizeToolbar.xul chrome://browser/skin/
 *       content/browser/aboutDialog.xul               (content/aboutDialog.xul)
 *       content/browser/aboutDialog.js                (content/aboutDialog.js)
         content/browser/aboutDialog.css               (content/aboutDialog.css)
+*       content/browser/aboutRobots.xhtml             (content/aboutRobots.xhtml)
 *       content/browser/browser.css                   (content/browser.css)
 *       content/browser/browser.js                    (content/browser.js)
 *       content/browser/browser.xul                   (content/browser.xul)
 *       content/browser/credits.xhtml                 (content/credits.xhtml)
 *       content/browser/EULA.js                       (content/EULA.js)
 *       content/browser/EULA.xhtml                    (content/EULA.xhtml)
 *       content/browser/EULA.xul                      (content/EULA.xul)
 *       content/browser/metaData.js                   (content/metaData.js)
--- a/browser/components/Makefile.in
+++ b/browser/components/Makefile.in
@@ -48,16 +48,17 @@ XPIDL_MODULE = browsercompsbase
 XPIDLSRCS = \
 	nsIBrowserHandler.idl \
 	nsIBrowserGlue.idl \
 	$(NULL)
 
 EXTRA_PP_COMPONENTS = \
 	nsBrowserContentHandler.js \
 	nsBrowserGlue.js \
+	aboutRobots.js \
 	$(NULL)
 
 EXTRA_JS_MODULES = distribution.js
 
 DIRS = \
 	dirprovider \
 	microsummaries \
 	migration \
new file mode 100644
--- /dev/null
+++ b/browser/components/aboutRobots.js
@@ -0,0 +1,73 @@
+/* ***** 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 About:IceCream.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Ryan Flint <rflint@mozilla.com>
+ *   Justin Dolske <dolske@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function AboutRobots() {}
+AboutRobots.prototype = {
+  classDescription: "About Robots",
+  contractID: "@mozilla.org/network/protocol/about;1?what=robots",
+  classID: Components.ID("{e18da21c-a4b8-4be5-98aa-942e1e19f35c}"),
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIAboutModule]),
+ 
+  getURIFlags: function(aURI) {
+    return (Ci.nsIAboutModule.ALLOW_SCRIPT |
+            Ci.nsIAboutModule.URI_SAFE_FOR_UNTRUSTED_CONTENT);
+  },
+
+  newChannel: function(aURI) {
+    var ios = Cc["@mozilla.org/network/io-service;1"].
+              getService(Ci.nsIIOService);
+
+    var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].
+                 getService(Ci.nsIScriptSecurityManager);
+
+    var channel = ios.newChannel("chrome://browser/content/aboutRobots.xhtml",
+                                 null, null);
+    var principal = secMan.getCodebasePrincipal(aURI);
+
+    channel.originalURI = aURI;
+    channel.owner = principal;
+
+    return channel;
+  }
+};
+
+function NSGetModule(compMgr, fileSpec)
+  XPCOMUtils.generateModule([AboutRobots]);
--- a/browser/components/feeds/src/WebContentConverter.js
+++ b/browser/components/feeds/src/WebContentConverter.js
@@ -164,26 +164,22 @@ ServiceInfo.prototype = {
       return this;
     throw Cr.NS_ERROR_NO_INTERFACE;
   }
 };
 
 function WebContentConverterRegistrar() {}
 
 WebContentConverterRegistrar.prototype = {
-  _stringBundle: null,
-
   get stringBundle() {
-    if (!this._stringBundle) {
-      this._stringBundle = Cc["@mozilla.org/intl/stringbundle;1"].
-                            getService(Ci.nsIStringBundleService).
-                            createBundle(STRING_BUNDLE_URI);
-    }
-
-    return this._stringBundle;
+    var sb = Cc["@mozilla.org/intl/stringbundle;1"].
+              getService(Ci.nsIStringBundleService).
+              createBundle(STRING_BUNDLE_URI);
+    delete WebContentConverterRegistrar.prototype.stringBundle;
+    return WebContentConverterRegistrar.prototype.stringBundle = sb;
   },
 
   _getFormattedString: function WCCR__getFormattedString(key, params) {
     return this.stringBundle.formatStringFromName(key, params, params.length);
   },
   
   _getString: function WCCR_getString(key) {
     return this.stringBundle.GetStringFromName(key);
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -40,16 +40,18 @@
 const Ci = Components.interfaces;
 const Cc = Components.classes;
 const Cr = Components.results;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource:///modules/distribution.js");
 
+const PREF_EM_NEW_ADDONS_LIST = "extensions.newAddons";
+
 // Factory object
 const BrowserGlueServiceFactory = {
   _instance: null,
   createInstance: function (outer, iid) 
   {
     if (outer != null)
       throw Components.results.NS_ERROR_NO_AGGREGATION;
     return this._instance == null ?
@@ -84,16 +86,19 @@ BrowserGlue.prototype = {
         this._onProfileShutdown();
         break;
       case "prefservice:after-app-defaults":
         this._onAppDefaults();
         break;
       case "final-ui-startup":
         this._onProfileStartup();
         break;
+      case "sessionstore-windows-restored":
+        this._onBrowserStartup();
+        break;
       case "browser:purge-session-history":
         // reset the console service's error buffer
         const cs = Cc["@mozilla.org/consoleservice;1"].
                    getService(Ci.nsIConsoleService);
         cs.logStringMessage(null); // clear the console (in case it's open)
         cs.reset();
         break;
       case "quit-application-requested":
@@ -117,32 +122,34 @@ BrowserGlue.prototype = {
   {
     // observer registration
     const osvr = Cc['@mozilla.org/observer-service;1'].
                  getService(Ci.nsIObserverService);
     osvr.addObserver(this, "quit-application", false);
     osvr.addObserver(this, "xpcom-shutdown", false);
     osvr.addObserver(this, "prefservice:after-app-defaults", false);
     osvr.addObserver(this, "final-ui-startup", false);
+    osvr.addObserver(this, "sessionstore-windows-restored", false);
     osvr.addObserver(this, "browser:purge-session-history", false);
     osvr.addObserver(this, "quit-application-requested", false);
     osvr.addObserver(this, "quit-application-granted", false);
     osvr.addObserver(this, "session-save", false);
   },
 
   // cleanup (called on application shutdown)
   _dispose: function() 
   {
     // observer removal 
     const osvr = Cc['@mozilla.org/observer-service;1'].
                  getService(Ci.nsIObserverService);
     osvr.removeObserver(this, "quit-application");
     osvr.removeObserver(this, "xpcom-shutdown");
     osvr.removeObserver(this, "prefservice:after-app-defaults");
     osvr.removeObserver(this, "final-ui-startup");
+    osvr.removeObserver(this, "sessionstore-windows-restored");
     osvr.removeObserver(this, "browser:purge-session-history");
     osvr.removeObserver(this, "quit-application-requested");
     osvr.removeObserver(this, "quit-application-granted");
     osvr.removeObserver(this, "session-save");
   },
 
   _onAppDefaults: function()
   {
@@ -197,16 +204,42 @@ BrowserGlue.prototype = {
 
   // profile shutdown handler (contains profile cleanup routines)
   _onProfileShutdown: function() 
   {
     this._shutdownPlaces();
     this.Sanitizer.onShutdown();
   },
 
+  // Browser startup complete. All initial windows have opened.
+  _onBrowserStartup: function()
+  {
+    var prefBranch = Cc["@mozilla.org/preferences-service;1"].
+                     getService(Ci.nsIPrefBranch);
+    // If new add-ons were installed during startup open the add-ons manager.
+    if (prefBranch.prefHasUserValue(PREF_EM_NEW_ADDONS_LIST)) {
+      var args = Cc["@mozilla.org/supports-array;1"].
+                 createInstance(Ci.nsISupportsArray);
+      var str = Cc["@mozilla.org/supports-string;1"].
+                createInstance(Ci.nsISupportsString);
+      str.data = "";
+      args.AppendElement(str);
+      var str = Cc["@mozilla.org/supports-string;1"].
+                createInstance(Ci.nsISupportsString);
+      str.data = prefBranch.getCharPref(PREF_EM_NEW_ADDONS_LIST);
+      args.AppendElement(str);
+      const EMURL = "chrome://mozapps/content/extensions/extensions.xul";
+      const EMFEATURES = "chrome,menubar,extra-chrome,toolbar,dialog=no,resizable";
+      var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
+               getService(Ci.nsIWindowWatcher);
+      ww.openWindow(null, EMURL, "_blank", EMFEATURES, args);
+      prefBranch.clearUserPref(PREF_EM_NEW_ADDONS_LIST);
+    }
+  },
+
   _onQuitRequest: function(aCancelQuit, aQuitType)
   {
     // If user has already dismissed quit request, then do nothing
     if ((aCancelQuit instanceof Ci.nsISupportsPRBool) && aCancelQuit.data)
       return;
 
     var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
              getService(Ci.nsIWindowMediator);
@@ -413,45 +446,50 @@ BrowserGlue.prototype = {
       this._rdf = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
       this._dataSource = this._rdf.GetDataSource("rdf:local-store");
       this._dirty = false;
 
       var currentSet = this._rdf.GetResource("currentset");
       var collapsed = this._rdf.GetResource("collapsed");
       var target;
       var moveHome;
+      var homePattern = /(?:^|,)home-button(?:$|,)/;
 
       // get an nsIRDFResource for the PersonalToolbar item
       var personalBar = this._rdf.GetResource("chrome://browser/content/browser.xul#PersonalToolbar");
       var personalBarCollapsed = this._getPersist(personalBar, collapsed) == "true";
 
       // get an nsIRDFResource for the nav-bar item
       var navBar = this._rdf.GetResource("chrome://browser/content/browser.xul#nav-bar");
       target = this._getPersist(navBar, currentSet);
       if (target) {
+        let originalTarget = target;
+
         // move Home if we find it in the nav-bar and the personal toolbar isn't collapsed
-        moveHome = !personalBarCollapsed && (target.indexOf("home-button") != -1);
-        if (moveHome)
-          target = target.replace("home-button", "");
+        if (!personalBarCollapsed)
+          target = target.replace(homePattern, ",");
+        moveHome = (target != originalTarget);
 
         // add the new combined back and forward button
-        target = "unified-back-forward-button," + target;
+        if (!/(?:^|,)unified-back-forward-button(?:$|,)/.test(target))
+          target = "unified-back-forward-button," + target;
 
-        this._setPersist(navBar, currentSet, target);
+        if (target != originalTarget)
+          this._setPersist(navBar, currentSet, target);
       } else {
         // nav-bar doesn't have a currentset, so the defaultset will be used,
         // which means Home will be moved
         moveHome = true;
       }
 
       if (moveHome) {
         // If the personal toolbar has a currentset, add Home. The defaultset will be
         // used otherwise.
         target = this._getPersist(personalBar, currentSet);
-        if (target && target.indexOf("home-button") == -1)
+        if (target && !homePattern.test(target))
           this._setPersist(personalBar, currentSet, "home-button," + target);
 
         // uncollapse the personal toolbar
         if (personalBarCollapsed)
           this._setPersist(personalBar, collapsed, "false");
       }
 
       // force the RDF to be saved
--- a/browser/components/places/content/editBookmarkOverlay.xul
+++ b/browser/components/places/content/editBookmarkOverlay.xul
@@ -157,17 +157,17 @@
         <row align="center" id="editBMPanel_tagsRow">
           <label value="&editBookmarkOverlay.tags.label;"
                  accesskey="&editBookmarkOverlay.tags.accesskey;"
                  control="editBMPanel_tagsField"
                  observes="paneElementsBroadcaster"/>
           <textbox id="editBMPanel_tagsField"
                    onblur="gEditItemOverlay.onTagsFieldBlur();"
                    observes="paneElementsBroadcaster"
-                   emptytext="&editBookmarkOverlay.tagsEmptyText.label;"/>
+                   emptytext="&editBookmarkOverlay.tagsEmptyDesc.label;"/>
           <button id="editBMPanel_tagsSelectorExpander"
                   class="expander-down"
                   tooltiptext="&editBookmarkOverlay.tagsExpanderDown.tooltip;"
                   tooltiptextdown="&editBookmarkOverlay.tagsExpanderDown.tooltip;"
                   tooltiptextup="&editBookmarkOverlay.expanderUp.tooltip;"
                   oncommand="gEditItemOverlay.toggleTagsSelector();"
                   observes="paneElementsBroadcaster"/>
         </row>
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -89,16 +89,23 @@ var PlacesOrganizer = {
     var findKey = document.getElementById("key_find");
     findKey.setAttribute("command", "OrganizerCommand_find:current");
 
     // 2. Disable some keybindings from browser.xul
     var elements = ["cmd_handleBackspace", "cmd_handleShiftBackspace"];
     for (var i=0; i < elements.length; i++) {
       document.getElementById(elements[i]).setAttribute("disabled", "true");
     }
+    
+    // 3. Disable the keyboard shortcut for the History menu back/forward
+    // in order to support those in the Library
+    var historyMenuBack = document.getElementById("historyMenuBack");
+    historyMenuBack.removeAttribute("key");
+    var historyMenuForward = document.getElementById("historyMenuForward");
+    historyMenuForward.removeAttribute("key");
 #endif
   },
 
   QueryInterface: function PO_QueryInterface(aIID) {
     if (aIID.equals(Components.interfaces.nsIDOMEventListener) ||
         aIID.equals(Components.interfaces.nsISupports))
       return this;
 
--- a/browser/components/places/content/places.xul
+++ b/browser/components/places/content/places.xul
@@ -59,16 +59,18 @@
 
 <!DOCTYPE window [
 <!ENTITY % placesDTD SYSTEM "chrome://browser/locale/places/places.dtd">
 %placesDTD;
 <!ENTITY % editMenuOverlayDTD SYSTEM "chrome://global/locale/editMenuOverlay.dtd">
 %editMenuOverlayDTD;
 <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
 %globalDTD;
+<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
+%browserDTD;
 ]>
 
 <window id="places"
         title="&places.library.title;" 
         windowtype="Places:Organizer" 
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         xmlns:html="http://www.w3.org/1999/xhtml"
         onload="PlacesOrganizer.init();"
@@ -128,16 +130,47 @@
     <key id="placesKey_find:all"
          command="OrganizerCommand_find:all" 
          key="&cmd.find.key;"
          modifiers="accel"/>
     <key id="placesKey_find:current"
          command="OrganizerCommand_find:current" 
          key="&cmd.find.key;"
          modifiers="accel,shift"/>
+
+    <!-- Back/Forward Keys Support -->
+#ifndef XP_MACOSX
+    <key id="placesKey_goBackKb"
+         keycode="VK_LEFT"
+         command="OrganizerCommand:Back"
+         modifiers="alt"/>
+    <key id="placesKey_goForwardKb"
+         keycode="VK_RIGHT"
+         command="OrganizerCommand:Forward"
+         modifiers="alt"/>
+#else
+    <key id="placesKey_goBackKb"
+         keycode="VK_LEFT"
+         command="OrganizerCommand:Back"
+         modifiers="accel"/>
+    <key id="placesKey_goForwardKb"
+         keycode="VK_RIGHT"
+         command="OrganizerCommand:Forward"
+         modifiers="accel"/>
+#endif
+#ifdef XP_UNIX
+    <key id="placesKey_goBackKb2"
+         key="&goBackCmd.commandKey;"
+         command="OrganizerCommand:Back"
+         modifiers="accel"/>
+    <key id="placesKey_goForwardKb2"
+         key="&goForwardCmd.commandKey;"
+         command="OrganizerCommand:Forward"
+         modifiers="accel"/>
+#endif
   </keyset>
 
   <keyset id="editMenuKeys">
 #ifdef XP_MACOSX
     <key id="key_delete2" keycode="VK_BACK" command="cmd_delete"/>
 #endif
   </keyset>
 
@@ -413,47 +446,48 @@
                        label="&saveSearch.label;" accesskey="&saveSearch.accesskey;"
                        command="OrganizerCommand_search:save"/>
             </hbox>
           </vbox>
           <vbox flex="1">
             <tree id="placeContent" class="placesTree" context="placesContext" 
                   flex="1" type="places"
                   flatList="true"
+                  enableColumnDrag="true"
                   onkeypress="if (event.keyCode == KeyEvent.DOM_VK_RETURN) PlacesOrganizer.openSelectedNode(event);"
                   ondblclick="PlacesOrganizer.openSelectedNode(event);"
                   onopenflatcontainer="PlacesOrganizer.openFlatContainer(aContainer);"
                   onselect="PlacesOrganizer.onContentTreeSelect();"
                   onclick="PlacesOrganizer.onTreeClick(event);">
               <treecols id="placeContentColumns">
-                <treecol label="&col.name.label;" anonid="title" flex="5" primary="true" 
+                <treecol label="&col.name.label;" id="placesContentTitle" anonid="title" flex="5" primary="true" ordinal="1" 
                          persist="width hidden ordinal sortActive sortDirection"/>
                 <splitter class="tree-splitter"/>
-                <treecol label="&col.tags.label;" anonid="tags" flex="2"
+                <treecol label="&col.tags.label;" id="placesContentTags" anonid="tags" flex="2"
                          persist="width hidden ordinal sortActive sortDirection"/>
                 <splitter class="tree-splitter"/>
-                <treecol label="&col.url.label;" anonid="url" flex="5" 
+                <treecol label="&col.url.label;" id="placesContentUrl" anonid="url" flex="5"
                          persist="width hidden ordinal sortActive sortDirection"/>
                 <splitter class="tree-splitter"/>
-                <treecol label="&col.lastvisit.label;" anonid="date" flex="1" hidden="true"
+                <treecol label="&col.lastvisit.label;" id="placesContentDate" anonid="date" flex="1" hidden="true"
                          persist="width hidden ordinal sortActive sortDirection"/>
                 <splitter class="tree-splitter"/>
-                <treecol label="&col.visitcount.label;" anonid="visitCount" flex="1" hidden="true"
+                <treecol label="&col.visitcount.label;" id="placesContentVisitCount" anonid="visitCount" flex="1" hidden="true"
                          persist="width hidden ordinal sortActive sortDirection"/>
                 <splitter class="tree-splitter"/>
-                <treecol label="&col.keyword.label;" anonid="keyword" flex="1" hidden="true"
+                <treecol label="&col.keyword.label;" id="placesContentKeyword" anonid="keyword" flex="1" hidden="true"
                          persist="width hidden ordinal sortActive sortDirection"/>
                 <splitter class="tree-splitter"/>
-                <treecol label="&col.description.label;" anonid="description" flex="1" hidden="true"
+                <treecol label="&col.description.label;" id="placesContentDescription" anonid="description" flex="1" hidden="true"
                          persist="width hidden ordinal sortActive sortDirection"/>
                 <splitter class="tree-splitter"/>
-                <treecol label="&col.dateadded.label;" anonid="dateAdded" flex="1" hidden="true"
+                <treecol label="&col.dateadded.label;" id="placesContentDateAdded" anonid="dateAdded" flex="1" hidden="true"
                          persist="width hidden ordinal sortActive sortDirection"/>
                 <splitter class="tree-splitter"/>
-                <treecol label="&col.lastmodified.label;" anonid="lastModified" flex="1" hidden="true"
+                <treecol label="&col.lastmodified.label;" id="placesContentLastModified" anonid="lastModified" flex="1" hidden="true"
                          persist="width hidden ordinal sortActive sortDirection"/>
               </treecols>
               <treechildren flex="1"/>
             </tree>
             <splitter id="contentSplitter" collapse="after" persist="state">
               <grippy/>
             </splitter>
             <hbox persist="height" id="infoPane">
--- a/browser/components/places/content/toolbar.xml
+++ b/browser/components/places/content/toolbar.xml
@@ -825,26 +825,31 @@
 
         canDrop: function TBV_DO_canDrop(event, session) {
           return PlacesControllerDragHelper.canDrop();
         },
 
         onDragOver: function TBV_DO_onDragOver(event, flavor, session) {
           PlacesControllerDragHelper.currentDropTarget = event.target;
           var dropPoint = this._getDropPoint(event);
+
           var ib = this._self._dropIndicatorBar;
           if (this._ibTimer) {
             this._ibTimer.cancel();
             this._ibTimer = null;
           }
-          if (dropPoint.folderNode) {
-            // Dropping over a menubutton, set styles and timer to open folder.
-            if (this._overFolder.node != dropPoint.folderNode) {
+
+          if (dropPoint.folderNode ||
+              event.originalTarget == this._self._chevron) {
+            // Dropping over a menubutton or chevron button
+            // set styles and timer to open relative menupopup
+            var overNode = dropPoint.folderNode || this._self._chevron;
+            if (this._overFolder.node != overNode) {
               this._clearOverFolder();
-              this._overFolder.node = dropPoint.folderNode;
+              this._overFolder.node = overNode;
               this._overFolder.openTimer = this._setTimer(this._overFolder.hoverTime);
             }
             if (!this._overFolder.node.hasAttribute("dragover"))
               this._overFolder.node.setAttribute("dragover", "true");
 
             ib.removeAttribute("dragging");
           }
           else {
--- a/browser/components/places/content/treeView.js
+++ b/browser/components/places/content/treeView.js
@@ -433,17 +433,18 @@ PlacesTreeView.prototype = {
   COLUMN_TYPE_VISITCOUNT: 4,
   COLUMN_TYPE_KEYWORD: 5,
   COLUMN_TYPE_DESCRIPTION: 6,
   COLUMN_TYPE_DATEADDED: 7,
   COLUMN_TYPE_LASTMODIFIED: 8,
   COLUMN_TYPE_TAGS: 9,
 
   _getColumnType: function PTV__getColumnType(aColumn) {
-    var columnType = aColumn.id || aColumn.element.getAttribute("anonid");
+    var columnType = aColumn.element.getAttribute("anonid") || aColumn.id;
+
     switch (columnType) {
       case "title":
         return this.COLUMN_TYPE_TITLE;
       case "url":
         return this.COLUMN_TYPE_URI;
       case "date":
         return this.COLUMN_TYPE_DATE;
       case "visitCount":
@@ -1090,18 +1091,18 @@ PlacesTreeView.prototype = {
       return this._visibleElements[aRow].node.indentLevel + 1;
 
     return this._visibleElements[aRow].node.indentLevel;
   },
 
   getImageSrc: function PTV_getImageSrc(aRow, aColumn) {
     this._ensureValidRow(aRow);
 
-    // only the first column has an image
-    if (aColumn.index != 0)
+    // only the title column has an image
+    if (this._getColumnType(aColumn) != this.COLUMN_TYPE_TITLE)
       return "";
 
     var node = this._visibleElements[aRow].node;
 
     // Containers may or may not have favicons. If not, we will return
     // nothing as the image, and the style rule should pick up the
     // default. Separator rows never have icons.
     if (PlacesUtils.nodeIsSeparator(node) ||
--- a/browser/components/places/src/nsPlacesTransactionsService.js
+++ b/browser/components/places/src/nsPlacesTransactionsService.js
@@ -574,20 +574,35 @@ function placesEditBookmarkURITransactio
 }
 
 placesEditBookmarkURITransactions.prototype = {
   __proto__: placesBaseTransaction.prototype,
 
   doTransaction: function PEBUT_doTransaction() {
     this._oldURI = PlacesUtils.bookmarks.getBookmarkURI(this._id);
     PlacesUtils.bookmarks.changeBookmarkURI(this._id, this._newURI);
+    // move tags from old URI to new URI
+    this._tags = PlacesUtils.tagging.getTagsForURI(this._oldURI, {});
+    if (this._tags.length != 0) {
+      // only untag the old URI if this is the only bookmark
+      if (PlacesUtils.getBookmarksForURI(this._oldURI, {}).length == 0)
+        PlacesUtils.tagging.untagURI(this._oldURI, this._tags);
+      PlacesUtils.tagging.tagURI(this._newURI, this._tags);
+    }
   },
 
   undoTransaction: function PEBUT_undoTransaction() {
     PlacesUtils.bookmarks.changeBookmarkURI(this._id, this._oldURI);
+    // move tags from new URI to old URI 
+    if (this._tags.length != 0) {
+      // only untag the new URI if this is the only bookmark
+      if (PlacesUtils.getBookmarksForURI(this._newURI, {}).length == 0)
+        PlacesUtils.tagging.untagURI(this._newURI, this._tags);
+      PlacesUtils.tagging.tagURI(this._oldURI, this._tags);
+    }
   }
 };
 
 function placesSetLoadInSidebarTransactions(aBookmarkId, aLoadInSidebar) {
   this.id = aBookmarkId;
   this._loadInSidebar = aLoadInSidebar;
   this.redoTransaction = this.doTransaction;
 }
--- a/browser/components/preferences/advanced.xul
+++ b/browser/components/preferences/advanced.xul
@@ -227,17 +227,17 @@
                         onsyncfrompreference="return gAdvancedPane.readCacheSize();"
                         onsynctopreference="return gAdvancedPane.writeCacheSize();"
                         aria-labelledby="useCacheBefore cacheSize useCacheAfter"/>
                <label id="useCacheAfter" flex="1">&useCacheAfter.label;</label>
                <button id="clearCacheButton" icon="clear"
                        label="&clearCacheNow.label;" accesskey="&clearCacheNow.accesskey;"
                        oncommand="gAdvancedPane.clearCache();"/>
              </hbox>
-	     <hbox>
+	     <hbox align="center">
 	       <checkbox id="offlineNotify" flex="1"
 			 label="&offlineNotify.label;" accesskey="&offlineNotify.accesskey;"
 			 preference="browser.offline-apps.notify"
 			 onsyncfrompreference="return gAdvancedPane.readOfflineNotify();"/>
 	       <button id="offlineNotifyExceptions"
 		       label="&offlineNotifyExceptions.label;"
 		       accesskey="&offlineNotifyExceptions.accesskey;"
 		       oncommand="gAdvancedPane.showOfflineExceptions();"/>
--- a/browser/components/preferences/connection.xul
+++ b/browser/components/preferences/connection.xul
@@ -94,17 +94,17 @@
 
     <stringbundle id="preferencesBundle" src="chrome://browser/locale/preferences/preferences.properties"/>
 
     <groupbox>
       <caption label="&proxyTitle.label;"/>
 
       <radiogroup id="networkProxyType" preference="network.proxy.type"
                   onsyncfrompreference="return gConnectionsDialog.readProxyType();">
-        <radio value="0" label="&directTypeRadio.label;" accesskey="&directTypeRadio.accesskey;"/>
+        <radio value="0" label="&noProxyTypeRadio.label;" accesskey="&noProxyTypeRadio.accesskey;"/>
         <radio value="4" label="&WPADTypeRadio.label;" accesskey="&WPADTypeRadio.accesskey;"/>
         <radio value="5" label="&systemTypeRadio.label;" accesskey="&systemTypeRadio.accesskey;" id="systemPref" hidden="true"/>
         <radio value="1" label="&manualTypeRadio.label;" accesskey="&manualTypeRadio.accesskey;"/>
         <grid class="indent" flex="1">
           <columns>
             <column/>
             <column flex="1"/>
           </columns>
--- a/browser/components/preferences/main.xul
+++ b/browser/components/preferences/main.xul
@@ -153,18 +153,17 @@
 
       <radiogroup id="saveWhere"
                   preference="browser.download.useDownloadDir"
                   onsyncfrompreference="return gMainPane.readUseDownloadDir();">
         <hbox id="saveToRow">
           <radio id="saveTo" value="true"
                  label="&saveTo.label;"
                  accesskey="&saveTo.accesskey;"
-                 xmlns:aaa="http://www.w3.org/2005/07/aaa"
-                 aaa:labelledby="saveTo downloadFolder"/>
+                 aria-labelledby="saveTo downloadFolder"/>
           <filefield id="downloadFolder" flex="1"
                      preference="browser.download.folderList"
                      preference-editable="true"
                      onsyncfrompreference="return gMainPane.displayDownloadDirPref();"
                      onsynctopreference="return gMainPane.getFolderListPref()"/>
           <button id="chooseFolder" oncommand="gMainPane.chooseFolder();"
 #ifdef XP_MACOSX
                   accesskey="&chooseFolderMac.accesskey;"
--- a/browser/components/preferences/privacy.xul
+++ b/browser/components/preferences/privacy.xul
@@ -96,28 +96,27 @@
 
     </preferences>
     
     <stringbundle id="bundlePreferences" src="chrome://browser/locale/preferences/preferences.properties"/>
     
     <script type="application/x-javascript" src="chrome://browser/content/preferences/privacy.js"/>
 
     <!-- History -->
-    <groupbox id="historyGroup"
-              xmlns:aaa="http://www.w3.org/2005/07/aaa">
+    <groupbox id="historyGroup">
       <caption label="&history.label;"/>
 
       <hbox align="center">
         <checkbox id="rememberHistoryDays"
                   label="&rememberDaysBefore.label;"
                   accesskey="&rememberDaysBefore.accesskey;"
                   oncommand="gPrivacyPane.onchangeHistoryDaysCheck();"
-                  aaa:labelledby="rememberHistoryDays historyDays rememberAfter"/>
+                  aria-labelledby="rememberHistoryDays historyDays rememberAfter"/>
         <textbox id="historyDays" type="number" size="3"
-                 aaa:labelledby="rememberHistoryDays historyDays rememberAfter"
+                 aria-labelledby="rememberHistoryDays historyDays rememberAfter"
                  onkeyup="gPrivacyPane.onkeyupHistoryDaysText();"
                  preference="browser.history_expire_days_min"/>
         <label id="rememberAfter"> &rememberDaysAfter.label;</label>
       </hbox>
       <checkbox id="rememberForms"
                 label="&rememberForms.label;"
                 accesskey="&rememberForms.accesskey;"
                 preference="browser.formfill.enable"/>
--- a/browser/components/preferences/security.xul
+++ b/browser/components/preferences/security.xul
@@ -129,17 +129,17 @@
                 label="&changeMasterPassword.label;"
                 accesskey="&changeMasterPassword.accesskey;"
                 oncommand="gSecurityPane.changeMasterPassword();"/>
       </hbox>
 
       <hbox id="showPasswordsBox">
         <spacer flex="1"/>
         <button id="showPasswords"
-                label="&showPasswords.label;" accesskey="&showPasswords.accesskey;"
+                label="&savedPasswords.label;" accesskey="&savedPasswords.accesskey;"
                 oncommand="gSecurityPane.showPasswords();"
                 preference="pref.privacy.disable_button.view_passwords"/>
       </hbox>
     </groupbox>
 
     <!-- Warning Messages -->
     <hbox class="bottomBox">
       <groupbox id="warningMessagesGroup" orient="horizontal" flex="1"
--- a/browser/components/safebrowsing/content/application.js
+++ b/browser/components/safebrowsing/content/application.js
@@ -131,26 +131,38 @@ PROT_Application.prototype.getReportURL 
 }
 
 /**
  * about:blocked implementation
  */
 PROT_Application.prototype.newChannel = function(uri) {
   var ioService = Cc["@mozilla.org/network/io-service;1"]
                  .getService(Ci.nsIIOService);
+  var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"]
+              .getService(Ci.nsIScriptSecurityManager);
+
   var childURI = ioService.newURI("chrome://browser/content/safebrowsing/blockedSite.xhtml",
                                   null, null);
   var channel = ioService.newChannelFromURI(childURI);
   channel.originalURI = uri;
+  
+  // Drop chrome privilege
+  var principal = secMan.getCodebasePrincipal(uri);
+  channel.owner = principal;
 
   return channel;
 }
 
 PROT_Application.prototype.getURIFlags = function(uri) {
-  return Ci.nsIAboutModule.ALLOW_SCRIPT;
+  // We don't particularly *want* people linking to this from
+  // untrusted content, but given that bad sites can cause this page
+  // to appear (e.g. by having an iframe pointing to known malware),
+  // we should code as though this is explicitly possible.
+  return Ci.nsIAboutModule.ALLOW_SCRIPT |
+         Ci.nsIAboutModule.URI_SAFE_FOR_UNTRUSTED_CONTENT;
 }
 
 PROT_Application.prototype.QueryInterface = function(iid) {
   if (iid.equals(Ci.nsISupports) ||
       iid.equals(Ci.nsISupportsWeakReference) ||
       iid.equals(Ci.nsIObserver) ||
       iid.equals(Ci.nsIAboutModule))
     return this;
--- a/browser/components/safebrowsing/content/blockedSite.xhtml
+++ b/browser/components/safebrowsing/content/blockedSite.xhtml
@@ -90,118 +90,106 @@
       }
       
       /**
        * Attempt to parse the result of getURL and extract a hostname.  Fail back
        * to getURL so that we always return something meaningful.
        */
       function getHostString()
       {
-        var ios = Components.classes["@mozilla.org/network/io-service;1"]
-                            .getService(Components.interfaces.nsIIOService);
-        var url = getURL();
-        try {
-          return ios.newURI(url, null, null).host;
-        } catch (e) {
-          return url;
-        }
+        return document.location.hostname;
       }
       
-      // Elements that tend to need content set
-      var errorTitleText, errorShortDescText, errorLongDesc, errorLongDescText;
-
-      // The string bundles managing strings for various blocked page scenarios
-      var sb = srGetStrBundle("chrome://browser/locale/safebrowsing/blockedSite.properties");
-      var brandBundle = srGetStrBundle("chrome://branding/locale/brand.properties");
-      var brandShortName = brandBundle.GetStringFromName("brandShortName");
-      
       function initPage()
       {
-        // Set up the cached elements
-        errorTitleText = document.getElementById("errorTitleText");
-        errorShortDescText = document.getElementById("errorShortDescText");
-        errorLongDesc = document.getElementById("errorLongDesc");
-        errorLongDescText = document.getElementById("errorLongDescText");
-        
         // Handoff to the appropriate initializer, based on error code
         switch(getErrorCode()) {
           case "malwareBlocked" :
             initPage_malware();
             break;
           case "phishingBlocked" :
             initPage_phishing();
             break;
         }
       }        
       
       /**
        * Initialize custom strings and functionality for blocked malware case
        */
       function initPage_malware()
       {
-        document.title = sb.GetStringFromName("malware.title");
-        errorTitleText.textContent = document.title;
-        errorShortDescText.textContent = sb.formatStringFromName("malware.shortDesc",
-                                                                 [getHostString()], 1);
-        errorLongDesc.innerHTML = sb.GetStringFromName("malware.longDesc");
+        // Remove phishing strings
+        var el = document.getElementById("errorTitleText_phishing");
+        el.parentNode.removeChild(el);
+
+        el = document.getElementById("errorShortDescText_phishing");
+        el.parentNode.removeChild(el);
+
+        el = document.getElementById("errorLongDescText_phishing");
+        el.parentNode.removeChild(el);
+
+        // Set sitename
+        document.getElementById("malware_sitename").textContent = getHostString();
+        document.title = document.getElementById("errorTitleText_malware")
+                                 .innerHTML;
       }
       
       /**
        * Initialize custom strings and functionality for blocked phishing case
        */
       function initPage_phishing()
       {
-        document.title = sb.GetStringFromName("phishing.title");
-        errorTitleText.textContent = document.title;
-        errorShortDescText.textContent = sb.formatStringFromName("phishing.shortDesc",
-                                                                 [getHostString()], 1);
-        
-        var longDesc = sb.GetStringFromName("phishing.longDesc");
+        // Remove malware strings
+        var el = document.getElementById("errorTitleText_malware");
+        el.parentNode.removeChild(el);
+
+        el = document.getElementById("errorShortDescText_malware");
+        el.parentNode.removeChild(el);
 
-        // If we have a more-info link for the phishing information, add it in,
-        // otherwise just use the generic text
-        var faqURL = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
-                               .getService(Components.interfaces.nsIURLFormatter)
-                               .formatURLPref("browser.safebrowsing.warning.infoURL");
-        if(faqURL && faqURL != "about:blank") {
-          longDesc += sb.formatStringFromName("phishing.learnMoreLink",
-                                              [brandShortName], 1);
-          errorLongDesc.innerHTML = longDesc;          
-          document.getElementById("faqLink").setAttribute("href", faqURL);
-        }
-        else 
-          errorLongDesc.innerHTML = longDesc;
+        el = document.getElementById("errorLongDescText_malware");
+        el.parentNode.removeChild(el);
+
+        // Set sitename
+        document.getElementById("phishing_sitename").textContent = getHostString();
+        document.title = document.getElementById("errorTitleText_phishing")
+                                 .innerHTML;
       }
     ]]></script>
   </head>
 
   <body dir="&locale.dir;">
     <div id="errorPageContainer">
     
       <!-- Error Title -->
       <div id="errorTitle">
-        <h1 id="errorTitleText" />
+        <h1 id="errorTitleText_phishing">&safeb.blocked.phishing.title;</h1>
+        <h1 id="errorTitleText_malware">&safeb.blocked.malware.title;</h1>
       </div>
       
       <div id="errorLongContent">
       
         <!-- Short Description -->
         <div id="errorShortDesc">
-          <p id="errorShortDescText" />
+          <p id="errorShortDescText_phishing">&safeb.blocked.phishing.shortDesc;</p>
+          <p id="errorShortDescText_malware">&safeb.blocked.malware.shortDesc;</p>
         </div>
 
         <!-- Long Description -->
         <div id="errorLongDesc">
-          <p id="errorLongDescText" />
+          <p id="errorLongDescText_phishing">&safeb.blocked.phishing.longDesc;</p>
+          <p id="errorLongDescText_malware">&safeb.blocked.malware.longDesc;</p>
         </div>
         
         <!-- Action buttons -->
         <div id="buttons">
+          <!-- Commands handled in browser.js -->
           <xul:button xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-                      id="getMeOutButton" label="&safeb.palm.accept.label;" oncommand="window.home();" />
+                      id="getMeOutButton" label="&safeb.palm.accept.label;"/>
+          <xul:button xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+                      id="reportButton" label="&safeb.palm.report.label;"/>
         </div>
       </div>
     </div>
     <!--
     - Note: It is important to run the script this way, instead of using
     - an onload handler. This is because error pages are loaded as
     - LOAD_BACKGROUND, which means that onload handlers will not be executed.
     -->
--- a/browser/components/safebrowsing/content/sb-loader.js
+++ b/browser/components/safebrowsing/content/sb-loader.js
@@ -33,34 +33,43 @@
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
 # ***** END LICENSE BLOCK *****
 
 var safebrowsing = {
   appContext: null,
 
   startup: function() {
-    setTimeout(safebrowsing.deferredStartup, 2000);
+    setTimeout(function() {
+      safebrowsing.deferredStartup();
+    }, 2000);
     window.removeEventListener("load", safebrowsing.startup, false);
   },
 
   deferredStartup: function() {
-    this.appContext = Cc["@mozilla.org/safebrowsing/application;1"].
-                      getService().wrappedJSObject;
     this.appContext.initialize();
   },
 
   setReportPhishingMenu: function() {
     var uri = getBrowser().currentURI;
     var broadcaster = document.getElementById("reportPhishingBroadcaster");
     if (uri && (uri.schemeIs("http") || uri.schemeIs("https")))
       broadcaster.removeAttribute("disabled");
     else
       broadcaster.disabled = true;
   },
+  
+  /**
+   * Lazy init getter for appContext
+   */
+  get appContext() {
+    delete this.appContext;
+    return this.appContext = Cc["@mozilla.org/safebrowsing/application;1"]
+                            .getService().wrappedJSObject;
+  },
 
   /**
    * Used to report a phishing page or a false positive
    * @param name String either "Phish" or "Error"
    * @return String the report phishing URL.
    */
   getReportURL: function(name) {
     var reportUrl = this.appContext.getReportURL(name);
--- a/browser/components/search/nsSearchService.js
+++ b/browser/components/search/nsSearchService.js
@@ -2749,16 +2749,22 @@ SearchService.prototype = {
       this._currentEngine = null;
 
     if (engineToRemove._readOnly) {
       // Just hide it (the "hidden" setter will notify) and remove its alias to
       // avoid future conflicts with other engines.
       engineToRemove.hidden = true;
       engineToRemove.alias = null;
     } else {
+      // Cancel the lazy serialization timer if it's running
+      if (engineToRemove._serializeTimer) {
+        engineToRemove._serializeTimer.cancel();
+        engineToRemove._serializeTimer = null;
+      }
+
       // Remove the engine file from disk (this might throw)
       engineToRemove._remove();
       engineToRemove._file = null;
 
       // Remove the engine from _sortedEngines
       var index = this._sortedEngines.indexOf(engineToRemove);
       ENSURE(index != -1, "Can't find engine to remove in _sortedEngines!",
              Cr.NS_ERROR_FAILURE);
--- a/browser/fuel/src/fuelApplication.js
+++ b/browser/fuel/src/fuelApplication.js
@@ -297,17 +297,17 @@ function Preference(aName, aBranch) {
 // Preference implementation
 Preference.prototype = {
   get name() {
     return this._name;
   },
 
   get type() {
     var value = "";
-    var type = this._prefs.getPrefType(name);
+    var type = this.branch._prefs.getPrefType(this._name);
 
     switch (type) {
       case Ci.nsIPrefBranch2.PREF_STRING:
         value = "String";
         break;
       case Ci.nsIPrefBranch2.PREF_BOOL:
         value = "Boolean";
         break;
--- a/browser/fuel/test/browser_ApplicationPrefs.js
+++ b/browser/fuel/test/browser_ApplicationPrefs.js
@@ -6,141 +6,153 @@ var testdata = {
   integer: "permissions.default.image",
   boolean: "browser.blink_allowed"
 };
 
 function test() {
   // test getting non-existing values
   var itemValue = Application.prefs.getValue(testdata.missing, "default");
   is(itemValue, "default", "Check 'Application.prefs.getValue' for non-existing item");
-  
+
   is(Application.prefs.get(testdata.missing), null, "Check 'Application.prefs.get' for non-existing item");
-  
+
   // test setting and getting a value
   Application.prefs.setValue(testdata.dummy, "dummy");
   itemValue = Application.prefs.getValue(testdata.dummy, "default");
   is(itemValue, "dummy", "Check 'Application.prefs.getValue' for existing item");
 
   // test for overwriting an existing value
   Application.prefs.setValue(testdata.dummy, "smarty");
   itemValue = Application.prefs.getValue(testdata.dummy, "default");
   is(itemValue, "smarty", "Check 'Application.prefs.getValue' for overwritten item");
-  
+
   // test setting and getting a value
   Application.prefs.get(testdata.dummy).value = "dummy2";
   itemValue = Application.prefs.get(testdata.dummy).value;
   is(itemValue, "dummy2", "Check 'Application.prefs.get().value' for existing item");
 
   // test resetting a pref [since there is no default value, the pref should disappear]
   Application.prefs.get(testdata.dummy).reset();
-  var itemValue = Application.prefs.getValue(testdata.dummy, "default");
+  itemValue = Application.prefs.getValue(testdata.dummy, "default");
   is(itemValue, "default", "Check 'Application.prefs.getValue' for reset pref");
-  
+
   // test to see if a non-existant property exists
   ok(!Application.prefs.has(testdata.dummy), "Check non-existant property for existance");
-  
+
   // PREF: string browser.active_color == #EE0000
-  
+
   // test to see if an existing string property exists
   ok(Application.prefs.has(testdata.string), "Check existing string property for existance");
-  
+
   // test accessing a non-existant string property
   var val = Application.prefs.getValue(testdata.dummy, "default");
   is(val, "default", "Check non-existant string property for expected value");
-  
+
   // test accessing an existing string property
   var val = Application.prefs.getValue(testdata.string, "default");
   is(val, "#EE0000", "Check existing string property for expected value");
-  
+
   // test manipulating an existing string property
   Application.prefs.setValue(testdata.string, "#EF0000");
   var val = Application.prefs.getValue(testdata.string, "default");
   is(val, "#EF0000", "Set existing string property");
-  
+
+  // test getting the type of an existing string property
+  var type = Application.prefs.get(testdata.string).type;
+  is(type, "String", "Check 'Application.prefs.get().type' for string pref");
+
   // test resetting an existing string property
   Application.prefs.get(testdata.string).reset();
   var val = Application.prefs.getValue(testdata.string, "default");
   is(val, "#EE0000", "Reset existing string property");
-  
+
   // PREF: integer permissions.default.image == 1
-  
+
   // test to see if an existing integer property exists
   ok(Application.prefs.has(testdata.integer), "Check existing integer property for existance");
-  
+
   // test accessing a non-existant integer property
   var val = Application.prefs.getValue(testdata.dummy, 0);
   is(val, 0, "Check non-existant integer property for expected value");
-  
+
   // test accessing an existing integer property
   var val = Application.prefs.getValue(testdata.integer, 0);
   is(val, 1, "Check existing integer property for expected value");
 
   // test manipulating an existing integer property
   Application.prefs.setValue(testdata.integer, 0);
   var val = Application.prefs.getValue(testdata.integer, 1);
   is(val, 0, "Set existing integer property");
-  
+
+  // test getting the type of an existing integer property
+  var type = Application.prefs.get(testdata.integer).type;
+  is(type, "Number", "Check 'Application.prefs.get().type' for integer pref");
+
   // test resetting an existing integer property
   Application.prefs.get(testdata.integer).reset();
   var val = Application.prefs.getValue(testdata.integer, 0);
   is(val, 1, "Reset existing integer property");
 
   // PREF: boolean browser.blink_allowed == true
-  
+
   // test to see if an existing boolean property exists
   ok(Application.prefs.has(testdata.boolean), "Check existing boolean property for existance");
-  
+
   // test accessing a non-existant boolean property
   var val = Application.prefs.getValue(testdata.dummy, true);
   ok(val, "Check non-existant boolean property for expected value");
-  
+
   // test accessing an existing boolean property
   var val = Application.prefs.getValue(testdata.boolean, false);
   ok(val, "Check existing boolean property for expected value");
-  
+
   // test manipulating an existing boolean property
   Application.prefs.setValue(testdata.boolean, false);
   var val = Application.prefs.getValue(testdata.boolean, true);
   ok(!val, "Set existing boolean property");
-  
+
+  // test getting the type of an existing boolean property
+  var type = Application.prefs.get(testdata.boolean).type;
+  is(type, "Boolean", "Check 'Application.prefs.get().type' for boolean pref");
+
   // test resetting an existing boolean property
   Application.prefs.get(testdata.boolean).reset();
   var val = Application.prefs.getValue(testdata.boolean, false);
   ok(val, "Reset existing string property for expected value");
-  
+
   // test getting all preferences
   var allPrefs = Application.prefs.all;
   ok(allPrefs.length >= 800, "Check 'Application.prefs.all' for the right number of preferences");
   ok(allPrefs[0].name.length > 0, "Check 'Application.prefs.all' for a valid name in the starting preference");
 
   // test the value of the preference root
   is(Application.prefs.root, "", "Check the Application preference root");
-  
+
   // test for user changed preferences
   ok(Application.prefs.get("browser.shell.checkDefaultBrowser").modified, "A single preference is marked as modified.");
   ok(!Application.prefs.get(testdata.string).modified, "A single preference is marked as not modified.");
-  
+
   // test for a locked preference
   var pref = Application.prefs.get(testdata.string);
   ok(!pref.locked, "A single preference should not be locked.");
-  
+
   pref.locked = true;
   ok(pref.locked, "A single preference should be locked.");
-  
+
   try {
     prev.value = "test value";
-    
+
     ok(false, "A locked preference should not be able to be modified.");
   } catch(e){
     ok(true, "A locked preference should not be able to be modified.");
   }
-  
+
   pref.locked = false;
   ok(!pref.locked, "A single preference should not be locked.");
-  
+
   // check for change event when setting a value
   waitForExplicitFinish();
   Application.prefs.events.addListener("change", onPrefChange);
   Application.prefs.setValue("fuel.fuel-test", "change event");
 }
 
 function onPrefChange(evt) {
   is(evt.data, testdata.dummy, "Check 'Application.prefs.set' fired a change event");
@@ -148,11 +160,11 @@ function onPrefChange(evt) {
 
   Application.prefs.get("fuel.fuel-test").events.addListener("change", onPrefChange2);
   Application.prefs.setValue("fuel.fuel-test", "change event2");
 }
 
 function onPrefChange2(evt) {
   is(evt.data, testdata.dummy, "Check 'Application.prefs.set' fired a change event for a single preference");
   Application.prefs.events.removeListener("change", onPrefChange2);
-  
+
   finish();
 }
--- a/browser/installer/unix/packages-static
+++ b/browser/installer/unix/packages-static
@@ -236,16 +236,17 @@ bin/components/txEXSLTRegExFunctions.js
 bin/components/nsLivemarkService.js
 bin/components/nsTaggingService.js
 bin/components/nsDefaultCLH.js
 bin/components/nsContentPrefService.js
 bin/components/nsContentDispatchChooser.js
 bin/components/nsHandlerService.js
 bin/components/nsWebHandlerApp.js
 bin/components/libdbusservice.so
+bin/components/aboutRobots.js
 
 ; Modules
 bin/modules/*
 
 ; Safe Browsing
 bin/components/nsSafebrowsingApplication.js
 bin/components/nsUrlClassifierListManager.js
 bin/components/nsUrlClassifierLib.js
--- a/browser/installer/windows/packages-static
+++ b/browser/installer/windows/packages-static
@@ -235,16 +235,17 @@ bin\components\brwsrcmp.dll
 bin\components\txEXSLTRegExFunctions.js
 bin\components\nsLivemarkService.js
 bin\components\nsTaggingService.js
 bin\components\nsDefaultCLH.js
 bin\components\nsContentPrefService.js
 bin\components\nsContentDispatchChooser.js
 bin\components\nsHandlerService.js
 bin\components\nsWebHandlerApp.js
+bin\components\aboutRobots.js
 
 ; Modules
 bin\modules\*
 
 ; Safe Browsing
 bin\components\nsSafebrowsingApplication.js
 bin\components\nsUrlClassifierListManager.js
 bin\components\nsUrlClassifierLib.js
--- a/browser/locales/en-US/chrome/browser/aboutRobots.dtd
+++ b/browser/locales/en-US/chrome/browser/aboutRobots.dtd
@@ -11,17 +11,17 @@
 <!ENTITY robots.errorTitleText "Welcome Humans!">
 <!-- Movie: The Day The Earth Stood Still. Spoken by Klaatu. -->
 <!ENTITY robots.errorShortDescText "We have come to visit you in peace and with goodwill!">
 <!-- Various books by Isaac Asimov. http://en.wikipedia.org/wiki/Three_Laws_of_Robotics -->
 <!ENTITY robots.errorLongDesc1 "Robots may not injure a human being or, through inaction, allow a human being to come to harm.">
 <!-- Movie: Blade Runner. Batty: "I've seen things you people wouldn't believe..." -->
 <!ENTITY robots.errorLongDesc2 "Robots have seen things you people wouldn't believe.">
 <!-- Book: Hitchiker's Guide To The Galaxy. What the Sirius Cybernetics Corporation calls robots. -->
-<!ENTITY robots.errorLongDesc3 "Robots are Your Plastic Pal Who's Fun To Be With">
+<!ENTITY robots.errorLongDesc3 "Robots are Your Plastic Pal Who's Fun To Be With.">
 <!-- TV: Futurama. Bender's first line is "Bite my shiny metal ass." -->
 <!ENTITY robots.errorLongDesc4 "Robots have shiny metal posteriors which should not be bitten.">
 <!-- TV: Battlestar Galactica (2004 series). From the opening text. -->
 <!ENTITY robots.errorTrailerDescText "And they have a plan.">
 <!-- TV: Battlestar Galactica (2004 series). Common expletive referring to Cylons. -->
 <!ENTITY robots.imgtitle "Frakkin' Toasters">
 <!-- Book: Hitchiker's Guide To The Galaxy. Arthur presses a button and it warns him. -->
 <!ENTITY robots.dontpress "Please do not press this button again.">
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -59,17 +59,17 @@
 
 <!ENTITY bookmarksMenu.label "Bookmarks">
 <!ENTITY bookmarksMenu.accesskey "B">
 <!ENTITY bookmarkThisPageCmd.label "Bookmark This Page">
 <!ENTITY bookmarkThisPageCmd.commandkey "d">
 <!ENTITY subscribeToPageMenupopup.label "Subscribe to This Page">
 <!ENTITY subscribeToPageMenuitem.label "Subscribe to This Page…">
 <!ENTITY addCurPagesCmd.label "Bookmark All Tabs…">
-<!ENTITY showAllBookmarksCmd.label "Show All Bookmarks…">
+<!ENTITY showAllBookmarksCmd2.label "Organize Bookmarks">
 <!ENTITY bookmarkAllCmd.label "Bookmark All Tabs…">
 
 <!ENTITY backCmd.label                "Back">
 <!ENTITY backCmd.accesskey            "B">
 <!ENTITY backButton.tooltip           "Go back one page">
 <!ENTITY forwardCmd.label             "Forward">
 <!ENTITY forwardCmd.accesskey         "F">
 <!ENTITY forwardButton.tooltip        "Go forward one page">
@@ -171,17 +171,17 @@
 <!ENTITY viewCustomizeToolbar.label       "Customize…"> 
 <!ENTITY viewCustomizeToolbar.accesskey     "C">
 
 <!ENTITY historyMenu.label "History">
 <!ENTITY historyMenu.accesskey "s">
 <!ENTITY historyUndoMenu.label "Recently Closed Tabs">
 
 <!ENTITY historyHomeCmd.label "Home">
-<!ENTITY showAllHistoryCmd.label "Show All History…">
+<!ENTITY showAllHistoryCmd2.label "Show All History">
 <!ENTITY showAllHistoryCmd.commandkey "H">
 
 <!ENTITY openCmd.commandkey           "l">
 <!ENTITY urlbar.emptyText             "Search Bookmarks and History">
 <!ENTITY urlbar.accesskey             "d">
 
 <!-- 
   Comment duplicated from browser-sets.inc:
@@ -357,17 +357,17 @@
 <!ENTITY editBookmark.cancel.label                   "Cancel">
 <!ENTITY editBookmark.removeBookmark.label           "Remove Bookmark">
 <!ENTITY editBookmark.removeBookmark.accessKey       "R">
 <!ENTITY editBookmark.undo.label                     "Undo">
 <!ENTITY editBookmark.undo.accessKey                 "U">
 <!ENTITY editBookmark.edit.label                     "Edit…">
 <!ENTITY editBookmark.edit.accessKey                 "E">
 
-<!ENTITY identity.unverifiedsite "You are connected to an unverified site.">
+<!ENTITY identity.unverifiedsite2 "This web site does not supply identity information.">
 <!ENTITY identity.connectedTo "You are connected to">
 <!-- Localization note (identity.runBy) : This string appears between a
 domain name (above) and an organization name (below). E.g.
 
 example.com
 which is run by
 Example Enterprises, Inc.
 
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -114,17 +114,17 @@ identity.identified.verified_by_you=You 
 identity.identified.state_and_country=%S, %S
 identity.identified.title_with_country=%S (%S)
 
 identity.encrypted=Your connection to this web site is encrypted to prevent eavesdropping.
 identity.unencrypted=Your connection to this web site is not encrypted.
 
 identity.unknown.tooltip=This web site does not supply identity information.
 
-identity.ownerUnknown=(no information provided)
+identity.ownerUnknown2=(unknown)
 
 # Downloads Monitor Panel
 # LOCALIZATION NOTE (activeDownloads, pausedDownloads): Semi-colon list of plural
 # forms. See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
 # #1 number of downloads; #2 time left
 # examples: One active download (2 minutes remaining); 11 paused downloads
 activeDownloads=One active download (#2);#1 active downloads (#2)
 pausedDownloads=One paused download;#1 paused downloads
--- a/browser/locales/en-US/chrome/browser/places/editBookmarkOverlay.dtd
+++ b/browser/locales/en-US/chrome/browser/places/editBookmarkOverlay.dtd
@@ -7,17 +7,17 @@
 <!ENTITY editBookmarkOverlay.siteLocation.label              "Site Location:">
 <!ENTITY editBookmarkOverlay.siteLocation.accesskey          "S">
 <!ENTITY editBookmarkOverlay.liveTitlesSeparator.label       "Live Titles">
 <!ENTITY editBookmarkOverlay.folder.label                    "Folder:">
 <!ENTITY editBookmarkOverlay.foldersExpanderDown.tooltip     "Show all the bookmarks folders">
 <!ENTITY editBookmarkOverlay.expanderUp.tooltip              "Hide">
 <!ENTITY editBookmarkOverlay.tags.label                      "Tags:">
 <!ENTITY editBookmarkOverlay.tags.accesskey                  "T">
-<!ENTITY editBookmarkOverlay.tagsEmptyText.label             "Separate tags with commas.">
+<!ENTITY editBookmarkOverlay.tagsEmptyDesc.label             "Separate tags with commas">
 <!ENTITY editBookmarkOverlay.description.label               "Description:">
 <!ENTITY editBookmarkOverlay.description.accesskey           "D">
 <!ENTITY editBookmarkOverlay.keyword.label                   "Keyword:">
 <!ENTITY editBookmarkOverlay.keyword.accesskey               "K">
 <!ENTITY editBookmarkOverlay.tagsExpanderDown.tooltip        "Show all tags">
 <!ENTITY editBookmarkOverlay.loadInSidebar.label             "Load this bookmark in the sidebar">
 <!ENTITY editBookmarkOverlay.loadInSidebar.accesskey         "h">
 <!ENTITY editBookmarkOverlay.choose.label                    "Choose…">
--- a/browser/locales/en-US/chrome/browser/preferences/advanced-scripts.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/advanced-scripts.dtd
@@ -35,16 +35,18 @@
 #endif
    - ***** END LICENSE BLOCK ***** -->
 
 <!ENTITY advancedJSDialog.title         "Advanced JavaScript Settings">
 <!ENTITY window.width                   "37em">
 
 <!ENTITY allowScripts.label             "Allow scripts to:">
 
+<!ENTITY moveResizeWindows.label        "Move or resize existing windows">
+<!ENTITY moveResizeWindows.accesskey    "M">
 <!ENTITY moveResizeNotAllowed.label      "Scripts may not move or resize existing windows">
 <!ENTITY raiseLowerWindows.label        "Raise or lower windows">
 <!ENTITY raiseLowerWindows.accesskey    "R">
 <!ENTITY disableContextMenus.label      "Disable or replace context menus">
 <!ENTITY disableContextMenus.accesskey  "D">
 <!ENTITY hideStatusBar.label            "Hide the status bar">
 <!ENTITY hideStatusBar.accesskey        "H">
 <!ENTITY changeStatusBar.label          "Change status bar text">
--- a/browser/locales/en-US/chrome/browser/preferences/connection.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/connection.dtd
@@ -1,16 +1,16 @@
 
 <!ENTITY  connectionsDialog.title       "Connection Settings">
 <!ENTITY  window.width                  "37em">
 <!ENTITY  window.macWidth               "39em">
 
 <!ENTITY  proxyTitle.label              "Configure Proxies to Access the Internet">
-<!ENTITY  directTypeRadio.label         "Direct connection to the Internet">
-<!ENTITY  directTypeRadio.accesskey     "d">
+<!ENTITY  noProxyTypeRadio.label        "No proxy">
+<!ENTITY  noProxyTypeRadio.accesskey    "x">
 <!ENTITY  systemTypeRadio.label         "Use system proxy settings">
 <!ENTITY  systemTypeRadio.accesskey     "u">
 <!ENTITY  WPADTypeRadio.label           "Auto-detect proxy settings for this network">
 <!ENTITY  WPADTypeRadio.accesskey       "w">
 <!ENTITY  manualTypeRadio.label         "Manual proxy configuration:">
 <!ENTITY  manualTypeRadio.accesskey     "m">
 <!ENTITY  autoTypeRadio.label           "Automatic proxy configuration URL:">
 <!ENTITY  autoTypeRadio.accesskey       "A">
--- a/browser/locales/en-US/chrome/browser/preferences/privacy.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/privacy.dtd
@@ -17,16 +17,19 @@
 <!ENTITY  rememberDownloads.accesskey   "d">
 
 
 <!ENTITY  cookies.label                 "Cookies">
 
 <!ENTITY  acceptCookies.label           "Accept cookies from sites">
 <!ENTITY  acceptCookies.accesskey       "c">
 
+<!ENTITY  acceptThirdParty.label        "Accept third-party cookies">
+<!ENTITY  acceptThirdParty.accesskey    "p">
+
 <!ENTITY  keepUntil.label               "Keep until:">
 <!ENTITY  keepUntil.accesskey           "K">
 
 <!ENTITY  expire.label                  "they expire">
 <!ENTITY  close.label                   "I close &brandShortName;">
 <!ENTITY  askEachTime.label             "ask me every time">
 
 <!ENTITY  cookieExceptions.label        "Exceptions…">
--- a/browser/locales/en-US/chrome/browser/preferences/security.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/security.dtd
@@ -25,18 +25,18 @@
 <!ENTITY  passwordExceptions.label      "Exceptions…">
 <!ENTITY  passwordExceptions.accesskey  "x">
 
 <!ENTITY  useMasterPassword.label        "Use a master password">
 <!ENTITY  useMasterPassword.accesskey    "U">
 <!ENTITY  changeMasterPassword.label     "Change Master Password…">
 <!ENTITY  changeMasterPassword.accesskey "M">
 
-<!ENTITY  showPasswords.label            "Show Passwords…">
-<!ENTITY  showPasswords.accesskey        "P">
+<!ENTITY  savedPasswords.label            "Saved Passwords…">
+<!ENTITY  savedPasswords.accesskey        "P">
 
 
 <!ENTITY  warnings.label                "Warning Messages">
 
 <!ENTITY  chooseWarnings.label          "Choose which warning messages you want to see while browsing the web">
 
 <!ENTITY  warningSettings.label         "Settings…">
 <!ENTITY  warningSettings.accesskey     "S">
--- a/browser/locales/en-US/chrome/browser/safebrowsing/blockedSite.properties
+++ b/browser/locales/en-US/chrome/browser/safebrowsing/blockedSite.properties
@@ -1,12 +1,7 @@
-malware.title=Suspected Attack Site!
+malware.title2=Reported Attack Site!
 malware.shortDesc=The web site at %S has been reported as an attack site and has been blocked based on your security preferences.
-malware.longDesc=<p>Attack sites try to install programs that steal private information, use your computer to attack others, or damage your system.</p>\n<p>Web site owners who believe their site has been reported as an attack site in error may <a href='http://www.stopbadware.org/home/reviewinfo' >request a review</a>.</p>
+malware.longDesc2=<p>Attack sites try to install programs that steal private information, use your computer to attack others, or damage your system.</p>\n<p>Some attack sites intentionally distribute harmful software, but many are compromised without the knowledge or permission of their owners.</p>
 
-phishing.title=Suspected Web Forgery!
-phishing.shortDesc=The web site at %S has been reported as a web forgery designed to trick users into sharing personal or financial information.
-phishing.longDesc=<p>Entering any personal information on this page may result in identity theft or other fraud.</p><p>These types of web forgeries are used in scams known as phishing attacks, in which fraudulent web pages and emails are used to imitate sources you may trust.</p>
-
-# Localization note (phishing.learnMoreLink): please leave the HTML tags as-is.
-# A localized href is pulled in from user preferences automatically.  The anchor
-# text, as well as the rest of the sentence, should be translated.
-phishing.learnMoreLink=<p>You can find out more about <a id="faqLink" href="">how %S protects you</a> from phishing attacks.</p>
+phishing.title2=Reported Web Forgery!
+phishing.shortDesc2=The web site at %S has been reported as a web forgery and has been blocked based on your security preferences.
+phishing.longDesc2=<p>Web forgeries are designed to trick you into revealing personal or financial information by imitating sources you may trust.</p><p>Entering any information on this web page may result in identity theft or other fraud.</p>
--- a/browser/locales/en-US/chrome/browser/safebrowsing/phishing-afterload-warning-message.dtd
+++ b/browser/locales/en-US/chrome/browser/safebrowsing/phishing-afterload-warning-message.dtd
@@ -8,10 +8,21 @@
 <!ENTITY safeb.palm.message.p2.linkText "how &brandShortName; protects you">
 <!ENTITY safeb.palm.message.p2.end " from phishing attacks.">
 
 <!ENTITY safeb.palm.accept.label "Get me out of here!">
 <!ENTITY safeb.palm.accept.statustext "Navigate to my home page">
 <!ENTITY safeb.palm.decline.label "Ignore this warning">
 <!ENTITY safeb.palm.decline.statustext "Close warning" >
 <!ENTITY safeb.palm.notforgery.label2 "This isn't a web forgery…">
+<!ENTITY safeb.palm.report.label "Why was this site blocked?">
 
 <!ENTITY safeb.urlbaricon.tooltip "This page might be dangerous; click for details.">
+
+<!ENTITY safeb.blocked.malware.title "Reported Attack Site!">
+<!-- Localization note (safeb.blocked.malware.shortDesc) - Please don't translate the contents of the <span id="malware_sitename"/> tag.  It will be replaced at runtime with a domain name (e.g. www.badsite.com) -->
+<!ENTITY safeb.blocked.malware.shortDesc "This web site at <span id='malware_sitename'/> has been reported as an attack site and has been blocked based on your security preferences.">
+<!ENTITY safeb.blocked.malware.longDesc "<p>Attack sites try to install programs that steal private information, use your computer to attack others, or damage your system.</p><p>Some attack sites intentionally distribute harmful software, but many are compromised without the knowledge or permission of their owners.</p>">
+
+<!ENTITY safeb.blocked.phishing.title "Reported Web Forgery!">
+<!-- Localization note (safeb.blocked.phishing.shortDesc) - Please don't translate the contents of the <span id="phishing_sitename"/> tag. It will be replaced at runtime with a domain name (e.g. www.badsite.com) -->
+<!ENTITY safeb.blocked.phishing.shortDesc "This web site at <span id='phishing_sitename'/> has been reported as a web forgery and has been blocked based on your security preferences.">
+<!ENTITY safeb.blocked.phishing.longDesc "<p>Web forgeries are designed to trick you into revealing personal or financial information by imitating sources you may trust.</p><p>Entering any information on this web page may result in identity theft or other fraud.</p>">
--- a/browser/locales/en-US/chrome/help/prefs.xhtml
+++ b/browser/locales/en-US/chrome/help/prefs.xhtml
@@ -463,19 +463,19 @@ Contributors:
     href="glossary.xhtml#master_password">master password</a>.  If you create a
     master password, each time you start &brandShortName;, it will ask you to enter
     the password the first time it needs to access a certificate or stored
     password. You can set, change, or remove the master password by
     by checking or unchecking this &pref.singular; or by clicking the
     <em>Change Master Password…</em> button.  If a master password is already
     set, you will need to enter it in order to change or remove the master password.</p>
 
-  <p><em>Show Passwords…</em><br/>
+  <p><em>Saved Passwords…</em><br/>
     You can manage saved passwords and delete individual passwords by clicking
-    the <em>View Saved Passwords</em> button.</p>
+    the <em>Saved Passwords</em> button.</p>
   
   <h3 id="warning_messages">Warning Messages</h3>
   <p>Click the <em>Settings…</em> button to configure the security warnings
     &brandShortName; displays while you browse the web.</p>
     
     <h4>Security Warnings Dialog</h4>
     <!--XXX massive suck!  do these provide *any* value whatsoever? -->
     <dl>
--- a/browser/locales/en-US/installer/custom.properties
+++ b/browser/locales/en-US/installer/custom.properties
@@ -56,23 +56,25 @@ OPTIONAL_COMPONENTS_SUBTITLE=Choose whic
 OPTIONAL_COMPONENTS_LABEL=Optional Components:
 DOMI_TITLE=DOM Inspector
 DOMI_TEXT=Inspects the structure and properties of a window and its contents.
 CONTEXT_OPTIONS=$BrandShortName &Options
 CONTEXT_SAFE_MODE=$BrandShortName &Safe Mode
 SAFE_MODE=Safe Mode
 OPTIONS_PAGE_TITLE=Setup Type
 OPTIONS_PAGE_SUBTITLE=Choose setup options
+OPTIONS_MAKE_DEFAULT=&Use $BrandShortName as my default web browser
 SHORTCUTS_PAGE_TITLE=Set Up Shortcuts
 SHORTCUTS_PAGE_SUBTITLE=Create Program Icons
 SUMMARY_PAGE_TITLE=Summary
 SUMMARY_PAGE_SUBTITLE=Ready to start installing $BrandShortName
 SUMMARY_INSTALLED_TO=$BrandShortName will be installed to the following location:
 SUMMARY_REBOOT_REQUIRED_INSTALL=A restart of your computer may be required to complete the installation.
 SUMMARY_REBOOT_REQUIRED_UNINSTALL=A restart of your computer may be required to complete the uninstall.
+SUMMARY_MAKE_DEAFULT=$BrandShortName will be set as your default web browser.
 SUMMARY_CLICK=Click Install to continue.
 SURVEY_TEXT=&Tell us what you thought of $BrandShortName
 LAUNCH_TEXT=&Launch $BrandShortName now
 WARN_APP_RUNNING_INSTALL=$BrandShortName must be closed to proceed with the installation.\n\nClick "OK" to exit $BrandShortName automatically and continue.
 CREATE_ICONS_DESC=Create icons for $BrandShortName:
 ICONS_DESKTOP=On my &Desktop
 ICONS_STARTMENU=In my &Start Menu Programs folder
 ICONS_QUICKLAUNCH=In my &Quick Launch bar
--- a/browser/locales/en-US/searchplugins/amazondotcom.xml
+++ b/browser/locales/en-US/searchplugins/amazondotcom.xml
@@ -1,13 +1,13 @@
 <SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
 <ShortName>Amazon.com</ShortName>
 <Description>Amazon.com Search</Description>
 <InputEncoding>ISO-8859-1</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsQAAALEAGtI711AAAAB3RJTUUH0wESEi0MqTATXwAAAjVJREFUeJyFUlGLElEU/mbVHd2aaaRgWGyJgmXRINiXfJCeRgaiLEiKgYXoRQrqRejNH7D1uNBDPvbWtGxvS64IG2IIQQhxScpYMpt1l1qdptVVZ+z2oM6qu9KBC4dzv/Od73z3AmPROmjeVlWVKopCRVGkHMdRURSpoig0lUrRcfxI6LoelWV5GwCddOLx+PEklmVej0QiI80Oh4OyLHuE5Fgl/aJ9gsEgzefzm4SQzVgs9n8VqqqO7EwIsUGEkEscx9kEsizbd85BEo3eenzzRkRstTsfAVwRBOH+EP/DSb4x4wVN0wq5XE7MZDKz5XIZlUoFtVoNu7u7NkaWZaTTaWZEQV8qDYfDKBaLkwZOVkAI8UuS9GkwiWVZNBr7sLZeo1V6hb/GFrxGwW6s84twzYbgGBRM0/yZzWZtQCKRQGhuD80PT0DbdUzxF9DmA2jzAbiNIjztHUzvvT+UIoqi7TLHcVTX9QeWZVLLMikh5Nzwf2h9USlNgtIk6NSAoNlsYjgXBOG50+liAGCe3/72ayOGP28f9fZ2ewEAv89GYRMEAgGboNvtYjBtf0PB9BsZJz8/Q7dR7d3Xeia75+/0XsGyTEqNrzC/p9HVSzCr7w4N+7GGOr+IE6GnOH3+KgCgo2XhAeCak+DU16PUWL0Mr1EYfdO+027/PZxaWIKJmY4kSaX1lysXnat+HARXMOM5wzA0iSP/etDILixhp9aGz+djAEDTtLt8aflFt1GFcG2NAYB/rN8dqx12fbIAAAAASUVORK5CYII=</Image>
+<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHgSURBVHjalFM9TNtQEP4cB7PwM1RITUXIgsRaYEEVEyKZwhiyZAQyd0BhpFOlIjoBqhjSqVQMoVMLLAjEwECCQJkSkBqJYDOAFOMKFSf28d7DTUxiUDnp/Pzeu/vuu7t3ICKF6SLTMv2/lB0fRWKfjwDm4JJisYh0Oo3fpZLYT0SjSCQS8JAFMADNDZ3NZsnf1taiqVTKi4nGASruk5lkkmTmMB6JUKFQqO+DfX1eABWeQoVR6f7HSdM0obqu48Yw8G1tDT82NsRd1TSbU9BbGPCog8PDj+jLzurFoAVgMh4XxoNDQ6SqKi0tL9eBvAB8zZwymYxYY7EYAoEA8vm82BNTg6XUIs0MeGTZoR1mhXSnwNl4pmAbjU7mcjkKhkL1ynMnntZ4OEw3VyrV8utk7s5TdW++0QXz+1i3P7IK36t+PCfVn1OQOoOA0gXr5DPak+cPXbBK+/T3S69AtY3LJ98vZ1or/iLr+pTuvr59/A6s003UdqZFJF/PCKQ3o5CUznoBST2AfbEF/9iqYEDaIfwj73VJPEfgNTe0tWNYR0uwy9uOW0OkrgHI7z5ADo2C7v48nLV3XHKAT+x/1m1sX58xsBxg8rZJrDYD8DHHp4aJj/MK09sXjPOt46PcCzAACXY8/u34wN0AAAAASUVORK5CYII=</Image>
 <Url type="text/html" method="GET" template="http://www.amazon.com/exec/obidos/external-search/">
   <Param name="field-keywords" value="{searchTerms}"/>
   <Param name="mode" value="blended"/>
   <Param name="tag" value="mozilla-20"/>
   <Param name="sourceid" value="Mozilla-search"/>
 </Url>
 <SearchForm>http://www.amazon.com/</SearchForm>
 </SearchPlugin>
--- a/browser/locales/en-US/searchplugins/creativecommons.xml
+++ b/browser/locales/en-US/searchplugins/creativecommons.xml
@@ -1,11 +1,11 @@
 <SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
 <ShortName>Creative Commons</ShortName>
 <Description>Find photos, movies, music, and text to rip, sample, mash, and share.</Description>
 <InputEncoding>utf-8</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAANbY1E9YMgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAA2UExURf///wAAAD8/P+/v7y8vL19fX9/f37+/vw8PD8/Pz09PT5+fn4+Pj6+vr29vbx8fH39/f////3TGU44AAAASdFJOU///////////////////////AOK/vxIAAACWSURBVHjaNI8LEsQgCEMJIvi3vf9lN3bbN6MD0USUm3QFaVNYc7kBuvLZ0xG8oLkQV1iiYBjyktFE+tk+FCEGl3oFT0aSQBaoVDAmAyWkmOCitVfHTvV4BEsWxqyleE+PYLQAi5b9WJShPnh7MnQytDP1IxmfvZXq22dkTkpZ4/TT/qPfiX/dqoXJz+dItE0tx6l/AgwA0e4FeJjn5bsAAAAASUVORK5CYII=</Image>
+<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAJUSURBVDiNjZO9S1thGMXPvTfJFbnkipNkLLS0ksFg0M0lf4CboNCEgIIg/RiKtEOn0qGWTtbVoBYcIji10I9J0ApWCjp0kRaXdhHjTW4+uGnur4NJ8GOwZ3nf4TnnfZ5z3scAdBGGYdyVdN+yrGHTNNOtVqsVhuG+pO+S3gE/LtV3BIxzPDJNc8FxHGN0dNRKpVIGoJ2dndr+/r5Vr9cl6bmkN0AoSQIEyHXdj5KYnZ3F932uolKpkM/nK5KQ9FmSCZwLOI7zQBLr6+vXiFdRLBaDtsiTTve3YrFYkM/nbyR3MDU1dSKpLumO+vr6Xruui+d5AFSrVVZWVtjY2KDRaABwdHTE4uIie3t7AJTLZaLRaFXSCyUSid1MJgOA53n09/eTTqdJJpPMzc2xurqKbduMj48Tj8fZ3d0FYHBw8FjSezmOU56fnwdgeXkZ27ap1WpUKhWazSZjY2Nks1kASqVSd4zp6eljSX/MtiHdRDpnEATyfb+bkiSVSqXu3TCM8xgHBga+dkY4OzvDdV2GhoZIJBLMzMxQKBSIRqNkMhlisRhbW1sAJJPJn5I+KB6Pv7poou/7rK2tsbm5SRAEXROXlpY4ODgAoFarYdu2J+llN8ZcLvffMeZyud+SGpLuCVBPT89jSRQKhRvJxWKxISmU9JTOT5Rk9Pb2fpHE5OQkJycn14inp6dMTEx4bdM/SbKAy8sk6WEkElmwLCuSSqUYGRmxgHB7e7t+eHgYazabgaRnkt7SeZnr63xbUtYwjGHTNNNhGP4F9iR9a6/zr4v1/wDE1D9XlC4rrAAAAABJRU5ErkJggg==</Image>
 <Url type="text/html" method="GET" template="http://search.creativecommons.org/">
   <Param name="q" value="{searchTerms}"/>
   <Param name="sourceid" value="Mozilla-search"/>
 </Url>
 <SearchForm>http://search.creativecommons.org/</SearchForm>
 </SearchPlugin>
--- a/browser/locales/en-US/searchplugins/eBay.xml
+++ b/browser/locales/en-US/searchplugins/eBay.xml
@@ -1,13 +1,13 @@
 <SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
 <ShortName>eBay</ShortName>
 <Description>eBay - Online actions</Description>
 <InputEncoding>ISO-8859-1</InputEncoding>
-<Image width="16" height="16">data:image/x-icon;base64,R0lGODlhEAAQAMQAAAAAAMz/zMwAADMAzOfn1sxmAP///5kAZpnM////AACZM/777zPMAP+ZAP8AAP9mmf/MzMwAZjNmAADMM/+ZM/9mM//MMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAQUAP8ALAAAAAAQABAAAAVPoCGOZGmeaKqiQDkMYqAoBqMELpxUlVTfBohjeHjBLJLZZCF0GASOAWJQSFAUE1FTwIUNKoYKTQslGCLSb6MBFD2G3Zdo0k4tVvi8fl8KAQA7</Image>
+<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAADAAAAA/wAAAABAAABAQAAAgEAAAMBAAAD/QAAAAIAAAECAAACAgAAAwIAAAP+AAAAAwAAAQMAAAIDAAADAwAAA/8AAAAD/AABA/wAAgP8AAMD/AAD//wAAAABAAEAAQACAAEAAwABAAP8AQAAAQEAAQEBAAIBAQADAQEAA/0BAAACAQABAgEAAgIBAAMCAQAD/gEAAAMBAAEDAQACAwEAAwMBAAP/AQAAA/0AAQP9AAID/QADA/0AA//9AAAAAgABAAIAAgACAAMAAgAD/AIAAAECAAEBAgACAQIAAwECAAP9AgAAAgIAAQICAAICAgADAgIAA/4CAAADAgABAwIAAgMCAAMDAgAD/wIAAAP+AAED/gACA/4AAwP+AAP//gAAAAMAAQADAAIAAwADAAMAA/wDAAABAwABAQMAAgEDAAMBAwAD/QMAAAIDAAECAwACAgMAAwIDAAP+AwAAAwMAAQMDAAIDAwADAwMAA/8DAAAD/wABA/8AAgP/AAMD/wAD//8AAAAD/AEAA/wCAAP8AwAD/AP8A/wAAQP8AQED/AIBA/wDAQP8A/0D/AACA/wBAgP8AgID/AMCA/wD/gP8AAMD/AEDA/wCAwP8AwMD/AP/A/wAA//8AQP//AID//wDA//8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8fHx8fHx8fHx8fHx8AAB8cGRkUFAcHBx8fBUKfAAAfFBkfHxNHF4cb29vCnwAAHxkZFBQUBx8HG98bwp8fAB8ZGR8UGQcXhxvb28KFXx8fHZkZGRNHBwcfG8jCgoQfAB8fHx8HBx8b29vCnwPCnwAAAB8fBwcfHx8EBB8Dwp8AAAAAHx8fHwAfHx8AHx8fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA//8AAP//AACAAwAAAAMAAAADAAAAAQAAAAAAAAAAAACAAAAA4AAAAPCIAAD//wAA//8AAP//AAA=</Image>
 <Url type="text/html" method="GET" template="http://search.ebay.com/search/search.dll">
   <Param name="query" value="{searchTerms}"/>
   <Param name="MfcISAPICommand" value="GetResult"/>
   <Param name="ht" value="1"/>
   <Param name="ebaytag1" value="ebayreg"/>
   <Param name="srchdesc" value="n"/>
   <Param name="maxRecordsReturned" value="300"/>
   <Param name="maxRecordsPerPage" value="50"/>
--- a/browser/themes/gnomestripe/browser/browser.css
+++ b/browser/themes/gnomestripe/browser/browser.css
@@ -450,17 +450,17 @@ menuitem[key="key_openHelp"] {
 
 /* Primary toolbar buttons */
 .toolbarbutton-1 {
   -moz-box-orient: vertical;
   min-width: 0;
   list-style-image: url("chrome://browser/skin/Toolbar.png");
 }
 
-.toolbarbutton-1 .toolbarbutton-icon {
+.toolbarbutton-1 > .toolbarbutton-icon {
   -moz-margin-end: 0px;
 }
 
 toolbar[mode="full"] .toolbarbutton-1,
 toolbar[mode="full"] .toolbarbutton-menubutton-button {
   min-width: 57px;
 }
 
@@ -596,20 +596,16 @@ toolbar[mode="full"] .toolbarbutton-menu
 
 /* 16px primary toolbar buttons */
 toolbar[iconsize="small"] .toolbarbutton-1 {
   -moz-box-orient: vertical;
   min-width: 0;
   list-style-image: url("chrome://browser/skin/Toolbar-small.png");
 }
 
-toolbar[iconsize="small"] .toolbarbutton-1 .toolbarbutton-icon {
-  -moz-margin-end: 0px;
-}
-
 toolbar[iconsize="small"] .toolbarbutton-1[type="menu-button"] {
   border: 0 !important;
 }
 
 toolbar[iconsize="small"] #back-button {
   list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=menu");
 }
 .unified-nav-back[_moz-menuactive] {
index eef07e04da40f23c82454932eb1cf4e81661c143..44dbb88b359ab5b5e8a6a0b3f3be1bc273596cdd
GIT binary patch
literal 9715
zc$_U-1yCGavt1;3aJS&@?u*M3Bpck_-Q6X4&<!pLkO0BmCAeE~-2lOLu^|6`_1;X~
zxiwd3x=)`oT{Ur<>Pl}h$T0u_z*`k%c`&?|hL>J66!^7q#rnSr!4s?`3#gu=JcQq%
zSg0z=1780-i@M6w;VtNH%KDxF04BkI1p$zgM+$F5^-@t&KwU;cB1C%2`fd;#0H6V=
z$jfN?t)AuwdKu{kp9BBp@#m0DCNikjbE+o4tFv55PX8=&ZdQVPkdI6A#>Jihv5S_F
zYi7>detzG?OeS~nc5}1ZYBumNGN%5_8S^w^P5}{}fz}nH*nhSDDa~p;jd3z@-+g}~
zZ+P=A#ouo;C)JtJeZ^!rOVD;|^IuC(&%tKTR`~0-TE^?aS;sjw8Zsgd8m*$!nn`)a
z+|(x(3|et9F{VtghIPZrKkAVCoosT%pcBh?9a6YxLI3FAJt+IFH9H%KP%5IiD^}Hm
z<GsWtH@gD&gu5@3yo7R}dzX4%V8bBf)_-Rms1beJ-8Dgb?8YG0va+%fD?XM|5jk9G
zTU%y1IXSzWq364;!U-$B0UY4dMIs6=8Zve3^^~|Ah;?Xah)3-@F*^tkq0F97NGK*F
zt>dhnof19*z=J_ZE_%1_35$!16Lt<$HD2*qTUa23Kh=C#Dn0`IO-SP8mCNVHyRX2Y
z46rkdJ&MKn6u)0UjV=`}8Cu1TC(T-lPWu_mbzGs!TIWo$*6eQF!YDw<e0==?H^+TY
zck@3YS<MAEMRv{gR(DI)T5XW|noyj4#CxWOztR%Z1N9vEamZQLJ0j|;=`-H>nk@3J
zuH5a_x<$nsHjQHm1qZ2<HgUsHK_t#|2}<nw`T0ouoCJJn*1=>d@gw}!%-gQ>U>sJ)
zoMtaig-YS?N0??F9%)WO<GsCr=jZ3Y?a3MVtc(Q*nbq=i;algf_f=Q6NA2o-*;eM}
z=Jt`??}O^Pk6;_bi1BVo!%zl%^!APpGD^x{0&2ULesQ6d=qnh&A*g!>*lD>oyr7_<
z8BKHQRh4LyvqAcjfBO2<palm9$ISfvz-p7DXvmY_o9PxgKv-LwsMA_mOA86B^;_T)
z^!#cOnEjg%u>yE4kzywhZ>@g=gDqY>Ss<~8oQYs(zmGXQwD)MEtUk_S@TPxTWKUkK
z`N>Tr(VTRg9+@K8CWk39GLoo}B-A7k4L+u^x7m5E^-r4WD*2Od_jP_cafGU3uSH?Y
z71ffryD>zSyDQ_TVM}vYyaH_ypZb~#ebMGY5`&8*t<Q=zgjYnQl_A8XsW6>Ry3aw3
z6OE-pX8PLA7?MOG+}xBi7^p#pkTu`NitiH;KptkqHN3q|6E0n}Cl#-=ZNG$gS{t@?
z&V6aq5d|urzkhzoLMa%vn(+>PI0@U?*(ob@U8yhqvpq3A-6BX+N|;mTe)IPO94u5+
zR0$!><Vjgr#q(@P8Q{{tGZPb7&CW}`E`EMrg8$t%Nq)HsjK-aqoSa=;9NgYElVe~h
zg`1aBGJsHR-a*TygJTvSacFq>@buLB`4I-+fgoY<sN$QCww`3}&P=f!Bb1F4Yi@Qn
z92arPdvwp^8<^F`#zvU|pAqT1!FIDHN#g|KtX+l{8+>(|ROKkk;pEJjnQFExi5fyA
z78Ln-&g}PmK%fR3e{l1g@qEH9vEn5Tj!jNZPLtagQ6H6qJp_@)gjXNG<s4(g1JLA7
zdfZ=_2LuFw>~LipiR3ui7k_BQzi0Z$7hJhEG4XywBy9SCo)R0Pv*J$qex9T5$JRMB
zAqE~AG7pyJtb5bXH%3d=0RcHHEBY}pG4ODin3!mk2P}E3BBVDtE_pocL4==89*#0!
z^WHQ0AC^LDohjx8&`~0dLZ4xjz>qxnL?$LC&`BMscw=-}$*D^YQ!<oCSXhY$mxdI}
zf)pjjTwu?CtyzUB9S%5NKEAn|7aO#kygYeOoVEUP^W@K#O%MaV`CvQ|77ot*#>V8!
z^FP(qZ)6mWgt)9jNKR`^>7%vQ<HRnlJ19cVtMX#`Hs<ExPC^M#5k`ul`>x&B1jLE+
zJI@X8CGEc#K8-^+Hv$9%1Xd0DbB6--^z`y{sqsYbsHv;XetyKqWd(;0CsP@@^}T`f
z72F4Knt|30Q`1wY5X8x|A!ZI@Cj?=*T~7)_w2V3)#mST4Y^5lcKO~^$bF$p0Z=0`u
zT_sJUi64;wo8?1{$04Vt=E^Q=uby988veI=Cne;xEX_eop9z9fhAO*eUZ?Zgx*s$t
zYG8+vjN{NNXLk0(?xjeXeZ9pXhR@l$K4dt-l3i(6g|^73=Xd&QxO7-$O?OUTpG<-O
zJ{jdOEg?qnvDk_e@w`CWVOj3q^K;X*(}M9m5w~qXLqmgJRx~(%qr;b*P0m0@+R&hv
z2dk{STvbB%l4igRj_FKx-K%?O3LK;t4?%ES3oaRbT-t+4xPH*5DYf$OsQ+~b5Byx$
z?(C_lsVs?wk3)zGc2uGsQ9pkCXy*-5oBw-!426>$cdoE26M2%y<seCe|MfokcMz++
zHT&6eon>NDlDR%H9C8U<?VrNK!<#MMlqbH4H(Blu{s$KbENpCijA(~5bY#Sn)ux1<
z9di^E6gH>ZtGJ}(WT6cLcyJ}cp*?E#-`KZr-CrIKTC9$m;{jiT6bv%Q;0CL!tD7r&
ze0+4!>p!@zvzg3kk4#eh3ZG=5uQMR^e%|VQv+Ebsonsu{4M!I^?d()OG3S9(v7`9J
z<0b#g7n*$a2A2&n_`VLehev8snIK*<F%Vs<-M!OV^GZ)Bke{FbkB2Cn`dT)849EM@
z25~iCIv8n-Iwz;6Av9tlBFkEn)(!f%=Ub+D+~3a{SSYaHNhLb3eVezh?z{r&R2!{i
zoz5fz1kqRwoK)X(e49T^Ga@A?uc$nO$5v2K-stFP8J{gY$l%V0Zv%I}J9LOqA(6x~
zeD_=f9U-2BS4!$XIe-o&Rhe|PM=-+Gb-5=rbZ|^pgN;0?-uHYHzeKhex5MYuAZ@yq
z6j5CiVT}2MmquVf02)dpTrqCXHVo@x^_n$IX>Tm*Na0%6&eh?2&gI-#Fa|iaXO#Y+
zeYVj7IXiRd-*Hn>&#3X^#nvMXK*gpsgEQ<}a~(&5V@+4q=H_O4j-Mggg~WLVbqcFX
zNmlH1#ZHaA!RVa0*I&(1s03W7Awf1pM2H#Fi!56f24~kYG3IVh_wI^HN~%&rIf9P=
ziGn)Y{?^15d*QjgWw;Ki{hE+#=cVFk->i53WUeq|>TOg1_>Nm^HSohaf6zxOX>k)1
z_p3o6IB9SYS9Yu!QH3=*=jMz1{uUgD7{BFugD^;HK3fL{T^?1|G{c@Txmve>vLYMq
zd>D4;!9tq8&bmpo$^Gh#-nXYH?caIvd>;C$BFRpQ)!l?utb?ve2u`}cvr5X>K`+Y0
z`3nREs*Z%sZ{&=|wj^SSWDlq%G?ipNWGx^L5*frpmK?4hg8q24wa0!xqBCnl*KB;k
zrk3ynt(1tY>;@g_N4kn(X5jpZCNa_TA=8{hEcr{Br(O_LX&)Z(n*inE7b|P&LXgxJ
zSq=6$zMK^vLQeIu((dK`BRs$q2&gvCI7zYaQ-)`~pOxW#$L-T+D-E`Ga7r3VrB|A=
zLxlT3M>6oXwctSVtsP2{+WYrG4{(0!2%axf+wngBjh8SuV$)!&wP{9!TLc&P@p`|L
zy5Xwq>}+mCS%3^pBV18BmTF92W0#D5^Xr2D`TQ&|KS;!j2ZM--iI*E}Q-Yo@hfnPU
z0;UtVyYIQBbpQyxI5)Sqw<Zm61=NTc*qH?V;HvOQ*cwtpr^PR`Po{>G4JQ1frv_l(
zOB{ytmj#y&F$(kh1xd6Oo{DRW3JDkba@ZTIFsq#{%5Cy!ioE_wYBS<b;Ji-1T)JYG
z-p+o?jed#K{vMMR$yay7!7-QC2MrW4q(>w)UJL8#sz-!A>0t(tWaenVT@vu>Vf7J#
z!Zl#~5xeK|lsovSY^H;2wdhVU!p`;+S_Xy%YeIP_?^*CpWlE0E)N}8S(z*BtpxMA=
zDBsKu!M~9EP^rzuHL5><I~9g}L_hNVjSic_j%<3Cu|Q9tkh+AZtbG`OrUZoy0sdnB
z#aRzMhZT39shi~MiO~B?9xVS-%e`K@yBO5iBz+uPq7DSyf7hXz9T}NQdbASwI7c<^
zuTq-j#aUW2Y8R85PvIR!$~uTtRn=A9!rp7;gun{nWkF<NO~uG?Y6uC_xrf}QG0bHR
z>@U(*RT&!sd(-{LxHRO^Bs47cDC<QjhMj+Ymc4vmyH!qbbVKl$XBE6(-~@&bd#G$T
z4%}puH=lXPWPjE?G9r2bSyM6X^T~g_EurOIgDICaObmm+O>i{N=WH)}=bu#r<SKQF
zypQclya~0Yr@woVYZ()>NQoW$bqZzEWV_>jN{iy$q>nQ5PAP2AjsBwghgcyD9Ffpc
zW#xA&swz7x94ZiVz&4|iXz4!ueN;vzuHUg9xeq&ERroHgk<x@r!)$*&Cy?oY-^p-o
z@kW$c2VDEvJ&vj2#{11GQ&^d!a%!x3C0Kec3;+^Tl=eQxc=S7H4k;O>tWjgCb#nax
z61IqZ$Vk#+ZI)h>zwo^WIW0S!$bz){Y%<X_e`3lY-1t6_iTV<~hKNknwQBQ=E+QfT
z$}GvMss<`tLW@IZmrb~z`ez!`Fr0_YGAE}ngyABruP^@F+mpdT`@67)kZ%(xmXZ=;
zwYuB;i;|2z7OG5G5m8>r{M|m{tQxmVa_|x1XaP;8R4<MEgr{-r{D(x1U|<FqW6fP9
zS9HIG)yL(`@@|k~_2`Z}lqddJ#ml%cG2)1qZ11a!HcBI%ai#xHYC>a;v<504)5ffP
zL!FjjmN8g745?A5NxG|{pUsuQPnALX;f@f4HTSCuYc!L9%W_**QYAf+(`-F2Bjz*4
zA|HZ;K5K5GN4K*Q8W)ohabOnMj5OlQq4_&iXgk+IwV{k54K5=3Cn02WK}Q`*$lbyZ
z832YvlZZGg4mP#0j7nA2<Vxj$7fKN4l}E^8CR<L6GfmN^`$H#S!c_IG7~m!<Xu06m
zwU(n$`&i8<d@;;2wVAEeEPpnrnb$o=@TV+Gl0{E}iplL#j6Tz?ChAf`QQfOCzY<Oc
zA{^Dk$uCu(?$PgwH7X>C$G7Lbujq=By2;68<A-E<a_SF{1TGGf<f3qZ-mSHlt&NWe
zXnnteVm38Vb5Ufygrp<D@s^hyU+0-*#b-?`VMyz2DN8IQ1{LAkk7v`#_0TF8pMs5q
z>bUl&eeE9*1?VDp@6<zEB@x0*tgMeM7cA2s5*cQy1W0BdU8bIG9JqH9J9ozTfZ<ID
zMVCdJAzym~5|j?hm|WZ*hhkC|2(ARbI0T3VlWN=95nW+KA1FHwGun12Yuod&m43-l
z<C!6_Qdrhtv7^CVPF9-p5TS1QEW3U8j|YRpY)z;dDno18I8bg$N)B42>vxO-L>p*%
z56+2p!}=LWs*ZQ+Js(x=zNqdSfD7SkgZOlk<@*_oKOrp0P0jug+bk@bo!$A`As&TG
zK8D(sC&!oHC(yw1rmv__Swz`(CS_+Hw?fBQSUE?`T@b3f1oI1-=BP;-Zr$$`yit6T
zXs{)oc05aG@AYI{$&=$Kuvs(vVpy}hnc?VguOBAOQ#f%sGVW>RoMJUrGR)n2&`$M!
z;@g)mYL|~z7_<Vi{V6jQoPCN0MP^6>5%sb=Vrhw)jG0qBf~U2i76qCk8Z_I(TRU>X
z0!QwJY|5tN_4>+XWG9!`#g0?@bF92e>F?hOx=SdCIq%qbuKSPs-^fQ)8Q|^i{;WI<
z-D3etW_<fP5L?EE`BTsaVKMJbhSnbs>>pk+s=_s9$Ez+T?@})3gRk}UW0e_{X|}mX
zV+dk1uBNB<obX2l@ZPNlKVRS<qxQbor$dIJ{z9PaAg4Q<0J^?-#7YPj&c*sNVnGIt
zmps|Tm1k8XpeBx6Gb2xQ$=Yg|t-6iIw8(FM27_x$sCOx}7Sd*ycBahSrw)`FkhU}6
z1<OqND3|fs&Fw*3@|1XH>KN8u?G|>U>saC%CuPU}98s~a)K|Cc>lYW{sQvl*p`uE@
zX6*Oum~N{-rAY~TtCyd*!gHA5GhWDnF4uOyxADX<J_iGzo{kAyAUMt22yBnZ4B6Yv
zZJDFO<{F)eFLf@UNbm@vg}ZmBssP)i)lY8V5kX4Qm40DE<NGk8!kV#A1_F&heieJ%
z!UE34b)Vyu`Mf5{R=^`q^C>R&n_2H9rzxg%p|-oSpH+wF24HGUrh}^nBwp<4Z#<J6
z?FVj4ur*$+uDE$Qa~M0`XJ(M3s-{p18Y|<BSLE|N({rkH(l24GNY&<Q^Nlf{(CY!-
zWTkYkd#{tcai!{wk+NbUK}~N-eM^l6{#uiK<*PCIv_xym9DOP8abmjs@O^DJ>kxIc
z3caE^o7swurJ*%V494vydiz^SwRF$U_JDw*o`mTQcWQ|98Le31_HR{`R=4pZ^6vrQ
z%Ok&_4+-vDbpqTcDHaAoqu)l=NZ!_(t7)hrHmn34)l0J@q<%TPNT2m5u5xMqiC#x%
zbli=C6e8sZv#DNgkB2!19R0>2%?Dlf|D_};*bouDQeN0S?7HUo=J^fGWQaPD*lFpk
z8rvdKit8Q0=uf*mLgB<qQ*X8^(Zj8{?zLPeG@&1i&?p8&62hwfF24NqYhT&wq)hfa
zTk?aA1=(CShq>J4@wrs_-XlUO{e$-GVGP=5=Mzl8AEOjF@_vCux%9Rsvjk}orGCaR
zR;&f_4bKODr8FIx{ccx~dF|)UF|~Zjkd--5SN}BhuLZJTJC4Wp<BEd0<nj#i0Xyk-
zU^n7YKS6KRoEBOi%pz~v>MqZm5A$>3nCe@>il+Lx`t<~SnQ+Mf1h$4{dMlT4gq#{X
zk{PTlW}RwcU7+cc>E1CAb?B&CgdY(LI~R~8;j6CY`RYWyWp~u?_hAGA8++N)(IvEN
zaVsei-Xv1<``esL*h~!xaB^)d3|g=KZu}`lq2CM=l$B19tu3B$moO2dwB^c%?luH2
zx0exwhBFdg9Hk0OCk?W&;b^dFEz*9Yza|ET1ZVk)#b($2#c>F-vzku}LSgMAU~@%D
z7z_KP>x|06sDXj7=WM|xx9;^RTe9l(?F`XEwn?qO$24UY{kWgjzHyaoXkFs~f$M}j
zM^@k1>h|*bziukzEInY+hcG2#+#)UgD*<br?H?kv_!<X(4%3uK8wihdA=uNUDmgBL
zAQsl%5&B>ClJMx^4d74_Ixx#2E^G}!stll4rIvFqSwzzu6xAu47)iGYH^}<@e#-Vs
z-gMsfP5nF}C~U@C;)ma%TN=sm?s76+u6OI%QwY~`<I%TA2zZA`14X+*niG+sK%%YI
zZ>^fM$Pwl1JXygye~NMKYzwwR>+=<i*%(+P0$Kf}DWjm%Angw8vi=%Im+kqm!`{H~
z9u@s>`_SG%FoP$ehdKfe?2a_yfb6j&$ouPJL54Tpwo0^N${Y1eTqjh-?7VS#Cdl17
zp&jDw`vVaXps5e_k3_VRT7;4-TpuThI2Xk?=Ji=KB>BY?G6CF(dO{YxYD<rYr%;@7
zxT$7N=ef%bH@Dp+AZtF=5n@86Y*8DP(Pr+&?0Q8E$e9j@PSZd1f=daLo#&y~weI%f
z`f98^ga$~*n#8xvl@H}CCyon62b}bX7*7c|_pa~OL%=B*DB|R2h)W+M!E8n~1>{C)
z+-@GopYysO5&V(!(8_gD<sGcU3>0a<I|#F=$0pjdARmu~?b#q`Hwl!t5((yK!1Rmo
z5x(z{M0_VtxzrLWc2q9^4V7?5lh>}7e(6m$7@FV3I2HJfGsE(mD2wRB2YrEC2fZRQ
zTF!Dtw1{`7DtTGMhF~I}82M<niRq6*JW*M*B!KXnZ3+!4Dajk6XeXdH6$htXJ0Iew
z-QN%{<i~nj5T|QsfVFwF>@%SB8yIxV)3|3DF8srr)Zj%xB^>n%h7|Oe`mo&pSnwHV
zSiAv~r3&remjuqDe`80eEYtqCO-r|Ljr|u(75ftl>K?u!l2V`SwjG4*(`^vIkiZ{n
zf*<1E{a9<kE~M%XQUwxRGqH|y)(xylhJxpjjb+{)>-ym5CtUr4Y8dQ46?214fHd`&
z`M$Bb&JP2QH9bSE+fS#fW8Fl5+i&;dYd_w&O{Y&NL7)Dy2mT>Q0b1Lp^WXit3+ibO
z3FEGR%qe&a37tc`b-HD+)p`cV5ugj_lB!V#KVY^k@0k9^*@nQ7LiB+}#J`0@1qE=?
zzN5}8d^+$u)>_0Q-5g5KXxAu|k1wy+ci*Bf<a0bmUB4B4g-I2@oQnHyylc1mD-^74
zMnL{ZRyT&9(sn}o;(QdiDO~sve<-qv`U2Zrk9$P;zlAG;Lm$JL+oN_ajdp9k_+ry#
z1}fr86QDeIs~If@<BTmnJOR7J?X5{e{(Rg|#CF@H>W&R@UJ53`sTMK(cY9K<;@{vm
zCbOH52PvlnZ*l}qD2WPt&?8A6CkdB@)O(!Y<%N!3x0We#83uN|SX}K0D;ZUm8mrn*
zGrr^`#JbGRE-157Z;NiWXTGRSOq@Eir@a1wWdP7Y_NOp*WZCgT1ms1Xl0_pIAp3Lf
z1!YZD2*9qL$IaS>>^L6d8*{BEO0xBKTR;JggL^8M=DnEF6D_J~Y=VPae&C!835vp7
z-CQZtSiqfg0DAaHA(0k_!j7BVWlCCfA;YleKR@>!b8MReL&Dnv%oQutQ9I@pFTm35
z^#KYofrFHaEkxm58gUl-I}gRV0#APa4olGQ&MgEfKFTxkobpxD#v>5VE?Si)N~cxT
zHt<h?5A1~rb;8zgJ8;z5_Lb?p^9sm`uJ8(b@THZUxe>a`aEK@;igdWOVUkI4{ghJu
z%;fu4@;yW<jJ{!cj_x4)Pp3c@WSa!@b)x8Xo!DfZY4+{tw`V$~xj=|KK<-X@MB$&q
zZFe{bapY0Abccl$<78V{_zCl!(KU_nV@`bF^&T4$C_ZMIz2`3MfuNw^m0W2;@|2+W
zoX|&Fud(LwTHoUt5H4NI7$lf0r+bO>vCum7G27tNS7K|V3@g(svXiR5vY9<)#)^9N
zu@~L%<dJ}4|5Ax^pDPp!-Ooi|w3Z8qXQKM3B10#TzUpRN>Psd4WJMq>LazR5S^CsT
z8kl6upYG@5to;Qnq+I6`$A#`~eR+2j6#&m=KcKPA()hO<p){^N8MGcH;lAM$P%9wz
zOYQ~ve$K=3gg(Ab{NwKY`ZEN0mu{?z8!_1!X7rfsTuS@(>ZzF&!6-cUczfU=I3`t1
z7@jnN0uT?0uu6n*dw(cOUv>~_=_KGuTl|%h3V3<W+qyf;v2ApaYZ2csL;HNBrTtm2
zGYk;}%b3rlD@;^4w(;3W@TU7#lV%~Vq30*L?5ZI$LXlhP<oM-z2}7&S7fhY*+)q6n
zO>r!7xay<WdSfCQm<T$k)3nE>Zlw*a<i7@VvO7(SIwthfqr`n07q%h<3tNyd6#XjC
zq&*Rpo2*<fQn*$Vw5Z8^!<mzViCDXu{q*N4L&WY<u)JJo{u(|lcA};O<%Cb3h_`;E
zAtd3taWurf^rDD0PQ~E7JQunu745K=Keuv*eeO*4iz<FF-<%EP#|w3p+wtdlz%=>t
zDlRa|etP}Y0CQ7VQ93;%8yI@p)#*5?)MkF_TAY9_@PUHetIMa~_6@&&{-;*<H`v4)
z@1Ke4PI#vdyVHoM9MK+h{>&egD$Er?^=vY9p(%XU-C!SFy*%maqR%`($qgea)R0*u
z3dC-gI;sER`4(K`vPU-A*-2(9&=|j6y4_ip%2;4W$<QGN<~?Hvwr`nf9|W{N1>4CE
zc+CCsoPW<`I*jLj6V}T^2*xm4>uq?8i#X}VD`w=?g?md<u8A^{9sAG#*&66T0gkC1
z17kl(56s>ibB-nl;mQw8-Sa~6s=S!1q2q=5H4fJtfJ~U0;N-vsh1V_eAt4t_bS})C
zY2eR<dd9+quMN6a_Psc#*8rz{l0g=N+Ml>F@s#Sy%jK8XVQ!{EXs}^uuJ#Tr=x+Pn
z9uk?XV071kgNRO;R#n2dPRM7Rjr$!1I@6M=bHd>{)cf4vyWQo_D$%5KTceV~Az5+_
z(38Tg0nho+l(IIve3!{7#dNU2B;IFXV?hraTy`?1tnmvVQ@1=#S|3T{#lxGNY6ljR
zyv`fs=Ed+fTnmvPs-DZKz^n|+KYl{7wjnVG{#GAl5+?$rg2&J6>DC9NryZ(A4!}Cy
zbrDMCFDyVNMs|Kh%}FG>xASU@BKna=^^oJGjq&qjiII-!_E;k)$wNIHef}`$k+Obf
z6KCIb?-co$INZu6)d%jSr{D0TiNz#8FwHjk*|a`OooRNEx%xg>Cn^xsq$sEcHO}2i
zIw1GkjI+Fk@eLaaM`3828tXzO2YUJ@4>rTg?6GP@V=H58_WRzwlJQ@^s@wV^hK}^}
zFvxNTX@sX=r>evpHnv=fw>%-_zig*Dy+&fzTtvq8&}6GvGSPL~jt`6ao;K&$MkC>g
zHL4S0MsHQd$ZA#&Bf_}jVl0;SH;7<JF^|752G@Efs>5;8^G*j76-KO|{F-CD`bNpD
z(rE=esS3BA8FivM^g+3TDOUpnp?&XnakJ$=?_9XJ^!&Yzfgxex*@-}!Eh8|Z=LmDm
z)7=RKFPn;hy&D~8yXlZnJnpsvug+X2F=?*(@XQkih~B8H=`$mITMky7kwyXu|39uP
z6v5QvSTl!CJL&X=gEL8GiaLh8ePF_JyhVv<7m-e(*RKS>bw#<!P;{Nz5^L74dh|G}
z8F-hJ*xC{KSEre|Itn=*g_dwvd`=aRz9idT_t%|Y?JfW<ZLv<QfQ4<3IDd~41zuem
z9yH5C!kF{-1(821?_BMkY+YYNQ_{RAS1-Pl)s?x1y@ni<wC-o!9$*3hZ*2ej7obX9
zh1ztmrr?!~Yo)V6{TYw~NtWpNzVUK&qTv^`>u6Pv&yTkwCoVO)QYqZbz(X-Pn6Ca4
z_a<X4g8$nm8|>?mVjyFI<XAMjYjKa~_x)-!ni1pkCvC;%6N`b~_I4POiR25G2K7BN
zmmzSjwnYxJ=5nMMRi%u;iU5zx;DNeY+|^eVh6JkQWb-^A#Hevv>PQ4&gPV2@*-KX3
zsdN24i#q11>TLCu6=2R*un|85NeNZ!oBGzq?!s3JkJTFyJad%dAN-2?&ceYQsL%ht
zrZp_({863)hBVfcQ}KyDL)?iOWT)(l$EoSVsxYN?y;~Q$Ju4SFq{^RSCJNIpX{XZA
zxca+;nhomNoH6G;WdKsY8s1I-Bl8ado^K1u+EUDDma`^j?4H2CWx^`g8NW^VoumM#
zgKX05ZqZ17wnt~?+X{AyXC_?V-<#G6-!c>wxh#x)<l=rG3^_;+O2{j<Wa?<UOWWG1
z%5+?7pkf2tuwk;cdFxAysbYL$ktq3%43xN`@!S`IV6XS>Z{`bfm<Q??h+g45t=+VI
z7TG2f3}z*)p$^R%#(r_-(~otkkM+%m(N>dpTd2U0$j8FkWi`c^y)S4EvOC>Q-en8o
zcxFC3<}HPC%Ft_JrCv20o?k=bYIZ74(96F$sK-KGFP@P?r(~HFr%o)sL;0jU7L_1>
z_yxq2Q)^@lAb>NKLF5Ducb=DzCBO0Z`JqlHZJ*DQ7b#V``o6}#P>v^%Y_nh#R}r{|
z<W0Z7en!G^w=&PjBkCV17_@c$x52oC!{WTR#2ek!&Sw_Kp_#&Hkxl=!y&Z|A&|J^f
z7+$yBlUi%Twqae0YY;+1#ym*?#kn3jNvUfHssG_3)pC5Nx6yG!_-NxW^V1boq+Gyt
z=C(eOyR-kkpPh)?iY5C;jy$QT#Noy6g0Ek|ZmtN|@(Q5Er7HnbxEuP1xP;EX9gLP$
z*#{yPd4pz09Q*^3CCBCZ@hSajyH`%cgq%@a#1+Q)G&Y4(==B`-q~k|VyR3|vx9>D{
z#0U}_epsq|RiP740&nvpcL;5aMDV8rCk@qqfn~lCgtD{hk&*Y8|2tAlp%@1o+>D0(
zMyDCEnWvmeEXlwI(M0VoKD=vi-HEQa%g)my)kfoEDc$+=^mHU1l1o&)*}PD+ruUYM
z9`ReRcd*C`Zow(im9|-7JaCH+!P|&=q~_$_>!ai{3gWu;1Qjt0qgw;Q<4W9D*~Wh+
z!llx7Qpf=VC+<HSFyoX7UFgYXa`?SK-{`>+OyUn$f$zkAD7}g78;Yp4a?ll(gJ*`E
zU$HccB%(DR?JM7D;yr!OLNKAHZ8hR6YUL|$;9gwD54w&vyF|_w30BET^I0r9;BZ8E
zQ_7H2t6@lzbCxlNl-UqwH-*SCuS!gWhSNpwyBaV9<7jP?HD*0(=&i@->sL0C9EHZd
zkh{mH&k@E~<tV9epL?(y5Jh<Co3@+=h`yYa-{muX{5pof&YxO|M{{NB#uJ2CJe6TJ
z`*=MQEggrCAfE~VV<=twKDu}Ei$iA0y=ktIMLqzf(cG>2q`JF%9K#+a{*bAK5rt=R
zEDz(!W-Q{kEjFarEyc#@nmRC)r4-B}FL&>Qk|$2xQ;+1I!v?0Wtkqr*Pa~fx`XTu+
zlcA42H1^Z9nZAne4G6^WOo7Mr=hAKQOUx#X$z4^!saKB(2V3^*T|1y>9N)Z#c|GA;
zg=6g7#i-`3YBe^Mxp-dQ2955JZN|WtqV|IaU=utEx^ekkvvMi(oW6q~L=nzk84?De
qH=p8bKgWBBK7_3Qe_9346JLNy#TrG`^t?#`_@SbpE?+Hc7V$r5L+k|r
--- a/browser/themes/gnomestripe/browser/pageInfo.css
+++ b/browser/themes/gnomestripe/browser/pageInfo.css
@@ -145,17 +145,17 @@ groupbox.treebox .groupbox-body {
   padding-top: 0;
 }
 
 #securityBox description { 
   -moz-margin-start: 10px;
 }
 
 #general-security-identity {
-  white-space: -moz-pre-wrap;
+  white-space: pre-wrap;
   line-height: 2em;
 }
 
 /* Media Tab */
 #imagetree {
   min-height: 10em;
 }
 
--- a/browser/themes/pinstripe/browser/browser.css
+++ b/browser/themes/pinstripe/browser/browser.css
@@ -293,23 +293,16 @@ toolbar:not([mode="text"]) #forward-butt
 
 toolbar[mode="icons"] #back-button .toolbarbutton-text-box,
 toolbar[mode="icons"] #forward-button .toolbarbutton-text-box,
 #back-button .toolbarbutton-menubutton-dropmarker,
 #forward-button .toolbarbutton-menubutton-dropmarker {
   display: none;
 }
 
-toolbar[mode="icons"] #back-button .toolbarbutton-text-box,
-toolbar[mode="icons"] #forward-button .toolbarbutton-text-box,
-#back-button .toolbarbutton-menubutton-dropmarker,
-#forward-button .toolbarbutton-menubutton-dropmarker {
-  display: none;
-}
-
 /* ----- DEFAULT PRIMARY TOOLBAR BUTTONS ----- */	
 
 .toolbarbutton-text-shadow,
 .tab-text-shadow {
   color: #f0f0f0;
   padding-top: 1px;
   opacity: 0.6;
 }
--- a/browser/themes/pinstripe/browser/pageInfo.css
+++ b/browser/themes/pinstripe/browser/pageInfo.css
@@ -142,17 +142,17 @@ groupbox.treebox .groupbox-body {
   padding: 0;
 }
 
 #securityBox description { 
   -moz-margin-start: 10px;
 }
 
 #general-security-identity {
-  white-space: -moz-pre-wrap;
+  white-space: pre-wrap;
   line-height: 2em;
 }
 
 /* Media Tab */
 #imagetree {
   min-height: 10em;
 }
 
--- a/browser/themes/winstripe/browser/browser.css
+++ b/browser/themes/winstripe/browser/browser.css
@@ -184,48 +184,44 @@ menuitem.bookmark-item {
 /* ::::: primary toolbar buttons ::::: */
 
 .toolbarbutton-1 {
   -moz-box-orient: vertical;
   min-width: 0;
   list-style-image: url("chrome://browser/skin/Toolbar.png");
 }
 
-.toolbarbutton-1 .toolbarbutton-icon {
+.toolbarbutton-1 > .toolbarbutton-icon {
   -moz-margin-end: 0px;
 }
 
 toolbar[mode="full"] .toolbarbutton-1,
 toolbar[mode="full"] .toolbarbutton-menubutton-button {
   min-width: 57px;
 }
 
-.toolbarbutton-1, .toolbarbutton-menubutton-button {
+.toolbarbutton-1,
+.toolbarbutton-menubutton-button {
   padding: 5px;
 }
 
 .toolbarbutton-1[checked="true"] {
   padding: 5px !important;
 }
 
 /* ::::: unified back and forward buttons ::::: */
 
-/* wrapper containing back, forward, and dropmarker, when unified with keyhole icons */
-
-toolbar[iconsize="large"][mode="icons"] #unified-back-forward-button > .toolbarbutton-1 {
-  -moz-appearance: none;
-  border: none;
-  padding: 0;
-}
-
 /* unified back button with keyhole icons */
 
 toolbar[iconsize="large"][mode="icons"] #back-button {
+  -moz-appearance: none;
   -moz-image-region: rect(0px 398px 34px 360px);
+  padding: 0;
   -moz-padding-start: 2px;
+  border: none;
 }
 toolbar[iconsize="large"][mode="icons"] #back-button:not([disabled="true"]):hover {
   -moz-image-region: rect(34px 398px 68px 360px);
 }
 toolbar[iconsize="large"][mode="icons"] #back-button[disabled="true"] {
   -moz-image-region: rect(68px 398px 102px 360px);
 }
 toolbar[iconsize="large"][mode="icons"] #back-button:not([disabled="true"]):active {
@@ -245,17 +241,20 @@ toolbar[iconsize="large"][mode="icons"] 
 }
 toolbar[iconsize="large"][mode="icons"] #back-button[chromedir="rtl"]:not([disabled="true"]):active {
   -moz-image-region: rect(102px 516px 136px 478px);
 }
 
 /* unified forward button with keyhole icons */
 
 toolbar[iconsize="large"][mode="icons"] #forward-button {
+  -moz-appearance: none;
   -moz-image-region: rect(3px 424px 31px 398px);
+  padding: 0;
+  border: none;
 }
 toolbar[iconsize="large"][mode="icons"] #forward-button:not([disabled="true"]):hover {
   -moz-image-region: rect(37px 424px 65px 398px);
 }
 toolbar[iconsize="large"][mode="icons"] #forward-button[disabled="true"] {
   -moz-image-region: rect(71px 424px 99px 398px);
 }
 toolbar[iconsize="large"][mode="icons"] #forward-button:not([disabled="true"]):active {
@@ -286,17 +285,16 @@ toolbar[iconsize="large"][mode="icons"] 
   padding: 0;
   -moz-padding-end: 2px;
   border: none;
 }
 
 toolbar[iconsize="large"][mode="icons"] #back-forward-dropmarker > image {
   display: -moz-box;
   margin: 0;
-  padding-top: 1px;
 }
 
 toolbar[iconsize="large"][mode="icons"] #back-forward-dropmarker > dropmarker {
   display: none;
 }
 
 toolbar[iconsize="large"][mode="icons"] #back-forward-dropmarker:not([disabled="true"]):hover {
   -moz-image-region: rect(37px 438px 65px 424px);
@@ -325,20 +323,16 @@ toolbar[iconsize="large"][mode="icons"] 
 }
 
 toolbar[iconsize="large"][mode="icons"] #back-forward-dropmarker[chromedir="rtl"]:not([disabled="true"]):active {
   -moz-image-region: rect(105px 452px 133px 438px);
 }
 
 /* ::::: 24px primary toolbar buttons ::::: */
 
-toolbar:not([iconsize="small"]) .toolbarbutton-1 .toolbarbutton-icon {
-  padding-top: 1px;
-}
-
 /* back button */
 
 #back-button {
   -moz-image-region: rect(0px 24px 24px 0px); 
 }
 #back-button:not([disabled="true"]):hover,
 #back-button[buttonover="true"] {
   -moz-image-region: rect(24px 24px 48px 0px);
@@ -502,17 +496,17 @@ toolbar:not([iconsize="small"]) .toolbar
   -moz-image-region: rect(48px 216px 72px 192px);
 }
 #print-button:not([disabled="true"]):hover:active {
   -moz-image-region: rect(96px 216px 120px 192px);
 }
 
 /* new tab button */
 
-toolbar:not([iconsize="small"]) #new-tab-button .toolbarbutton-icon {
+toolbar:not([iconsize="small"]) #new-tab-button > .toolbarbutton-icon {
   padding-left: 1px;
 }
 #new-tab-button {
   -moz-image-region: rect(0px 240px 24px 216px);
 }
 #new-tab-button:not([disabled="true"]):hover {
   -moz-image-region: rect(24px 240px 48px 216px);
 }
@@ -520,17 +514,17 @@ toolbar:not([iconsize="small"]) #new-tab
   -moz-image-region: rect(48px 240px 72px 216px);
 }
 #new-tab-button:not([disabled="true"]):hover:active {
   -moz-image-region: rect(96px 240px 120px 216px);
 }
 
 /* new window button */
 
-toolbar:not([iconsize="small"]) #new-window-button .toolbarbutton-icon {
+toolbar:not([iconsize="small"]) #new-window-button > .toolbarbutton-icon {
   padding-left: 1px;
 }
 #new-window-button {
   -moz-image-region: rect(0px 264px 24px 240px);
 }
 #new-window-button:not([disabled="true"]):hover {
   -moz-image-region: rect(24px 264px 48px 240px);
 }
@@ -589,27 +583,23 @@ toolbar:not([iconsize="small"]) #new-win
 /* ::::: 16px primary toolbar buttons ::::: */
 
 toolbar[iconsize="small"] .toolbarbutton-1 {
   -moz-box-orient: vertical;
   min-width: 0;
   list-style-image: url("chrome://browser/skin/Toolbar-small.png");
 }
 
-toolbar[iconsize="small"] .toolbarbutton-1 .toolbarbutton-icon {
-  -moz-margin-end: 0px;
-}
-
 toolbar[iconsize="small"] .toolbarbutton-1[type="menu-button"] {
   border: 0 !important;
 }
 
 /* back button */
 
-toolbar[iconsize="small"] #back-button .toolbarbutton-icon {
+toolbar[iconsize="small"] #back-button > .toolbarbutton-icon {
   padding-right: 1px;
 }
 toolbar[iconsize="small"] #back-button {
   -moz-image-region: rect(0px 16px 16px 0px);
 }
 toolbar[iconsize="small"] #back-button:not([disabled="true"]):hover,
 toolbar[iconsize="small"] #back-button[buttonover="true"] {
   -moz-image-region: rect(16px 16px 32px 0px);
@@ -636,17 +626,17 @@ toolbar[iconsize="small"] #back-button[c
 }
 .unified-nav-back[_moz-menuactive],
 menupopup[chromedir="rtl"] > .unified-nav-forward[_moz-menuactive] {
   list-style-image: url("chrome://browser/skin/menu-back.png") !important;
 }
 
 /* forward button */
 
-toolbar[iconsize="small"] #forward-button .toolbarbutton-icon {
+toolbar[iconsize="small"] #forward-button > .toolbarbutton-icon {
   padding-right: 1px;
 }
 toolbar[iconsize="small"] #forward-button {
   -moz-image-region: rect(0px 32px 16px 16px);
 }
 toolbar[iconsize="small"] #forward-button:not([disabled="true"]):hover,
 toolbar[iconsize="small"] #forward-button[buttonover="true"] {
   -moz-image-region: rect(16px 32px 32px 16px);
@@ -673,17 +663,17 @@ toolbar[iconsize="small"] #forward-butto
 }
 .unified-nav-forward[_moz-menuactive],
 menupopup[chromedir="rtl"] > .unified-nav-back[_moz-menuactive] {
   list-style-image: url("chrome://browser/skin/menu-forward.png") !important;
 }
 
 /* stop button */
 
-toolbar[iconsize="small"] #stop-button .toolbarbutton-icon {
+toolbar[iconsize="small"] #stop-button > .toolbarbutton-icon {
   padding-left: 1px;
 }
 toolbar[iconsize="small"] #stop-button {
   -moz-image-region: rect(0px 48px 16px 32px);
 }
 toolbar[iconsize="small"] #stop-button:not([disabled="true"]):hover {
   -moz-image-region: rect(16px 48px 32px 32px);
 }
@@ -691,17 +681,17 @@ toolbar[iconsize="small"] #stop-button[d
   -moz-image-region: rect(32px 48px 48px 32px);
 }
 toolbar[iconsize="small"] #stop-button:not([disabled="true"]):hover:active {
   -moz-image-region: rect(64px 48px 80px 32px);
 }
 
 /* reload button */
 
-toolbar[iconsize="small"] #reload-button .toolbarbutton-icon {
+toolbar[iconsize="small"] #reload-button > .toolbarbutton-icon {
   padding-left: 1px;
 }
 toolbar[iconsize="small"] #reload-button {
   -moz-image-region: rect(0px 64px 16px 48px);
 }
 toolbar[iconsize="small"] #reload-button:not([disabled="true"]):hover {
   -moz-image-region: rect(16px 64px 32px 48px);
 }
@@ -709,17 +699,17 @@ toolbar[iconsize="small"] #reload-button
   -moz-image-region: rect(32px 64px 48px 48px);
 }
 toolbar[iconsize="small"] #reload-button:not([disabled="true"]):hover:active {
   -moz-image-region: rect(64px 64px 80px 48px);
 }
 
 /* home button */
 
-toolbar[iconsize="small"] #home-button.toolbarbutton-1 .toolbarbutton-icon {
+toolbar[iconsize="small"] #home-button.toolbarbutton-1 > .toolbarbutton-icon {
   padding-left: 1px;
 }
 #home-button.bookmark-item {
   list-style-image: url("chrome://browser/skin/Toolbar-small.png");
 }
 toolbar[iconsize="small"] #home-button ,
 #home-button.bookmark-item {
   -moz-image-region: rect(0px 80px 16px 64px);
@@ -734,17 +724,17 @@ toolbar[iconsize="small"] #home-button[d
 }
 toolbar[iconsize="small"] #home-button:not([disabled="true"]):hover:active ,
 #home-button.bookmark-item:not([disabled="true"]):hover:active {
   -moz-image-region: rect(64px 80px 80px 64px);
 }
 
 /* download manager button */
 
-toolbar[iconsize="small"] #downloads-button .toolbarbutton-icon {
+toolbar[iconsize="small"] #downloads-button > .toolbarbutton-icon {
   padding-left: 1px;
 }
 toolbar[iconsize="small"] #downloads-button {
   -moz-image-region: rect(0px 96px 16px 80px);
 }
 toolbar[iconsize="small"] #downloads-button:not([disabled="true"]):hover {
   -moz-image-region: rect(16px 96px 32px 80px);
 }
@@ -752,17 +742,17 @@ toolbar[iconsize="small"] #downloads-but
   -moz-image-region: rect(32px 96px 48px 80px);
 }
 toolbar[iconsize="small"] #downloads-button:not([disabled="true"]):hover:active {
   -moz-image-region: rect(64px 96px 80px 80px);
 }
 
 /* history sidebar button */
 
-toolbar[iconsize="small"] #history-button .toolbarbutton-icon {
+toolbar[iconsize="small"] #history-button > .toolbarbutton-icon {
   padding-left: 1px;
 }
 toolbar[iconsize="small"] #history-button {
   -moz-image-region: rect(0px 112px 16px 96px);
 }
 toolbar[iconsize="small"] #history-button:not([disabled="true"]):not([checked="true"]):hover {
   -moz-image-region: rect(16px 112px 32px 96px);
 }
@@ -773,17 +763,17 @@ toolbar[iconsize="small"] #history-butto
   -moz-image-region: rect(48px 112px 64px 96px);
 }
 toolbar[iconsize="small"] #history-button:not([disabled="true"]):not([checked="true"]):hover:active {
   -moz-image-region: rect(64px 112px 80px 96px);
 }
 
 /* bookmark sidebar button */
 
-toolbar[iconsize="small"] #bookmarks-button .toolbarbutton-icon {
+toolbar[iconsize="small"] #bookmarks-button > .toolbarbutton-icon {
   padding-left: 2px;
 }
 toolbar[iconsize="small"] #bookmarks-button {
   -moz-image-region: rect(0px 128px 16px 112px);
 }
 toolbar[iconsize="small"] #bookmarks-button:not([disabled="true"]):not([checked="true"]):hover {
   -moz-image-region: rect(16px 128px 32px 112px);
 }
@@ -794,17 +784,17 @@ toolbar[iconsize="small"] #bookmarks-but
   -moz-image-region: rect(48px 128px 64px 112px);
 }
 toolbar[iconsize="small"] #bookmarks-button:not([disabled="true"]):not([checked="true"]):hover:active {
   -moz-image-region: rect(64px 128px 80px 112px);
 }
 
 /* print button */
 
-toolbar[iconsize="small"] #print-button .toolbarbutton-icon {
+toolbar[iconsize="small"] #print-button > .toolbarbutton-icon {
   padding-left: 1px;
 }
 toolbar[iconsize="small"] #print-button {
   -moz-image-region: rect(0px 144px 16px 128px);
 }
 toolbar[iconsize="small"] #print-button:not([disabled="true"]):hover {
   -moz-image-region: rect(16px 144px 32px 128px);
 }
@@ -812,17 +802,17 @@ toolbar[iconsize="small"] #print-button[
   -moz-image-region: rect(32px 144px 48px 128px);
 }
 toolbar[iconsize="small"] #print-button:not([disabled="true"]):hover:active {
   -moz-image-region: rect(64px 144px 80px 128px);
 }
 
 /* new tab button */
 
-toolbar[iconsize="small"] #new-tab-button .toolbarbutton-icon {
+toolbar[iconsize="small"] #new-tab-button > .toolbarbutton-icon {
   padding-left: 1px;
 }
 toolbar[iconsize="small"] #new-tab-button {
   -moz-image-region: rect(0px 160px 16px 144px);
 }
 toolbar[iconsize="small"] #new-tab-button:not([disabled="true"]):hover {
   -moz-image-region: rect(16px 160px 32px 144px);
 }
@@ -845,17 +835,17 @@ toolbar[iconsize="small"] #new-window-bu
   -moz-image-region: rect(32px 176px 48px 160px);
 }
 toolbar[iconsize="small"] #new-window-button:not([disabled="true"]):hover:active {
   -moz-image-region: rect(64px 176px 80px 160px);
 }
 
 /* cut button */
 
-toolbar[iconsize="small"] #cut-button .toolbarbutton-icon {
+toolbar[iconsize="small"] #cut-button > .toolbarbutton-icon {
   padding-right: 1px;
 }
 toolbar[iconsize="small"] #cut-button {
   -moz-image-region: rect(0px 192px 16px 176px);
 }
 toolbar[iconsize="small"] #cut-button:not([disabled="true"]):hover {
   -moz-image-region: rect(16px 192px 32px 176px);
 }
@@ -863,17 +853,17 @@ toolbar[iconsize="small"] #cut-button[di
   -moz-image-region: rect(32px 192px 48px 176px);
 }
 toolbar[iconsize="small"] #cut-button:not([disabled="true"]):hover:active {
   -moz-image-region: rect(64px 192px 80px 176px);
 }
 
 /* copy button */
 
-toolbar[iconsize="small"] #copy-button .toolbarbutton-icon {
+toolbar[iconsize="small"] #copy-button > .toolbarbutton-icon {
   padding-left: 1px;
 }
 toolbar[iconsize="small"] #copy-button {
   -moz-image-region: rect(0px 208px 16px 192px);
 }
 toolbar[iconsize="small"] #copy-button:not([disabled="true"]):hover {
   -moz-image-region: rect(16px 208px 32px 192px);
 }
@@ -881,17 +871,17 @@ toolbar[iconsize="small"] #copy-button[d
   -moz-image-region: rect(32px 208px 48px 192px);
 }
 toolbar[iconsize="small"] #copy-button:not([disabled="true"]):hover:active {
   -moz-image-region: rect(64px 208px 80px 192px);
 }
 
 /* paste button */
 
-toolbar[iconsize="small"] #paste-button .toolbarbutton-icon {
+toolbar[iconsize="small"] #paste-button > .toolbarbutton-icon {
   padding-left: 1px;
 }
 toolbar[iconsize="small"] #paste-button {
   -moz-image-region: rect(0px 224px 16px 208px);
 }
 toolbar[iconsize="small"] #paste-button:not([disabled="true"]):hover {
   -moz-image-region: rect(16px 224px 32px 208px);
 }
@@ -1187,18 +1177,17 @@ toolbar[iconsize="small"] #navigator-thr
 toolbar[mode="text"] #navigator-throbber[busy="true"] {
   list-style-image: url("chrome://global/skin/throbber/Throbber-small.gif");
   opacity: 0.5;
 }
 
 /* Tabstrip */
 .tabbrowser-tabs {
   padding-top: 0px;
-  background: -moz-dialog url("chrome://browser/skin/tabbrowser/tabbrowser-tabs-bkgnd.png");
-  background-repeat: repeat-x;
+  background: -moz-dialog url("chrome://browser/skin/tabbrowser/tabbrowser-tabs-bkgnd.png") repeat-x;
 }
 
 .tabs-container:not([overflow="true"]) {
   -moz-padding-start: 3px;
 }
 
 /* Tabs */
 .tabbrowser-tab {
@@ -1224,23 +1213,24 @@ toolbar[mode="text"] #navigator-throbber
   -moz-border-top-colors: ThreeDShadow;
   -moz-border-right-colors: ThreeDShadow;
   -moz-border-left-colors: ThreeDShadow;
 }
 
 .tabbrowser-tab:not([selected="true"]):hover {
   margin: 2px 0px 4px;
   padding: 2px 1px 1px;
-  background: url("chrome://browser/skin/tabbrowser/tab-active-bkgnd.png") repeat-x;
+  background-image: url("chrome://browser/skin/tabbrowser/tab-hover-bkgnd.png");
 }
 
 .tabbrowser-tab[selected="true"] {
   margin: 2px 0px 3px;
   padding: 1px;
-  background: -moz-dialog url("chrome://browser/skin/tabbrowser/tab-active-bkgnd.png") repeat-x;
+  background-image: url("chrome://browser/skin/tabbrowser/tab-active-bkgnd.png");
+  background-color: -moz-dialog;
   font-weight: bold;
 }
 
 .tabbrowser-tab[busy] > .tab-icon-image {
   list-style-image: url("chrome://global/skin/throbber/Throbber-small.gif") !important;
   opacity: 0.6;
 }
 
@@ -1337,31 +1327,29 @@ tabpanels {
   margin: 3px 0px 4px;
   padding: 0px;
   border: 2px solid;
   border-right-width: 1px;
   border-bottom: none;
   -moz-border-top-colors: ThreeDShadow rgba(255,255,255,.3);
   -moz-border-right-colors: ThreeDShadow;
   -moz-border-left-colors: ThreeDShadow rgba(255,255,255,.3);
-  background: url("chrome://browser/skin/tabbrowser/tab-bkgnd.png");
-  background-repeat: repeat-x;
+  background: url("chrome://browser/skin/tabbrowser/tab-bkgnd.png") repeat-x;
   -moz-image-region: rect(0, 11px, 14px, 0);
 }
 
 .tabbrowser-arrowscrollbox > .scrollbutton-up:not([disabled="true"]):hover,
 .tabbrowser-arrowscrollbox > .scrollbutton-down:not([disabled="true"]):hover,
 .tabs-alltabs-button:hover {
   border-top-width: 1px;
   padding-top: 1px;
   -moz-border-top-colors: ThreeDShadow;
   -moz-border-right-colors: ThreeDShadow;
   -moz-border-left-colors: ThreeDShadow transparent;
-  background: url("chrome://browser/skin/tabbrowser/tab-active-bkgnd.png");
-  background-repeat: repeat-x;
+  background-image: url("chrome://browser/skin/tabbrowser/tab-hover-bkgnd.png");
 }
 
 .tabbrowser-arrowscrollbox > .scrollbutton-up:not([disabled="true"]):hover,
 .tabbrowser-arrowscrollbox > .scrollbutton-down:not([disabled="true"]):hover {
   -moz-image-region: rect(0, 22px, 14px, 11px);
 }
 
 .tabbrowser-arrowscrollbox > .scrollbutton-up[disabled="true"],
@@ -1479,18 +1467,17 @@ stack[chromedir="rtl"] > hbox > .tabs-al
 
 .tabs-closebutton:hover:active {
   -moz-image-region: rect(0px, 48px, 16px, 32px);
 }
 
 .tabs-container > .tabs-closebutton {
   margin: 3px 0px 3px;
   padding: 4px 2px 2px;
-  background: -moz-dialog url("chrome://browser/skin/tabbrowser/tab-active-bkgnd.png");
-  background-repeat: repeat-x;
+  background: -moz-dialog url("chrome://browser/skin/tabbrowser/tab-active-bkgnd.png") repeat-x;
   border-left: 1px solid threedshadow;
   border-top: 1px solid threedshadow;
   -moz-border-radius-topleft: 2px;
 }
 
 .tabs-container > .tabs-closebutton[chromedir="rtl"] {
   border-left: none;
   border-right: 1px solid threedshadow;
--- a/browser/themes/winstripe/browser/jar.mn
+++ b/browser/themes/winstripe/browser/jar.mn
@@ -139,12 +139,14 @@ classic.jar:
         skin/classic/browser/tabbrowser/tabbrowser-tabs-bkgnd.png               (tabbrowser/tabbrowser-tabs-bkgnd.png)
         skin/classic/aero/browser/tabbrowser/tabbrowser-tabs-bkgnd.png          (tabbrowser/tabbrowser-tabs-bkgnd.png)
         skin/classic/browser/tabbrowser/tabDragIndicator.png                    (tabbrowser/tabDragIndicator.png)
         skin/classic/aero/browser/tabbrowser/tabDragIndicator.png               (tabbrowser/tabDragIndicator-aero.png)
         skin/classic/browser/tabbrowser/tab-bkgnd.png                           (tabbrowser/tab-bkgnd.png)
         skin/classic/aero/browser/tabbrowser/tab-bkgnd.png                      (tabbrowser/tab-bkgnd.png)
         skin/classic/browser/tabbrowser/tab-active-bkgnd.png                    (tabbrowser/tab-active-bkgnd.png)
         skin/classic/aero/browser/tabbrowser/tab-active-bkgnd.png               (tabbrowser/tab-active-bkgnd.png)
+        skin/classic/browser/tabbrowser/tab-hover-bkgnd.png                     (tabbrowser/tab-hover-bkgnd.png)
+        skin/classic/aero/browser/tabbrowser/tab-hover-bkgnd.png                (tabbrowser/tab-hover-bkgnd.png)
         skin/classic/browser/tabbrowser/tabstrip-bottom.png                     (tabbrowser/tabstrip-bottom.png)
         skin/classic/aero/browser/tabbrowser/tabstrip-bottom.png                (tabbrowser/tabstrip-bottom.png)
         icon.png
         preview.png
--- a/browser/themes/winstripe/browser/pageInfo.css
+++ b/browser/themes/winstripe/browser/pageInfo.css
@@ -163,17 +163,17 @@ groupbox.treebox .groupbox-body {
   padding-top: 0;
 }
 
 #securityBox description { 
   -moz-margin-start: 10px;
 }
 
 #general-security-identity {
-  white-space: -moz-pre-wrap;
+  white-space: pre-wrap;
   line-height: 2em;
 }
 
 /* Media Tab */
 #imagetree {
   min-height: 10em;
 }
 
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..75d2fba75b7ac71fd3b6cd12ed342a302681ed8c
GIT binary patch
literal 892
zc%17D@N?(olHy`uVBq!ia0vp^j6m$o!3HEZUVGaNq&O0jLwtZV3rLdtRG1r(mP&(&
zF~Br1z<?3+3r5D{N8_Y`?3tb}jv*3L?;hO9)fB+cc2QqRNhzyKfuo5-NvVC?v}Mbd
z9cznwf9QRc;2l>Py%!1^9E&>6C%(UExh41a()YjlW3TVcob}8#_PYP7RaF7gp3YsQ
zk@uwX-9(j>qS<TPRro!{Ywp`8_gE(OSSr12SYkV=%;Q$l+Pea64`-S9hFd(J<`TF?
z;q)fULYea%O$lAac}+_U4;%FSNVZQ&@&3MWW57=&uP|cwO3bz`=YZ^`X(^5&K$;2a
z9S4SnhxSbhO$t#`Qccq`1e!RcdbVxbwhV|Duz#`fo5LC#;}R&t_w)+;j(dyWJ7@n*
zm1yIyy}$qEu6M15&pHjCIo{q@K5N;|g<JOpg--RJq#`~gNYAOmc;EZ^A8g)t2s~<-
za>>zar#eTItk+82M2WnPMH#-+QngQQikbBMXOoHV^DCvci#5753uXK_T<hC-tq<s}
zrxKwbHcL<BM)DRjc5iJ|NLL54mqWe90`k_v?n4O@2Oi2dISTMJB^XNTMd-x{c1Q5c
z>Uoy!_Im5-^8Yu#_3<A|$jwPi&B<xr`~J}L{|`S0T>onS*y7*9Rr_b$<WKu{<c!>k
zSLUm#(k0rYYwyRO{QRe@_+3-SoX$lrTqN4uU7k1yuvE_}j_)|3UMTb4W73mm6W{G3
zt{WG=-esD5dtJt?G|$jb?o*rQOisPY^Zu{M`@b#b-<bZri+-9Y7;_TIW2`vh>y>CM
zklhFM7#rAQ>zWuO8ZPD=OYpEYA51Ww`7X_P29KC|x9i$(x6h{SzPau_)9=QOhDwc2
zY4hJdv@D7J?pS;I`(N&_oxdFRF1{D=KXCmD@mt$$CqMt$*<mp$^=4zojmat}`yftN
zRJt}Lb?2g0tL$Ixio0ZTmZ`MQ%6aZ0zkuT_l&>hhYLNfNx{Ntt$HRSJUx1wH>FVdQ
I&MBb@07dC#^8f$<
--- a/caps/idl/nsIPrincipal.idl
+++ b/caps/idl/nsIPrincipal.idl
@@ -219,17 +219,17 @@ interface nsIPrincipal : nsISerializable
      *       function.
      *
      *
      * @param uri    The URI about to be loaded.
      * @param report If true, will report a warning to the console service
      *               if the load is not allowed.
      * @throws NS_ERROR_DOM_BAD_URI if the load is not allowed.
      */
-    [noscript] void checkMayLoad(in nsIUri uri, in boolean report);
+    [noscript] void checkMayLoad(in nsIURI uri, in boolean report);
 
     /**
      * The subject name for the certificate.  This actually identifies the
      * subject of the certificate.  This may well not be a string that would
      * mean much to a typical user on its own (e.g. it may have a number of
      * different names all concatenated together with some information on what
      * they mean in between).
      *
--- a/chrome/src/nsChromeRegistry.cpp
+++ b/chrome/src/nsChromeRegistry.cpp
@@ -695,16 +695,17 @@ nsChromeRegistry::Canonify(nsIURL* aChro
           // chrome: URIs with double-escapes are trying to trick us.
           // watch for %2e, and %25 in case someone triple unescapes
           if (pos[1] == '2' &&
                ( pos[2] == 'e' || pos[2] == 'E' || 
                  pos[2] == '5' ))
             return NS_ERROR_DOM_BAD_URI;
           break;
         case '?':
+        case '#':
           pos = end;
           continue;
       }
       ++pos;
     }
   }
 
   return NS_OK;
--- a/client.mk
+++ b/client.mk
@@ -178,32 +178,55 @@ all build clean depend distclean export 
 build_all: build
 build_all_dep: alldep
 build_all_depend: alldep
 clobber clobber_all: clean
 
 # Do everything from scratch
 everything: clean build
 
+####################################
+# Profile-Guided Optimization
+#  To use this, you should set the following variables in your mozconfig
+#    mk_add_options PROFILE_GEN_SCRIPT=/path/to/profile-script
+#
+#  The profile script should exercise the functionality to be included
+#  in the profile feedback.
+#
+#  This is up here, outside of the MOZ_CURRENT_PROJECT logic so that this
+#  is usable in multi-pass builds, where you might not have a runnable
+#  application until all the build passes and postflight scripts have run.
+ifdef MOZ_OBJDIR
+  PGO_OBJDIR = $(MOZ_OBJDIR)
+else
+  PGO_OBJDIR := $(TOPSRCDIR)
+endif
+
+profiledbuild::
+	$(MAKE) -f $(TOPSRCDIR)/client.mk build MOZ_PROFILE_GENERATE=1
+	OBJDIR=${PGO_OBJDIR} $(PROFILE_GEN_SCRIPT)
+	$(MAKE) -f $(TOPSRCDIR)/client.mk maybe_clobber_profiledbuild
+	$(MAKE) -f $(TOPSRCDIR)/client.mk build MOZ_PROFILE_USE=1
+
 #####################################################
 # Build date unification
 
 ifdef MOZ_UNIFY_BDATE
 ifndef MOZ_BUILD_DATE
 ifdef MOZ_BUILD_PROJECTS
 MOZ_BUILD_DATE = $(shell $(PYTHON) $(TOPSRCDIR)/toolkit/xre/make-platformini.py --print-buildid)
 export MOZ_BUILD_DATE
 endif
 endif
 endif
 
 #####################################################
 # Preflight, before building any project
 
-build profiledbuild alldep preflight_all::
+build alldep preflight_all::
 ifeq (,$(MOZ_CURRENT_PROJECT)$(if $(MOZ_PREFLIGHT_ALL),,1))
 # Don't run preflight_all for individual projects in multi-project builds
 # (when MOZ_CURRENT_PROJECT is set.)
 ifndef MOZ_BUILD_PROJECTS
 # Building a single project, OBJDIR is usable.
 	set -e; \
 	for mkfile in $(MOZ_PREFLIGHT_ALL); do \
 	  $(MAKE) -f $(TOPSRCDIR)/$$mkfile preflight_all TOPSRCDIR=$(TOPSRCDIR) OBJDIR=$(OBJDIR) MOZ_OBJDIR=$(MOZ_OBJDIR); \
@@ -217,17 +240,17 @@ else
 	done
 endif
 endif
 
 # If we're building multiple projects, but haven't specified which project,
 # loop through them.
 
 ifeq (,$(MOZ_CURRENT_PROJECT)$(if $(MOZ_BUILD_PROJECTS),,1))
-configure depend build profiledbuild install export libs clean realclean distclean alldep preflight postflight::
+configure depend build install export libs clean realclean distclean alldep preflight postflight maybe_clobber_profiledbuild::
 	set -e; \
 	for app in $(MOZ_BUILD_PROJECTS); do \
 	  $(MAKE) -f $(TOPSRCDIR)/client.mk $@ MOZ_CURRENT_PROJECT=$$app; \
 	done
 
 else
 
 # MOZ_CURRENT_PROJECT: either doing a single-project build, or building an
@@ -303,68 +326,54 @@ endif
 # Depend
 
 depend:: $(OBJDIR)/Makefile $(OBJDIR)/config.status
 	$(MOZ_MAKE) export && $(MOZ_MAKE) depend
 
 ####################################
 # Preflight
 
-build profiledbuild alldep preflight::
+build alldep preflight::
 ifdef MOZ_PREFLIGHT
 	set -e; \
 	for mkfile in $(MOZ_PREFLIGHT); do \
 	  $(MAKE) -f $(TOPSRCDIR)/$$mkfile preflight TOPSRCDIR=$(TOPSRCDIR) OBJDIR=$(OBJDIR) MOZ_OBJDIR=$(MOZ_OBJDIR); \
 	done
 endif
 
 ####################################
 # Build it
 
 build::  $(OBJDIR)/Makefile $(OBJDIR)/config.status
 	$(MOZ_MAKE)
 
 ####################################
-# Profile-feedback build (gcc only)
-#  To use this, you should set the following variables in your mozconfig
-#    mk_add_options PROFILE_GEN_SCRIPT=/path/to/profile-script
-#
-#  The profile script should exercise the functionality to be included
-#  in the profile feedback.
-
-profiledbuild:: $(OBJDIR)/Makefile $(OBJDIR)/config.status
-	$(MOZ_MAKE) MOZ_PROFILE_GENERATE=1
-	OBJDIR=${OBJDIR} $(PROFILE_GEN_SCRIPT)
-	$(MOZ_MAKE) maybe_clobber_profiledbuild
-	$(MOZ_MAKE) MOZ_PROFILE_USE=1
-
-####################################
 # Other targets
 
 # Pass these target onto the real build system
-install export libs clean realclean distclean alldep:: $(OBJDIR)/Makefile $(OBJDIR)/config.status
+install export libs clean realclean distclean alldep maybe_clobber_profiledbuild:: $(OBJDIR)/Makefile $(OBJDIR)/config.status
 	$(MOZ_MAKE) $@
 
 ####################################
 # Postflight
 
-build profiledbuild alldep postflight::
+build alldep postflight::
 ifdef MOZ_POSTFLIGHT
 	set -e; \
 	for mkfile in $(MOZ_POSTFLIGHT); do \
 	  $(MAKE) -f $(TOPSRCDIR)/$$mkfile postflight TOPSRCDIR=$(TOPSRCDIR) OBJDIR=$(OBJDIR) MOZ_OBJDIR=$(MOZ_OBJDIR); \
 	done
 endif
 
 endif # MOZ_CURRENT_PROJECT
 
 ####################################
 # Postflight, after building all projects
 
-build profiledbuild alldep postflight_all::
+build alldep postflight_all::
 ifeq (,$(MOZ_CURRENT_PROJECT)$(if $(MOZ_POSTFLIGHT_ALL),,1))
 # Don't run postflight_all for individual projects in multi-project builds
 # (when MOZ_CURRENT_PROJECT is set.)
 ifndef MOZ_BUILD_PROJECTS
 # Building a single project, OBJDIR is usable.
 	set -e; \
 	for mkfile in $(MOZ_POSTFLIGHT_ALL); do \
 	  $(MAKE) -f $(TOPSRCDIR)/$$mkfile postflight_all TOPSRCDIR=$(TOPSRCDIR) OBJDIR=$(OBJDIR) MOZ_OBJDIR=$(MOZ_OBJDIR); \
@@ -389,9 +398,9 @@ cleansrcdir:
 	          -o -exec test ! -d {}/CVS \; \) -prune \
 	          -o \( -name '*.[ao]' -o -name '*.so' \) -type f -print`; \
 	   build/autoconf/clean-config.sh; \
 	fi;
 
 echo-variable-%:
 	@echo $($*)
 
-.PHONY: checkout real_checkout depend build profiledbuild export libs alldep install clean realclean distclean cleansrcdir pull_all build_all clobber clobber_all pull_and_build_all everything configure preflight_all preflight postflight postflight_all
+.PHONY: checkout real_checkout depend build profiledbuild maybe_clobber_profiledbuild export libs alldep install clean realclean distclean cleansrcdir pull_all build_all clobber clobber_all pull_and_build_all everything configure preflight_all preflight postflight postflight_all
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -278,16 +278,17 @@ ACDEFINES	= @MOZ_DEFINES@
 WARNINGS_AS_ERRORS = @WARNINGS_AS_ERRORS@
 
 MOZ_OPTIMIZE	= @MOZ_OPTIMIZE@
 MOZ_OPTIMIZE_FLAGS = @MOZ_OPTIMIZE_FLAGS@
 MOZ_OPTIMIZE_LDFLAGS = @MOZ_OPTIMIZE_LDFLAGS@
 
 MOZ_RTTI_FLAGS_ON = @_MOZ_RTTI_FLAGS_ON@
 
+MOZ_PROFILE_GUIDED_OPTIMIZE_DISABLE = @MOZ_PROFILE_GUIDED_OPTIMIZE_DISABLE@
 PROFILE_GEN_CFLAGS = @PROFILE_GEN_CFLAGS@
 PROFILE_GEN_LDFLAGS = @PROFILE_GEN_LDFLAGS@
 PROFILE_USE_CFLAGS = @PROFILE_USE_CFLAGS@
 PROFILE_USE_LDFLAGS = @PROFILE_USE_LDFLAGS@
 
 XCFLAGS		= @XCFLAGS@
 XLDFLAGS	= @XLDFLAGS@
 XLIBS		= @XLIBS@
--- a/config/config.mk
+++ b/config/config.mk
@@ -346,16 +346,21 @@ ifndef _ENABLE_PIC
 DSO_CFLAGS=
 ifeq ($(OS_ARCH)_$(HAVE_GCC3_ABI),Darwin_1)
 DSO_PIC_CFLAGS=-mdynamic-no-pic
 else
 DSO_PIC_CFLAGS=
 endif
 endif
 
+# This comes from configure
+ifdef MOZ_PROFILE_GUIDED_OPTIMIZE_DISABLE
+NO_PROFILE_GUIDED_OPTIMIZE = 1
+endif
+
 # Enable profile-based feedback
 ifndef NO_PROFILE_GUIDED_OPTIMIZE
 ifdef MOZ_PROFILE_GENERATE
 # No sense in profiling tools
 ifndef INTERNAL_TOOLS
 OS_CFLAGS += $(PROFILE_GEN_CFLAGS)
 OS_CXXFLAGS += $(PROFILE_GEN_CFLAGS)
 OS_LDFLAGS += $(PROFILE_GEN_LDFLAGS)
--- a/configure.in
+++ b/configure.in
@@ -112,17 +112,17 @@ dnl Set the minimum version of toolkit l
 dnl ========================================================
 GLIB_VERSION=1.2.0
 LIBIDL_VERSION=0.6.3
 PERL_VERSION=5.006
 LIBART_VERSION=2.3.4
 CAIRO_VERSION=1.5.2
 GLITZ_VERSION=0.4.0
 PANGO_VERSION=1.10.0
-GTK2_VERSION=1.8.0
+GTK2_VERSION=2.10.0
 MAKE_VERSION=3.78
 WINDRES_VERSION=2.14.90
 W32API_VERSION=3.8
 GNOMEVFS_VERSION=2.0
 GNOMEUI_VERSION=2.2.0
 GCONF_VERSION=1.2.1
 LIBGNOME_VERSION=2.0
 STARTUP_NOTIFICATION_VERSION=0.8
@@ -6535,16 +6535,25 @@ fi
 
 dnl ========================================================
 dnl Profile guided optimization
 dnl ========================================================
 dnl Test for profiling options
 dnl Under gcc 3.3, use -fprofile-arcs/-fbranch-probabilities
 dnl Under gcc 3.4+, use -fprofile-generate/-fprofile-use
 
+dnl Provide a switch to disable PGO even when called via profiledbuild.
+MOZ_ARG_DISABLE_BOOL(profile-guided-optimization,
+[  --disable-profile-guided-optimization
+                           Don't build with PGO even if called via make profiledbuild],
+MOZ_PROFILE_GUIDED_OPTIMIZE_DISABLE=1,
+MOZ_PROFILE_GUIDED_OPTIMIZE_DISABLE=)
+
+AC_SUBST(MOZ_PROFILE_GUIDED_OPTIMIZE_DISABLE)
+
 _SAVE_CFLAGS="$CFLAGS"
 CFLAGS="$CFLAGS -fprofile-generate"
 
 AC_MSG_CHECKING([whether C compiler supports -fprofile-generate])
 AC_TRY_COMPILE([], [return 0;],
                [ PROFILE_GEN_CFLAGS="-fprofile-generate"
                  result="yes" ], result="no")
 AC_MSG_RESULT([$result])
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -896,20 +896,23 @@ public:
                                 PRInt32 aNamespaceID);
 
   /**
    * Creates a DocumentFragment from text using a context node to resolve
    * namespaces.
    *
    * @param aContextNode the node which is used to resolve namespaces
    * @param aFragment the string which is parsed to a DocumentFragment
+   * @param aWillOwnFragment is PR_TRUE if ownership of the fragment should be
+   *                         transferred to the caller.
    * @param aReturn [out] the created DocumentFragment
    */
   static nsresult CreateContextualFragment(nsIDOMNode* aContextNode,
                                            const nsAString& aFragment,
+                                           PRBool aWillOwnFragment,
                                            nsIDOMDocumentFragment** aReturn);
 
   /**
    * Creates a new XML document, which is marked to be loaded as data.
    *
    * @param aNamespaceURI Namespace for the root element to create and insert in
    *                      the document. Only used if aQualifiedName is not
    *                      empty.
--- a/content/base/src/nsContentAreaDragDrop.cpp
+++ b/content/base/src/nsContentAreaDragDrop.cpp
@@ -1709,17 +1709,17 @@ nsTransferableFactory::SerializeNodeOrSe
     do_CreateInstance(NS_HTMLCOPY_ENCODER_CONTRACTID);
   NS_ENSURE_TRUE(encoder, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIDOMDocument> domDoc;
   inWindow->GetDocument(getter_AddRefs(domDoc));
   NS_ENSURE_TRUE(domDoc, NS_ERROR_FAILURE);
 
   PRUint32 flags = nsIDocumentEncoder::OutputAbsoluteLinks |
-                   nsIDocumentEncoder::OutputEncodeW3CEntities;
+                   nsIDocumentEncoder::OutputEncodeHTMLEntities;
   nsCOMPtr<nsIDOMRange> range;
   nsCOMPtr<nsISelection> selection;
   if (inNode) {
     // make a range around this node
     rv = NS_NewRange(getter_AddRefs(range));
     NS_ENSURE_SUCCESS(rv, rv);
     rv = range->SelectNode(inNode);
     NS_ENSURE_SUCCESS(rv, rv);
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -3349,16 +3349,17 @@ nsContentUtils::IsValidNodeName(nsIAtom 
   return aPrefix != nsGkAtoms::xmlns &&
          (aNamespaceID == kNameSpaceID_XML || aPrefix != nsGkAtoms::xml);
 }
 
 /* static */
 nsresult
 nsContentUtils::CreateContextualFragment(nsIDOMNode* aContextNode,
                                          const nsAString& aFragment,
+                                         PRBool aWillOwnFragment,
                                          nsIDOMDocumentFragment** aReturn)
 {
   NS_ENSURE_ARG(aContextNode);
   *aReturn = nsnull;
 
   nsresult rv;
   nsCOMPtr<nsINode> node = do_QueryInterface(aContextNode);
   NS_ENSURE_TRUE(node, NS_ERROR_NOT_AVAILABLE);
@@ -3494,17 +3495,17 @@ nsContentUtils::CreateContextualFragment
       NS_NOTREACHED("unknown mode");
       break;
   }
 
   // XXX Shouldn't we be returning rv if it's a failure code?
   rv = parser->ParseFragment(aFragment, nsnull, tagStack,
                              !bHTML, contentType, mode);
   if (NS_SUCCEEDED(rv)) {
-    rv = sink->GetFragment(aReturn);
+    rv = sink->GetFragment(aWillOwnFragment, aReturn);
   }
 
   document->SetFragmentParser(parser);
 
   return NS_OK;
 }
 
 /* static */
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -132,17 +132,16 @@
 
 #ifdef ACCESSIBILITY
 #include "nsIAccessibilityService.h"
 #include "nsIAccessibleEvent.h"
 #endif /* ACCESSIBILITY */
 
 #include "nsCycleCollectionParticipant.h"
 #include "nsCCUncollectableMarker.h"
-#include "nsCycleCollector.h"
 
 #ifdef MOZ_SVG
 PRBool NS_SVG_TestFeature(const nsAString &fstr);
 #endif /* MOZ_SVG */
 
 #ifdef DEBUG_waterson
 
 /**
@@ -1195,19 +1194,16 @@ nsGenericElement::nsGenericElement(nsINo
   // does extra work we know isn't necessary here...
   SetFlags(nsIProgrammingLanguage::JAVASCRIPT << NODE_SCRIPT_TYPE_OFFSET);
 }
 
 nsGenericElement::~nsGenericElement()
 {
   NS_PRECONDITION(!IsInDoc(),
                   "Please remove this from the document properly");
-#ifdef DEBUG
-  nsCycleCollector_DEBUG_wasFreed(static_cast<nsINode*>(this));
-#endif
 }
 
 NS_IMETHODIMP
 nsGenericElement::GetNodeName(nsAString& aNodeName)
 {
   mNodeInfo->GetQualifiedName(aNodeName);
   return NS_OK;
 }
@@ -2224,19 +2220,16 @@ nsGenericElement::UnbindFromTree(PRBool 
       // Note that we pass PR_FALSE for aNullParent here, since we don't want
       // the kids to forget us.  We _do_ want them to forget their binding
       // parent, though, since this only walks non-anonymous kids.
       mAttrsAndChildren.ChildAt(i)->UnbindFromTree(PR_TRUE, PR_FALSE);
     }
   }
 
   nsNodeUtils::ParentChainChanged(this);
-#ifdef DEBUG
-  nsCycleCollector_DEBUG_shouldBeFreed(static_cast<nsINode*>(this));
-#endif
 }
 
 nsresult
 nsGenericElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
 {
   return nsGenericElement::doPreHandleEvent(this, aVisitor);
 }
 
--- a/content/base/src/nsPlainTextSerializer.cpp
+++ b/content/base/src/nsPlainTextSerializer.cpp
@@ -592,17 +592,17 @@ nsPlainTextSerializer::DoOpenContainer(c
     mIgnoreAboveIndex = mTagStackIndex - 1;
     return NS_OK;
   }
 
   if (type == eHTMLTag_body) {
     // Try to figure out here whether we have a
     // preformatted style attribute.
     //
-    // Trigger on the presence of a "-moz-pre-wrap" in the
+    // Trigger on the presence of a "pre-wrap" in the
     // style attribute. That's a very simplistic way to do
     // it, but better than nothing.
     // Also set mWrapColumn to the value given there
     // (which arguably we should only do if told to do so).
     nsAutoString style;
     PRInt32 whitespace;
     if(NS_SUCCEEDED(GetAttributeValue(aNode, nsGkAtoms::style, style)) &&
        (kNotFound != (whitespace = style.Find("white-space:")))) {
--- a/content/base/src/nsRange.cpp
+++ b/content/base/src/nsRange.cpp
@@ -1789,13 +1789,14 @@ nsRange::Detach()
 }
 
 // nsIDOMNSRange interface
 NS_IMETHODIMP    
 nsRange::CreateContextualFragment(const nsAString& aFragment,
                                   nsIDOMDocumentFragment** aReturn)
 {
   nsCOMPtr<nsIDOMNode> start = do_QueryInterface(mStartParent);
-  return
-    mIsPositioned
-    ? nsContentUtils::CreateContextualFragment(start, aFragment, aReturn)
-    : NS_ERROR_FAILURE;
+  if (mIsPositioned) {
+    return nsContentUtils::CreateContextualFragment(start, aFragment, PR_TRUE,
+                                                    aReturn);
+  }
+  return NS_ERROR_FAILURE;
 }
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -170,16 +170,17 @@ include $(topsrcdir)/config/rules.mk
 		test_bug415860.html \
 		test_bug414190.html \
 		test_bug414796.html \
 		test_bug416383.html \
 		test_bug417255.html \
 		test_bug417384.html \
 		test_bug418214.html \
 		test_bug420609.xhtml \
+		test_bug420700.html \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
 
 check::
 	@$(EXIT_ON_ERROR) \
 	for f in $(subst .cpp,,$(CPP_UNIT_TESTS)); do \
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug420700.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=420700
+-->
+<head>
+  <title>Test for Bug 420700</title>
+  <script type="text/javascript" src="/MochiKit/MochiKit.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=420700">Mozilla Bug 420700</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+  var r = document.createRange();
+  r.selectNode(document.documentElement);
+
+  var df = r.createContextualFragment("<p>BAD</p>");
+
+  var display = document.getElementById("display");
+  display.innerHTML = "<p>GOOD</p>";
+
+  var p = display.firstChild;
+
+  is(p.textContent, "GOOD", "createContextualFragment tests");
+</script>
+</pre>
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/content/canvas/crashtests/421715-1.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <script type="text/javascript">
+      function stringify(a) {
+        if (a)
+          return a.toSource();
+        return ''+a;
+      }
+      var args = [undefined, null, [], {}, 0, "0"];
+      var stringArgs = args.map(stringify);
+
+      function test_method(context, method, arity) {
+        function testParams(existingParams, depth) {
+          for each (var arg in stringArgs) {
+            var code = "context[method](" + existingParams + arg + ")";
+            try {
+              eval(code);
+            } catch (ex) {
+              // Exceptions are expected
+            }
+
+            if (depth < arity)
+              testParams(existingParams + arg + ",", depth + 1);
+          }
+        }
+        testParams("", 1);
+      }
+
+      function startTest() {
+        var canvas = document.getElementById("img");
+        var context = canvas.getContext('2d');;
+        test_method(context, "getImageData", 4);
+        test_method(context, "putImageData", 3);
+      }
+    </script>
+  </head>
+  <body onload="startTest()">
+    <canvas id="img">No canvas support.</canvas>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/canvas/crashtests/crashtests.list
@@ -0,0 +1,1 @@
+load 421715-1.html
--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp
+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp
@@ -415,16 +415,41 @@ protected:
 
     // cairo helpers
     nsresult CairoSurfaceFromElement(nsIDOMElement *imgElt,
                                      cairo_surface_t **aCairoSurface,
                                      PRUint8 **imgDataOut,
                                      PRInt32 *widthOut, PRInt32 *heightOut,
                                      nsIPrincipal **prinOut,
                                      PRBool *forceWriteOnlyOut);
+
+    // other helpers
+    void GetAppUnitsValues(PRUint32 *perDevPixel, PRUint32 *perCSSPixel) {
+        // If we don't have a canvas element, we just return something generic.
+        PRUint32 devPixel = 60;
+        PRUint32 cssPixel = 60;
+
+        nsCOMPtr<nsINode> elem = do_QueryInterface(mCanvasElement);
+        if (elem) {
+            nsIDocument *doc = elem->GetOwnerDoc();
+            if (!doc) goto FINISH;
+            nsIPresShell *ps = doc->GetPrimaryShell();
+            if (!ps) goto FINISH;
+            nsPresContext *pc = ps->GetPresContext();
+            if (!pc) goto FINISH;
+            devPixel = pc->AppUnitsPerDevPixel();
+            cssPixel = pc->AppUnitsPerCSSPixel();
+        }
+
+      FINISH:
+        if (perDevPixel)
+            *perDevPixel = devPixel;
+        if (perCSSPixel)
+            *perCSSPixel = cssPixel;
+    }
 };
 
 NS_IMPL_ADDREF(nsCanvasRenderingContext2D)
 NS_IMPL_RELEASE(nsCanvasRenderingContext2D)
 
 NS_INTERFACE_MAP_BEGIN(nsCanvasRenderingContext2D)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCanvasRenderingContext2D)
   NS_INTERFACE_MAP_ENTRY(nsICanvasRenderingContextInternal)
@@ -565,17 +590,23 @@ nsCanvasRenderingContext2D::DirtyAllStyl
     }
 }
 
 void
 nsCanvasRenderingContext2D::DoDrawImageSecurityCheck(nsIPrincipal* aPrincipal,
                                                      PRBool forceWriteOnly)
 {
     NS_PRECONDITION(aPrincipal, "Must have a principal here");
-    
+
+    // Callers should ensure that mCanvasElement is non-null before calling this
+    if (!mCanvasElement) {
+        NS_WARNING("DoDrawImageSecurityCheck called without canvas element!");
+        return;
+    }
+
     if (mCanvasElement->IsWriteOnly())
         return;
 
     // If we explicitly set WriteOnly just do it and get out
     if (forceWriteOnly) {
         mCanvasElement->SetWriteOnly();
         return;
     }
@@ -605,16 +636,19 @@ nsCanvasRenderingContext2D::ApplyStyle(P
         return;
     }
 
     mDirtyStyle[aWhichStyle] = PR_FALSE;
     mLastStyle = aWhichStyle;
 
     nsCanvasPattern* pattern = CurrentState().patternStyles[aWhichStyle];
     if (pattern) {
+        if (!mCanvasElement)
+            return;
+
         DoDrawImageSecurityCheck(pattern->Principal(),
                                  pattern->GetForceWriteOnly());
         pattern->Apply(mCairo);
         return;
     }
 
     if (CurrentState().gradientStyles[aWhichStyle]) {
         CurrentState().gradientStyles[aWhichStyle]->Apply(mCairo);
@@ -1427,31 +1461,38 @@ nsCanvasRenderingContext2D::Rect(float x
 // text
 //
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::SetMozTextStyle(const nsAString& textStyle)
 {
     if(mTextStyle.Equals(textStyle)) return NS_OK;
 
     nsCOMPtr<nsINode> elem = do_QueryInterface(mCanvasElement);
-    NS_ASSERTION(elem, "Canvas element must be a dom node");
-
-    nsCOMPtr<nsIPrincipal> elemPrincipal;
-    nsCOMPtr<nsIDocument> elemDocument;
-
-    elemPrincipal = elem->NodePrincipal();
-    elemDocument = elem->GetOwnerDoc();
-
-    NS_ASSERTION(elemDocument && elemPrincipal, "Element is missing document or principal");
+    if (!elem) {
+        NS_WARNING("Canvas element must be an nsINode and non-null");
+        return NS_ERROR_FAILURE;
+    }
+
+    nsIPrincipal* elemPrincipal = elem->NodePrincipal();
+    nsIDocument* elemDocument = elem->GetOwnerDoc();
+
+    if (!elemDocument || !elemPrincipal) {
+        NS_WARNING("Element is missing document or principal");
+        return NS_ERROR_FAILURE;
+    }
+
+    nsIPresShell* presShell = elemDocument->GetPrimaryShell();
+    if (!presShell)
+        return NS_ERROR_FAILURE;
 
     nsIURI *docURL = elemDocument->GetDocumentURI();
     nsIURI *baseURL = elemDocument->GetBaseURI();
 
     nsCString langGroup;
-    elemDocument->GetPrimaryShell()->GetPresContext()->GetLangGroup()->ToUTF8String(langGroup);
+    presShell->GetPresContext()->GetLangGroup()->ToUTF8String(langGroup);
 
     nsCOMArray<nsIStyleRule> rules;
     PRBool changed;
 
     nsCOMPtr<nsICSSStyleRule> rule;
     mCSSParser->ParseStyleAttribute(
             EmptyString(),
             docURL,
@@ -1464,24 +1505,24 @@ nsCanvasRenderingContext2D::SetMozTextSt
                               docURL,
                               baseURL,
                               elemPrincipal,
                               rule->GetDeclaration(),
                               &changed);
 
     rules.AppendObject(rule);
 
-    nsStyleSet *styleSet = elemDocument->GetPrimaryShell()->StyleSet();
+    nsStyleSet *styleSet = presShell->StyleSet();
 
     nsRefPtr<nsStyleContext> sc = styleSet->ResolveStyleForRules(nsnull,rules);
     const nsStyleFont *fontStyle = sc->GetStyleFont();
 
     NS_ASSERTION(fontStyle, "Could not obtain font style");
 
-    PRUint32 aupdp = elemDocument->GetPrimaryShell()->GetPresContext()->AppUnitsPerDevPixel();
+    PRUint32 aupdp = presShell->GetPresContext()->AppUnitsPerDevPixel();
 
     gfxFontStyle style(fontStyle->mFont.style,
                        fontStyle->mFont.weight,
                        NSAppUnitsToFloatPixels(fontStyle->mFont.size,aupdp),
                        langGroup,
                        fontStyle->mFont.sizeAdjust,
                        fontStyle->mFont.systemFont,
                        fontStyle->mFont.familyNameQuirks);
@@ -1509,26 +1550,23 @@ gfxFontGroup *nsCanvasRenderingContext2D
         NS_ASSERTION(res == NS_OK, "Default canvas font is invalid");
     }
     return mFontGroup;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::MozDrawText(const nsAString& textToDraw)
 {
-    nsCOMPtr<nsINode> elem = do_QueryInterface(mCanvasElement);
-    NS_ASSERTION(elem, "Canvas element must be an nsINode");
-
-    nsCOMPtr<nsIDocument> elemDocument(elem->GetOwnerDoc());
-
     const PRUnichar* textdata;
     textToDraw.GetData(&textdata);
 
     PRUint32 textrunflags = 0;
-    PRUint32 aupdp = elemDocument->GetPrimaryShell()->GetPresContext()->AppUnitsPerDevPixel();
+
+    PRUint32 aupdp;
+    GetAppUnitsValues(&aupdp, NULL);
 
     gfxTextRunCache::AutoTextRun textRun;
     textRun = gfxTextRunCache::MakeTextRun(textdata,
                                            textToDraw.Length(),
                                            GetCurrentFontStyle(),
                                            mThebesContext,
                                            aupdp,
                                            textrunflags);
@@ -1549,59 +1587,52 @@ nsCanvasRenderingContext2D::MozDrawText(
                   nsnull,
                   nsnull);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::MozMeasureText(const nsAString& textToMeasure, float *retVal)
 {
-    nsCOMPtr<nsINode> elem = do_QueryInterface(mCanvasElement);
-    NS_ASSERTION(elem, "Canvas element must be an nsINode");
-
-    nsCOMPtr<nsIDocument> elemDocument(elem->GetOwnerDoc());
-
     const PRUnichar* textdata;
     textToMeasure.GetData(&textdata);
 
     PRUint32 textrunflags = 0;
-    PRUint32 aupdp = elemDocument->GetPrimaryShell()->GetPresContext()->AppUnitsPerDevPixel();
+    PRUint32 aupdp, aupcp;
+    GetAppUnitsValues(&aupdp, &aupcp);
 
     gfxTextRunCache::AutoTextRun textRun;
     textRun = gfxTextRunCache::MakeTextRun(textdata,
                                            textToMeasure.Length(),
                                            GetCurrentFontStyle(),
                                            mThebesContext,
                                            aupdp,
                                            textrunflags);
 
     if(!textRun.get())
         return NS_ERROR_FAILURE;
 
     PRBool tightBoundingBox = PR_FALSE;
     gfxTextRun::Metrics metrics = textRun->MeasureText(/* offset = */ 0, textToMeasure.Length(),
                                                        tightBoundingBox, mThebesContext,
                                                        nsnull);
-    *retVal = float(metrics.mAdvanceWidth/gfxFloat(elemDocument->GetPrimaryShell()->GetPresContext()->AppUnitsPerCSSPixel()));
+    *retVal = float(metrics.mAdvanceWidth/gfxFloat(aupcp));
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::MozPathText(const nsAString& textToPath)
 {
-    nsCOMPtr<nsINode> elem = do_QueryInterface(mCanvasElement);
-    NS_ASSERTION(elem, "Canvas element must be an nsINode");
-
-    nsCOMPtr<nsIDocument> elemDocument(elem->GetOwnerDoc());
-
     const PRUnichar* textdata;
     textToPath.GetData(&textdata);
 
     PRUint32 textrunflags = 0;
-    PRUint32 aupdp = elemDocument->GetPrimaryShell()->GetPresContext()->AppUnitsPerDevPixel();
+
+    PRUint32 aupdp;
+    GetAppUnitsValues(&aupdp, NULL);
 
     gfxTextRunCache::AutoTextRun textRun;
     textRun = gfxTextRunCache::MakeTextRun(textdata,
                                            textToPath.Length(),
                                            GetCurrentFontStyle(),
                                            mThebesContext,
                                            aupdp,
                                            textrunflags);
@@ -1621,26 +1652,23 @@ nsCanvasRenderingContext2D::MozPathText(
 }
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::MozTextAlongPath(const nsAString& textToDraw, PRBool stroke)
 {
     // Most of this code is copied from its svg equivalent
     nsRefPtr<gfxFlattenedPath> path(mThebesContext->GetFlattenedPath());
 
-    nsCOMPtr<nsINode> elem = do_QueryInterface(mCanvasElement);
-    NS_ASSERTION(elem, "Canvas element must be an nsINode");
-
-    nsCOMPtr<nsIDocument> elemDocument(elem->GetOwnerDoc());
-
     const PRUnichar* textdata;
     textToDraw.GetData(&textdata);
 
     PRUint32 textrunflags = 0;
-    PRUint32 aupdp = elemDocument->GetPrimaryShell()->GetPresContext()->AppUnitsPerDevPixel();
+
+    PRUint32 aupdp;
+    GetAppUnitsValues(&aupdp, NULL);
 
     gfxTextRunCache::AutoTextRun textRun;
     textRun = gfxTextRunCache::MakeTextRun(textdata,
                                            textToDraw.Length(),
                                            GetCurrentFontStyle(),
                                            mThebesContext,
                                            aupdp,
                                            textrunflags);
@@ -1704,17 +1732,17 @@ nsCanvasRenderingContext2D::MozTextAlong
         if(stroke) {
             textRun->DrawToPath(mThebesContext, pt, i, 1, nsnull, nsnull);
         } else {
             textRun->Draw(mThebesContext, pt, i, 1, nsnull, nsnull, nsnull);
         }
         mThebesContext->SetMatrix(matrix);
     }
 
-    delete[] cp;
+    delete [] cp;
 
     return NS_OK;
 }
 
 //
 // line caps/joins
 //
 NS_IMETHODIMP
@@ -1846,16 +1874,21 @@ nsCanvasRenderingContext2D::IsPointInPat
 // drawImage(in HTMLImageElement image, in float sx, in float sy, in float sw, in float sh, in float dx, in float dy, in float dw, in float dh);
 //   -- render the region defined by (sx,sy,sw,wh) in image-local space into the region (dx,dy,dw,dh) on the canvas
 
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::DrawImage()
 {
     nsresult rv;
 
+    // we can't do a security check without a canvas element, so
+    // just skip this entirely
+    if (!mCanvasElement)
+        return NS_ERROR_FAILURE;
+
     nsAXPCNativeCallContext *ncc = nsnull;
     rv = nsContentUtils::XPConnect()->
         GetCurrentNativeCallContext(&ncc);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (!ncc)
         return NS_ERROR_FAILURE;
 
@@ -2215,19 +2248,28 @@ nsCanvasRenderingContext2D::CairoSurface
     if (NS_FAILED(rv))
         return NS_ERROR_FAILURE;
 
     if (widthOut)
         *widthOut = imgWidth;
     if (heightOut)
         *heightOut = imgHeight;
 
-    nsRefPtr<gfxASurface> gfxsurf;
-    rv = img->GetSurface(getter_AddRefs(gfxsurf));
-    NS_ENSURE_SUCCESS(rv, rv);
+    nsRefPtr<gfxPattern> gfxpattern;
+    img->GetPattern(getter_AddRefs(gfxpattern));
+    nsRefPtr<gfxASurface> gfxsurf = gfxpattern->GetSurface();
+
+    if (!gfxsurf) {
+        gfxsurf = new gfxImageSurface (gfxIntSize(imgWidth, imgHeight), gfxASurface::ImageFormatARGB32);
+        nsRefPtr<gfxContext> ctx = new gfxContext(gfxsurf);
+
+        ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
+        ctx->SetPattern(gfxpattern);
+        ctx->Paint();
+    }
 
     *aCairoSurface = gfxsurf->CairoSurface();
     cairo_surface_reference (*aCairoSurface);
     *imgData = nsnull;
 
     return NS_OK;
 }
 
@@ -2346,17 +2388,17 @@ nsCanvasRenderingContext2D::DrawWindow(n
 //
 // device pixel getting/setting
 //
 
 // ImageData getImageData (in float x, in float y, in float width, in float height);
 NS_IMETHODIMP
 nsCanvasRenderingContext2D::GetImageData()
 {
-    if (!mValid)
+    if (!mValid || !mCanvasElement)
         return NS_ERROR_FAILURE;
 
     if (mCanvasElement->IsWriteOnly() && !nsContentUtils::IsCallerTrustedForRead()) {
         // XXX ERRMSG we need to report an error to developers here! (bug 329026)
         return NS_ERROR_DOM_SECURITY_ERR;
     }
 
     nsAXPCNativeCallContext *ncc = nsnull;
@@ -2501,16 +2543,19 @@ nsCanvasRenderingContext2D::PutImageData
     JSAutoRequest ar(ctx);
 
     JSObject *dataObject;
     int32 x, y;
 
     if (!JS_ConvertArguments (ctx, argc, argv, "ojj", &dataObject, &x, &y))
         return NS_ERROR_DOM_SYNTAX_ERR;
 
+    if (!dataObject)
+        return NS_ERROR_DOM_SYNTAX_ERR;
+
     int32 w, h;
     JSObject *dataArray;
     jsval v;
 
     if (!JS_GetProperty(ctx, dataObject, "width", &v) ||
         !JS_ValueToInt32(ctx, v, &w))
         return NS_ERROR_DOM_SYNTAX_ERR;
 
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -741,16 +741,17 @@ nsGenericHTMLElement::SetInnerHTML(const
     loader = doc->ScriptLoader();
     scripts_enabled = loader->GetEnabled();
     loader->SetEnabled(PR_FALSE);
   }
 
   nsCOMPtr<nsIDOMNode> thisNode(do_QueryInterface(static_cast<nsIContent *>
                                                              (this)));
   nsresult rv = nsContentUtils::CreateContextualFragment(thisNode, aInnerHTML,
+                                                         PR_FALSE,
                                                          getter_AddRefs(df));
   if (NS_SUCCEEDED(rv)) {
     nsCOMPtr<nsIDOMNode> tmpNode;
     rv = thisNode->AppendChild(df, getter_AddRefs(tmpNode));
   }
 
   if (scripts_enabled) {
     // If we disabled scripts, re-enable them now that we're
--- a/content/html/document/src/nsHTMLFragmentContentSink.cpp
+++ b/content/html/document/src/nsHTMLFragmentContentSink.cpp
@@ -114,17 +114,18 @@ public:
   NS_IMETHOD OpenContainer(const nsIParserNode& aNode);
   NS_IMETHOD CloseContainer(const nsHTMLTag aTag);
   NS_IMETHOD AddLeaf(const nsIParserNode& aNode);
   NS_IMETHOD AddComment(const nsIParserNode& aNode);
   NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode);
   NS_IMETHOD AddDocTypeDecl(const nsIParserNode& aNode);
 
   // nsIFragmentContentSink
-  NS_IMETHOD GetFragment(nsIDOMDocumentFragment** aFragment);
+  NS_IMETHOD GetFragment(PRBool aWillOwnFragment,
+                         nsIDOMDocumentFragment** aFragment);
   NS_IMETHOD SetTargetDocument(nsIDocument* aDocument);
   NS_IMETHOD WillBuildContent();
   NS_IMETHOD DidBuildContent();
   NS_IMETHOD IgnoreFirstContainer();
 
   nsIContent* GetCurrentContent();
   PRInt32 PushContent(nsIContent *aContent);
   nsIContent* PopContent();
@@ -603,20 +604,25 @@ nsHTMLFragmentContentSink::AddProcessing
 
 NS_IMETHODIMP
 nsHTMLFragmentContentSink::AddDocTypeDecl(const nsIParserNode& aNode)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsHTMLFragmentContentSink::GetFragment(nsIDOMDocumentFragment** aFragment)
+nsHTMLFragmentContentSink::GetFragment(PRBool aWillOwnFragment,
+                                       nsIDOMDocumentFragment** aFragment)
 {
   if (mRoot) {
-    return CallQueryInterface(mRoot, aFragment);
+    nsresult rv = CallQueryInterface(mRoot, aFragment);
+    if (NS_SUCCEEDED(rv) && aWillOwnFragment) {
+      mRoot = nsnull;
+    }
+    return rv;
   }
 
   *aFragment = nsnull;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/content/svg/content/Makefile.in
+++ b/content/svg/content/Makefile.in
@@ -40,10 +40,14 @@ DEPTH		= ../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 DIRS		= src
 
+ifdef MOZ_MOCHITEST
+DIRS += test
+endif
+
 include $(topsrcdir)/config/rules.mk
 
--- a/content/svg/content/src/Makefile.in
+++ b/content/svg/content/src/Makefile.in
@@ -169,12 +169,11 @@ INCLUDES += 	\
 		-I$(srcdir)/../../../xml/content/src \
 		-I$(srcdir)/../../../../dom \
 		-I$(srcdir)/../../../base/src \
 		-I$(srcdir)/../../../../layout/svg/base/src \
 		-I$(srcdir)/../../../../layout/style \
 		-I$(srcdir)/../../../events/src \
 		-I$(srcdir)/../../../html/content/src \
 		-I$(topsrcdir)/content/xbl/src \
-		-I$(topsrcdir)/gfx/src/thebes \
 		$(NULL)
 
 DEFINES += -D_IMPL_NS_LAYOUT
--- a/content/svg/content/src/nsSVGFeaturesList.h
+++ b/content/svg/content/src/nsSVGFeaturesList.h
@@ -52,25 +52,25 @@ SVG_SUPPORTED_FEATURE("http://www.w3.org
 SVG_SUPPORTED_FEATURE("http://www.w3.org/TR/SVG11/feature#OpacityAttribute")
 SVG_SUPPORTED_FEATURE("http://www.w3.org/TR/SVG11/feature#GraphicsAttribute")
 SVG_SUPPORTED_FEATURE("http://www.w3.org/TR/SVG11/feature#Marker")
 SVG_UNSUPPORTED_FEATURE("http://www.w3.org/TR/SVG11/feature#ColorProfile")
 SVG_SUPPORTED_FEATURE("http://www.w3.org/TR/SVG11/feature#Gradient")
 SVG_SUPPORTED_FEATURE("http://www.w3.org/TR/SVG11/feature#Pattern")
 SVG_SUPPORTED_FEATURE("http://www.w3.org/TR/SVG11/feature#Clip")
 SVG_SUPPORTED_FEATURE("http://www.w3.org/TR/SVG11/feature#Mask")
-SVG_SUPPORTED_FEATURE("http://www.w3.org/TR/SVG11/feature#Filter")
+SVG_UNSUPPORTED_FEATURE("http://www.w3.org/TR/SVG11/feature#Filter")
 
 // Basic features
 SVG_SUPPORTED_FEATURE("http://www.w3.org/TR/SVG11/feature#BasicStructure")
 SVG_SUPPORTED_FEATURE("http://www.w3.org/TR/SVG11/feature#BasicText")
 SVG_SUPPORTED_FEATURE("http://www.w3.org/TR/SVG11/feature#BasicPaintAttribute")
 SVG_SUPPORTED_FEATURE("http://www.w3.org/TR/SVG11/feature#BasicGraphicsAttribute")
 SVG_SUPPORTED_FEATURE("http://www.w3.org/TR/SVG11/feature#BasicClip")
-SVG_SUPPORTED_FEATURE("http://www.w3.org/TR/SVG11/feature#BasicFilter")
+SVG_UNSUPPORTED_FEATURE("http://www.w3.org/TR/SVG11/feature#BasicFilter")
 
 // Animation feature
 SVG_UNSUPPORTED_FEATURE("http://www.w3.org/TR/SVG11/feature#Animation")
 
 // Dynamic features
 SVG_SUPPORTED_FEATURE("http://www.w3.org/TR/SVG11/feature#DocumentEventsAttribute")
 SVG_SUPPORTED_FEATURE("http://www.w3.org/TR/SVG11/feature#GraphicalEventsAttribute")
 SVG_UNSUPPORTED_FEATURE("http://www.w3.org/TR/SVG11/feature#AnimationEventsAttribute")
--- a/content/svg/content/src/nsSVGFilters.cpp
+++ b/content/svg/content/src/nsSVGFilters.cpp
@@ -58,17 +58,17 @@
 #include "nsIDocument.h"
 #include "nsIFrame.h"
 #include "gfxContext.h"
 #include "nsSVGLengthList.h"
 #include "nsIDOMSVGURIReference.h"
 #include "nsImageLoadingContent.h"
 #include "imgIContainer.h"
 #include "gfxIImageFrame.h"
-#include "nsThebesImage.h"
+#include "nsIImage.h"
 #include "nsSVGAnimatedPreserveAspectRatio.h"
 #include "nsSVGPreserveAspectRatio.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsSVGMatrix.h"
 #include "nsSVGFilterElement.h"
 #if defined(XP_WIN)
 // Prevent Windows redefining LoadImage
 #undef LoadImage
@@ -5577,46 +5577,41 @@ nsSVGFEImageElement::Filter(nsSVGFilterI
   nsCOMPtr<imgIContainer> imageContainer;
   if (currentRequest)
     currentRequest->GetImage(getter_AddRefs(imageContainer));
 
   nsCOMPtr<gfxIImageFrame> currentFrame;
   if (imageContainer)
     imageContainer->GetCurrentFrame(getter_AddRefs(currentFrame));
 
-  gfxASurface *thebesSurface = nsnull;
+  nsRefPtr<gfxPattern> thebesPattern = nsnull;
   if (currentFrame) {
     nsCOMPtr<nsIImage> img(do_GetInterface(currentFrame));
 
-    nsThebesImage *thebesImage = nsnull;
-    if (img)
-      thebesImage = static_cast<nsThebesImage*>(img.get());
-
-    if (thebesImage)
-      thebesSurface = thebesImage->ThebesSurface();
+    img->GetPattern(getter_AddRefs(thebesPattern));
   }
 
-  if (thebesSurface) {
+  if (thebesPattern) {
     PRInt32 x, y, nativeWidth, nativeHeight;
     currentFrame->GetX(&x);
     currentFrame->GetY(&y);
     currentFrame->GetWidth(&nativeWidth);
     currentFrame->GetHeight(&nativeHeight);
 
     nsCOMPtr<nsIDOMSVGMatrix> trans;
     trans = nsSVGUtils::GetViewBoxTransform(filterSubregion.width, filterSubregion.height,
                                             x, y,
                                             nativeWidth, nativeHeight,
                                             mPreserveAspectRatio);
     nsCOMPtr<nsIDOMSVGMatrix> xy, fini;
     NS_NewSVGMatrix(getter_AddRefs(xy), 1, 0, 0, 1, filterSubregion.x, filterSubregion.y);
     xy->Multiply(trans, getter_AddRefs(fini));
 
     gfxContext ctx(targetSurface);
-    nsSVGUtils::CompositeSurfaceMatrix(&ctx, thebesSurface, fini, 1.0);
+    nsSVGUtils::CompositePatternMatrix(&ctx, thebesPattern, fini, nativeWidth, nativeHeight, 1.0);
   }
 
   return NS_OK;
 }
 
 nsRect
 nsSVGFEImageElement::ComputeTargetBBox(const nsTArray<nsRect>& aSourceBBoxes,
         const nsSVGFilterInstance& aInstance)
--- a/content/svg/content/src/nsSVGStyleElement.cpp
+++ b/content/svg/content/src/nsSVGStyleElement.cpp
@@ -336,11 +336,14 @@ nsSVGStyleElement::GetStyleSheetInfo(nsA
   aTitle.Assign(title);
 
   GetAttr(kNameSpaceID_None, nsGkAtoms::media, aMedia);
   // SVG spec refers to the HTML4.0 spec which is inconsistent, make it
   // case INSENSITIVE
   ToLowerCase(aMedia);
 
   GetAttr(kNameSpaceID_None, nsGkAtoms::type, aType);
+  if (aType.IsEmpty()) {
+    aType.AssignLiteral("text/css");
+  }
 
   return;
 }
new file mode 100644
--- /dev/null
+++ b/content/svg/content/test/Makefile.in
@@ -0,0 +1,53 @@
+#
+# ***** 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
+# Jeff Walden <jwalden+code@mit.edu>.
+# Portions created by the Initial Developer are Copyright (C) 2008
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH		= ../../../..
+topsrcdir	= @top_srcdir@
+srcdir		= @srcdir@
+VPATH		= @srcdir@
+relativesrcdir  = content/svg/content/test
+
+include $(DEPTH)/config/autoconf.mk
+include $(topsrcdir)/config/rules.mk
+
+_TEST_FILES = \
+		test_getSubStringLength.xhtml \
+		getSubStringLength-helper.svg \
+		$(NULL)
+
+libs:: $(_TEST_FILES)
+	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/content/svg/content/test/getSubStringLength-helper.svg
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="750">
+  <style type="text/css">
+.t { font: 20px monospace; }
+  </style>
+  <text id="text" x="5" class="t" y="25">abc</text>
+</svg>
new file mode 100644
--- /dev/null
+++ b/content/svg/content/test/test_getSubStringLength.xhtml
@@ -0,0 +1,105 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=420243
+-->
+<head>
+  <title>Test for Bug 420243</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=420243">Mozilla Bug 420243</a>
+<p id="display"></p>
+<div id="content" style="display: none"></div>
+
+<iframe id="svg" src="getSubStringLength-helper.svg"></iframe>
+
+<pre id="test">
+<script class="testbody" type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+
+function runTests(text, charWidth)
+{
+  function chars(n) { return charWidth * n; }
+
+  function expectThrow(charnum, nchars)
+  {
+    try
+    {
+      text.getSubStringLength(charnum, nchars);
+      ok(false,
+         "text.getSubStringLength(" + charnum + "," + nchars + ") " +
+         "should have thrown");
+    }
+    catch (e)
+    {
+      is(e.code, DOMException.INDEX_SIZE_ERR,
+         "expected an index error for " +
+         "text.getSubStringLength(" + charnum + "," + nchars + ")");
+    }
+  }
+  
+  function expectValue(charnum, nchars, expected)
+  {
+    try
+    {
+      is(text.getSubStringLength(charnum, nchars), expected,
+         "text.getSubStringLength(" + charnum + "," + nchars + ") " +
+         "returned wrong value");
+    }
+    catch (e)
+    {
+      ok(false,
+         "unexpected exception for " +
+         "text.getSubStringLength(" + charnum + "," + nchars + ")");
+    }
+  }
+
+  expectThrow(-1, 2);
+  expectThrow(-1, 0);
+  expectThrow(1, 3);
+  expectThrow(0, 4);
+  expectThrow(3, 0);
+
+  expectValue(0, 0, chars(0));
+  expectValue(1, 0, chars(0));
+  expectValue(2, 0, chars(0));
+  expectValue(0, 1, chars(1));
+  expectValue(1, 1, chars(1));
+  expectValue(2, 1, chars(1));
+  expectValue(0, 2, chars(2));
+  expectValue(1, 2, chars(2));
+  expectValue(0, 3, chars(3));
+
+  expectThrow(1, -1);
+  expectThrow(2, -1);
+  expectThrow(3, -1);
+  expectThrow(3, -3);
+  expectThrow(-1, -1);
+}
+
+
+function run()
+{
+  try
+  {
+    var document = $("svg").contentWindow.document;
+    var text = document.getElementById("text");
+
+    runTests(text, text.getSubStringLength(0, 1));
+  }
+  catch (e)
+  {
+    ok(false, "threw error: " + e);
+  }
+
+  SimpleTest.finish();
+}
+
+window.addEventListener("load", run, false);
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/xbl/crashtests/418133-1.xhtml
@@ -0,0 +1,22 @@
+<html xmlns="http://www.w3.org/1999/xhtml"
+      xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+<head>
+<script type="text/javascript">
+
+function boom()
+{
+  for(var p in document.getElementById("prefs")) {
+  }
+  
+  for(var p in window) {
+  }
+}
+
+</script>
+</head>
+<body onload="boom();">
+
+<xul:preferences id="prefs" />
+
+</body>
+</html>
--- a/content/xbl/crashtests/crashtests.list
+++ b/content/xbl/crashtests/crashtests.list
@@ -2,8 +2,9 @@ load 368276-1.xhtml
 load 368641-1.xhtml
 load 382376-1.xhtml
 load 382376-2.xhtml
 load 342954-1.xhtml
 load 342954-2.xhtml
 load 406900-1.xul
 load 406904-1.xhtml
 load 406904-2.xhtml
+load 418133-1.xhtml
--- a/content/xbl/src/nsXBLProtoImplField.cpp
+++ b/content/xbl/src/nsXBLProtoImplField.cpp
@@ -114,37 +114,47 @@ nsXBLProtoImplField::InstallField(nsIScr
   nsresult rv;
   nsAutoGCRoot root(&result, &rv);
   if (NS_FAILED(rv))
     return rv;
 
   nsCAutoString uriSpec;
   aBindingDocURI->GetSpec(uriSpec);
   
+  JSContext* cx = (JSContext*) aContext->GetNativeContext();
+  NS_ASSERTION(!::JS_IsExceptionPending(cx),
+               "Shouldn't get here when an exception is pending!");
+  
   // compile the literal string
   // XXX Could we produce a better principal here?  Should be able
   // to, really!
   PRBool undefined;
   nsCOMPtr<nsIScriptContext> context = aContext;
   rv = context->EvaluateStringWithValue(nsDependentString(mFieldText,
                                                           mFieldTextLength), 
                                         aBoundNode,
                                         nsnull, uriSpec.get(),
                                         mLineNumber, JSVERSION_LATEST,
                                         (void*) &result, &undefined);
   if (NS_FAILED(rv))
     return rv;
 
+  // If EvaluateStringWithValue() threw an exception, just report it now.
+  // Failure to evaluate a field should stop neither the get of the field value
+  // nor an enumeration attempt.
+  if (::JS_IsExceptionPending(cx)) {
+    ::JS_ReportPendingException(cx);
+  }
+
   if (undefined) {
     result = JSVAL_VOID;
   }
 
   // Define the evaluated result as a JS property
   nsDependentString name(mName);
-  JSContext* cx = (JSContext*) aContext->GetNativeContext();
   JSAutoRequest ar(cx);
   if (!::JS_DefineUCProperty(cx, aBoundNode,
                              reinterpret_cast<const jschar*>(mName), 
                              name.Length(), result, nsnull, nsnull,
                              mJSAttributes)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
--- a/content/xml/document/src/nsXMLFragmentContentSink.cpp
+++ b/content/xml/document/src/nsXMLFragmentContentSink.cpp
@@ -97,17 +97,18 @@ public:
   NS_IMETHOD DidBuildModel();
   NS_IMETHOD SetDocumentCharset(nsACString& aCharset);
   virtual nsISupports *GetTarget();
   NS_IMETHOD DidProcessATokenImpl();
 
   // nsIXMLContentSink
 
   // nsIFragmentContentSink
-  NS_IMETHOD GetFragment(nsIDOMDocumentFragment** aFragment);
+  NS_IMETHOD GetFragment(PRBool aWillOwnFragment,
+                         nsIDOMDocumentFragment** aFragment);
   NS_IMETHOD SetTargetDocument(nsIDocument* aDocument);
   NS_IMETHOD WillBuildContent();
   NS_IMETHOD DidBuildContent();
   NS_IMETHOD IgnoreFirstContainer();
 
 protected:
   virtual PRBool SetDocElement(PRInt32 aNameSpaceID, 
                                nsIAtom *aTagName,
@@ -395,24 +396,29 @@ void
 nsXMLFragmentContentSink::StartLayout()
 {
   NS_NOTREACHED("fragments shouldn't layout");
 }
 
 ////////////////////////////////////////////////////////////////////////
 
 NS_IMETHODIMP 
-nsXMLFragmentContentSink::GetFragment(nsIDOMDocumentFragment** aFragment)
+nsXMLFragmentContentSink::GetFragment(PRBool aWillOwnFragment,
+                                      nsIDOMDocumentFragment** aFragment)
 {
   *aFragment = nsnull;
   if (mParseError) {
     //XXX PARSE_ERR from DOM3 Load and Save would be more appropriate
     return NS_ERROR_DOM_SYNTAX_ERR;
   } else if (mRoot) {
-    return CallQueryInterface(mRoot, aFragment);
+    nsresult rv = CallQueryInterface(mRoot, aFragment);
+    if (NS_SUCCEEDED(rv) && aWillOwnFragment) {
+      mRoot = nsnull;
+    }
+    return rv;
   } else {
     return NS_OK;
   }
 }
 
 NS_IMETHODIMP
 nsXMLFragmentContentSink::SetTargetDocument(nsIDocument* aTargetDocument)
 {
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -548,47 +548,87 @@ nsXULElement::GetEventListenerManagerFor
     return nsGenericElement::GetEventListenerManagerForAttr(aManager,
                                                             aTarget,
                                                             aDefer);
 }
 
 PRBool
 nsXULElement::IsFocusable(PRInt32 *aTabIndex)
 {
-  // Use incoming tabindex as default value
-  PRInt32 tabIndex = aTabIndex? *aTabIndex : -1;
-  PRBool disabled = tabIndex < 0;
+  /* 
+   * Returns true if an element may be focused, and false otherwise. The inout
+   * argument aTabIndex will be set to the tab order index to be used; -1 for
+   * elements that should not be part of the tab order and a greater value to
+   * indicate its tab order.
+   *
+   * Confusingly, the supplied value for the aTabIndex argument may indicate
+   * whether the element may be focused as a result of the -moz-user-focus
+   * property.
+   *
+   * For controls, the element cannot be focused and is not part of the tab
+   * order if it is disabled.
+   *
+   * Controls (those that implement nsIDOMXULControlElement):
+   *  *aTabIndex = -1  no tabindex     Not focusable or tabbable
+   *  *aTabIndex = -1  tabindex="-1"   Not focusable or tabbable
+   *  *aTabIndex = -1  tabindex=">=0"  Focusable and tabbable
+   *  *aTabIndex >= 0  no tabindex     Focusable and tabbable
+   *  *aTabIndex >= 0  tabindex="-1"   Focusable but not tabbable
+   *  *aTabIndex >= 0  tabindex=">=0"  Focusable and tabbable
+   * Non-controls:
+   *  *aTabIndex = -1                  Not focusable or tabbable
+   *  *aTabIndex >= 0                  Focusable and tabbable
+   *
+   * If aTabIndex is null, then the tabindex is not computed, and
+   * true is returned for non-disabled controls and false otherwise.
+   */
+
+  // elements are not focusable by default
+  PRBool shouldFocus = PR_FALSE;
+
   nsCOMPtr<nsIDOMXULControlElement> xulControl = 
     do_QueryInterface(static_cast<nsIContent*>(this));
   if (xulControl) {
+    // a disabled element cannot be focused and is not part of the tab order
+    PRBool disabled;
     xulControl->GetDisabled(&disabled);
     if (disabled) {
-      tabIndex = -1;  // Can't tab to disabled elements
+      if (aTabIndex)
+        *aTabIndex = -1;
+      return PR_FALSE;
     }
-    else if (HasAttr(kNameSpaceID_None, nsGkAtoms::tabindex)) {
-      // If attribute not set, will use default value passed in
+    shouldFocus = PR_TRUE;
+  }
+
+  if (aTabIndex) {
+    if (xulControl && HasAttr(kNameSpaceID_None, nsGkAtoms::tabindex)) {
+      // if either the aTabIndex argument or a specified tabindex is non-negative,
+      // the element becomes focusable.
+      PRInt32 tabIndex = 0;
       xulControl->GetTabIndex(&tabIndex);
+      shouldFocus = *aTabIndex >= 0 || tabIndex >= 0;
+      *aTabIndex = tabIndex;
     }
-    if (tabIndex != -1 && sTabFocusModelAppliesToXUL &&
+    else {
+      shouldFocus = *aTabIndex >= 0;
+    }
+
+    if (shouldFocus && sTabFocusModelAppliesToXUL &&
         !(sTabFocusModel & eTabFocus_formElementsMask)) {
       // By default, the tab focus model doesn't apply to xul element on any system but OS X.
       // on OS X we're following it for UI elements (XUL) as sTabFocusModel is based on
       // "Full Keyboard Access" system setting (see mac/nsILookAndFeel).
       // both textboxes and list elements (i.e. trees and list) should always be focusable
       // (textboxes are handled as html:input)
       if (!mNodeInfo->Equals(nsGkAtoms::tree) && !mNodeInfo->Equals(nsGkAtoms::listbox))
-        tabIndex = -1; 
+        *aTabIndex = -1; 
     }
   }
 
-  if (aTabIndex) {
-    *aTabIndex = tabIndex;
-  }
-
-  return tabIndex >= 0 || (!disabled && HasAttr(kNameSpaceID_None, nsGkAtoms::tabindex));
+  return shouldFocus;
 }
 
 void
 nsXULElement::PerformAccesskey(PRBool aKeyCausesActivation,
                                PRBool aIsTrustedEvent)
 {
     nsCOMPtr<nsIContent> content(this);
 
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -340,18 +340,19 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
                                                      nsIScriptGlobalObjectOwner)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mCommandDispatcher,
                                                      nsIDOMXULCommandDispatcher)
 
     PRUint32 i, count = tmp->mPrototypes.Length();
     for (i = 0; i < count; ++i) {
         cb.NoteXPCOMChild(static_cast<nsIScriptGlobalObjectOwner*>(tmp->mPrototypes[i]));
     }
-    
+
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTooltipNode)
+    NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mLocalStore)
 
     if (tmp->mOverlayLoadObservers.IsInitialized())
         tmp->mOverlayLoadObservers.EnumerateRead(TraverseObservers, &cb);
     if (tmp->mPendingOverlayLoadNotifications.IsInitialized())
         tmp->mPendingOverlayLoadNotifications.EnumerateRead(TraverseObservers, &cb);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_ADDREF_INHERITED(nsXULDocument, nsXMLDocument)
@@ -2756,16 +2757,17 @@ nsXULDocument::ResumeWalk()
     // is, a parent is built before any of its children; a node is
     // only built after all of its siblings to the left are fully
     // constructed.
     //
     // It is interruptable so that transcluded documents (e.g.,
     // <html:script src="..." />) can be properly re-loaded if the
     // cached copy of the document becomes stale.
     nsresult rv;
+    nsCOMPtr<nsIURI> overlayURI = mCurrentPrototype->GetURI();
 
     while (1) {
         // Begin (or resume) walking the current prototype.
 
         while (mContextStack.Depth() > 0) {
             // Look at the top of the stack to determine what we're
             // currently working on.
             // This will always be a node already constructed and
@@ -2944,18 +2946,16 @@ nsXULDocument::ResumeWalk()
                 // <?xul-overlay?> and <?xml-stylesheet?> don't have effect
                 // outside the prolog, like they used to. Issue a warning.
 
                 if (piProto->mTarget.EqualsLiteral("xml-stylesheet") ||
                     piProto->mTarget.EqualsLiteral("xul-overlay")) {
 
                     const PRUnichar* params[] = { piProto->mTarget.get() };
 
-                    nsCOMPtr<nsIURI> overlayURI = mCurrentPrototype->GetURI();
-
                     nsContentUtils::ReportToConsole(
                                         nsContentUtils::eXUL_PROPERTIES,
                                         "PINotInProlog",
                                         params, NS_ARRAY_LENGTH(params),
                                         overlayURI,
                                         EmptyString(), /* source line */
                                         0, /* line number */
                                         0, /* column number */
@@ -3000,18 +3000,31 @@ nsXULDocument::ResumeWalk()
                                  &failureFromContent);
         if (failureFromContent)
             // The failure |rv| was the result of a problem in the content
             // rather than an unexpected problem in our implementation, so
             // just continue with the next overlay.
             continue;
         if (NS_FAILED(rv))
             return rv;
+        if (mOverlayLoadObservers.IsInitialized()) {
+            nsIObserver *obs = mOverlayLoadObservers.GetWeak(overlayURI);
+            if (obs) {
+                // This overlay has an unloaded overlay, so it will never
+                // notify. The best we can do is to notify for the unloaded
+                // overlay instead, assuming nobody is already notifiable
+                // for it. Note that this will confuse the observer.
+                if (!mOverlayLoadObservers.GetWeak(uri))
+                    mOverlayLoadObservers.Put(uri, obs);
+                mOverlayLoadObservers.Remove(overlayURI);
+            }
+        }
         if (shouldReturn)
             return NS_OK;
+        overlayURI.swap(uri);
     }
 
     // If we get here, there is nothing left for us to walk. The content
     // model is built and ready for layout.
     rv = ResolveForwardReferences();
     if (NS_FAILED(rv)) return rv;
 
     rv = ApplyPersistentAttributes();
--- a/docshell/shistory/src/nsSHistory.cpp
+++ b/docshell/shistory/src/nsSHistory.cpp
@@ -782,16 +782,21 @@ nsSHistory::EvictWindowContentViewers(PR
   // We make the assumption that entries outside this range have no viewers so
   // that we don't have to walk the whole entire session history checking for
   // content viewers.
 
   // This can happen on the first load of a page in a particular window
   if (aFromIndex < 0 || aToIndex < 0) {
     return;
   }
+  NS_ASSERTION(aFromIndex < mLength, "aFromIndex is out of range");
+  NS_ASSERTION(aToIndex < mLength, "aToIndex is out of range");
+  if (aFromIndex >= mLength || aToIndex >= mLength) {
+    return;
+  }
 
   // These indices give the range of SHEntries whose content viewers will be
   // evicted
   PRInt32 startIndex, endIndex;
   if (aToIndex > aFromIndex) { // going forward
     endIndex = aToIndex - gHistoryMaxViewers;
     if (endIndex <= 0) {
       return;
--- a/docshell/test/chrome/Makefile.in
+++ b/docshell/test/chrome/Makefile.in
@@ -41,12 +41,14 @@ VPATH		= @srcdir@
 relativesrcdir	= docshell/test/chrome 
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES =	\
 		test_bug364461.xul \
 		bug364461_window.xul \
+		test_bug396519.xul \
+		bug396519_window.xul \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/docshell/test/chrome/bug396519_window.xul
@@ -0,0 +1,182 @@
+<?xml version="1.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 bug 364461 mochitest
+   -
+   - The Initial Developer of the Original Code is
+   - Sylvain Pasche <sylvain.pasche@gmail.com>.
+   - Portions created by the Initial Developer are Copyright (C) 2007
+   - the Initial Developer. All Rights Reserved.
+   -
+   - Contributor(s):
+   -   Andrew Schultz <ajschult@verizon.net>
+   -
+   - Alternatively, the contents of this file may be used under the terms of
+   - either the GNU General Public License Version 2 or later (the "GPL"), or
+   - 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 LGPL or the GPL. 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 ***** -->
+
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+
+<window id="396519Test"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        width="600"
+        height="600"
+        onload="onLoad();"
+        title="396519 test">
+
+  <script type="application/javascript"><![CDATA[
+
+    const LISTEN_EVENTS = ["pageshow"];
+
+    var gBrowser;
+    var gTestCount = 0;
+    var gTestsIterator;
+    var gExpected = [];
+
+    function ok(condition, message) {
+      window.opener.wrappedJSObject.SimpleTest.ok(condition, message);
+    }
+    function is(a, b, message) {
+      window.opener.wrappedJSObject.SimpleTest.is(a, b, message);
+    }
+    function finish() {
+      for each (let eventType in LISTEN_EVENTS) {
+        gBrowser.removeEventListener(eventType, eventListener, true);
+      }
+    
+      window.close();
+      window.opener.wrappedJSObject.SimpleTest.finish();
+    }
+
+    function onLoad() {
+      gBrowser = document.getElementById("content");
+
+      for each (let eventType in LISTEN_EVENTS) {
+        gBrowser.addEventListener(eventType, eventListener, true);
+      }
+      
+      gTestsIterator = testsIterator();
+      nextTest();
+    }
+
+    function eventListener(event) {
+      // we're in pageshow, but we need to let that finish
+      // content eviction and saving happen during pageshow, so when doTest
+      // runs, we should should be in a testable state
+      setTimeout(doTest, 0);
+    }
+
+    function doTest() {
+      var history = gBrowser.webNavigation.sessionHistory;
+      if (history.count == gExpected.length) {
+        for (var i=0; i<history.count; i++) {
+          var shEntry = history.getEntryAtIndex(i,false).
+                          QueryInterface(Components.interfaces.nsISHEntry);
+          is(!!shEntry.contentViewer, gExpected[i], "content viewer "+i+", test "+gTestCount);
+        }
+      }
+      else {
+        is(history.count, gExpected.length, "Wrong history length in test "+gTestCount);
+      }
+
+      setTimeout(nextTest, 0);
+    }
+
+    function nextTest() {
+      try {
+        gTestsIterator.next();
+      } catch (err if err instanceof StopIteration) {
+        finish();
+      }
+    }
+
+    function testsIterator() {
+
+      // Tests 1 + 2:
+      //  Back/forward between two simple documents. Bfcache will be used.
+
+      var test1Doc = "data:text/html,<html><head><title>test1</title></head>" +
+                     "<body>test1</body></html>";
+
+      gTestCount++;
+      gExpected = [false];
+      gBrowser.loadURI(test1Doc);
+      yield;
+
+      gTestCount++;
+      gExpected = [true, false];
+      var test2Doc = test1Doc.replace(/1/,"2");
+      gBrowser.loadURI(test2Doc);
+      yield;
+
+      gTestCount++;
+      gExpected = [true, true, false];
+      gBrowser.loadURI(test1Doc);
+      yield;
+
+      gTestCount++;
+      gExpected = [true, true, true, false];
+      gBrowser.loadURI(test2Doc);
+      yield;
+
+      gTestCount++;
+      gExpected = [false, true, true, true, false];
+      gBrowser.loadURI(test1Doc);
+      yield;
+
+      gTestCount++;
+      gExpected = [false, false, true, true, true, false];
+      gBrowser.loadURI(test2Doc);
+      yield;
+
+      gTestCount++;
+      gExpected = [false, false, true, true, false, true];
+      gBrowser.goBack();
+      yield;
+
+      gTestCount++;
+      gExpected = [false, false, true, true, true, false];
+      gBrowser.goForward();
+      yield;
+
+      gTestCount++;
+      gExpected = [false, false, true, true, true, false];
+      gBrowser.gotoIndex(1);
+      yield;
+
+      gTestCount++;
+      gExpected = [false, true, true, true, false, false];
+      gBrowser.goBack();
+      yield;
+
+      gTestCount++;
+      gExpected = [false, false, true, true, false, false];
+      gBrowser.gotoIndex(5);
+      yield;
+    }
+  ]]></script>
+
+  <browser type="content-primary" flex="1" id="content" src="about:blank"/>
+</window>
new file mode 100644
--- /dev/null
+++ b/docshell/test/chrome/test_bug396519.xul
@@ -0,0 +1,31 @@
+<?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"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=396519
+-->
+<window title="Mozilla Bug 396519"
+  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>
+
+  <!-- test resuls are displayed in the html:body -->
+  <body xmlns="http://www.w3.org/1999/xhtml">
+  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=396519"
+     target="_blank">Mozilla Bug 396519</a>
+  </body>
+
+  <!-- test code goes here -->
+  <script type="application/javascript"><![CDATA[
+
+    /** Test for Bug 396519 **/
+
+    SimpleTest.waitForExplicitFinish();
+    window.open("bug396519_window.xul", "bug396519",
+                "chrome,width=600,height=600");
+
+  ]]></script>
+</window>
--- a/dom/locales/en-US/chrome/layout/css.properties
+++ b/dom/locales/en-US/chrome/layout/css.properties
@@ -92,16 +92,17 @@ PEPseudoSelTrailing=Found trailing token
 PEPseudoSelMultiplePE=Extra pseudo-element '%1$S'.
 PEPseudoSelUnknown=Unknown pseudo-class or pseudo-element '%1$S'.
 PENegationEOF=selector within negation
 PENegationBadInner=Malformed simple selector as negation pseudo-class argument '%1$S'.
 PENegationNoClose=Missing closing ')' in negation pseudo-class '%1$S'.
 PENegationBadArg=Missing argument in negation pseudo-class '%1$S'.
 PEPseudoClassArgEOF=argument to pseudo-class selector
 PEPseudoClassArgNotIdent=Expected identifier for pseudo-class parameter but found '%1$S'.
+PEPseudoClassArgNotNth=Expected part of argument to pseudo-class but found '%1$S'.
 PEPseudoClassNoClose=Missing closing ')' in pseudo-class, found '%1$S' instead.
 PEPseudoClassNoArg=Missing argument in pseudo-class '%1$S'.
 PESelectorEOF=selector
 PEBadDeclBlockStart=Expected '{' to begin declaration block but found '%1$S'.
 PEColorEOF=color
 PEColorNotColor=Expected color but found '%1$S'.
 PEColorComponentEOF=color component
 PEExpectedPercent=Expected a percentage but found '%1$S'.
--- a/dom/src/base/nsDOMClassInfo.cpp
+++ b/dom/src/base/nsDOMClassInfo.cpp
@@ -491,16 +491,17 @@ static const char kDOMStringBundleURL[] 
    nsIXPCScriptable::WANT_SETPROPERTY |                                       \
    nsIXPCScriptable::WANT_CALL)
 
 #define DOCUMENT_SCRIPTABLE_FLAGS                                             \
   (NODE_SCRIPTABLE_FLAGS |                                                    \
    nsIXPCScriptable::WANT_ADDPROPERTY |                                       \
    nsIXPCScriptable::WANT_DELPROPERTY |                                       \
    nsIXPCScriptable::WANT_GETPROPERTY |                                       \
+   nsIXPCScriptable::WANT_ENUMERATE   |                                       \
    nsIXPCScriptable::WANT_POSTCREATE  |                                       \
    nsIXPCScriptable::WANT_FINALIZE)
 
 #define ARRAY_SCRIPTABLE_FLAGS                                                \
   (DOM_DEFAULT_SCRIPTABLE_FLAGS       |                                       \
    nsIXPCScriptable::WANT_GETPROPERTY |                                       \
    nsIXPCScriptable::WANT_ENUMERATE)
 
@@ -588,18 +589,17 @@ static nsDOMClassInfoData sClassInfoData
                            DOM_BASE_SCRIPTABLE_FLAGS |
                            nsIXPCScriptable::WANT_HASINSTANCE |
                            nsIXPCScriptable::WANT_CALL |
                            nsIXPCScriptable::WANT_CONSTRUCT |
                            nsIXPCScriptable::DONT_ENUM_QUERY_INTERFACE)
 
   // Core classes
   NS_DEFINE_CLASSINFO_DATA(XMLDocument, nsDocumentSH,
-                           DOCUMENT_SCRIPTABLE_FLAGS |
-                           nsIXPCScriptable::WANT_ENUMERATE)
+                           DOCUMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(DocumentType, nsNodeSH,
                            NODE_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(DOMImplementation, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(DOMException, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(DocumentFragment, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
@@ -637,18 +637,17 @@ static nsDOMClassInfoData sClassInfoData
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(KeyboardEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(PopupBlockedEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   // Misc HTML classes
   NS_DEFINE_CLASSINFO_DATA(HTMLDocument, nsHTMLDocumentSH,
-                           DOCUMENT_SCRIPTABLE_FLAGS |
-                           nsIXPCScriptable::WANT_ENUMERATE)
+                           DOCUMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLOptionsCollection,
                            nsHTMLOptionsCollectionSH,
                            ARRAY_SCRIPTABLE_FLAGS |
                            nsIXPCScriptable::WANT_SETPROPERTY)
   NS_DEFINE_CLASSINFO_DATA_WITH_NAME(HTMLFormControlCollection, HTMLCollection,
                                      nsFormControlListSH,
                                      ARRAY_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA_WITH_NAME(HTMLGenericCollection, HTMLCollection,
@@ -808,18 +807,17 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(Range, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(Selection, nsDOMGenericSH,
                            DEFAULT_SCRIPTABLE_FLAGS)
 
   // XUL classes
 #ifdef MOZ_XUL
   NS_DEFINE_CLASSINFO_DATA(XULDocument, nsDocumentSH,
-                           DOCUMENT_SCRIPTABLE_FLAGS |
-                           nsIXPCScriptable::WANT_ENUMERATE)
+                           DOCUMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(XULElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(XULCommandDispatcher, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 #endif
   NS_DEFINE_CLASSINFO_DATA(XULControllers, nsNonDOMObjectSH,
                            DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(BoxObject, nsDOMGenericSH,
@@ -867,18 +865,17 @@ static nsDOMClassInfoData sClassInfoData
                                      nsContentListSH,
                                      ARRAY_SCRIPTABLE_FLAGS |
                                      nsIXPCScriptable::WANT_PRECREATE)
 
   NS_DEFINE_CLASSINFO_DATA(XMLStylesheetProcessingInstruction, nsNodeSH,
                            NODE_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(ImageDocument, nsHTMLDocumentSH,
-                           DOCUMENT_SCRIPTABLE_FLAGS |
-                           nsIXPCScriptable::WANT_ENUMERATE)
+                           DOCUMENT_SCRIPTABLE_FLAGS)
 
 #ifdef MOZ_XUL
   NS_DEFINE_CLASSINFO_DATA(XULTemplateBuilder, nsDOMGenericSH,
                            DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(XULTreeBuilder, nsDOMGenericSH,
                            DEFAULT_SCRIPTABLE_FLAGS)
 #endif
@@ -3735,28 +3732,30 @@ nsDOMClassInfo::SetProperty(nsIXPConnect
 
   return NS_ERROR_UNEXPECTED;
 }
 
 NS_IMETHODIMP
 nsDOMClassInfo::Enumerate(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                           JSObject *obj, PRBool *_retval)
 {
-  if (!sSecMan)
+#ifdef DEBUG
+  if (!sSecMan) {
+    NS_ERROR("No security manager!!!");
     return NS_OK;
+  }
 
   // Ask the security manager if it's OK to enumerate
   nsresult rv =
     sSecMan->CheckPropertyAccess(cx, obj, mData->mName, sEnumerate_id,
                                  nsIXPCSecurityManager::ACCESS_GET_PROPERTY);
 
-  if (NS_FAILED(rv)) {
-    // Let XPConnect know that the access was not granted.
-    *_retval = PR_FALSE;
-  }
+  NS_ASSERTION(NS_SUCCEEDED(rv),
+               "XOWs should have stopped us from getting here!!!");
+#endif
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMClassInfo::NewEnumerate(nsIXPConnectWrappedNative *wrapper,
                              JSContext *cx, JSObject *obj, PRUint32 enum_op,
                              jsval *statep, jsid *idp, PRBool *_retval)
--- a/dom/src/base/nsGlobalWindow.cpp
+++ b/dom/src/base/nsGlobalWindow.cpp
@@ -655,17 +655,17 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalW
   // to create the entropy collector, so we should
   // try to get one until we succeed.
   if (gRefCnt++ == 0 || !gEntropyCollector) {
     CallGetService(NS_ENTROPYCOLLECTOR_CONTRACTID, &gEntropyCollector);
   }
 #ifdef DEBUG
   printf("++DOMWINDOW == %d (%p) [serial = %d] [Outer = %p]\n", gRefCnt,
          static_cast<void*>(static_cast<nsIScriptGlobalObject*>(this)),
-         ++gSerialCounter, aOuterWindow);
+         ++gSerialCounter, static_cast<void*>(aOuterWindow));
   mSerial = gSerialCounter;
 #endif
 
 #ifdef PR_LOGGING
   if (!gDOMLeakPRLog)
     gDOMLeakPRLog = PR_NewLogModule("DOMLeak");
 
   if (gDOMLeakPRLog)
@@ -677,17 +677,17 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalW
 nsGlobalWindow::~nsGlobalWindow()
 {
   if (!--gRefCnt) {
     NS_IF_RELEASE(gEntropyCollector);
   }
 #ifdef DEBUG
   printf("--DOMWINDOW == %d (%p) [serial = %d] [Outer = %p]\n",
          gRefCnt, static_cast<void*>(static_cast<nsIScriptGlobalObject*>(this)),
-         mSerial, mOuterWindow);
+         mSerial, static_cast<void*>(mOuterWindow));
 #endif
 
 #ifdef PR_LOGGING
   if (gDOMLeakPRLog)
     PR_LOG(gDOMLeakPRLog, PR_LOG_DEBUG,
            ("DOMWINDOW %p destroyed", this));
 #endif
 
@@ -9023,16 +9023,26 @@ nsNavigator::GetPlatform(nsAString& aPla
   }
 
   return rv;
 }
 
 NS_IMETHODIMP
 nsNavigator::GetOscpu(nsAString& aOSCPU)
 {
+  if (!nsContentUtils::IsCallerTrustedForRead()) {
+    const nsAdoptingCString& override =
+      nsContentUtils::GetCharPref("general.oscpu.override");
+
+    if (override) {
+      CopyUTF8toUTF16(override, aOSCPU);
+      return NS_OK;
+    }
+  }
+
   nsresult rv;
   nsCOMPtr<nsIHttpProtocolHandler>
     service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
   if (NS_SUCCEEDED(rv)) {
     nsCAutoString oscpu;
     rv = service->GetOscpu(oscpu);
     CopyASCIItoUTF16(oscpu, aOSCPU);
   }
@@ -9084,16 +9094,35 @@ nsNavigator::GetProduct(nsAString& aProd
   }
 
   return rv;
 }
 
 NS_IMETHODIMP
 nsNavigator::GetProductSub(nsAString& aProductSub)
 {
+  if (!nsContentUtils::IsCallerTrustedForRead()) {
+    const nsAdoptingCString& override =
+      nsContentUtils::GetCharPref("general.productSub.override");
+
+    if (override) {
+      CopyUTF8toUTF16(override, aProductSub);
+      return NS_OK;
+    } else {
+      // 'general.useragent.productSub' backwards compatible with 1.8 branch.
+      const nsAdoptingCString& override2 =
+        nsContentUtils::GetCharPref("general.useragent.productSub");
+
+      if (override2) {
+        CopyUTF8toUTF16(override2, aProductSub);
+        return NS_OK;
+      }
+    }
+  }
+
   nsresult rv;
   nsCOMPtr<nsIHttpProtocolHandler>
     service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
   if (NS_SUCCEEDED(rv)) {
     nsCAutoString productSub;
     rv = service->GetProductSub(productSub);
     CopyASCIItoUTF16(productSub, aProductSub);
   }
@@ -9159,16 +9188,26 @@ nsNavigator::GetOnLine(PRBool* aOnline)
   
   *aOnline = !NS_IsOffline();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsNavigator::GetBuildID(nsAString& aBuildID)
 {
+  if (!nsContentUtils::IsCallerTrustedForRead()) {
+    const nsAdoptingCString& override =
+      nsContentUtils::GetCharPref("general.buildID.override");
+
+    if (override) {
+      CopyUTF8toUTF16(override, aBuildID);
+      return NS_OK;
+    }
+  }
+
   nsCOMPtr<nsIXULAppInfo> appInfo =
     do_GetService("@mozilla.org/xre/app-info;1");
   if (!appInfo)
     return NS_ERROR_NOT_IMPLEMENTED;
 
   nsCAutoString buildID;
   nsresult rv = appInfo->GetAppBuildID(buildID);
   if (NS_FAILED(rv))
--- a/dom/src/base/nsJSTimeoutHandler.cpp
+++ b/dom/src/base/nsJSTimeoutHandler.cpp
@@ -249,27 +249,22 @@ nsJSScriptTimeoutHandler::Init(nsGlobalW
 
   if (expr) {
     rv = NS_HOLD_JS_OBJECTS(this, nsJSScriptTimeoutHandler);
     NS_ENSURE_SUCCESS(rv, rv);
 
     mExpr = expr;
 
     nsIPrincipal *prin = aWindow->GetPrincipal();
-    JSPrincipals *jsprins;
-    rv = prin->GetJSPrincipals(cx, &jsprins);
-    NS_ENSURE_SUCCESS(rv, rv);
 
     // Get the calling location.
     const char *filename;
-    if (nsJSUtils::GetCallingLocation(cx, &filename, &mLineNo, jsprins)) {
+    if (nsJSUtils::GetCallingLocation(cx, &filename, &mLineNo, prin)) {
       mFileName.Assign(filename);
     }
-
-    JSPRINCIPALS_DROP(cx, jsprins);
   } else if (funobj) {
     rv = NS_HOLD_JS_OBJECTS(this, nsJSScriptTimeoutHandler);
     NS_ENSURE_SUCCESS(rv, rv);
 
     mFunObj = funobj;
 
     // Create our arg array - leave an extra slot for a secret final argument
     // that indicates to the called function how "late" the timeout is.  We
--- a/dom/src/base/nsJSUtils.cpp
+++ b/dom/src/base/nsJSUtils.cpp
@@ -57,58 +57,50 @@
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
 #include "nsIScriptSecurityManager.h"
 
 #include "nsDOMJSUtils.h" // for GetScriptContextFromJSContext
 
 JSBool
 nsJSUtils::GetCallingLocation(JSContext* aContext, const char* *aFilename,
-                              PRUint32* aLineno, JSPrincipals* aPrincipals)
+                              PRUint32* aLineno, nsIPrincipal* aPrincipal)
 {
   // Get the current filename and line number
   JSStackFrame* frame = nsnull;
   JSScript* script = nsnull;
   do {
     frame = ::JS_FrameIterator(aContext, &frame);
 
     if (frame) {
       script = ::JS_GetFrameScript(aContext, frame);
     }
   } while (frame && !script);
 
   if (script) {
     // If aPrincipals is non-null then our caller is asking us to ensure
     // that the filename we return does not have elevated privileges.
-    if (aPrincipals) {
-      // The principals might not be in the script, but we can always
-      // find the right principals in the frame's callee.
-      JSPrincipals* scriptPrins = JS_GetScriptPrincipals(aContext, script);
-      if (!scriptPrins) {
-        JSObject *callee = JS_GetFrameCalleeObject(aContext, frame);
-        nsCOMPtr<nsIPrincipal> prin;
+    if (aPrincipal) {
+      uint32 flags = JS_GetScriptFilenameFlags(script);
+
+      // Use the principal for the filename if it shouldn't be receiving
+      // implicit XPCNativeWrappers.
+      PRBool system;
+      if (flags & JSFILENAME_PROTECTED) {
         nsIScriptSecurityManager *ssm = nsContentUtils::GetSecurityManager();
-        if (NS_FAILED(ssm->GetObjectPrincipal(aContext, callee,
-                                              getter_AddRefs(prin))) ||
-            !prin) {
-          return JS_FALSE;
+
+        if (NS_FAILED(ssm->IsSystemPrincipal(aPrincipal, &system)) || !system) {
+          JSPrincipals* jsprins;
+          aPrincipal->GetJSPrincipals(aContext, &jsprins);
+
+          *aFilename = jsprins->codebase;
+          *aLineno = 0;
+          JSPRINCIPALS_DROP(aContext, jsprins);
+          return JS_TRUE;
         }
-
-        prin->GetJSPrincipals(aContext, &scriptPrins);
-
-        // The script has a reference to the principals.
-        JSPRINCIPALS_DROP(aContext, scriptPrins);
-      }
-
-      // Return the weaker of the two principals if they differ.
-      if (scriptPrins != aPrincipals &&
-          scriptPrins->subsume(scriptPrins, aPrincipals)) {
-        *aFilename = aPrincipals->codebase;
-        *aLineno = 0;
-        return JS_TRUE;
       }
     }
 
     const char* filename = ::JS_GetScriptFilename(aContext, script);
 
     if (filename) {
       PRUint32 lineno = 0;
       jsbytecode* bytecode = ::JS_GetFramePC(aContext, frame);
--- a/dom/src/base/nsJSUtils.h
+++ b/dom/src/base/nsJSUtils.h
@@ -47,22 +47,23 @@
 
 #include "nsISupports.h"
 #include "jsapi.h"
 #include "nsString.h"
 
 class nsIDOMEventListener;
 class nsIScriptContext;
 class nsIScriptGlobalObject;
+class nsIPrincipal;
 
 class nsJSUtils
 {
 public:
   static JSBool GetCallingLocation(JSContext* aContext, const char* *aFilename,
-                                   PRUint32* aLineno, JSPrincipals* aPrincipals);
+                                   PRUint32* aLineno, nsIPrincipal* aPrincipal);
 
   static jsval ConvertStringToJSVal(const nsString& aProp,
                                     JSContext* aContext);
 
   static void ConvertJSValToString(nsAString& aString,
                                    JSContext* aContext, jsval aValue);
 
   static PRBool ConvertJSValToUint32(PRUint32* aProp, JSContext* aContext,
--- a/dom/tests/mochitest/whatwg/test_postMessage_closed.html
+++ b/dom/tests/mochitest/whatwg/test_postMessage_closed.html
@@ -59,15 +59,20 @@ function iframeLoaded(evt)
   SimpleTest.finish();
 }
 
 var openedWindow;
 
 function run()
 {
   openedWindow = window.open("postMessage_closed_helper.html?opener", "foobar");
+  if (!openedWindow)
+  {
+    ok(false, "this test must be run with popup blocking disabled");
+    SimpleTest.finish();
+  }
 }
 
 window.addEventListener("load", run, false);
 </script>
 </pre>
 </body>
 </html>
--- a/dom/tests/mochitest/whatwg/test_postMessage_special.xhtml
+++ b/dom/tests/mochitest/whatwg/test_postMessage_special.xhtml
@@ -138,35 +138,22 @@ function messageReceiver(evt)
     {
       is(evt.origin, "http://localhost:8888",
          "wrong origin for event from about:blank #2");
       is(evt.source, aboutBlank2Window, "wrong source");
       aboutBlank2ResponseReceived = true;
     }
     else if (evt.data === "data-response")
     {
-      // Again, HTML5 hasn't yet defined this, but we're going to do the same
-      // thing as with about:blank -- for a data: URL opened from page A, the
-      // uri and domain properties correspond to those of page A.  This happens
-      // to fall out naturally from using the window's security principal to
-      // determine these two properties.
-      //
-      // Mozilla currently gives data: URLs the principal of the opener/parent
-      // window, and at least for now we'll test for that behavior.  If we ever
-      // change how data: URLs are given principals, we can update this test
-      // then.
-      if (isMozilla)
-      {
-        is(evt.origin, "http://localhost:8888",
-           "wrong origin for event from data URL (but note that this URI is " +
-           "the result of Mozilla's current policy that data: URLs inherit " +
-           "the principal of their opener/parent, a policy not currently " +
-           "specified by any standards)");
-      }
-
+      // HTML5 defines the origin of a data: URI as the origin of the window or
+      // script that opened the data: URI.
+      is(evt.origin, "http://localhost:8888",
+         "wrong origin for event from data URL (should be the origin of the " +
+         "window/script that opened the URL, in this case the origin of this " +
+         "file)");
       is(evt.source, dataWindow, "wrong source");
       dataResponseReceived = true;
     }
     else
     {
       ok(false, "unexpected message: " + evt.data);
     }
   }
--- a/editor/libeditor/html/nsHTMLDataTransfer.cpp
+++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp
@@ -2638,17 +2638,17 @@ nsresult nsHTMLEditor::ParseFragment(con
   // parse the fragment
   parser->SetContentSink(sink);
   if (bContext)
     parser->Parse(aFragStr, (void*)0, NS_LITERAL_CSTRING("text/html"), PR_TRUE, eDTDMode_fragment);
   else
     parser->ParseFragment(aFragStr, 0, aTagStack, PR_FALSE, NS_LITERAL_CSTRING("text/html"), eDTDMode_quirks);
   // get the fragment node
   nsCOMPtr<nsIDOMDocumentFragment> contextfrag;
-  res = fragSink->GetFragment(getter_AddRefs(contextfrag));
+  res = fragSink->GetFragment(PR_TRUE, getter_AddRefs(contextfrag));
   NS_ENSURE_SUCCESS(res, res);
   *outNode = do_QueryInterface(contextfrag);
   
   return res;
 }
 
 nsresult nsHTMLEditor::CreateTagStack(nsTArray<nsAutoString> &aTagStack, nsIDOMNode *aNode)
 {
--- a/embedding/browser/gtk/tests/TestGtkEmbed.cpp
+++ b/embedding/browser/gtk/tests/TestGtkEmbed.cpp
@@ -41,27 +41,33 @@
 #include <string.h>
 #include <stdlib.h>
 
 // mozilla specific headers
 #include "nsIDOMKeyEvent.h"
 #include "nsIDOMMouseEvent.h"
 #include "nsIDOMUIEvent.h"
 
+#include "nsCOMPtr.h"
+#include "nsISupportsUtils.h"
+#include "nsServiceManagerUtils.h"
+#include "nsIObserverService.h"
+
 #include "nsStringAPI.h"
 #include "gtkmozembed_glue.cpp"
 
 typedef struct _TestGtkBrowser {
   GtkWidget  *topLevelWindow;
   GtkWidget  *topLevelVBox;
   GtkWidget  *menuBar;
   GtkWidget  *fileMenuItem;
   GtkWidget  *fileMenu;
   GtkWidget  *fileOpenNewBrowser;
   GtkWidget  *fileStream;
+  GtkWidget  *fileMemory;
   GtkWidget  *fileClose;
   GtkWidget  *fileQuit;
   GtkWidget  *toolbarHBox;
   GtkWidget  *toolbar;
   GtkWidget  *backButton;
   GtkWidget  *stopButton;
   GtkWidget  *forwardButton;
   GtkWidget  *reloadButton;
@@ -102,16 +108,18 @@ static void     forward_clicked_cb (GtkB
 static void     reload_clicked_cb  (GtkButton   *button,
 				    TestGtkBrowser *browser);
 static void     url_activate_cb    (GtkEditable *widget, 
 				    TestGtkBrowser *browser);
 static void     menu_open_new_cb   (GtkMenuItem *menuitem,
 				    TestGtkBrowser *browser);
 static void     menu_stream_cb     (GtkMenuItem *menuitem,
 				    TestGtkBrowser *browser);
+static void     menu_memory_cb     (GtkMenuItem *menuitem,
+				    TestGtkBrowser *browser);
 static void     menu_close_cb      (GtkMenuItem *menuitem,
 				    TestGtkBrowser *browser);
 static void     menu_quit_cb       (GtkMenuItem *menuitem,
 				    TestGtkBrowser *browser);
 static gboolean delete_cb          (GtkWidget *widget, GdkEventAny *event,
 				    TestGtkBrowser *browser);
 static void     destroy_cb         (GtkWidget *widget,
 				    TestGtkBrowser *browser);
@@ -323,16 +331,21 @@ new_gtk_browser(guint32 chromeMask)
   gtk_menu_append(GTK_MENU(browser->fileMenu),
 		  browser->fileOpenNewBrowser);
   
   browser->fileStream =
     gtk_menu_item_new_with_label("Test Stream");
   gtk_menu_append(GTK_MENU(browser->fileMenu),
 		  browser->fileStream);
 
+  browser->fileMemory =
+    gtk_menu_item_new_with_label("Release Memory");
+  gtk_menu_append(GTK_MENU(browser->fileMenu),
+		  browser->fileMemory);
+
   browser->fileClose =
     gtk_menu_item_new_with_label("Close");
   gtk_menu_append(GTK_MENU(browser->fileMenu),
 		  browser->fileClose);
 
   browser->fileQuit =
     gtk_menu_item_new_with_label("Quit");
   gtk_menu_append(GTK_MENU(browser->fileMenu),
@@ -460,16 +473,19 @@ new_gtk_browser(guint32 chromeMask)
 		     GTK_SIGNAL_FUNC(url_activate_cb), browser);
 
   // hook up to the open new browser activation
   gtk_signal_connect(GTK_OBJECT(browser->fileOpenNewBrowser), "activate",
 		     GTK_SIGNAL_FUNC(menu_open_new_cb), browser);
   // hook up to the stream test
   gtk_signal_connect(GTK_OBJECT(browser->fileStream), "activate",
 		     GTK_SIGNAL_FUNC(menu_stream_cb), browser);
+  // hook up the memory pressure release function
+  gtk_signal_connect(GTK_OBJECT(browser->fileMemory), "activate",
+		     GTK_SIGNAL_FUNC(menu_memory_cb), browser);
   // close this window
   gtk_signal_connect(GTK_OBJECT(browser->fileClose), "activate",
 		     GTK_SIGNAL_FUNC(menu_close_cb), browser);
   // quit the application
   gtk_signal_connect(GTK_OBJECT(browser->fileQuit), "activate",
 		     GTK_SIGNAL_FUNC(menu_quit_cb), browser);
 
   // hook up the location change to update the urlEntry
@@ -668,16 +684,31 @@ menu_stream_cb     (GtkMenuItem *menuite
   gtk_moz_embed_append_data(GTK_MOZ_EMBED(browser->mozEmbed),
 			    data, strlen(data));
   gtk_moz_embed_append_data(GTK_MOZ_EMBED(browser->mozEmbed),
 			    data2, strlen(data2));
   gtk_moz_embed_close_stream(GTK_MOZ_EMBED(browser->mozEmbed));
 }
 
 void
+menu_memory_cb (GtkMenuItem *menuitem, TestGtkBrowser *browser)
+{
+  g_print("menu_memory_cb\n");
+  nsCOMPtr<nsIObserverService> os = do_GetService("@mozilla.org/observer-service;1");
+  if (!os)
+    return;
+
+  // Compact like you mean it.  We do this three times to give the
+  // cycle collector a chance to try and reclaim as much as we can.
+  os->NotifyObservers(nsnull, "memory-pressure", NS_LITERAL_STRING("heap-minimize").get());
+  os->NotifyObservers(nsnull, "memory-pressure", NS_LITERAL_STRING("heap-minimize").get());
+  os->NotifyObservers(nsnull, "memory-pressure", NS_LITERAL_STRING("heap-minimize").get());
+}
+
+void
 menu_close_cb (GtkMenuItem *menuitem, TestGtkBrowser *browser)
 {
   gtk_widget_destroy(browser->topLevelWindow);
 }
 
 void
 menu_quit_cb (GtkMenuItem *menuitem, TestGtkBrowser *browser)
 {
--- a/embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp
+++ b/embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp
@@ -476,20 +476,22 @@ NS_IMETHODIMP nsWebBrowserPersist::SaveD
     if (NS_SUCCEEDED(rv) && datapathAsURI)
     {
         rv = SaveGatheredURIs(fileAsURI);
     }
     else if (mProgressListener)
     {
         // tell the listener we're done
         mProgressListener->OnStateChange(nsnull, nsnull,
-                                         nsIWebProgressListener::STATE_START,
+                                         nsIWebProgressListener::STATE_START |
+                                         nsIWebProgressListener::STATE_IS_NETWORK,
                                          NS_OK);
         mProgressListener->OnStateChange(nsnull, nsnull,
-                                         nsIWebProgressListener::STATE_STOP,
+                                         nsIWebProgressListener::STATE_STOP |
+                                         nsIWebProgressListener::STATE_IS_NETWORK,
                                          rv);
     }
 
     return rv;
 }
 
 /* void cancel(nsresult aReason); */
 NS_IMETHODIMP nsWebBrowserPersist::Cancel(nsresult aReason)
@@ -1339,16 +1341,17 @@ nsresult nsWebBrowserPersist::SaveChanne
         // data and just ignore it.
         return NS_SUCCESS_DONT_FIXUP;
     }
     else if (NS_FAILED(rv))
     {
         // Opening failed, but do we care?
         if (mPersistFlags & PERSIST_FLAGS_FAIL_ON_BROKEN_LINKS)
         {
+            SendErrorStatusChange(PR_TRUE, rv, aChannel, aFile);
             EndDownload(NS_ERROR_FAILURE);
             return NS_ERROR_FAILURE;
         }
         return NS_SUCCESS_DONT_FIXUP;
     }
     else
     {
         // Add the output transport to the output map with the channel as the key
--- a/gfx/cairo/README
+++ b/gfx/cairo/README
@@ -26,8 +26,9 @@ win32-logical-font-scale.patch: set CAIR
 nonfatal-assertions.patch: Make assertions non-fatal
 
 buggy-repeat.patch: Unconditionally turn on buggy-repeat handling to bandaid bug 413583.
 
 ==== pixman patches ====
 
 endian.patch: include cairo-platform.h for endian macros
 
+pixman-fbFetchTransformed-backout.patch: back out bad pixman commit, see http://lists.cairographics.org/archives/cairo/2008-March/013294.html
--- a/gfx/cairo/libpixman/src/pixman-compose.c
+++ b/gfx/cairo/libpixman/src/pixman-compose.c
@@ -4187,18 +4187,18 @@ fbFetchTransformed(bits_image_t * pict, 
     pixman_vector_t v;
     pixman_vector_t unit;
     pixman_bool_t affine = TRUE;
 
     bits = pict->bits;
     stride = pict->rowstride;
 
     /* reference point is the center of the pixel */
-    v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1 / 2 - 1;
-    v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1 / 2 - 1;
+    v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1 / 2;
+    v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1 / 2;
     v.vector[2] = pixman_fixed_1;
 
     /* when using convolution filters one might get here without a transform */
     if (pict->common.transform)
     {
         if (!pixman_transform_point_3d (pict->common.transform, &v))
         {
             fbFinishAccess (pict->pDrawable);
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/pixman-fbFetchTransformed-backout.patch
@@ -0,0 +1,32 @@
+diff -NrpU12 mozilla-trunk.c81ad22ccb3f/gfx/cairo/libpixman/src/pixman-compose.c mozilla-trunk/gfx/cairo/libpixman/src/pixman-compose.c
+--- mozilla-trunk.c81ad22ccb3f/gfx/cairo/libpixman/src/pixman-compose.c	2008-03-07 16:22:34.000000000 +1300
++++ mozilla-trunk/gfx/cairo/libpixman/src/pixman-compose.c	2008-03-07 16:22:35.000000000 +1300
+@@ -4183,26 +4183,26 @@ static void
+ fbFetchTransformed(bits_image_t * pict, int x, int y, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
+ {
+     uint32_t     *bits;
+     int32_t    stride;
+     pixman_vector_t v;
+     pixman_vector_t unit;
+     pixman_bool_t affine = TRUE;
+ 
+     bits = pict->bits;
+     stride = pict->rowstride;
+ 
+     /* reference point is the center of the pixel */
+-    v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1 / 2 - 1;
+-    v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1 / 2 - 1;
++    v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1 / 2;
++    v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1 / 2;
+     v.vector[2] = pixman_fixed_1;
+ 
+     /* when using convolution filters one might get here without a transform */
+     if (pict->common.transform)
+     {
+         if (!pixman_transform_point_3d (pict->common.transform, &v))
+         {
+             fbFinishAccess (pict->pDrawable);
+             return;
+         }
+         unit.vector[0] = pict->common.transform->matrix[0][0];
+         unit.vector[1] = pict->common.transform->matrix[1][0];
--- a/gfx/public/nsCoord.h
+++ b/gfx/public/nsCoord.h
@@ -215,16 +215,39 @@ NSCoordSaturatingSubtract(nscoord a, nsc
                        "nscoord subtraction capped to nscoord_MAX");
 
       // Cap the result, in case we're dealing with numbers near nscoord_MAX
       return PR_MIN(nscoord_MAX, a - b);
     }
   }
 #endif
 }
+/** compare against a nscoord "b", which might be unconstrained
+  * "a" must not be unconstrained.
+  * Every number is smaller than a unconstrained one
+  */
+inline PRBool
+NSCoordLessThan(nscoord a,nscoord b)
+{
+  NS_ASSERTION(a != nscoord_MAX, 
+               "This coordinate should be constrained");
+  return ((a < b) || (b == nscoord_MAX));
+}
+
+/** compare against a nscoord "b", which might be unconstrained
+  * "a" must not be unconstrained
+  * No number is larger than a unconstrained one.
+  */
+inline PRBool
+NSCoordGreaterThan(nscoord a,nscoord b)
+{
+  NS_ASSERTION(a != nscoord_MAX, 
+               "This coordinate should be constrained");
+  return ((a > b) && (b != nscoord_MAX));
+}
 
 /**
  * Convert an nscoord to a PRInt32. This *does not* do rounding because
  * coords are never fractional. They can be out of range, so this does
  * clamp out of bounds coord values to PR_INT32_MIN and PR_INT32_MAX.
  */
 inline PRInt32 NSCoordToInt(nscoord aCoord) {
   VERIFY_COORD(aCoord);
--- a/gfx/public/nsIImage.h
+++ b/gfx/public/nsIImage.h
@@ -39,16 +39,17 @@
 #define nsIImage_h___
 
 #include "nsISupports.h"
 #include "nsIRenderingContext.h"
 #include "nsRect.h"
 #include "gfxRect.h"
 
 class gfxASurface;
+class gfxPattern;
 
 class nsIDeviceContext;
 
 struct nsColorMap
 {
   //I lifted this from the image lib. The difference is that
   //this uses nscolor instead of NI_RGB. Multiple color pollution
   //is a bad thing. MMP
@@ -66,20 +67,20 @@ typedef enum {
     nsMaskRequirements_kNeeds8Bit
 } nsMaskRequirements;
 
 
 #define  nsImageUpdateFlags_kColorMapChanged 0x1
 #define  nsImageUpdateFlags_kBitsChanged     0x2
 
 // IID for the nsIImage interface
-// fd31e1f2-bd46-47f1-b8b6-b94ce954f9ce
+// 96d9d7ce-e575-4265-8507-35555112a430
 #define NS_IIMAGE_IID \
-{ 0xfd31e1f2, 0xbd46, 0x47f1, \
-  { 0xb8, 0xb6, 0xb9, 0x4c, 0xe9, 0x54, 0xf9, 0xce } }
+{ 0x96d9d7ce, 0xe575, 0x4265, \
+  { 0x85, 0x07, 0x35, 0x55, 0x51, 0x12, 0xa4, 0x30 } }
 
 // Interface to Images
 class nsIImage : public nsISupports
 {
 
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IIMAGE_IID)
 
@@ -184,20 +185,24 @@ public:
    * @update - dwc 2/1/99
    * @return if non null, the colormap for the pixelmap,otherwise the image is not color mapped
    */
   virtual nsColorMap * GetColorMap() = 0;
 
   /**
    * BitBlit the nsIImage to a device, the source and dest can be scaled
    * @param aSourceRect  source rectangle, in image pixels
+   * @param aSubimageRect the subimage that we're extracting the contents from.
+   * It must contain aSourceRect. Pixels outside this rectangle must not
+   * be sampled.
    * @param aDestRect  destination rectangle, in device pixels
    */
   NS_IMETHOD Draw(nsIRenderingContext &aContext,
                   const gfxRect &aSourceRect,
+                  const gfxRect &aSubimageRect,
                   const gfxRect &aDestRect) = 0;
 
   /**
    * Get the alpha depth for the image mask
    * @update - lordpixel 2001/05/16
    * @return  the alpha mask depth for the image, ie, 0, 1 or 8
    */
   virtual PRInt8 GetAlphaDepth() = 0;
@@ -208,17 +213,21 @@ public:
    * @return a bitmap info structure for the Device Dependent Bits
    */
   virtual void* GetBitInfo() = 0;
 
 
   /**
    * LockImagePixels
    * Lock the image pixels so that we can access them directly,
-   * with safely. May be a noop on some platforms.
+   * with safety. May be a noop on some platforms.
+   *
+   * If you want to be able to call GetSurface(), wrap the call in
+   * LockImagePixels()/UnlockImagePixels(). This also allows you to write to
+   * the surface returned by GetSurface().
    *
    * aMaskPixels = PR_TRUE for the mask, PR_FALSE for the image
    *
    * Must be balanced by a call to UnlockImagePixels().
    *
    * @update - sfraser 10/18/99
    * @return error result
    */
@@ -234,24 +243,35 @@ public:
    *
    * @update - sfraser 10/18/99
    * @return error result
    */
   NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels) = 0;
 
   /**
    * GetSurface
-   * Return the Thebes gfxASurface in aSurface.
+   * Return the Thebes gfxASurface in aSurface, if there is one. Should be
+   * wrapped by LockImagePixels()/UnlockImagePixels().
    *
    * aSurface will be AddRef'd (as with most getters), so
    * getter_AddRefs should be used.
    */
   NS_IMETHOD GetSurface(gfxASurface **aSurface) = 0;
 
   /**
+   * GetSurface
+   * Return the Thebes gfxPattern in aPattern. It is always possible to get a
+   * gfxPattern (unlike the gfxASurface from GetSurface()).
+   *
+   * aPattern will be AddRef'd (as with most getters), so
+   * getter_AddRefs should be used.
+   */
+  NS_IMETHOD GetPattern(gfxPattern **aPattern) = 0;
+
+  /**
    * SetHasNoAlpha
    *
    * Hint to the image that all the pixels are fully opaque, even if
    * the original format requested a 1-bit or 8-bit alpha mask
    */
   virtual void SetHasNoAlpha() = 0;
 };
 
--- a/gfx/src/thebes/nsThebesImage.cpp
+++ b/gfx/src/thebes/nsThebesImage.cpp
@@ -254,34 +254,26 @@ nsThebesImage::Optimize(nsIDeviceContext
                 mSinglePixelColor = gfxRGBA
                     (firstPixel,
                      (mFormat == gfxImageSurface::ImageFormatRGB24 ?
                       gfxRGBA::PACKED_XRGB :
                       gfxRGBA::PACKED_ARGB_PREMULTIPLIED));
 
                 mSinglePixel = PR_TRUE;
 
-                // XXX we can't do this until we either teach anyone
-                // who calls GetSurface() about single-color stuff,
-                // or until we make GetSurface() create a new temporary
-                // surface to return (and that callers understand that
-                // modifying that surface won't modify the image).
-                // Current users are drag & drop and clipboard.
-#if 0
                 // blow away the older surfaces, to release data
 
                 mImageSurface = nsnull;
                 mOptSurface = nsnull;
 #ifdef XP_WIN
                 mWinSurface = nsnull;
 #endif
 #ifdef XP_MACOSX
                 mQuartzSurface = nsnull;
 #endif
-#endif
                 return NS_OK;
             }
         }
 
         // if it's not RGB24/ARGB32, don't optimize, but we never hit this at the moment
     }
 
     // if we're being forced to use image surfaces due to
@@ -386,17 +378,25 @@ nsThebesImage::LockImagePixels(PRBool aM
             return NS_ERROR_OUT_OF_MEMORY;
         gfxContext context(mImageSurface);
         context.SetOperator(gfxContext::OPERATOR_SOURCE);
         if (mSinglePixel)
             context.SetColor(mSinglePixelColor);
         else
             context.SetSource(mOptSurface);
         context.Paint();
+
+#ifdef XP_WIN
+        mWinSurface = nsnull;
+#endif
+#ifdef XP_MACOSX
+        mQuartzSurface = nsnull;
+#endif
     }
+
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsThebesImage::UnlockImagePixels(PRBool aMaskPixels)
 {
     if (aMaskPixels)
         return NS_ERROR_NOT_IMPLEMENTED;
@@ -407,16 +407,17 @@ nsThebesImage::UnlockImagePixels(PRBool 
 #endif
     return NS_OK;
 }
 
 /* NB: These are pixels, not twips. */
 NS_IMETHODIMP
 nsThebesImage::Draw(nsIRenderingContext &aContext,
                     const gfxRect &aSourceRect,
+                    const gfxRect &aSubimageRect,
                     const gfxRect &aDestRect)
 {
     if (NS_UNLIKELY(aDestRect.IsEmpty())) {
         NS_ERROR("nsThebesImage::Draw zero dest size - please fix caller.");
         return NS_OK;
     }
 
     nsThebesRenderingContext *thebesRC = static_cast<nsThebesRenderingContext*>(&aContext);
@@ -447,42 +448,77 @@ nsThebesImage::Draw(nsIRenderingContext 
         ctx->SetOperator(op);
         return NS_OK;
     }
 
     gfxFloat xscale = aDestRect.size.width / aSourceRect.size.width;
     gfxFloat yscale = aDestRect.size.height / aSourceRect.size.height;
 
     gfxRect srcRect(aSourceRect);
+    gfxRect subimageRect(aSubimageRect);
     gfxRect destRect(aDestRect);
 
     if (!GetIsImageComplete()) {
-      srcRect = srcRect.Intersect(gfxRect(mDecoded.x, mDecoded.y,
-                                          mDecoded.width, mDecoded.height));
+        gfxRect decoded = gfxRect(mDecoded.x, mDecoded.y,
+                                  mDecoded.width, mDecoded.height);
+        srcRect = srcRect.Intersect(decoded);
+        subimageRect = subimageRect.Intersect(decoded);
 
-      // This happens when mDecoded.width or height is zero. bug 368427.
-      if (NS_UNLIKELY(srcRect.size.width == 0 || srcRect.size.height == 0))
-          return NS_OK;
+        // This happens when mDecoded.width or height is zero. bug 368427.
+        if (NS_UNLIKELY(srcRect.size.width == 0 || srcRect.size.height == 0))
+            return NS_OK;
 
-      destRect.pos.x += (srcRect.pos.x - aSourceRect.pos.x)*xscale;
-      destRect.pos.y += (srcRect.pos.y - aSourceRect.pos.y)*yscale;
+        destRect.pos.x += (srcRect.pos.x - aSourceRect.pos.x)*xscale;
+        destRect.pos.y += (srcRect.pos.y - aSourceRect.pos.y)*yscale;
 
-      destRect.size.width  = srcRect.size.width * xscale;
-      destRect.size.height = srcRect.size.height * yscale;
+        destRect.size.width  = srcRect.size.width * xscale;
+        destRect.size.height = srcRect.size.height * yscale;
     }
 
     // if either rectangle is empty now (possibly after the image complete check)
     if (srcRect.IsEmpty() || destRect.IsEmpty())
         return NS_OK;
 
     // Reject over-wide or over-tall images.
     if (!AllowedImageSize(destRect.size.width + 1, destRect.size.height + 1))
         return NS_ERROR_FAILURE;
 
+    // Expand the subimageRect to place its edges on integer coordinates.
+    // Basically, if we're allowed to sample part of a pixel we can
+    // sample the whole pixel.
+    subimageRect.RoundOut();
+
     nsRefPtr<gfxPattern> pat;
+    PRBool ctxHasNonTranslation = ctx->CurrentMatrix().HasNonTranslation();
+    if ((xscale == 1.0 && yscale == 1.0 && !ctxHasNonTranslation) ||
+        subimageRect == gfxRect(0, 0, mWidth, mHeight))
+    {
+        // No need to worry about sampling outside the subimage rectangle,
+        // so no need for a temporary
+        // XXX should we also check for situations where the source rect
+        // is well inside the subimage so we can't sample outside?
+        pat = new gfxPattern(ThebesSurface());
+    } else {
+        // Because of the RoundOut above, the subimageRect has
+        // integer width and height.
+        gfxIntSize size(PRInt32(subimageRect.Width()),
+                        PRInt32(subimageRect.Height()));
+        nsRefPtr<gfxASurface> temp =
+            gfxPlatform::GetPlatform()->CreateOffscreenSurface(size, mFormat);
+        if (!temp || temp->CairoStatus() != 0)
+            return NS_ERROR_FAILURE;
+
+        gfxContext tempctx(temp);
+        tempctx.SetSource(ThebesSurface(), -subimageRect.pos);
+        tempctx.SetOperator(gfxContext::OPERATOR_SOURCE);
+        tempctx.Paint();
+
+        pat = new gfxPattern(temp);
+        srcRect.MoveBy(-subimageRect.pos);
+    }
 
     /* See bug 364968 to understand the necessity of this goop; we basically
      * have to pre-downscale any image that would fall outside of a scaled 16-bit
      * coordinate space.
      */
     if (aDestRect.pos.x * (1.0 / xscale) >= 32768.0 ||
         aDestRect.pos.y * (1.0 / yscale) >= 32768.0)
     {
@@ -495,73 +531,79 @@ nsThebesImage::Draw(nsIRenderingContext 
 
         nsRefPtr<gfxASurface> temp =
             gfxPlatform::GetPlatform()->CreateOffscreenSurface (dim,  mFormat);
         if (!temp || temp->CairoStatus() != 0)
             return NS_ERROR_FAILURE;
 
         gfxContext tempctx(temp);
 
-        gfxPattern srcpat(ThebesSurface());
         gfxMatrix mat;
         mat.Translate(srcRect.pos);
         mat.Scale(1.0 / xscale, 1.0 / yscale);
-        srcpat.SetMatrix(mat);
+        pat->SetMatrix(mat);
 
-        tempctx.SetPattern(&srcpat);
+        tempctx.SetPattern(pat);
         tempctx.SetOperator(gfxContext::OPERATOR_SOURCE);
         tempctx.NewPath();
         tempctx.Rectangle(gfxRect(0.0, 0.0, dim.width, dim.height));
         tempctx.Fill();
 
         pat = new gfxPattern(temp);
 
         srcRect.pos.x = 0.0;
         srcRect.pos.y = 0.0;
         srcRect.size.width = dim.width;
         srcRect.size.height = dim.height;
 
         xscale = 1.0;
         yscale = 1.0;
     }
 
-    if (!pat) {
-        pat = new gfxPattern(ThebesSurface());
-    }
-
     gfxMatrix mat;
     mat.Translate(srcRect.pos);
     mat.Scale(1.0/xscale, 1.0/yscale);
 
     /* Translate the start point of the image (srcRect.pos)
      * to coincide with the destination rectangle origin
      */
     mat.Translate(-destRect.pos);
 
     pat->SetMatrix(mat);
 
-#if !defined(XP_MACOSX) && !defined(XP_WIN) && !defined(XP_OS2)
-    // See bug 324698.  This is a workaround.
-    //
-    // Set the filter to CAIRO_FILTER_FAST if we're scaling up -- otherwise,
-    // pixman's sampling will sample transparency for the outside edges and we'll
-    // get blurry edges.  CAIRO_EXTEND_PAD would also work here, if
-    // available
-    //
-    // This effectively disables smooth upscaling for images.
-    if (xscale > 1.0 || yscale > 1.0)
-        pat->SetFilter(0);
-#endif
+    nsRefPtr<gfxASurface> target = ctx->CurrentSurface();
+    switch (target->GetType()) {
+    case gfxASurface::SurfaceTypeXlib:
+    case gfxASurface::SurfaceTypeXcb:
+        // See bug 324698.  This is a workaround for EXTEND_PAD not being
+        // implemented correctly on linux in the X server.
+        //
+        // Set the filter to CAIRO_FILTER_FAST if we're scaling up -- otherwise,
+        // pixman's sampling will sample transparency for the outside edges and we'll
+        // get blurry edges.  CAIRO_EXTEND_PAD would also work here, if
+        // available
+        //
+        // This effectively disables smooth upscaling for images.
+        if (xscale > 1.0 || yscale > 1.0 || ctxHasNonTranslation)
+            pat->SetFilter(0);
+        break;
 
-#if defined(XP_WIN) || defined(XP_OS2)
-    // turn on EXTEND_PAD only for win32, and only when scaling;
-    // it's not implemented correctly on linux in the X server.
-    if (xscale != 1.0 || yscale != 1.0)
-        pat->SetExtend(gfxPattern::EXTEND_PAD);
-#endif
+    case gfxASurface::SurfaceTypeQuartz:
+    case gfxASurface::SurfaceTypeQuartzImage:
+        // Do nothing, Mac seems to be OK. Really?
+        break;
+
+    default:
+        // turn on EXTEND_PAD.
+        // This is what we really want for all surface types, if the
+        // implementation was universally good.
+        if (xscale != 1.0 || yscale != 1.0 || ctxHasNonTranslation)
+            pat->SetExtend(gfxPattern::EXTEND_PAD);
+        break;
+    }
 
     gfxContext::GraphicsOperator op = ctx->CurrentOperator();
     if (op == gfxContext::OPERATOR_OVER && mFormat == gfxASurface::ImageFormatRGB24)
         ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
 
     ctx->NewPath();
     ctx->SetPattern(pat);
     ctx->Rectangle(destRect);
--- a/gfx/src/thebes/nsThebesImage.h
+++ b/gfx/src/thebes/nsThebesImage.h
@@ -39,16 +39,17 @@
 #ifndef _NSTHEBESIMAGE_H_
 #define _NSTHEBESIMAGE_H_
 
 #include "nsIImage.h"
 
 #include "gfxColor.h"
 #include "gfxASurface.h"
 #include "gfxImageSurface.h"
+#include "gfxPattern.h"
 #if defined(XP_WIN)
 #include "gfxWindowsSurface.h"
 #elif defined(XP_MACOSX)
 #include "gfxQuartzImageSurface.h"
 #endif
 
 class nsThebesImage : public nsIImage
 {
@@ -71,16 +72,17 @@ public:
     virtual PRInt32 GetAlphaLineStride();
     virtual PRBool GetIsImageComplete();
     virtual void ImageUpdated(nsIDeviceContext *aContext, PRUint8 aFlags, nsRect *aUpdateRect);
     virtual nsresult Optimize(nsIDeviceContext* aContext);
     virtual nsColorMap *GetColorMap();
 
     NS_IMETHOD Draw(nsIRenderingContext &aContext,
                     const gfxRect &aSourceRect,
+                    const gfxRect &aSubimageRect,
                     const gfxRect &aDestRect);
 
     nsresult ThebesDrawTile(gfxContext *thebesContext,
                             nsIDeviceContext* dx,
                             const gfxPoint& aOffset,
                             const gfxRect& aTileRect,
                             const PRInt32 aXPadding,
                             const PRInt32 aYPadding);
@@ -91,16 +93,32 @@ public:
     NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels);
 
     NS_IMETHOD GetSurface(gfxASurface **aSurface) {
         *aSurface = ThebesSurface();
         NS_ADDREF(*aSurface);
         return NS_OK;
     }
 
+    NS_IMETHOD GetPattern(gfxPattern **aPattern) {
+        *aPattern = ThebesPattern();
+        NS_ADDREF(*aPattern);
+        return NS_OK;
+    }
+
+    gfxPattern* ThebesPattern() {
+        gfxPattern *pattern;
+        if (mSinglePixel)
+            pattern = new gfxPattern(mSinglePixelColor);
+        else
+            pattern = new gfxPattern(ThebesSurface());
+
+        return pattern;
+    }
+
     gfxASurface* ThebesSurface() {
         if (mOptSurface)
             return mOptSurface;
 #if defined(XP_WIN)
         if (mWinSurface)
             return mWinSurface;
 #elif defined(XP_MACOSX)
         if (mQuartzSurface)
--- a/gfx/thebes/public/gfxPattern.h
+++ b/gfx/thebes/public/gfxPattern.h
@@ -73,16 +73,27 @@ public:
         EXTEND_REFLECT,
         EXTEND_PAD
     };
 
     // none, repeat, reflect
     void SetExtend(GraphicsExtend extend);
     GraphicsExtend Extend() const;
 
+    enum GraphicsPatternType {
+        PATTERN_SOLID,
+        PATTERN_SURFACE,
+        PATTERN_LINEAR,
+        PATTERN_RADIAL
+    };
+
+    GraphicsPatternType GetType() const;
+
+    int CairoStatus();
+
     void SetFilter(int filter);
     int Filter() const;
 
     /* returns TRUE if it succeeded */
     PRBool GetSoli