Merge TM -> JM.
authorBrian Hackett <bhackett1024@gmail.com>
Fri, 12 Nov 2010 09:02:43 -0800
changeset 73835 89a22a6962e14aa6ef2e9e9d702d98ce9318360b
parent 73834 9d2dc0a6f234a0784387bd7a4b0638b1bbe33b29 (current diff)
parent 57802 cb76b2d6109678b8a7a9c3165d38a96d99c2ac3e (diff)
child 73836 ea441b7eac2af498feac5f0db728fed1ab5f980f
push idunknown
push userunknown
push dateunknown
milestone2.0b8pre
Merge TM -> JM.
browser/base/content/tabview/infoitems.js
content/events/test/Makefile.in
content/svg/content/src/nsSVGPathSeg.cpp
content/svg/content/src/nsSVGPathSeg.h
content/svg/content/src/nsSVGPathSegList.cpp
content/svg/content/src/nsSVGPathSegList.h
js/src/assembler/assembler/X86Assembler.h
js/src/config/autoconf.mk.in
js/src/configure.in
js/src/jsanalyze.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsarray.cpp
js/src/jsarray.h
js/src/jsatom.cpp
js/src/jsbuiltins.h
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jsdate.cpp
js/src/jsdbgapi.cpp
js/src/jsemit.cpp
js/src/jsemit.h
js/src/jsexn.cpp
js/src/jsfun.cpp
js/src/jsfun.h
js/src/jsgc.cpp
js/src/jsinfer.cpp
js/src/jsinterp.cpp
js/src/jsinterp.h
js/src/jsiter.cpp
js/src/jsnum.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/jsopcode.tbl
js/src/jsparse.cpp
js/src/jsparse.h
js/src/jsproxy.cpp
js/src/jsregexp.cpp
js/src/jsregexpinlines.h
js/src/jsscope.cpp
js/src/jsscopeinlines.h
js/src/jsscript.cpp
js/src/jsstr.cpp
js/src/jstracer.cpp
js/src/jstypedarray.cpp
js/src/jsval.h
js/src/jsxdrapi.h
js/src/jsxml.cpp
js/src/methodjit/BaseAssembler.h
js/src/methodjit/Compiler.cpp
js/src/methodjit/Compiler.h
js/src/methodjit/FastArithmetic.cpp
js/src/methodjit/FastOps.cpp
js/src/methodjit/FrameState-inl.h
js/src/methodjit/FrameState.cpp
js/src/methodjit/FrameState.h
js/src/methodjit/ImmutableSync.cpp
js/src/methodjit/InvokeHelpers.cpp
js/src/methodjit/MachineRegs.h
js/src/methodjit/MethodJIT.cpp
js/src/methodjit/MethodJIT.h
js/src/methodjit/MonoIC.cpp
js/src/methodjit/MonoIC.h
js/src/methodjit/PolyIC.cpp
js/src/methodjit/RematInfo.h
js/src/methodjit/StubCalls.cpp
js/src/methodjit/StubCalls.h
js/src/methodjit/TrampolineCompiler.cpp
js/src/shell/js.cpp
js/src/tests/ecma_3/RegExp/regress-375715-02.js
js/src/tests/ecma_5/misc/explicit-undefined-optional-argument.diff
js/src/tracejit/Writer.cpp
js/src/tracejit/Writer.h
media/libtheora/bug559343.patch
media/libtheora/include/theora/config.h
media/libtheora/lib/cpu.c
media/libtheora/lib/cpu.h
media/libtheora/lib/encint.h
media/libtheora/lib/encoder_disabled.c
media/libtheora/lib/enquant.h
media/libtheora/lib/huffenc.h
media/libtheora/lib/x86/mmxfrag.h
media/libtheora/lib/x86_vc/mmxfrag.h
media/libvpx/frame_buf_ref.patch
media/libvpx/reduce-warnings-1.patch
media/libvpx/subpixel-qword.patch
media/libvpx/vp8/common/segmentation_common.h
media/libvpx/vp8/decoder/demode.c
media/libvpx/vp8/decoder/demode.h
testing/mochitest/runtests.py.in
testing/mozmill/tests/firefox/testPrivateBrowsing/testStartStopPBMode.js
--- a/Makefile.in
+++ b/Makefile.in
@@ -166,17 +166,17 @@ endif
 SYM_STORE_SOURCE_DIRS := $(topsrcdir)
 
 include $(topsrcdir)/toolkit/mozapps/installer/package-name.mk
 
 ifdef MOZ_SYMBOLS_EXTRA_BUILDID
 EXTRA_BUILDID := -$(MOZ_SYMBOLS_EXTRA_BUILDID)
 endif
 
-SYMBOL_INDEX_NAME = \
+export SYMBOL_INDEX_NAME = \
   $(MOZ_APP_NAME)-$(MOZ_APP_VERSION)-$(OS_TARGET)-$(BUILDID)$(EXTRA_BUILDID)-symbols.txt
 
 buildsymbols:
 ifdef MOZ_CRASHREPORTER
 	echo building symbol store
 	$(RM) -rf $(DIST)/crashreporter-symbols
 	$(RM) -f "$(DIST)/$(SYMBOL_ARCHIVE_BASENAME).zip"
 	$(NSINSTALL) -D $(DIST)/crashreporter-symbols
--- a/accessible/src/base/nsAccessNode.cpp
+++ b/accessible/src/base/nsAccessNode.cpp
@@ -77,17 +77,16 @@
 /* For documentation of the accessibility architecture, 
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
 nsIStringBundle *nsAccessNode::gStringBundle = 0;
 nsIStringBundle *nsAccessNode::gKeyStringBundle = 0;
 nsINode *nsAccessNode::gLastFocusedNode = nsnull;
 
-PRBool nsAccessNode::gIsCacheDisabled = PR_FALSE;
 PRBool nsAccessNode::gIsFormFillEnabled = PR_FALSE;
 
 nsApplicationAccessible *nsAccessNode::gApplicationAccessible = nsnull;
 
 /*
  * Class nsAccessNode
  */
  
@@ -212,17 +211,16 @@ void nsAccessNode::InitXPAccessibility()
     stringBundleService->CreateBundle(PLATFORM_KEYS_BUNDLE_URL, 
                                       &gKeyStringBundle);
   }
 
   nsAccessibilityAtoms::AddRefAtoms();
 
   nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID));
   if (prefBranch) {
-    prefBranch->GetBoolPref("accessibility.disablecache", &gIsCacheDisabled);
     prefBranch->GetBoolPref("browser.formfill.enable", &gIsFormFillEnabled);
   }
 
   NotifyA11yInitOrShutdown(PR_TRUE);
 }
 
 // nsAccessNode protected static
 void nsAccessNode::NotifyA11yInitOrShutdown(PRBool aIsInit)
--- a/accessible/src/base/nsAccessNode.h
+++ b/accessible/src/base/nsAccessNode.h
@@ -151,17 +151,17 @@ public:
     return DOMNode;
   }
 
   /**
    * Return DOM node associated with the accessible.
    */
   virtual nsINode* GetNode() const { return mContent; }
   nsIContent* GetContent() const { return mContent; }
-  nsIDocument* GetDocumentNode() const
+  virtual nsIDocument* GetDocumentNode() const
     { return mContent ? mContent->GetOwnerDoc() : nsnull; }
 
   /**
    * Return node type information of DOM node associated with the accessible.
    */
   PRBool IsContent() const
   {
     return GetNode() && GetNode()->IsNodeOfType(nsINode::eCONTENT);
@@ -207,17 +207,16 @@ protected:
      * Notify global nsIObserver's that a11y is getting init'd or shutdown
      */
     static void NotifyA11yInitOrShutdown(PRBool aIsInit);
 
     // Static data, we do our own refcounting for our static data
     static nsIStringBundle *gStringBundle;
     static nsIStringBundle *gKeyStringBundle;
 
-    static PRBool gIsCacheDisabled;
     static PRBool gIsFormFillEnabled;
 
 private:
   static nsApplicationAccessible *gApplicationAccessible;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsAccessNode,
                               NS_ACCESSNODE_IMPL_CID)
--- a/accessible/src/base/nsAccessibilityAtomList.h
+++ b/accessible/src/base/nsAccessibilityAtomList.h
@@ -95,28 +95,31 @@ ACCESSIBILITY_ATOM(tableOuterFrame, "Tab
 ACCESSIBILITY_ATOM(tableRowGroupFrame, "TableRowGroupFrame")
 ACCESSIBILITY_ATOM(tableRowFrame, "TableRowFrame")
 
   // Alphabetical list of tag names
 ACCESSIBILITY_ATOM(a, "a")
 ACCESSIBILITY_ATOM(abbr, "abbr")
 ACCESSIBILITY_ATOM(acronym, "acronym")
 ACCESSIBILITY_ATOM(area, "area")
+ACCESSIBILITY_ATOM(article, "article") // HTML landmark
 ACCESSIBILITY_ATOM(autocomplete, "autocomplete")
 ACCESSIBILITY_ATOM(blockquote, "blockquote")
 ACCESSIBILITY_ATOM(br, "br")
 ACCESSIBILITY_ATOM(body, "body")
 ACCESSIBILITY_ATOM(caption, "caption") // XUL
 ACCESSIBILITY_ATOM(choices, "choices") // XForms
 ACCESSIBILITY_ATOM(description, "description")    // XUL
 ACCESSIBILITY_ATOM(dd, "dd")
 ACCESSIBILITY_ATOM(div, "div")
 ACCESSIBILITY_ATOM(dl, "dl")
 ACCESSIBILITY_ATOM(dt, "dt")
+ACCESSIBILITY_ATOM(footer, "footer") // HTML landmark
 ACCESSIBILITY_ATOM(form, "form")
+ACCESSIBILITY_ATOM(header, "header") // HTML landmark
 ACCESSIBILITY_ATOM(h1, "h1")
 ACCESSIBILITY_ATOM(h2, "h2")
 ACCESSIBILITY_ATOM(h3, "h3")
 ACCESSIBILITY_ATOM(h4, "h4")
 ACCESSIBILITY_ATOM(h5, "h5")
 ACCESSIBILITY_ATOM(h6, "h6")
 ACCESSIBILITY_ATOM(item, "item") // XForms
 ACCESSIBILITY_ATOM(itemset, "itemset") // XForms
@@ -130,16 +133,17 @@ ACCESSIBILITY_ATOM(listcell, "listcell")
 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(menupopup, "menupopup")     // XUL
 ACCESSIBILITY_ATOM(object, "object")
+ACCESSIBILITY_ATOM(nav, "nav") // HTML landmark
 ACCESSIBILITY_ATOM(ol, "ol")
 ACCESSIBILITY_ATOM(optgroup, "optgroup")
 ACCESSIBILITY_ATOM(option, "option")
 ACCESSIBILITY_ATOM(output, "output")
 ACCESSIBILITY_ATOM(panel, "panel") // XUL
 ACCESSIBILITY_ATOM(q, "q")
 ACCESSIBILITY_ATOM(select, "select")
 ACCESSIBILITY_ATOM(select1, "select1") // XForms
@@ -191,16 +195,17 @@ ACCESSIBILITY_ATOM(longDesc, "longdesc")
 ACCESSIBILITY_ATOM(max, "max") // XUL
 ACCESSIBILITY_ATOM(maxpos, "maxpos") // XUL
 ACCESSIBILITY_ATOM(minpos, "minpos") // XUL
 ACCESSIBILITY_ATOM(_moz_menuactive, "_moz-menuactive") // XUL
 ACCESSIBILITY_ATOM(multiline, "multiline") // XUL
 ACCESSIBILITY_ATOM(name, "name")
 ACCESSIBILITY_ATOM(onclick, "onclick")
 ACCESSIBILITY_ATOM(popup, "popup")
+ACCESSIBILITY_ATOM(placeholder, "placeholder")
 ACCESSIBILITY_ATOM(readonly, "readonly")
 ACCESSIBILITY_ATOM(scope, "scope") // HTML table
 ACCESSIBILITY_ATOM(seltype, "seltype") // XUL listbox
 ACCESSIBILITY_ATOM(simple, "simple") // XLink
 ACCESSIBILITY_ATOM(src, "src")
 ACCESSIBILITY_ATOM(selected, "selected")
 ACCESSIBILITY_ATOM(summary, "summary")
 ACCESSIBILITY_ATOM(tabindex, "tabindex")
@@ -284,8 +289,9 @@ ACCESSIBILITY_ATOM(containerBusy, "conta
 ACCESSIBILITY_ATOM(containerLive, "container-live")
 ACCESSIBILITY_ATOM(containerLiveRole, "container-live-role")
 ACCESSIBILITY_ATOM(containerRelevant, "container-relevant")
 ACCESSIBILITY_ATOM(level, "level")
 ACCESSIBILITY_ATOM(live, "live")
 ACCESSIBILITY_ATOM(lineNumber, "line-number")
 ACCESSIBILITY_ATOM(posinset, "posinset") 
 ACCESSIBILITY_ATOM(setsize, "setsize")
+ACCESSIBILITY_ATOM(xmlroles, "xml-roles")
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -472,64 +472,78 @@ nsAccessibilityService::CreateHTMLCaptio
 }
 
 void
 nsAccessibilityService::ContentRangeInserted(nsIPresShell* aPresShell,
                                              nsIContent* aContainer,
                                              nsIContent* aStartChild,
                                              nsIContent* aEndChild)
 {
-#ifdef DEBUG_A11Y
+#ifdef DEBUG_CONTENTMUTATION
   nsAutoString tag;
   aStartChild->Tag()->ToString(tag);
-  nsIAtom* id = aStartChild->GetID();
-  nsCAutoString strid;
-  if (id)
-    id->ToUTF8String(strid);
+
+  nsIAtom* atomid = aStartChild->GetID();
+  nsCAutoString id;
+  if (atomid)
+    atomid->ToUTF8String(id);
+
   nsAutoString ctag;
-  aContainer->Tag()->ToString(ctag);
-  nsIAtom* cid = aContainer->GetID();
-  nsCAutoString strcid;
-  if (cid)
-    cid->ToUTF8String(strcid);
+  nsCAutoString cid;
+  nsIAtom* catomid = nsnull;
+  if (aContainer) {
+    aContainer->Tag()->ToString(ctag);
+    catomid = aContainer->GetID();
+    if (catomid)
+      catomid->ToUTF8String(cid);
+  }
+
   printf("\ncontent inserted: %s@id='%s', container: %s@id='%s', end node: %p\n\n",
-         NS_ConvertUTF16toUTF8(tag).get(), strid.get(),
-         NS_ConvertUTF16toUTF8(ctag).get(), strcid.get(), aEndChild);
+         NS_ConvertUTF16toUTF8(tag).get(), id.get(),
+         NS_ConvertUTF16toUTF8(ctag).get(), cid.get(), aEndChild);
 #endif
 
-  // XXX: bug 606082. aContainer is null when root element is inserted into
-  // document, we need to handle this and update the tree, also we need to
-  // update a content node of the document accessible.
-  if (aContainer) {
-    nsDocAccessible* docAccessible = GetDocAccessible(aPresShell->GetDocument());
-    if (docAccessible)
-      docAccessible->UpdateTree(aContainer, aStartChild, aEndChild, PR_TRUE);
-  }
+  nsDocAccessible* docAccessible = GetDocAccessible(aPresShell->GetDocument());
+  if (docAccessible)
+    docAccessible->UpdateTree(aContainer, aStartChild, aEndChild, PR_TRUE);
 }
 
 void
 nsAccessibilityService::ContentRemoved(nsIPresShell* aPresShell,
                                        nsIContent* aContainer,
                                        nsIContent* aChild)
 {
-#ifdef DEBUG_A11Y
-  nsAutoString id;
-  aChild->Tag()->ToString(id);
-  printf("\ncontent removed: %s\n", NS_ConvertUTF16toUTF8(id).get());
+#ifdef DEBUG_CONTENTMUTATION
+  nsAutoString tag;
+  aChild->Tag()->ToString(tag);
+
+  nsIAtom* atomid = aChild->GetID();
+  nsCAutoString id;
+  if (atomid)
+    atomid->ToUTF8String(id);
+
+  nsAutoString ctag;
+  nsCAutoString cid;
+  nsIAtom* catomid = nsnull;
+  if (aContainer) {
+    aContainer->Tag()->ToString(ctag);
+    catomid = aContainer->GetID();
+    if (catomid)
+      catomid->ToUTF8String(cid);
+  }
+
+  printf("\ncontent removed: %s@id='%s', container: %s@id='%s'\n\n",
+           NS_ConvertUTF16toUTF8(tag).get(), id.get(),
+           NS_ConvertUTF16toUTF8(ctag).get(), cid.get());
 #endif
 
-  // XXX: bug 606082. aContainer is null when root element is inserted into
-  // document, we need to handle this and update the tree, perhaps destroy
-  // the document accessible.
-  if (aContainer) {
-    nsDocAccessible* docAccessible = GetDocAccessible(aPresShell->GetDocument());
-    if (docAccessible)
-      docAccessible->UpdateTree(aContainer, aChild, aChild->GetNextSibling(),
-                                PR_FALSE);
-  }
+  nsDocAccessible* docAccessible = GetDocAccessible(aPresShell->GetDocument());
+  if (docAccessible)
+    docAccessible->UpdateTree(aContainer, aChild, aChild->GetNextSibling(),
+                              PR_FALSE);
 }
 
 void
 nsAccessibilityService::PresShellDestroyed(nsIPresShell *aPresShell)
 {
   // Presshell destruction will automatically destroy shells for descendant
   // documents, so no need to worry about those. Just shut down the accessible
   // for this one document. That keeps us from having bad behavior in case of
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -462,19 +462,16 @@ nsAccessible::GetPreviousSibling(nsIAcce
 
   /* readonly attribute nsIAccessible firstChild; */
 NS_IMETHODIMP
 nsAccessible::GetFirstChild(nsIAccessible **aFirstChild) 
 {
   NS_ENSURE_ARG_POINTER(aFirstChild);
   *aFirstChild = nsnull;
 
-  if (gIsCacheDisabled)
-    InvalidateChildren();
-
   PRInt32 childCount = GetChildCount();
   NS_ENSURE_TRUE(childCount != -1, NS_ERROR_FAILURE);
 
   if (childCount > 0)
     NS_ADDREF(*aFirstChild = GetChildAt(0));
 
   return NS_OK;
 }
@@ -2728,64 +2725,77 @@ nsAccessible::InvalidateChildren()
   mEmbeddedObjCollector = nsnull;
   mChildren.Clear();
   mChildrenFlags = eChildrenUninitialized;
 }
 
 PRBool
 nsAccessible::AppendChild(nsAccessible* aChild)
 {
+  if (!aChild)
+    return PR_FALSE;
+
   if (!mChildren.AppendElement(aChild))
     return PR_FALSE;
 
   if (!nsAccUtils::IsEmbeddedObject(aChild))
     mChildrenFlags = eMixedChildren;
 
   aChild->BindToParent(this, mChildren.Length() - 1);
   return PR_TRUE;
 }
 
 PRBool
 nsAccessible::InsertChildAt(PRUint32 aIndex, nsAccessible* aChild)
 {
+  if (!aChild)
+    return PR_FALSE;
+
   if (!mChildren.InsertElementAt(aIndex, aChild))
     return PR_FALSE;
 
-  for (PRUint32 idx = aIndex + 1; idx < mChildren.Length(); idx++)
-    mChildren[idx]->mIndexInParent++;
+  for (PRUint32 idx = aIndex + 1; idx < mChildren.Length(); idx++) {
+    NS_ASSERTION(mChildren[idx]->mIndexInParent == idx - 1, "Accessible child index doesn't match");
+    mChildren[idx]->mIndexInParent = idx;
+  }
 
   if (nsAccUtils::IsText(aChild))
     mChildrenFlags = eMixedChildren;
 
   mEmbeddedObjCollector = nsnull;
 
   aChild->BindToParent(this, aIndex);
   return PR_TRUE;
 }
 
 PRBool
 nsAccessible::RemoveChild(nsAccessible* aChild)
 {
-  if (aChild->mParent != this || aChild->mIndexInParent == -1)
+  if (!aChild)
     return PR_FALSE;
 
-  if (aChild->mIndexInParent >= mChildren.Length() ||
-      mChildren[aChild->mIndexInParent] != aChild) {
+  PRInt32 index = aChild->mIndexInParent;
+  if (aChild->mParent != this || index == -1)
+    return PR_FALSE;
+
+  if (index >= mChildren.Length() || mChildren[index] != aChild) {
     NS_ERROR("Child is bound to parent but parent hasn't this child at its index!");
     aChild->UnbindFromParent();
     return PR_FALSE;
   }
 
-  for (PRUint32 idx = aChild->mIndexInParent + 1; idx < mChildren.Length(); idx++)
-    mChildren[idx]->mIndexInParent--;
-
-  mChildren.RemoveElementAt(aChild->mIndexInParent);
-  mEmbeddedObjCollector = nsnull;
+  for (PRUint32 idx = index + 1; idx < mChildren.Length(); idx++) {
+    NS_ASSERTION(mChildren[idx]->mIndexInParent == idx, "Accessible child index doesn't match");
+    mChildren[idx]->mIndexInParent = idx - 1;
+  }
 
   aChild->UnbindFromParent();
+  mChildren.RemoveElementAt(index);
+  mEmbeddedObjCollector = nsnull;
+
   return PR_TRUE;
 }
 
 nsAccessible*
 nsAccessible::GetParent()
 {
   if (mParent)
     return mParent;
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -280,18 +280,22 @@ nsDocAccessible::GetStateInternal(PRUint
 
   if (IsDefunct()) {
     if (aExtraState)
       *aExtraState = nsIAccessibleStates::EXT_STATE_DEFUNCT;
 
     return NS_OK_DEFUNCT_OBJECT;
   }
 
-  if (aExtraState)
-    *aExtraState = 0;
+  if (aExtraState) {
+    // The root content of the document might be removed so that mContent is
+    // out of date.
+    *aExtraState = (mContent->GetCurrentDoc() == mDocument) ?
+      0 : nsIAccessibleStates::EXT_STATE_STALE;
+  }
 
 #ifdef MOZ_XUL
   nsCOMPtr<nsIXULDocument> xulDoc(do_QueryInterface(mDocument));
   if (!xulDoc)
 #endif
   {
     // XXX Need to invent better check to see if doc is focusable,
     // which it should be if it is scrollable. A XUL document could be focusable.
@@ -670,18 +674,20 @@ nsDocAccessible::Shutdown()
   if (mParent) {
     nsDocAccessible* parentDocument = mParent->GetDocAccessible();
     if (parentDocument)
       parentDocument->RemoveChildDocument(this);
 
     mParent->RemoveChild(this);
   }
 
-  PRUint32 childDocCount = mChildDocuments.Length();
-  for (PRUint32 idx = 0; idx < childDocCount; idx++)
+  // Walk the array backwards because child documents remove themselves from the
+  // array as they are shutdown.
+  PRInt32 childDocCount = mChildDocuments.Length();
+  for (PRInt32 idx = childDocCount - 1; idx >= 0; idx--)
     mChildDocuments[idx]->Shutdown();
 
   mChildDocuments.Clear();
 
   mWeakShell = nsnull;  // Avoid reentrancy
 
   mNodeToAccessibleMap.Clear();
   ClearCache(mAccessibleCache);
@@ -1234,22 +1240,27 @@ void nsDocAccessible::ContentAppended(ns
 {
 }
 
 void nsDocAccessible::ContentStatesChanged(nsIDocument* aDocument,
                                            nsIContent* aContent1,
                                            nsIContent* aContent2,
                                            nsEventStates aStateMask)
 {
-  if (!aStateMask.HasState(NS_EVENT_STATE_CHECKED)) {
-    return;
+  if (aStateMask.HasState(NS_EVENT_STATE_CHECKED)) {
+    nsHTMLSelectOptionAccessible::SelectionChangedIfOption(aContent1);
+    nsHTMLSelectOptionAccessible::SelectionChangedIfOption(aContent2);
   }
 
-  nsHTMLSelectOptionAccessible::SelectionChangedIfOption(aContent1);
-  nsHTMLSelectOptionAccessible::SelectionChangedIfOption(aContent2);
+  if (aStateMask.HasState(NS_EVENT_STATE_INVALID)) {
+    nsRefPtr<AccEvent> event =
+      new AccStateChangeEvent(aContent1, nsIAccessibleStates::STATE_INVALID,
+                              PR_FALSE, PR_TRUE);
+    FireDelayedAccessibleEvent(event);
+   }
 }
 
 void nsDocAccessible::DocumentStatesChanged(nsIDocument* aDocument,
                                             nsEventStates aStateMask)
 {
 }
 
 void nsDocAccessible::CharacterDataWillChange(nsIDocument *aDocument,
@@ -1341,32 +1352,59 @@ nsDocAccessible::UpdateTree(nsIContent* 
                             PRBool aIsInsert)
 {
   // Content change notification mostly are async, thus we can't detect whether
   // these actions are from user. This information is used to fire or do not
   // fire events to avoid events that are generated because of document loading.
   // Since this information may be not correct then we need to fire some events
   // regardless the document loading state.
 
+  // Update the whole tree of this document accessible when the container is
+  // null (document element is inserted or removed).
+
   nsCOMPtr<nsIPresShell> presShell = GetPresShell();
   nsIEventStateManager* esm = presShell->GetPresContext()->EventStateManager();
   PRBool fireAllEvents = PR_TRUE;//IsContentLoaded() || esm->IsHandlingUserInputExternal();
 
-  // We don't create new accessibles on content removal.
-  nsAccessible* container = aIsInsert ?
-    GetAccService()->GetAccessibleOrContainer(aContainerNode, mWeakShell) :
-    GetAccService()->GetCachedAccessibleOrContainer(aContainerNode);
+  // XXX: bug 608887 reconsider accessible tree update logic because
+  // 1) elements appended outside the HTML body don't get accessibles;
+  // 2) the document having elements that should be accessible may function
+  // without body.
+  nsAccessible* container = nsnull;
+  if (aIsInsert) {
+    container = aContainerNode ?
+      GetAccService()->GetAccessibleOrContainer(aContainerNode, mWeakShell) :
+      this;
 
-  if (aIsInsert) {
+    // The document children were changed; the root content might be affected.
+    if (container == this) {
+      nsIContent* rootContent = nsCoreUtils::GetRoleContent(mDocument);
+
+      // No root content (for example HTML document element was inserted but no
+      // body). Nothing to update.
+      if (!rootContent)
+        return;
+
+      // New root content has been inserted, update it and update the tree.
+      if (rootContent != mContent)
+        mContent = rootContent;
+    }
+
     // XXX: Invalidate parent-child relations for container accessible and its
     // children because there's no good way to find insertion point of new child
     // accessibles into accessible tree. We need to invalidate children even
     // there's no inserted accessibles in the end because accessible children
     // are created while parent recaches child accessibles.
     container->InvalidateChildren();
+
+  } else {
+    // Don't create new accessibles on content removal.
+    container = aContainerNode ?
+      GetAccService()->GetCachedAccessibleOrContainer(aContainerNode) :
+      this;
   }
 
   EIsFromUserInput fromUserInput = esm->IsHandlingUserInputExternal() ?
     eFromUserInput : eNoUserInput;
 
   // Update the accessible tree in the case of content removal and fire events
   // if allowed.
   PRUint32 updateFlags =
--- a/accessible/src/base/nsDocAccessible.h
+++ b/accessible/src/base/nsDocAccessible.h
@@ -103,16 +103,17 @@ public:
   NS_DECL_NSIDOCUMENTOBSERVER
 
   // nsAccessNode
   virtual PRBool Init();
   virtual void Shutdown();
   virtual nsIFrame* GetFrame();
   virtual PRBool IsDefunct();
   virtual nsINode* GetNode() const { return mDocument; }
+  virtual nsIDocument* GetDocumentNode() const { return mDocument; }
 
   // nsAccessible
   virtual PRUint32 NativeRole();
   virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
   virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState);
 
   virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
 
--- a/accessible/src/base/nsOuterDocAccessible.cpp
+++ b/accessible/src/base/nsOuterDocAccessible.cpp
@@ -191,18 +191,23 @@ nsOuterDocAccessible::InvalidateChildren
   // accessible is created and appended as a child when it's requested.
 
   mChildrenFlags = eChildrenUninitialized;
 }
 
 PRBool
 nsOuterDocAccessible::AppendChild(nsAccessible *aAccessible)
 {
-  NS_ASSERTION(!mChildren.Length(),
-               "Previous child document of outerdoc accessible wasn't removed!");
+  // We keep showing the old document for a bit after creating the new one,
+  // and while building the new DOM and frame tree. That's done on purpose
+  // to avoid weird flashes of default background color.
+  // The old viewer will be destroyed after the new one is created.
+  // For a11y, it should be safe to shut down the old document now.
+  if (mChildren.Length())
+    mChildren[0]->Shutdown();
 
   if (!nsAccessible::AppendChild(aAccessible))
     return PR_FALSE;
 
   NS_LOG_ACCDOCCREATE("append document to outerdoc",
                       aAccessible->GetDocumentNode())
   NS_LOG_ACCDOCCREATE_ACCADDRESS("outerdoc", this)
 
--- a/accessible/src/html/nsHTMLFormControlAccessible.cpp
+++ b/accessible/src/html/nsHTMLFormControlAccessible.cpp
@@ -407,26 +407,34 @@ nsresult
 nsHTMLTextFieldAccessible::GetNameInternal(nsAString& aName)
 {
   nsresult rv = nsAccessible::GetNameInternal(aName);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!aName.IsEmpty())
     return NS_OK;
 
-  if (!mContent->GetBindingParent())
+  if (mContent->GetBindingParent())
+  {
+    // XXX: bug 459640
+    // There's a binding parent.
+    // This means we're part of another control, so use parent accessible for name.
+    // This ensures that a textbox inside of a XUL widget gets
+    // an accessible name.
+    nsAccessible* parent = GetParent();
+    parent->GetName(aName);
+  }
+
+  if (!aName.IsEmpty())
     return NS_OK;
 
-  // XXX: bug 459640
-  // There's a binding parent.
-  // This means we're part of another control, so use parent accessible for name.
-  // This ensures that a textbox inside of a XUL widget gets
-  // an accessible name.
-  nsAccessible* parent = GetParent();
-  return parent ? parent->GetName(aName) : NS_OK;
+  // text inputs and textareas might have useful placeholder text
+  mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::placeholder, aName);
+
+  return NS_OK;
 }
 
 NS_IMETHODIMP nsHTMLTextFieldAccessible::GetValue(nsAString& _retval)
 {
   PRUint32 state;
   nsresult rv = GetStateInternal(&state, nsnull);
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -129,28 +129,38 @@ nsresult nsHyperTextAccessible::QueryInt
 PRUint32
 nsHyperTextAccessible::NativeRole()
 {
   nsIAtom *tag = mContent->Tag();
 
   if (tag == nsAccessibilityAtoms::form)
     return nsIAccessibleRole::ROLE_FORM;
 
-  if (tag == nsAccessibilityAtoms::div ||
-      tag == nsAccessibilityAtoms::blockquote)
+  if (tag == nsAccessibilityAtoms::article ||
+      tag == nsAccessibilityAtoms::blockquote ||
+      tag == nsAccessibilityAtoms::div ||
+      tag == nsAccessibilityAtoms::nav)
     return nsIAccessibleRole::ROLE_SECTION;
 
   if (tag == nsAccessibilityAtoms::h1 ||
       tag == nsAccessibilityAtoms::h2 ||
       tag == nsAccessibilityAtoms::h3 ||
       tag == nsAccessibilityAtoms::h4 ||
       tag == nsAccessibilityAtoms::h5 ||
       tag == nsAccessibilityAtoms::h6)
     return nsIAccessibleRole::ROLE_HEADING;
 
+  // Deal with html landmark elements
+  if (tag == nsAccessibilityAtoms::header)
+    return nsIAccessibleRole::ROLE_HEADER;
+
+  if (tag == nsAccessibilityAtoms::footer)
+    return nsIAccessibleRole::ROLE_FOOTER;
+
+  // Treat block frames as paragraphs
   nsIFrame *frame = GetFrame();
   if (frame && frame->GetType() == nsAccessibilityAtoms::blockFrame &&
       frame->GetContent()->Tag() != nsAccessibilityAtoms::input) {
     // An html:input @type="file" is the only input that is exposed as a
     // blockframe. It must be exposed as ROLE_TEXT_CONTAINER for JAWS.
     return nsIAccessibleRole::ROLE_PARAGRAPH;
   }
 
@@ -1192,16 +1202,31 @@ nsHyperTextAccessible::GetAttributesInte
     if (lineNumber >= 1) {
       nsAutoString strLineNumber;
       strLineNumber.AppendInt(lineNumber);
       nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::lineNumber,
                              strLineNumber);
     }
   }
 
+  // For the html landmark elements we expose them like we do aria landmarks to
+  // make AT navigation schemes "just work".
+  if (mContent->Tag() == nsAccessibilityAtoms::nav)
+    nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::xmlroles,
+                           NS_LITERAL_STRING("navigation"));
+  else if (mContent->Tag() == nsAccessibilityAtoms::header) 
+    nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::xmlroles,
+                           NS_LITERAL_STRING("banner"));
+  else if (mContent->Tag() == nsAccessibilityAtoms::footer) 
+    nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::xmlroles,
+                           NS_LITERAL_STRING("contentinfo"));
+  else if (mContent->Tag() == nsAccessibilityAtoms::article) 
+    nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::xmlroles,
+                           NS_LITERAL_STRING("main"));
+
   return  NS_OK;
 }
 
 /*
  * Given an offset, the x, y, width, and height values are filled appropriately.
  */
 NS_IMETHODIMP nsHyperTextAccessible::GetCharacterExtents(PRInt32 aOffset, PRInt32 *aX, PRInt32 *aY,
                                                          PRInt32 *aWidth, PRInt32 *aHeight,
--- a/accessible/tests/mochitest/Makefile.in
+++ b/accessible/tests/mochitest/Makefile.in
@@ -90,16 +90,17 @@ include $(topsrcdir)/config/rules.mk
 		test_aria_roles.xul \
 		test_aria_token_attrs.html \
 		test_bug420863.html \
 	$(warning   test_childAtPoint.html temporarily disabled) \
 	$(warning	test_childAtPoint.xul temporarily disabled) \
 		test_descr.html \
 		test_editabletext_1.html \
 		test_editabletext_2.html \
+		test_elm_landmarks.html \
 		test_elm_listbox.xul \
 	$(warning   test_elm_media.html temporarily disabled) \
 		test_elm_nsApplicationAcc.html \
 		test_elm_plugin.html \
 		test_name.html \
 		test_name.xul \
 		test_name_button.html \
 		test_name_link.html \
--- a/accessible/tests/mochitest/events/test_statechange.html
+++ b/accessible/tests/mochitest/events/test_statechange.html
@@ -21,20 +21,16 @@
   <script type="application/javascript">
     ////////////////////////////////////////////////////////////////////////////
     // Invokers
 
     function makeEditableDoc(aDocNode, aIsEnabled)
     {
       this.DOMNode = aDocNode;
 
-      this.eventSeq = [
-        new invokerChecker(EVENT_STATE_CHANGE, getAccessible(this.DOMNode))
-      ];
-
       this.invoke = function editabledoc_invoke() {
         // Note: this should fire an EVENT_STATE_CHANGE
         this.DOMNode.designMode = 'on';
       };
 
       this.check = function editabledoc_check(aEvent) {
 
         testStates(aDocNode, 0, EXT_STATE_EDITABLE);
@@ -53,50 +49,79 @@
         ok(event.isEnabled(), "Expected editable state to be enabled");
       }
 
       this.getID = function editabledoc_getID() {
         return prettyName(aDocNode) + " editable state changed";
       };
     }
 
+    function invalidInput(aNodeOrID)
+    {
+      this.DOMNode = getNode(aNodeOrID);
+
+      this.invoke = function invalidInput_invoke() {
+        // Note: this should fire an EVENT_STATE_CHANGE
+        this.DOMNode.value = "I am too long";
+      };
+
+      this.check = function invalidInput_check() {
+        testStates(aNodeOrID, STATE_INVALID);
+      };
+
+      this.getID = function invalidInput_getID() {
+        return prettyName(aNodeOrID) + " became invalid";
+      };
+    }
+
     ////////////////////////////////////////////////////////////////////////////
     // Do tests
 
     var gQueue = null;
 
     // var gA11yEventDumpID = "eventdump"; // debug stuff
 
     function doTests()
     {
-      gQueue = new eventQueue();
+      gQueue = new eventQueue(nsIAccessibleEvent.EVENT_STATE_CHANGE);
 
       // Test delayed editable state change
       var doc = document.getElementById("iframe").contentDocument;
       gQueue.push(new makeEditableDoc(doc));
 
+      // invalid state change
+      gQueue.push(new invalidInput("maxlength"));
+
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTests);
   </script>
 </head>
 
 <body>
 
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=564471"
      title="Make state change events async">
     Mozilla Bug 564471
+  </a><br>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=555728"
+     title="Fire a11y event based on HTML5 constraint validation">
+    Mozilla Bug 555728
   </a>
 
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <div id="testContainer">
     <iframe id="iframe"></iframe>
   </div>
+
+  <input id="maxlength" maxlength="1">
+
   <div id="eventdump"></div>
 </body>
 </html>
--- a/accessible/tests/mochitest/role.js
+++ b/accessible/tests/mochitest/role.js
@@ -14,21 +14,23 @@ const ROLE_CHROME_WINDOW = nsIAccessible
 const ROLE_COMBOBOX = nsIAccessibleRole.ROLE_COMBOBOX;
 const ROLE_COMBOBOX_LIST = nsIAccessibleRole.ROLE_COMBOBOX_LIST;
 const ROLE_COMBOBOX_OPTION = nsIAccessibleRole.ROLE_COMBOBOX_OPTION;
 const ROLE_COLUMNHEADER = nsIAccessibleRole.ROLE_COLUMNHEADER;
 const ROLE_DIALOG = nsIAccessibleRole.ROLE_DIALOG;
 const ROLE_DOCUMENT = nsIAccessibleRole.ROLE_DOCUMENT;
 const ROLE_EMBEDDED_OBJECT = nsIAccessibleRole.ROLE_EMBEDDED_OBJECT;
 const ROLE_ENTRY = nsIAccessibleRole.ROLE_ENTRY;
+const ROLE_FOOTER = nsIAccessibleRole.ROLE_FOOTER;
 const ROLE_FLAT_EQUATION = nsIAccessibleRole.ROLE_FLAT_EQUATION;
 const ROLE_FORM = nsIAccessibleRole.ROLE_FORM;
 const ROLE_GRAPHIC = nsIAccessibleRole.ROLE_GRAPHIC;
 const ROLE_GRID_CELL = nsIAccessibleRole.ROLE_GRID_CELL;
 const ROLE_GROUPING = nsIAccessibleRole.ROLE_GROUPING;
+const ROLE_HEADER = nsIAccessibleRole.ROLE_HEADER;
 const ROLE_HEADING = nsIAccessibleRole.ROLE_HEADING;
 const ROLE_IMAGE_MAP = nsIAccessibleRole.ROLE_IMAGE_MAP;
 const ROLE_INTERNAL_FRAME = nsIAccessibleRole.ROLE_INTERNAL_FRAME;
 const ROLE_LABEL = nsIAccessibleRole.ROLE_LABEL;
 const ROLE_LINK = nsIAccessibleRole.ROLE_LINK;
 const ROLE_LIST = nsIAccessibleRole.ROLE_LIST;
 const ROLE_LISTBOX = nsIAccessibleRole.ROLE_LISTBOX;
 const ROLE_LISTITEM = nsIAccessibleRole.ROLE_LISTITEM;
--- a/accessible/tests/mochitest/states.js
+++ b/accessible/tests/mochitest/states.js
@@ -33,16 +33,17 @@ const STATE_UNAVAILABLE = nsIAccessibleS
 
 const EXT_STATE_ACTIVE = nsIAccessibleStates.EXT_STATE_ACTIVE;
 const EXT_STATE_DEFUNCT = nsIAccessibleStates.EXT_STATE_DEFUNCT;
 const EXT_STATE_EDITABLE = nsIAccessibleStates.EXT_STATE_EDITABLE;
 const EXT_STATE_EXPANDABLE = nsIAccessibleStates.EXT_STATE_EXPANDABLE;
 const EXT_STATE_HORIZONTAL = nsIAccessibleStates.EXT_STATE_HORIZONTAL;
 const EXT_STATE_MULTI_LINE = nsIAccessibleStates.EXT_STATE_MULTI_LINE;
 const EXT_STATE_SINGLE_LINE = nsIAccessibleStates.EXT_STATE_SINGLE_LINE;
+const EXT_STATE_STALE = nsIAccessibleStates.EXT_STATE_STALE;
 const EXT_STATE_SUPPORTS_AUTOCOMPLETION =
   nsIAccessibleStates.EXT_STATE_SUPPORTS_AUTOCOMPLETION;
 const EXT_STATE_VERTICAL = nsIAccessibleStates.EXT_STATE_VERTICAL;
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // Test functions
 
--- a/accessible/tests/mochitest/states/test_docarticle.html
+++ b/accessible/tests/mochitest/states/test_docarticle.html
@@ -12,27 +12,28 @@
 
   <script type="application/javascript"
           src="../common.js"></script>
   <script type="application/javascript"
           src="../states.js"></script>
 
   <script type="application/javascript">
     function doTest()
-    {      
+    {
       var docAcc = getAccessible(document, [nsIAccessibleDocument]);
       if (docAcc) {
         testStates(docAcc, STATE_READONLY);
         testStates("article", STATE_READONLY);
         testStates("editable_article", 0, EXT_STATE_EDITABLE);
 
         document.designMode = "on";
 
         testStates(docAcc, 0, EXT_STATE_EDITABLE);
         testStates("article", 0, EXT_STATE_EDITABLE);
+        testStates("article", 0, EXT_STATE_EDITABLE);
         testStates("editable_article", 0, EXT_STATE_EDITABLE);
   
         document.designMode = "off";
 
         testStates(docAcc, STATE_READONLY);
         testStates("article", STATE_READONLY);
         testStates("editable_article", 0, EXT_STATE_EDITABLE);
       }
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/test_elm_landmarks.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>HTML landmark 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"
+          src="common.js"></script>
+  <script type="application/javascript"
+          src="role.js"></script>
+  <script type="application/javascript"
+          src="attributes.js"></script>
+
+  <script type="application/javascript">
+
+    function doTest()
+    {
+      testRole("nav", ROLE_SECTION);
+      testRole("header", ROLE_HEADER);
+      testRole("footer", ROLE_FOOTER);
+      testRole("article", ROLE_SECTION);
+
+      // Some AT may look for this
+      testAttrs("nav", {"xml-roles" : "navigation"}, true);
+      testAttrs("header", {"xml-roles" : "banner"}, true);
+      testAttrs("footer", {"xml-roles" : "contentinfo"}, true);
+      testAttrs("article", {"xml-roles" : "main"}, true);
+      testAttrs("document", {"xml-roles" : "document"}, true); // ARIA override
+
+      // And some AT may look for this
+      testAttrs("nav", {"tag" : "NAV"}, true);
+      testAttrs("header", {"tag" : "HEADER"}, true);
+      testAttrs("footer", {"tag" : "FOOTER"}, true);
+      testAttrs("article", {"tag" : "ARTICLE"}, true);
+      testAttrs("document", {"tag" : "ARTICLE"}, true); // no override expected
+
+      SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  </script>
+</head>
+<body>
+
+  <a target="_blank"
+     title="Provide mappings for html5 <nav> <header> <footer> <article>"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=593368">Bug 593368</a>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+
+  <nav id="nav">a nav</nav>
+  <header id="header">a header</header>
+  <footer id="footer">a footer</footer>
+  <article id="article">an article</article>
+
+  <article id="document" role="document">a document</article>
+
+</body>
+</html>
--- a/accessible/tests/mochitest/test_name.html
+++ b/accessible/tests/mochitest/test_name.html
@@ -171,16 +171,24 @@
       testName("checkbox", "Play the Haliluya sound when new mail arrives");
 
       testName("comboinend", "This day was sunny");
       testName("combo6", "This day was");
 
       testName("textboxinend", "This day was sunny");
       testName("textbox2", "This day was");
 
+      // placeholder
+      testName("ph_password", "a placeholder");
+      testName("ph_text", "a placeholder");
+      testName("ph_textarea", "a placeholder");
+      testName("ph_text2", "a label");
+      testName("ph_textarea2", "a label");
+      testName("ph_text3", "a label");
+
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 
 </head>
@@ -191,16 +199,21 @@
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=444279"
      title="mochitest for accessible name calculating">
     Mozilla Bug 444279
   </a><br>
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=530081"
      title="Clean up our tree walker ">
     Mozilla Bug 530081
+  </a><br>
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=604391"
+     title="Use placeholder as name if name is otherwise empty">
+    Mozilla Bug 604391
   </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
 
   <!-- aria-label, simple label -->
   <span id="btn_simple_aria_label" role="button" aria-label="I am a button"/>
@@ -416,10 +429,23 @@
       </select></label>
 
     <label id="textboxinend">
       This day was
       <input id="textbox2" value="sunny">
     </label>
   </form>
 
+  <!-- placeholder  -->
+  <input id="ph_password" type="password" value="" placeholder="a placeholder" />
+  <input id="ph_text" type="text" placeholder="a placeholder" />
+  <textarea id="ph_textarea" cols="5" placeholder="a placeholder"></textarea>  
+
+  <!-- placeholder does not win -->
+  <input id="ph_text2" type="text" aria-label="a label" placeholder="meh" />
+  <textarea id="ph_textarea2" cols="5" aria-labelledby="ph_text2" 
+            placeholder="meh"></textarea>
+
+  <label for="ph_text3">a label</label>
+  <input id="ph_text3" placeholder="meh" />
+
 </body>
 </html>
--- a/accessible/tests/mochitest/treeupdate/Makefile.in
+++ b/accessible/tests/mochitest/treeupdate/Makefile.in
@@ -41,16 +41,17 @@ topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = accessible/treeupdate
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 _TEST_FILES =\
+		test_doc.html \
 		test_list_editabledoc.html \
 		test_list.html \
 		test_recreation.html \
 		test_tableinsubtree.html \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/a11y/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/treeupdate/test_doc.html
@@ -0,0 +1,370 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+  <title>Test document root content mutations</title>
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+  <script type="application/javascript"
+          src="../common.js"></script>
+  <script type="application/javascript"
+          src="../role.js"></script>
+  <script type="application/javascript"
+          src="../states.js"></script>
+  <script type="application/javascript"
+          src="../events.js"></script>
+
+  <script type="application/javascript">
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Helpers
+
+    function getDocNode(aID)
+    {
+      return getNode(aID).contentDocument;
+    }
+    function getDocChildNode(aID)
+    {
+      return getDocNode(aID).body.firstChild;
+    }
+
+    function rootContentReplaced(aID, aTextName)
+    {
+      this.eventSeq = [
+        new invokerChecker(EVENT_SHOW, getDocChildNode, aID),
+        new invokerChecker(EVENT_REORDER, getDocNode, aID)
+      ];
+
+      this.finalCheck = function rootContentReplaced_finalCheck()
+      {
+        var tree = {
+          role: ROLE_DOCUMENT,
+          children: [
+            {
+              role: ROLE_TEXT_LEAF,
+              name: aTextName
+            }
+          ]
+        };
+        testAccessibleTree(getDocNode(aID), tree);
+      }
+    }
+
+    function rootContentRemoved(aID)
+    {
+      this.eventSeq = [
+        new invokerChecker(EVENT_HIDE, null),
+        new invokerChecker(EVENT_REORDER, getDocNode, aID)
+      ];
+
+      this.preinvoke = function rootContentRemoved_preinvoke()
+      {
+        // Set up target for hide event before we invoke.
+        var text = getAccessible(getAccessible(getDocNode(aID)).firstChild,
+                                               [nsIAccessNode]).DOMNode;
+        this.eventSeq[0].target = text;
+      }
+
+      this.finalCheck = function rootContentRemoved_finalCheck()
+      {
+        var tree = {
+          role: ROLE_DOCUMENT,
+          states: {
+            // Out of date root content involves stale state presence.
+            states: 0,
+            extraStates: EXT_STATE_STALE
+          },
+          children: [ ]
+        };
+        testAccessibleTree(getDocNode(aID), tree);
+      }
+    }
+
+    function rootContentInserted(aID, aTextName)
+    {
+      this.eventSeq = [
+        new invokerChecker(EVENT_SHOW, getDocChildNode, aID),
+        new invokerChecker(EVENT_REORDER, getDocNode, aID)
+      ];
+
+      this.finalCheck = function rootContentInserted_finalCheck()
+      {
+        var tree = {
+          role: ROLE_DOCUMENT,
+          states: {
+            states: 0,
+            extraStates: 0,
+            absentStates: 0,
+            absentExtraStates: EXT_STATE_STALE
+          },
+          children: [
+            {
+              role: ROLE_TEXT_LEAF,
+              name: aTextName
+            }
+          ]
+        };
+        testAccessibleTree(getDocNode(aID), tree);
+      }
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Invokers
+
+    function writeIFrameDoc(aID)
+    {
+      this.__proto__ = new rootContentReplaced(aID, "hello");
+
+      this.invoke = function writeIFrameDoc_invoke()
+      {
+        var docNode = getDocNode(aID);
+
+        // We can't use open/write/close outside of iframe document because of
+        // security error.
+        var script = docNode.createElement("script");
+        script.textContent = "document.open(); document.write('hello'); document.close();";
+        docNode.body.appendChild(script);
+      }
+
+      this.getID = function writeIFrameDoc_getID()
+      {
+        return "write document";
+      }
+    }
+
+    /**
+     * Replace HTML element.
+     */
+    function replaceIFrameHTMLElm(aID)
+    {
+      this.__proto__ = new rootContentReplaced(aID, "New Wave");
+
+      this.invoke = function replaceIFrameHTMLElm_invoke()
+      {
+        var docNode = getDocNode(aID);
+        var newHTMLNode = docNode.createElement("html");
+        var newBodyNode = docNode.createElement("body");
+        var newTextNode = docNode.createTextNode("New Wave");
+        newBodyNode.appendChild(newTextNode);
+        newHTMLNode.appendChild(newBodyNode);
+        docNode.replaceChild(newHTMLNode, docNode.documentElement);
+      }
+
+      this.getID = function replaceIFrameBody_getID()
+      {
+        return "replace HTML element";
+      }
+    }
+
+    /**
+     * Replace HTML body.
+     */
+    function replaceIFrameBody(aID)
+    {
+      this.__proto__ = new rootContentReplaced(aID, "New Hello");
+
+      this.invoke = function replaceIFrameBody_invoke()
+      {
+        var docNode = getDocNode(aID);
+        var newBodyNode = docNode.createElement("body");
+        var newTextNode = docNode.createTextNode("New Hello");
+        newBodyNode.appendChild(newTextNode);
+        docNode.documentElement.replaceChild(newBodyNode, docNode.body);
+      }
+
+      this.finalCheck = function replaceIFrameBody_finalCheck()
+      {
+        var tree = {
+          role: ROLE_DOCUMENT,
+          children: [
+            {
+              role: ROLE_TEXT_LEAF,
+              name: "New Hello"
+            }
+          ]
+        };
+        testAccessibleTree(getDocNode(aID), tree);
+      }
+
+      this.getID = function replaceIFrameBody_getID()
+      {
+        return "replace body";
+      }
+    }
+
+    /**
+     * Open/close document pair.
+     */
+    function openIFrameDoc(aID)
+    {
+      this.__proto__ = new rootContentRemoved(aID);
+
+      this.invoke = function openIFrameDoc_invoke()
+      {
+        this.preinvoke();
+
+        // Open document.
+        var docNode = getDocNode(aID);
+        var script = docNode.createElement("script");
+        script.textContent = "function closeMe() { document.write('Works?'); document.close(); } window.closeMe = closeMe; document.open();";
+        docNode.body.appendChild(script);
+      }
+
+      this.getID = function openIFrameDoc_getID()
+      {
+        return "open document";
+      }
+    }
+
+    function closeIFrameDoc(aID)
+    {
+      this.__proto__ = new rootContentInserted(aID, "Works?");
+
+      this.invoke = function closeIFrameDoc_invoke()
+      {
+        // Write and close document.
+        getDocNode(aID).write('Works?'); getDocNode(aID).close();
+      }
+
+      this.getID = function closeIFrameDoc_getID()
+      {
+        return "close document";
+      }
+    }
+
+    /**
+     * Remove/insert HTML element pair.
+     */
+    function removeHTMLFromIFrameDoc(aID)
+    {
+      this.__proto__ = new rootContentRemoved(aID);
+
+      this.invoke = function removeHTMLFromIFrameDoc_invoke()
+      {
+        this.preinvoke();
+
+        // Remove HTML element.
+        var docNode = getDocNode(aID);
+        docNode.removeChild(docNode.firstChild);
+      }
+
+      this.getID = function removeHTMLFromIFrameDoc_getID()
+      {
+        return "remove HTML element";
+      }
+    }
+
+    function insertHTMLToIFrameDoc(aID)
+    {
+      this.__proto__ = new rootContentInserted(aID, "Haha");
+
+      this.invoke = function insertHTMLToIFrameDoc_invoke()
+      {
+        // Insert HTML element.
+        var docNode = getDocNode(aID);
+        var html = docNode.createElement("html");
+        var body = docNode.createElement("body");
+        var text = docNode.createTextNode("Haha");
+        body.appendChild(text);
+        html.appendChild(body);
+        docNode.appendChild(html);
+      }
+
+      this.getID = function insertHTMLToIFrameDoc_getID()
+      {
+        return "insert HTML element document";
+      }
+    }
+
+    /**
+     * Remove/insert HTML body pair.
+     */
+    function removeBodyFromIFrameDoc(aID)
+    {
+      this.__proto__ = new rootContentRemoved(aID);
+
+      this.invoke = function removeBodyFromIFrameDoc_invoke()
+      {
+        this.preinvoke();
+
+        // Remove body element.
+        var docNode = getDocNode(aID);
+        docNode.documentElement.removeChild(docNode.body);
+      }
+
+      this.getID = function removeBodyFromIFrameDoc_getID()
+      {
+        return "remove body element";
+      }
+    }
+
+    function insertBodyToIFrameDoc(aID)
+    {
+      this.__proto__ = new rootContentInserted(aID, "Yo ho ho i butylka roma!");
+
+      this.invoke = function insertBodyToIFrameDoc_invoke()
+      {
+        // Insert body element.
+        var docNode = getDocNode(aID);
+        var body = docNode.createElement("body");
+        var text = docNode.createTextNode("Yo ho ho i butylka roma!");
+        body.appendChild(text);
+        docNode.documentElement.appendChild(body);
+      }
+
+      this.getID = function insertBodyToIFrameDoc_getID()
+      {
+        return "insert body element";
+      }
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Test
+
+    //gA11yEventDumpID = "eventdump"; // debug stuff
+
+    var gQueue = null;
+
+    function doTest()
+    {
+      gQueue = new eventQueue();
+
+      gQueue.push(new writeIFrameDoc("iframe"));
+      gQueue.push(new replaceIFrameHTMLElm("iframe"));
+      gQueue.push(new replaceIFrameBody("iframe"));
+      gQueue.push(new openIFrameDoc("iframe"));
+      gQueue.push(new closeIFrameDoc("iframe"));
+      gQueue.push(new removeHTMLFromIFrameDoc("iframe"));
+      gQueue.push(new insertHTMLToIFrameDoc("iframe"));
+      gQueue.push(new removeBodyFromIFrameDoc("iframe"));
+      gQueue.push(new insertBodyToIFrameDoc("iframe"));
+
+      gQueue.invoke(); // SimpleTest.finish() will be called in the end
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  </script>
+</head>
+<body>
+
+  <a target="_blank"
+     title="Update accessible tree when root element is changed"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=606082">Mozilla Bug 606082</a>
+
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+
+  <iframe id="iframe"></iframe>
+
+  <div id="eventdump"></div>
+</body>
+</html>
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -54,19 +54,19 @@ pref("browser.chromeURL","chrome://brows
 pref("browser.hiddenWindowChromeURL", "chrome://browser/content/hiddenWindow.xul");
 
 // Enables some extra Extension System Logging (can reduce performance)
 pref("extensions.logging.enabled", false);
 
 // Preferences for AMO integration
 pref("extensions.getAddons.cache.enabled", true);
 pref("extensions.getAddons.maxResults", 15);
-pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/search/guid:%IDS%");
+pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/search/guid:%IDS%?src=firefox");
 pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/%APP%/search?q=%TERMS%");
-pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/search/%TERMS%/all/%MAX_RESULTS%/%OS%/%VERSION%");
+pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/search/%TERMS%/all/%MAX_RESULTS%/%OS%/%VERSION%?src=firefox");
 pref("extensions.webservice.discoverURL", "https://services.addons.mozilla.org/%LOCALE%/%APP%/discovery/%VERSION%/%OS%");
 
 // Blocklist preferences
 pref("extensions.blocklist.enabled", true);
 pref("extensions.blocklist.interval", 86400);
 // Controls what level the blocklist switches from warning about items to forcibly
 // blocking them.
 pref("extensions.blocklist.level", 2);
@@ -234,16 +234,18 @@ pref("general.autoScroll", true);
 // is the default browser.
 pref("browser.shell.checkDefaultBrowser", true);
 
 // 0 = blank, 1 = home (browser.startup.homepage), 2 = last visited page, 3 = resume previous browser session
 // The behavior of option 3 is detailed at: http://wiki.mozilla.org/Session_Restore
 pref("browser.startup.page",                1);
 pref("browser.startup.homepage",            "chrome://branding/locale/browserconfig.properties");
 
+pref("browser.aboutHomeSnippets.updateUrl", "http://snippets.mozilla.com/%STARTPAGE_VERSION%/%NAME%/%VERSION%/%APPBUILDID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/");
+
 pref("browser.enable_automatic_image_resizing", true);
 pref("browser.chrome.site_icons", true);
 pref("browser.chrome.favicons", true);
 pref("browser.warnOnQuit", true);
 pref("browser.warnOnRestart", true);
 pref("browser.fullscreen.autohide", true);
 pref("browser.fullscreen.animateUp", 1);
 
--- a/browser/base/Makefile.in
+++ b/browser/base/Makefile.in
@@ -77,13 +77,14 @@ endif
 
 ifneq (,$(filter windows cocoa gtk2, $(MOZ_WIDGET_TOOLKIT)))
 ifneq ($(OS_ARCH),WINCE)
 DEFINES += -DCONTEXT_COPY_IMAGE_CONTENTS=1
 endif
 endif
 
 ifneq (,$(filter windows, $(MOZ_WIDGET_TOOLKIT)))
+DEFINES += -DCAN_DRAW_IN_TITLEBAR=1
 DEFINES += -DMENUBAR_CAN_AUTOHIDE=1
 endif
 
 libs::
 	$(NSINSTALL) $(srcdir)/content/tabview/modules/* $(FINAL_TARGET)/modules/tabview
--- a/browser/base/content/aboutHome.css
+++ b/browser/base/content/aboutHome.css
@@ -99,16 +99,17 @@ body[dir="rtl"] #searchEngineLinks {
   float: left;
 }
 
 #searchEngineLogo {
   margin: 5px;
 }
 
 #searchText {
+  margin-bottom: 10px;
   width: 100%;
 }
 
 #aboutMozilla {
   text-align: center;
 }
 
 #defaultSnippets {
--- a/browser/base/content/aboutHome.js
+++ b/browser/base/content/aboutHome.js
@@ -134,60 +134,70 @@ function setupSearchEngine()
 
 function loadSnippets()
 {
   // Check last snippets update.
   let lastUpdate = localStorage["snippets-last-update"];
   let updateURL = localStorage["snippets-update-url"];
   if (updateURL && (!lastUpdate ||
                     Date.now() - lastUpdate > SNIPPETS_UPDATE_INTERVAL_MS)) {
+    // Even if fetching should fail we don't want to spam the server, thus
+    // set the last update time regardless its results.  Will retry tomorrow.
+    localStorage["snippets-last-update"] = Date.now();
+
     // Try to update from network.
     let xhr = new XMLHttpRequest();
     xhr.open('GET', updateURL, true);
     xhr.onerror = function (event) {
       showSnippets();
     };
     xhr.onload = function (event)
     {
       if (xhr.status == 200) {
         localStorage["snippets"] = xhr.responseText;
-        localStorage["snippets-last-update"] = Date.now();
       }
       showSnippets();
     };
     xhr.send(null);
   } else {
     showSnippets();
   }
 }
 
 function showSnippets()
 {
   let snippets = localStorage["snippets"];
+  // If there are remotely fetched snippets, try to to show them.
   if (snippets) {
     let snippetsElt = document.getElementById("snippets");
-    snippetsElt.innerHTML = snippets;
-    // Scripts injected by innerHTML are inactive, so we have to relocate them
-    // through DOM manipulation to activate their contents.
-    Array.forEach(snippetsElt.getElementsByTagName("script"), function(elt) {
-      let relocatedScript = document.createElement("script");
-      relocatedScript.type = "text/javascript;version=1.8";
-      relocatedScript.text = elt.text;
-      elt.parentNode.replaceChild(relocatedScript, elt);
-    });
-    snippetsElt.hidden = false;
-  } else {
-    // If there are no saved snippets, show one of the default ones.
-    let defaultSnippetsElt = document.getElementById("defaultSnippets");
-    let entries = defaultSnippetsElt.querySelectorAll("span");
-    // Choose a random snippet.  Assume there is always at least one.
-    let randIndex = Math.round(Math.random() * (entries.length - 1));
-    let entry = entries[randIndex];
-    // Inject url in the eventual link.
-    if (DEFAULT_SNIPPETS_URLS[randIndex]) {
-      let links = entry.getElementsByTagName("a");
-      if (links.length != 1)
-        return; // Something is messed up in this entry, we support just 1 link.
-      links[0].href = DEFAULT_SNIPPETS_URLS[randIndex];
+    // Injecting snippets can throw if they're invalid XML.
+    try {
+      snippetsElt.innerHTML = snippets;
+      // Scripts injected by innerHTML are inactive, so we have to relocate them
+      // through DOM manipulation to activate their contents.
+      Array.forEach(snippetsElt.getElementsByTagName("script"), function(elt) {
+        let relocatedScript = document.createElement("script");
+        relocatedScript.type = "text/javascript;version=1.8";
+        relocatedScript.text = elt.text;
+        elt.parentNode.replaceChild(relocatedScript, elt);
+      });
+      snippetsElt.hidden = false;
+      return;
+    } catch (ex) {
+      // Bad content, continue to show default snippets.
     }
-    entry.hidden = false;
   }
+
+  // Show default snippets otherwise.
+  let defaultSnippetsElt = document.getElementById("defaultSnippets");
+  let entries = defaultSnippetsElt.querySelectorAll("span");
+  // Choose a random snippet.  Assume there is always at least one.
+  let randIndex = Math.round(Math.random() * (entries.length - 1));
+  let entry = entries[randIndex];
+  // Inject url in the eventual link.
+  if (DEFAULT_SNIPPETS_URLS[randIndex]) {
+    let links = entry.getElementsByTagName("a");
+    if (links.length != 1)
+      return; // Something is messed up in this entry, we support just 1 link.
+    links[0].href = DEFAULT_SNIPPETS_URLS[randIndex];
+  }
+  entry.hidden = false;
 }
--- a/browser/base/content/aboutHome.xhtml
+++ b/browser/base/content/aboutHome.xhtml
@@ -67,17 +67,16 @@
       <div id="topSection">
         <div id="brandStart">
           &abouthome.brandStart;
         </div>
         <div id ="searchContainer">
           <img id="searchEngineLogo"/>
           <form name="searchForm" onsubmit="onSearchSubmit(event)">
             <input type="text" name="searchText" value="" id="searchText" maxLength="256"/>
-            <br/>
             <input type="submit" value="&abouthome.searchEngineButton.label;"/>
             <span id="searchEngineLinks">
               <a hidden="true" id="searchEngineAdvancedLink">&abouthome.searchEngineLinks.advanced;</a>
               <a hidden="true" id="searchEngineAdvancedPreferences">&abouthome.searchEngineLinks.preferences;</a>
             </span>
           </form>
         </div>
       </div>
--- a/browser/base/content/baseMenuOverlay.xul
+++ b/browser/base/content/baseMenuOverlay.xul
@@ -108,25 +108,16 @@
                   label="&helpFeedbackPage.label;"
                   oncommand="openFeedbackPage()"
                   onclick="checkForMiddleClick(this, event);"/>
         <menuitem id="helpSafeMode"
                   accesskey="&helpSafeMode.accesskey;"
                   label="&helpSafeMode.label;"
                   oncommand="safeModeRestart();"/>
         <menuseparator/>
-        <menuseparator id="updateSeparator"/>
-#ifdef XP_MACOSX
-#ifdef MOZ_UPDATER
-        <menuitem id="checkForUpdates"
-                  label="&updateCmd.label;"
-                  class="menuitem-iconic"
-                  oncommand="checkForUpdates();"/>
-#endif
-#endif
         <menuseparator id="aboutSeparator"/>
         <menuitem id="aboutName"
                   accesskey="&aboutProduct.accesskey;"
                   label="&aboutProduct.label;"
                   oncommand="openAboutDialog();"/>
       </menupopup>
     </menu>
 
new file mode 100644
--- /dev/null
+++ b/browser/base/content/browser-appmenu.inc
@@ -0,0 +1,409 @@
+# -*- Mode: HTML -*-
+# ***** 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 Firefox Application Menu.
+#
+# The Initial Developer of the Original Code is
+# The Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2010
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Dão Gottwald <dao@mozilla.com>
+#   Joshua M. <soapyhamhocks@gmail.com>
+#   Margaret Leibovic <margaret.leibovic@gmail.com>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+<menupopup id="appmenu-popup"
+#ifdef MOZ_SERVICES_SYNC
+           onpopupshowing="updateEditUIVisibility();gSyncUI.updateUI();">
+#else
+           onpopupshowing="updateEditUIVisibility();">
+#endif
+  <hbox>
+    <vbox id="appmenuPrimaryPane">
+      <hbox flex="1"
+            class="split-menuitem">
+        <menuitem id="appmenu_newTab"
+                  class="menuitem-tooltip split-menuitem-item"
+                  flex="1"
+                  label="&tabCmd.label;"
+                  command="cmd_newNavigatorTab"
+                  key="key_newNavigatorTab"/>
+        <menu class="split-menuitem-menu">
+          <menupopup>
+            <menuitem id="appmenu_newTab_popup"
+                      label="&tabCmd.label;"
+                      command="cmd_newNavigatorTab"
+                      key="key_newNavigatorTab"/>
+            <menuitem id="appmenu_newNavigator"
+                      label="&newNavigatorCmd.label;"
+                      command="cmd_newNavigator"
+                      key="key_newNavigator"/>
+            <menuseparator/>
+            <menuitem id="appmenu_openFile"
+                      label="&openFileCmd.label;"
+                      command="Browser:OpenFile"
+                      key="openFileKb"/>
+          </menupopup>
+        </menu>
+      </hbox>
+      <menuitem id="appmenu_privateBrowsing"
+                class="menuitem-iconic menuitem-iconic-tooltip"
+                label="&privateBrowsingCmd.start.label;"
+                startlabel="&privateBrowsingCmd.start.label;"
+                stoplabel="&privateBrowsingCmd.stop.label;"
+                command="Tools:PrivateBrowsing"
+                key="key_privatebrowsing"/>
+      <menuitem label="&goOfflineCmd.label;"
+                id="appmenu_offlineModeRecovery"
+                type="checkbox"
+                observes="workOfflineMenuitemState"
+                oncommand="BrowserOffline.toggleOfflineStatus();"/>
+      <menuseparator class="appmenu-menuseparator"/>
+      <hbox>
+        <menuitem id="appmenu-edit-label"
+                  label="&appMenuEdit.label;"
+                  disabled="true"/>
+        <toolbarbutton id="appmenu-cut"
+                       class="appmenu-edit-button"
+                       command="cmd_cut"
+                       onclick="if (!this.disabled) hidePopup();"
+                       tooltiptext="&cutButton.tooltip;"/>
+        <toolbarbutton id="appmenu-copy"
+                       class="appmenu-edit-button"
+                       command="cmd_copy"
+                       onclick="if (!this.disabled) hidePopup();"
+                       tooltiptext="&copyButton.tooltip;"/>
+        <toolbarbutton id="appmenu-paste"
+                       class="appmenu-edit-button"
+                       command="cmd_paste"
+                       onclick="if (!this.disabled) hidePopup();"
+                       tooltiptext="&pasteButton.tooltip;"/>
+      </hbox>
+      <menuitem id="appmenu_find"
+                class="menuitem-tooltip"
+                label="&appMenuFind.label;"
+                command="cmd_find"
+                key="key_find"/>
+      <menuseparator class="appmenu-menuseparator"/>
+      <menuitem id="appmenu_savePage"
+                class="menuitem-tooltip"
+                label="&savePageCmd.label;"
+                command="Browser:SavePage"
+                key="key_savePage"/>
+      <menuitem id="appmenu_sendLink"
+                label="&sendPageCmd.label;"
+                command="Browser:SendLink"/>
+      <hbox flex="1"
+            class="split-menuitem">
+        <menuitem id="appmenu_print"
+                  class="menuitem-iconic menuitem-iconic-tooltip split-menuitem-item"
+                  flex="1"
+                  label="&printCmd.label;"
+                  command="cmd_print"
+                  key="printKb"/>
+        <menu class="split-menuitem-menu">
+          <menupopup>
+            <menuitem id="appmenu_print_popup"
+                      class="menuitem-iconic"
+                      label="&printCmd.label;"
+                      command="cmd_print"
+                      key="printKb"/>
+            <menuitem id="appmenu_printPreview"
+                      label="&printPreviewCmd.label;"
+                      command="cmd_printPreview"/>
+            <menuitem id="appmenu_printSetup"
+                      label="&printSetupCmd.label;"
+                      command="cmd_pageSetup"/>
+          </menupopup>
+        </menu>
+      </hbox>
+      <menuseparator class="appmenu-menuseparator"/>
+      <menu id="appmenu_webDeveloper"
+            label="&appMenuWebDeveloper.label;">
+        <menupopup id="appmenu_webDeveloper_popup">
+          <menuitem id="appmenu_webConsole"
+                    label="&webConsoleCmd.label;"
+                    oncommand="HUDConsoleUI.toggleHUD();"
+                    key="key_webConsole"/>
+          <menuitem id="appmenu_pageInspect"
+                    hidden="true"
+                    label="&inspectMenu.label;"
+                    type="checkbox"
+                    command="Tools:Inspect"
+                    key="key_inspect"/>
+          <menuseparator/>
+          <menuitem id="appmenu_pageSource"
+                    label="&viewPageSourceCmd.label;"
+                    command="View:PageSource"
+                    key="key_viewSource"/>
+          <menuseparator/>
+#define ID_PREFIX appmenu_developer_
+#include browser-charsetmenu.inc
+#undef ID_PREFIX
+          <menuseparator/>
+          <menuitem label="&goOfflineCmd.label;"
+                    type="checkbox"
+                    observes="workOfflineMenuitemState"
+                    oncommand="BrowserOffline.toggleOfflineStatus();"/>
+        </menupopup>
+      </menu>
+      <menuseparator class="appmenu-menuseparator"/>
+#define ID_PREFIX appmenu_
+#include browser-charsetmenu.inc
+#undef ID_PREFIX
+      <menuitem id="appmenu_fullScreen"
+                class="menuitem-tooltip"
+                label="&fullScreenCmd.label;"
+                type="checkbox"
+                observes="View:FullScreen"
+                key="key_fullScreen"/>
+      <menuitem id="appmenu-quit"
+                class="menuitem-iconic"
+#ifdef XP_WIN
+                label="&quitApplicationCmdWin.label;"
+#else
+                label="&quitApplicationCmd.label;"
+#endif
+                command="cmd_quitApplication"/>
+    </vbox>
+    <vbox id="appmenuSecondaryPane">
+      <hbox class="split-menuitem">
+        <menuitem id="appmenu_bookmarks"
+                  class="menuitem-iconic menuitem-iconic-tooltip split-menuitem-item"
+                  flex="1"
+                  label="&bookmarksMenu.label;"
+                  command="Browser:ShowAllBookmarks"
+                  key="manBookmarkKb"/>
+        <menu id="appmenu_bookmarksMenu"
+              class="split-menuitem-menu">
+          <menupopup id="appmenu_bookmarksPopup"
+                     placespopup="true"
+                     context="placesContext"
+                     openInTabs="children"
+                     oncommand="BookmarksEventHandler.onCommand(event);"
+                     onclick="BookmarksEventHandler.onClick(event);"
+                     onpopupshowing="BookmarksMenuButton.onPopupShowing(event);
+                                     if (!this.parentNode._placesView)
+                                       new PlacesMenu(event, 'place:folder=BOOKMARKS_MENU');"
+                     tooltip="bhTooltip"
+                     popupsinherittooltip="true">
+            <menuitem id="appmenu_showAllBookmarks"
+                      label="&showAllBookmarks.label;"
+                      command="Browser:ShowAllBookmarks"
+                      context=""
+                      key="manBookmarkKb"/>
+            <menuseparator/>
+            <menuitem id="appmenu_bookmarkThisPage"
+                      class="menuitem-iconic"
+                      label="&bookmarkThisPageCmd.label;"
+                      command="Browser:AddBookmarkAs"
+                      key="addBookmarkAsKb"/>
+            <menuitem id="appmenu_subscribeToPage"
+                      class="menuitem-iconic"
+                      label="&subscribeToPageMenuitem.label;"
+                      oncommand="return FeedHandler.subscribeToFeed(null, event);"
+                      onclick="checkForMiddleClick(this, event);"
+                      observes="singleFeedMenuitemState"/>
+            <menu id="appmenu_subscribeToPageMenu"
+                  class="menu-iconic"
+                  label="&subscribeToPageMenupopup.label;"
+                  observes="multipleFeedsMenuState">
+              <menupopup id="appmenu_subscribeToPageMenupopup"
+                         onpopupshowing="return FeedHandler.buildFeedList(event.target);"
+                         oncommand="return FeedHandler.subscribeToFeed(null, event);"
+                         onclick="checkForMiddleClick(this, event);"/>
+            </menu>
+            <menuseparator/>
+            <menu id="appmenu_bookmarksToolbar"
+                  placesanonid="toolbar-autohide"
+                  class="menu-iconic bookmark-item"
+                  label="&personalbarCmd.label;"
+                  container="true">
+              <menupopup id="appmenu_bookmarksToolbarPopup"
+                         placespopup="true"
+                         context="placesContext"
+                         onpopupshowing="if (!this.parentNode._placesView)
+                                           new PlacesMenu(event, 'place:folder=TOOLBAR');"/>
+            </menu>
+            <menuseparator/>
+            <!-- Bookmarks menu items -->
+            <menuseparator builder="end"
+                           class="hide-if-empty-places-result"/>
+            <menuitem id="appmenu_unsortedBookmarks"
+                      label="&appMenuUnsorted.label;"
+                      oncommand="PlacesCommandHook.showPlacesOrganizer('UnfiledBookmarks');"
+                      class="menuitem-iconic"/>
+          </menupopup>
+        </menu>
+      </hbox>
+      <hbox class="split-menuitem">
+        <menuitem id="appmenu_history"
+                  class="menuitem-iconic menuitem-iconic-tooltip split-menuitem-item"
+                  flex="1"
+                  label="&historyMenu.label;"
+                  command="Browser:ShowAllHistory"
+                  key="showAllHistoryKb"/>
+        <menu id="appmenu_historyMenu"
+              class="split-menuitem-menu">
+          <menupopup id="appmenu_historyMenupopup"
+                     placespopup="true"
+                     oncommand="this.parentNode._placesView._onCommand(event);"
+                     onclick="checkForMiddleClick(this, event);"
+                     onpopupshowing="if (!this.parentNode._placesView)
+                                       new HistoryMenu(event);"
+                     tooltip="bhTooltip"
+                     popupsinherittooltip="true">
+            <menuitem id="appmenu_showAllHistory"
+                      label="&showAllHistoryCmd2.label;"
+                      command="Browser:ShowAllHistory"
+                      key="showAllHistoryKb"/>
+            <menuseparator/>
+            <menuitem id="appmenu_sanitizeHistory"
+                      label="&clearRecentHistory.label;"
+                      key="key_sanitize"
+                      command="Tools:Sanitize"/>
+            <menuseparator class="hide-if-empty-places-result"/>
+            <menuitem id="appmenu_restoreLastSession"
+                      class="restoreLastSession"
+                      label="&historyRestoreLastSession.label;"
+                      oncommand="restoreLastSession();"
+                      disabled="true"/>
+            <menu id="appmenu_recentlyClosedTabsMenu"
+                  class="recentlyClosedTabsMenu"
+                  label="&historyUndoMenu.label;"
+                  disabled="true">
+              <menupopup id="appmenu_recentlyClosedTabsMenupopup"
+                         onpopupshowing="document.getElementById('appmenu_historyMenu')._placesView.populateUndoSubmenu();"/>
+            </menu>
+            <menu id="appmenu_recentlyClosedWindowsMenu"
+                  class="recentlyClosedWindowsMenu"
+                  label="&historyUndoWindowMenu.label;"
+                  disabled="true">
+              <menupopup id="appmenu_recentlyClosedWindowsMenupopup"
+                         onpopupshowing="document.getElementById('appmenu_historyMenu')._placesView.populateUndoWindowSubmenu();"/>
+            </menu>
+            <menuseparator/>
+          </menupopup>
+        </menu>
+      </hbox>
+      <menuitem id="appmenu_downloads"
+                class="menuitem-tooltip"
+                label="&downloads.label;"
+                command="Tools:Downloads"
+                key="key_openDownloads"/>
+      <spacer id="appmenuSecondaryPane-spacer"/>
+      <menuitem id="appmenu_addons"
+                class="menuitem-iconic menuitem-iconic-tooltip"
+                label="&addons.label;"
+                command="Tools:Addons"
+                key="key_openAddons"/>
+      <hbox class="split-menuitem">
+        <menuitem id="appmenu_customize"
+#ifdef XP_UNIX
+                  label="&preferencesCmdUnix.label;"
+#else
+                  label="&preferencesCmd.label;"
+#endif
+                  class="split-menuitem-item"
+                  flex="1"
+                  oncommand="openPreferences();"/>
+        <menu class="split-menuitem-menu"
+              label="&preferencesCmd.label;">
+          <menupopup id="appmenu_customizeMenu"
+                     onpopupshowing="onViewToolbarsPopupShowing(event, document.getElementById('appmenu_toggleTabsOnTop').previousSibling);">
+            <menuitem id="appmenu_preferences"
+#ifdef XP_UNIX
+                      label="&preferencesCmdUnix.label;"
+#else
+                      label="&preferencesCmd.label;"
+#endif
+                      oncommand="openPreferences();"/>
+            <menuseparator/>
+            <menuseparator/>
+            <menuitem id="appmenu_toggleTabsOnTop"
+                      label="&viewTabsOnTop.label;"
+                      type="checkbox"
+                      command="cmd_ToggleTabsOnTop"/>
+            <menuitem id="appmenu_toolbarLayout"
+                      label="&appMenuToolbarLayout.label;"
+                      command="cmd_CustomizeToolbars"/>
+          </menupopup>
+        </menu>
+      </hbox>
+      <hbox class="split-menuitem">
+        <menuitem id="appmenu_help"
+                  class="split-menuitem-item"
+                  flex="1"
+                  label="&helpMenu.label;"
+                  oncommand="openHelpLink('firefox-help')"/>
+        <menu class="split-menuitem-menu">
+          <menupopup id="appmenu_helpMenupopup">
+            <menuitem id="appmenu_openHelp"
+                      label="&helpMenu.label;"
+                      oncommand="openHelpLink('firefox-help')"
+                      onclick="checkForMiddleClick(this, event);"/>
+            <menuitem id="appmenu_gettingStarted"
+                      label="&appMenuGettingStarted.label;"
+                      oncommand="gBrowser.loadOneTab('http://www.mozilla.com/firefox/central/', {inBackground: false});"
+                      onclick="checkForMiddleClick(this, event);"/>
+            <menuitem id="appmenu_troubleshootingInfo"
+                      label="&helpTroubleshootingInfo.label;"
+                      oncommand="openTroubleshootingPage()"
+                      onclick="checkForMiddleClick(this,event);"/>
+            <menuitem id="appmenu_feedbackPage"
+                      label="&helpFeedbackPage.label;"
+                      oncommand="openFeedbackPage()"
+                      onclick="checkForMiddleClick(this, event);"/>
+            <menuseparator/>
+            <menuitem id="appmenu_safeMode"
+                      accesskey="&appMenuSafeMode.accesskey;"
+                      label="&appMenuSafeMode.label;"
+                      oncommand="safeModeRestart();"/>
+            <menuseparator/>
+            <menuitem id="appmenu_about"
+                      label="&aboutProduct.label;"
+                      oncommand="openAboutDialog();"/>
+          </menupopup>
+        </menu>
+      </hbox>
+#ifdef MOZ_SERVICES_SYNC
+      <spacer flex="1"/>
+      <!-- only one of sync-setup or sync-syncnow will be showing at once -->
+      <menuitem id="sync-setup-appmenu"
+                label="&syncSetup.label;"
+                observes="sync-setup-state"
+                oncommand="gSyncUI.openSetup()"/>
+      <menuitem id="sync-syncnowitem-appmenu"
+                label="&syncSyncNowItem.label;"
+                observes="sync-syncnow-state"
+                oncommand="gSyncUI.doSync(event);"/>
+#endif
+    </vbox>
+  </hbox>
+</menupopup>
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -434,21 +434,27 @@
                onpopupshowing="if (!this.parentNode._placesView)
                                  new PlacesMenu(event, 'place:folder=BOOKMARKS_MENU');"
                tooltip="bhTooltip" popupsinherittooltip="true">
       <menuitem id="menu_bookmarkThisPage"
                 label="&bookmarkThisPageCmd.label;"
                 command="Browser:AddBookmarkAs"
                 key="addBookmarkAsKb"/>
       <menuitem id="subscribeToPageMenuitem"
+#ifndef XP_MACOSX
+                class="menuitem-iconic"
+#endif
                 label="&subscribeToPageMenuitem.label;"
                 oncommand="return FeedHandler.subscribeToFeed(null, event);"
                 onclick="checkForMiddleClick(this, event);"
                 observes="singleFeedMenuitemState"/>
       <menu id="subscribeToPageMenupopup"
+#ifndef XP_MACOSX
+            class="menu-iconic"
+#endif
             label="&subscribeToPageMenupopup.label;"
             observes="multipleFeedsMenuState">
         <menupopup id="subscribeToPageSubmenuMenupopup"
                    onpopupshowing="return FeedHandler.buildFeedList(event.target);"
                    oncommand="return FeedHandler.subscribeToFeed(null, event);"
                    onclick="checkForMiddleClick(this, event);"/>
       </menu>
       <menuitem id="menu_bookmarkAllTabs"
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -75,17 +75,17 @@ toolbar[printpreview="true"] {
 #TabsToolbar {
   -moz-box-ordinal-group: 100;
 }
 
 #TabsToolbar[tabsontop="true"] {
   -moz-box-ordinal-group: 10;
 }
 
-%ifdef MENUBAR_CAN_AUTOHIDE
+%ifdef CAN_DRAW_IN_TITLEBAR
 #main-window[inFullscreen] > #titlebar {
   display: none;
 }
 
 #titlebar {
   -moz-binding: url("chrome://global/content/bindings/general.xml#windowdragbox");
 }
 %endif
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1908,31 +1908,31 @@ function BrowserReload() {
 }
 
 function BrowserReloadSkipCache() {
   // Bypass proxy and cache.
   const reloadFlags = nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY | nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE;
   BrowserReloadWithFlags(reloadFlags);
 }
 
-function BrowserHome()
-{
-  var homePage = gHomeButton.getHomePage();
-  loadOneOrMoreURIs(homePage);
-}
-
+var BrowserHome = BrowserGoHome;
 function BrowserGoHome(aEvent) {
   if (aEvent && "button" in aEvent &&
       aEvent.button == 2) // right-click: do nothing
     return;
 
   var homePage = gHomeButton.getHomePage();
   var where = whereToOpenLink(aEvent, false, true);
   var urls;
 
+  // Home page should open in a new tab when current tab is an app tab
+  if (where == "current" &&
+      gBrowser.selectedTab.pinned)
+    where = "tab";
+
   // openUILinkIn in utilityOverlay.js doesn't handle loading multiple pages
   switch (where) {
   case "current":
     loadOneOrMoreURIs(homePage);
     break;
   case "tabshifted":
   case "tab":
     urls = homePage.split("|");
@@ -3484,20 +3484,21 @@ function BrowserToolboxCustomizeDone(aTo
 #ifndef XP_MACOSX
     updateEditUIVisibility();
 #endif
   }
 
   PlacesToolbarHelper.customizeDone();
   BookmarksMenuButton.customizeDone();
 
+  // The url bar splitter state is dependent on whether stop/reload
+  // and the location bar are combined, so we need this ordering
+  CombinedStopReload.init();
   UpdateUrlbarSearchSplitterState();
 
-  CombinedStopReload.init();
-
   // Update the urlbar
   if (gURLBar) {
     URLBarSetURI();
     XULBrowserWindow.asyncUpdateUI();
     PlacesStarButton.updateState();
   }
 
   // Re-enable parts of the UI we disabled during the dialog
@@ -4718,24 +4719,28 @@ var TabsOnTop = {
 
 #ifdef MENUBAR_CAN_AUTOHIDE
 function updateAppButtonDisplay() {
   var displayAppButton =
     !gInPrintPreviewMode &&
     window.menubar.visible &&
     document.getElementById("toolbar-menubar").getAttribute("autohide") == "true";
 
+#ifdef CAN_DRAW_IN_TITLEBAR
   document.getElementById("titlebar").hidden = !displayAppButton;
 
   if (displayAppButton)
     document.documentElement.setAttribute("chromemargin", "0,-1,-1,-1");
   else
     document.documentElement.removeAttribute("chromemargin");
-}
-
+#endif
+}
+#endif
+
+#ifdef CAN_DRAW_IN_TITLEBAR
 function onTitlebarMaxClick() {
   if (window.windowState == window.STATE_MAXIMIZED)
     window.restore();
   else
     window.maximize();
 }
 #endif
 
@@ -4978,165 +4983,191 @@ function asyncOpenWebPanel(event)
 }
 
 /*
  * - [ Dependencies ] ---------------------------------------------------------
  *  utilityOverlay.js:
  *    - gatherTextUnder
  */
 
- // Called whenever the user clicks in the content area,
- // except when left-clicking on links (special case)
- // should always return true for click to go through
- function contentAreaClick(event, fieldNormalClicks)
- {
-   if (!event.isTrusted || event.getPreventDefault()) {
-     return true;
-   }
-
-   var target = event.target;
-   var linkNode;
-
-   if (target instanceof HTMLAnchorElement ||
-       target instanceof HTMLAreaElement ||
-       target instanceof HTMLLinkElement) {
-     if (target.hasAttribute("href"))
-       linkNode = target;
-
-     // xxxmpc: this is kind of a hack to work around a Gecko bug (see bug 266932)
-     // we're going to walk up the DOM looking for a parent link node,
-     // this shouldn't be necessary, but we're matching the existing behaviour for left click
-     var parent = target.parentNode;
-     while (parent) {
-       if (parent instanceof HTMLAnchorElement ||
-           parent instanceof HTMLAreaElement ||
-           parent instanceof HTMLLinkElement) {
-           if (parent.hasAttribute("href"))
-             linkNode = parent;
-       }
-       parent = parent.parentNode;
-     }
-   }
-   else {
-     linkNode = event.originalTarget;
-     while (linkNode && !(linkNode instanceof HTMLAnchorElement))
-       linkNode = linkNode.parentNode;
-     // <a> cannot be nested.  So if we find an anchor without an
-     // href, there is no useful <a> around the target
-     if (linkNode && !linkNode.hasAttribute("href"))
-       linkNode = null;
-   }
-   var wrapper = null;
-   if (linkNode) {
-     wrapper = linkNode;
-     if (event.button == 0 && !event.ctrlKey && !event.shiftKey &&
-         !event.altKey && !event.metaKey) {
-       // A Web panel's links should target the main content area.  Do this
-       // if no modifier keys are down and if there's no target or the target equals
-       // _main (the IE convention) or _content (the Mozilla convention).
-       // XXX Now that markLinkVisited is gone, we may not need to field _main and
-       // _content here.
-       target = wrapper.getAttribute("target");
-       if (fieldNormalClicks &&
-           (!target || target == "_content" || target  == "_main"))
-         // IE uses _main, SeaMonkey uses _content, we support both
-       {
-         if (!wrapper.href)
-           return true;
-         if (wrapper.getAttribute("onclick"))
-           return true;
-         // javascript links should be executed in the current browser
-         if (wrapper.href.substr(0, 11) === "javascript:")
-           return true;
-         // data links should be executed in the current browser
-         if (wrapper.href.substr(0, 5) === "data:")
-           return true;
-
-         try {
-           urlSecurityCheck(wrapper.href, wrapper.ownerDocument.nodePrincipal);
-         }
-         catch(ex) {
-           return false;
-         }
-
-         var postData = { };
-         var url = getShortcutOrURI(wrapper.href, postData);
-         if (!url)
-           return true;
-         loadURI(url, null, postData.value, false);
-         event.preventDefault();
-         return false;
-       }
-       else if (linkNode.getAttribute("rel") == "sidebar") {
-         // This is the Opera convention for a special link that - when clicked - allows
-         // you to add a sidebar panel.  We support the Opera convention here.  The link's
-         // title attribute contains the title that should be used for the sidebar panel.
-         PlacesUIUtils.showMinimalAddBookmarkUI(makeURI(wrapper.href),
-                                                wrapper.getAttribute("title"),
-                                                null, null, true, true);
-         event.preventDefault();
-         return false;
-       }
-     }
-     else {
-       handleLinkClick(event, wrapper.href, linkNode);
-     }
-
-     return true;
-   } else {
-     // Try simple XLink
-     var href, realHref, baseURI;
-     linkNode = target;
-     while (linkNode) {
-       if (linkNode.nodeType == Node.ELEMENT_NODE) {
-         wrapper = linkNode;
-
-         realHref = wrapper.getAttributeNS("http://www.w3.org/1999/xlink", "href");
-         if (realHref) {
-           href = realHref;
-           baseURI = wrapper.baseURI
-         }
-       }
-       linkNode = linkNode.parentNode;
-     }
-     if (href) {
-       href = makeURLAbsolute(baseURI, href);
-       handleLinkClick(event, href, null);
-       return true;
-     }
-   }
-   if (event.button == 1 &&
-       gPrefService.getBoolPref("middlemouse.contentLoadURL") &&
-       !gPrefService.getBoolPref("general.autoScroll")) {
-     middleMousePaste(event);
-   }
-   return true;
- }
-
+/**
+ * Extracts linkNode and href for the current click target.
+ *
+ * @param event
+ *        The click event.
+ * @return [href, linkNode].
+ *
+ * @note linkNode will be null if the click wasn't on an anchor
+ *       element (or XLink).
+ */
+function hrefAndLinkNodeForClickEvent(event)
+{
+  function isHTMLLink(aNode)
+  {
+    return aNode instanceof HTMLAnchorElement ||
+           aNode instanceof HTMLAreaElement ||
+           aNode instanceof HTMLLinkElement;
+  }
+
+  let linkNode;
+  if (isHTMLLink(event.target)) {
+    // This is a hack to work around Gecko bug 266932.
+    // Walk up the DOM looking for a parent link node, to match the existing
+    // behaviour for left click.
+    // TODO: this is no more needed and should be removed in bug 325652.
+    let node = event.target;
+    while (node) {
+      if (isHTMLLink(node) && node.hasAttribute("href"))
+        linkNode = node;
+      node = node.parentNode;
+    }
+  }
+  else {
+    let node = event.originalTarget;
+    while (node && !(node instanceof HTMLAnchorElement)) {
+      node = node.parentNode;
+    }
+    // <a> cannot be nested.  So if we find an anchor without an
+    // href, there is no useful <a> around the target.
+    if (node && node.hasAttribute("href"))
+      linkNode = node;
+  }
+
+  if (linkNode)
+    return [linkNode.href, linkNode];
+
+  // If there is no linkNode, try simple XLink.
+  let href, baseURI;
+  let node = event.target;
+  while (node) {
+    if (node.nodeType == Node.ELEMENT_NODE) {
+      href = node.getAttributeNS("http://www.w3.org/1999/xlink", "href");
+      if (href)
+        baseURI = node.baseURI;
+    }
+    node = node.parentNode;
+  }
+
+  // In case of XLink, we don't return the node we got href from since
+  // callers expect <a>-like elements.
+  return [href ? makeURLAbsolute(baseURI, href) : null, null];
+}
+
+/**
+ * Called whenever the user clicks in the content area.
+ *
+ * @param event
+ *        The click event.
+ * @param isPanelClick
+ *        Whether the event comes from a web panel.
+ * @note default event is prevented if the click is handled.
+ */
+function contentAreaClick(event, isPanelClick)
+{
+  if (!event.isTrusted || event.getPreventDefault() || event.button == 2)
+    return true;
+
+  let [href, linkNode] = hrefAndLinkNodeForClickEvent(event);
+  if (!href) {
+    // Not a link, handle middle mouse navigation.
+    if (event.button == 1 &&
+        gPrefService.getBoolPref("middlemouse.contentLoadURL") &&
+        !gPrefService.getBoolPref("general.autoScroll")) {
+      middleMousePaste(event);
+      event.preventDefault();
+    }
+    return true;
+  }
+
+  // This code only applies if we have a linkNode (i.e. clicks on real anchor
+  // elements, as opposed to XLink).
+  if (linkNode && event.button == 0 &&
+      !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey) {
+    // A Web panel's links should target the main content area.  Do this
+    // if no modifier keys are down and if there's no target or the target
+    // equals _main (the IE convention) or _content (the Mozilla convention).
+    let target = linkNode.target;
+    let mainTarget = !target || target == "_content" || target  == "_main";
+    if (isPanelClick && mainTarget) {
+      // javascript and data links should be executed in the current browser.
+      if (linkNode.getAttribute("onclick") ||
+          href.substr(0, 11) === "javascript:" ||
+          href.substr(0, 5) === "data:")
+        return true;
+
+      try {
+        urlSecurityCheck(href, linkNode.ownerDocument.nodePrincipal);
+      }
+      catch(ex) {
+        // Prevent loading unsecure destinations.
+        event.preventDefault();
+        return true;
+      }
+
+      let postData = {};
+      let url = getShortcutOrURI(href, postData);
+      if (!url)
+        return true;
+      loadURI(url, null, postData.value, false);
+      event.preventDefault();
+      return true;
+    }
+
+    if (linkNode.getAttribute("rel") == "sidebar") {
+      // This is the Opera convention for a special link that, when clicked,
+      // allows to add a sidebar panel.  The link's title attribute contains
+      // the title that should be used for the sidebar panel.
+      PlacesUIUtils.showMinimalAddBookmarkUI(makeURI(href),
+                                             linkNode.getAttribute("title"),
+                                             null, null, true, true);
+      event.preventDefault();
+      return true;
+    }
+  }
+
+  handleLinkClick(event, href, linkNode);
+
+  // Mark the page as a user followed link.  This is done so that history can
+  // distinguish automatic embed visits from user activated ones.  For example
+  // pages loaded in frames are embed visits and lost with the session, while
+  // visits across frames should be preserved.
+  try {
+    PlacesUIUtils.markPageAsFollowedLink(href);
+  } catch (ex) { /* Skip invalid URIs. */ }
+
+  return true;
+}
+
+/**
+ * Handles clicks on links.
+ *
+ * @return true if the click event was handled, false otherwise.
+ */
 function handleLinkClick(event, href, linkNode) {
   if (event.button == 2) // right click
     return false;
 
   var where = whereToOpenLink(event);
   if (where == "current")
     return false;
 
   var doc = event.target.ownerDocument;
 
   if (where == "save") {
     saveURL(href, linkNode ? gatherTextUnder(linkNode) : "", null, true,
             true, doc.documentURIObject);
+    event.preventDefault();
     return true;
   }
 
   urlSecurityCheck(href, doc.nodePrincipal);
   openLinkIn(href, where, { fromContent: true,
                             referrerURI: doc.documentURIObject,
                             charset: doc.characterSet });
-  event.stopPropagation();
+  event.preventDefault();
   return true;
 }
 
 function middleMousePaste(event) {
   var url = getShortcutOrURI(readFromClipboard());
   try {
     makeURI(url);
   } catch (ex) {
@@ -7830,27 +7861,21 @@ var LightWeightThemeWebInstaller = {
 function switchToTabHavingURI(aURI, aOpenNew, aCallback) {
   function switchIfURIInWindow(aWindow) {
     if (!("gBrowser" in aWindow))
       return false;
     let browsers = aWindow.gBrowser.browsers;
     for (let i = 0; i < browsers.length; i++) {
       let browser = browsers[i];
       if (browser.currentURI.equals(aURI)) {
-        gURLBar.handleRevert();
-        // We need the current tab so we can check if we should close it
-        let prevTab = gBrowser.selectedTab;
         // Focus the matching window & tab
         aWindow.focus();
         aWindow.gBrowser.tabContainer.selectedIndex = i;
         if (aCallback)
           aCallback(browser);
-        // Close the previously selected tab if it was empty
-        if (isTabEmpty(prevTab))
-          gBrowser.removeTab(prevTab);
         return true;
       }
     }
     return false;
   }
 
   // This can be passed either nsIURI or a string.
   if (!(aURI instanceof Ci.nsIURI))
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -424,403 +424,35 @@
       <iframe id="customizeToolbarSheetIFrame"
               style="&dialog.style;"
               hidden="true"/>
     </panel>
 
     <tooltip id="tabbrowser-tab-tooltip" onpopupshowing="gBrowser.createTooltip(event);"/>
   </popupset>
 
-#ifdef MENUBAR_CAN_AUTOHIDE
-  <vbox id="titlebar">
+#ifdef CAN_DRAW_IN_TITLEBAR
+<vbox id="titlebar">
   <hbox id="titlebar-content">
-  <hbox id="appmenu-button-container" align="start">
-  <button id="appmenu-button"
-          type="menu"
-#ifdef XP_WIN
-          label="&brandShortName;"
-#else
-          label="&appMenuButton.label;"
-#endif
-          style="-moz-user-focus: ignore;">
-    <menupopup id="appmenu-popup"
-#ifdef MOZ_SERVICES_SYNC
-               onpopupshowing="updateEditUIVisibility();gSyncUI.updateUI();">
-#else
-               onpopupshowing="updateEditUIVisibility();">
-#endif
-      <hbox>
-        <vbox id="appmenuPrimaryPane">
-          <hbox flex="1"
-                class="split-menuitem">
-            <menuitem id="appmenu_newTab"
-                      class="menuitem-tooltip split-menuitem-item"
-                      flex="1"
-                      label="&tabCmd.label;"
-                      command="cmd_newNavigatorTab"
-                      key="key_newNavigatorTab"/>
-              <menu class="split-menuitem-menu">
-                <menupopup>
-                  <menuitem id="appmenu_newTab_popup"
-                            label="&tabCmd.label;"
-                            command="cmd_newNavigatorTab"
-                            key="key_newNavigatorTab"/>
-                  <menuitem id="appmenu_newNavigator"
-                            label="&newNavigatorCmd.label;"
-                            command="cmd_newNavigator"
-                            key="key_newNavigator"/>
-                  <menuseparator/>
-                  <menuitem id="appmenu_openFile"
-                            label="&openFileCmd.label;"
-                            command="Browser:OpenFile"
-                            key="openFileKb"/>
-                </menupopup>
-               </menu>
-          </hbox>
-          <menuitem id="appmenu_privateBrowsing"
-                    class="menuitem-iconic menuitem-iconic-tooltip"
-                    label="&privateBrowsingCmd.start.label;"
-                    startlabel="&privateBrowsingCmd.start.label;"
-                    stoplabel="&privateBrowsingCmd.stop.label;"
-                    command="Tools:PrivateBrowsing"
-                    key="key_privatebrowsing"/>
-          <menuitem label="&goOfflineCmd.label;"
-                    id="appmenu_offlineModeRecovery"
-                    type="checkbox"
-                    observes="workOfflineMenuitemState"
-                    oncommand="BrowserOffline.toggleOfflineStatus();"/>
-          <menuseparator class="appmenu-menuseparator"/>
-          <hbox>
-            <menuitem id="appmenu-edit-label"
-                      label="&appMenuEdit.label;"
-                      disabled="true"/>
-            <toolbarbutton id="appmenu-cut"
-                           class="appmenu-edit-button"
-                           command="cmd_cut"
-                           onclick="if (!this.disabled) hidePopup();"
-                           tooltiptext="&cutButton.tooltip;"/>
-            <toolbarbutton id="appmenu-copy"
-                           class="appmenu-edit-button"
-                           command="cmd_copy"
-                           onclick="if (!this.disabled) hidePopup();"
-                           tooltiptext="&copyButton.tooltip;"/>
-            <toolbarbutton id="appmenu-paste"
-                           class="appmenu-edit-button"
-                           command="cmd_paste"
-                           onclick="if (!this.disabled) hidePopup();"
-                           tooltiptext="&pasteButton.tooltip;"/>
-          </hbox>
-          <menuitem id="appmenu_find"
-                    class="menuitem-tooltip"
-                    label="&appMenuFind.label;"
-                    command="cmd_find"
-                    key="key_find"/>
-          <menuseparator class="appmenu-menuseparator"/>
-          <menuitem id="appmenu_savePage"
-                    class="menuitem-tooltip"
-                    label="&savePageCmd.label;"
-                    command="Browser:SavePage"
-                    key="key_savePage"/>
-          <menuitem id="appmenu_sendLink"
-                    label="&sendPageCmd.label;"
-                    command="Browser:SendLink"/>
-          <hbox flex="1"
-                class="split-menuitem">
-            <menuitem id="appmenu_print"
-                      class="menuitem-iconic menuitem-iconic-tooltip split-menuitem-item"
-                      flex="1"
-                      label="&printCmd.label;"
-                      command="cmd_print"
-                      key="printKb"/>
-            <menu class="split-menuitem-menu">
-              <menupopup>
-                <menuitem id="appmenu_print_popup"
-                          class="menuitem-iconic"
-                          label="&printCmd.label;"
-                          command="cmd_print"
-                          key="printKb"/>
-                <menuitem id="appmenu_printPreview"
-                          label="&printPreviewCmd.label;"
-                          command="cmd_printPreview"/>
-                <menuitem id="appmenu_printSetup"
-                          label="&printSetupCmd.label;"
-                          command="cmd_pageSetup"/>
-              </menupopup>
-            </menu>
-          </hbox>
-          <menuseparator class="appmenu-menuseparator"/>
-          <menu id="appmenu_webDeveloper"
-                label="&appMenuWebDeveloper.label;">
-            <menupopup id="appmenu_webDeveloper_popup">
-              <menuitem id="appmenu_webConsole"
-                        label="&webConsoleCmd.label;"
-                        oncommand="HUDConsoleUI.toggleHUD();"
-                        key="key_webConsole"/>
-              <menuitem id="appmenu_pageInspect"
-                        hidden="true"
-                        label="&inspectMenu.label;"
-                        type="checkbox"
-                        command="Tools:Inspect"
-                        key="key_inspect"/>
-              <menuseparator/>
-              <menuitem id="appmenu_pageSource"
-                        label="&viewPageSourceCmd.label;"
-                        command="View:PageSource"
-                        key="key_viewSource"/>
-              <menuseparator/>
-#define ID_PREFIX appmenu_developer_
-#include browser-charsetmenu.inc
-#undef ID_PREFIX
-              <menuseparator/>
-              <menuitem label="&goOfflineCmd.label;"
-                        type="checkbox"
-                        observes="workOfflineMenuitemState"
-                        oncommand="BrowserOffline.toggleOfflineStatus();"/>
-            </menupopup>
-          </menu>
-          <menuseparator class="appmenu-menuseparator"/>
-#define ID_PREFIX appmenu_
-#include browser-charsetmenu.inc
-#undef ID_PREFIX
-          <menuitem id="appmenu_fullScreen"
-                    class="menuitem-tooltip"
-                    label="&fullScreenCmd.label;"
-                    type="checkbox"
-                    observes="View:FullScreen"
-                    key="key_fullScreen"/>
-          <menuitem id="appmenu-quit"
-                    class="menuitem-iconic"
-#ifdef XP_WIN
-                    label="&quitApplicationCmdWin.label;"
-#else
-                    label="&quitApplicationCmd.label;"
-#endif
-                    command="cmd_quitApplication"/>
-        </vbox>
-        <vbox id="appmenuSecondaryPane">
-          <hbox class="split-menuitem">
-            <menuitem id="appmenu_bookmarks"
-                      class="menuitem-iconic menuitem-iconic-tooltip split-menuitem-item"
-                      flex="1"
-                      label="&bookmarksMenu.label;"
-                      command="Browser:ShowAllBookmarks"
-                      key="manBookmarkKb"/>
-            <menu id="appmenu_bookmarksMenu"
-                  class="split-menuitem-menu">
-              <menupopup id="appmenu_bookmarksPopup"
-                         placespopup="true"
-                         context="placesContext"
-                         openInTabs="children"
-                         oncommand="BookmarksEventHandler.onCommand(event);"
-                         onclick="BookmarksEventHandler.onClick(event);"
-                         onpopupshowing="BookmarksMenuButton.onPopupShowing(event);
-                                         if (!this.parentNode._placesView)
-                                           new PlacesMenu(event, 'place:folder=BOOKMARKS_MENU');"
-                         tooltip="bhTooltip"
-                         popupsinherittooltip="true">
-                <menuitem id="appmenu_showAllBookmarks"
-                          label="&showAllBookmarks.label;"
-                          command="Browser:ShowAllBookmarks"
-                          context=""
-                          key="manBookmarkKb"/>
-                <menuseparator/>
-                <menuitem id="appmenu_bookmarkThisPage"
-                          class="menuitem-iconic"
-                          label="&bookmarkThisPageCmd.label;"
-                          command="Browser:AddBookmarkAs"
-                          key="addBookmarkAsKb"/>
-                <menuitem id="appmenu_subscribeToPage"
-                          class="menuitem-iconic"
-                          label="&subscribeToPageMenuitem.label;"
-                          oncommand="return FeedHandler.subscribeToFeed(null, event);"
-                          onclick="checkForMiddleClick(this, event);"
-                          observes="singleFeedMenuitemState"/>
-                <menu id="appmenu_subscribeToPageMenu"
-                      class="menu-iconic"
-                      label="&subscribeToPageMenupopup.label;"
-                      observes="multipleFeedsMenuState">
-                  <menupopup id="appmenu_subscribeToPageMenupopup"
-                             onpopupshowing="return FeedHandler.buildFeedList(event.target);"
-                             oncommand="return FeedHandler.subscribeToFeed(null, event);"
-                             onclick="checkForMiddleClick(this, event);"/>
-                </menu>
-                <menuseparator/>
-                <menu id="appmenu_bookmarksToolbar"
-                      placesanonid="toolbar-autohide"
-                      class="menu-iconic bookmark-item"
-                      label="&personalbarCmd.label;"
-                      container="true">
-                  <menupopup id="appmenu_bookmarksToolbarPopup"
-                             placespopup="true"
-                             context="placesContext"
-                             onpopupshowing="if (!this.parentNode._placesView)
-                                               new PlacesMenu(event, 'place:folder=TOOLBAR');"/>
-                </menu>
-                <menuseparator/>
-                <!-- Bookmarks menu items -->
-                <menuseparator builder="end"
-                               class="hide-if-empty-places-result"/>
-                <menuitem id="appmenu_unsortedBookmarks"
-                          label="&appMenuUnsorted.label;"
-                          oncommand="PlacesCommandHook.showPlacesOrganizer('UnfiledBookmarks');"
-                          class="menuitem-iconic"/>
-              </menupopup>
-            </menu>
-          </hbox>
-          <hbox class="split-menuitem">
-            <menuitem id="appmenu_history"
-                      class="menuitem-iconic menuitem-iconic-tooltip split-menuitem-item"
-                      flex="1"
-                      label="&historyMenu.label;"
-                      command="Browser:ShowAllHistory"
-                      key="showAllHistoryKb"/>
-            <menu id="appmenu_historyMenu"
-                  class="split-menuitem-menu">
-              <menupopup id="appmenu_historyMenupopup"
-                         placespopup="true"
-                         oncommand="this.parentNode._placesView._onCommand(event);"
-                         onclick="checkForMiddleClick(this, event);"
-                         onpopupshowing="if (!this.parentNode._placesView)
-                                           new HistoryMenu(event);"
-                         tooltip="bhTooltip"
-                         popupsinherittooltip="true">
-                <menuitem id="appmenu_showAllHistory"
-                          label="&showAllHistoryCmd2.label;"
-                          command="Browser:ShowAllHistory"
-                          key="showAllHistoryKb"/>
-                <menuseparator/>
-                <menuitem id="appmenu_sanitizeHistory"
-                          label="&clearRecentHistory.label;"
-                          key="key_sanitize"
-                          command="Tools:Sanitize"/>
-                <menuseparator class="hide-if-empty-places-result"/>
-                <menuitem id="appmenu_restoreLastSession"
-                          class="restoreLastSession"
-                          label="&historyRestoreLastSession.label;"
-                          oncommand="restoreLastSession();"
-                          disabled="true"/>
-                <menu id="appmenu_recentlyClosedTabsMenu"
-                      class="recentlyClosedTabsMenu"
-                      label="&historyUndoMenu.label;"
-                      disabled="true">
-                  <menupopup id="appmenu_recentlyClosedTabsMenupopup"
-                             onpopupshowing="document.getElementById('appmenu_historyMenu')._placesView.populateUndoSubmenu();"/>
-                </menu>
-                <menu id="appmenu_recentlyClosedWindowsMenu"
-                      class="recentlyClosedWindowsMenu"
-                      label="&historyUndoWindowMenu.label;"
-                      disabled="true">
-                  <menupopup id="appmenu_recentlyClosedWindowsMenupopup"
-                             onpopupshowing="document.getElementById('appmenu_historyMenu')._placesView.populateUndoWindowSubmenu();"/>
-                </menu>
-                <menuseparator/>
-              </menupopup>
-            </menu>
-          </hbox>
-            <menuitem id="appmenu_downloads"
-                      class="menuitem-tooltip"
-                      label="&downloads.label;"
-                      command="Tools:Downloads"
-                      key="key_openDownloads"/>
-            <spacer id="appmenuSecondaryPane-spacer"/>
-            <menuitem id="appmenu_addons"
-                      class="menuitem-iconic menuitem-iconic-tooltip"
-                      label="&addons.label;"
-                      command="Tools:Addons"
-                      key="key_openAddons"/>
-            <hbox class="split-menuitem">
-              <menuitem id="appmenu_customize"
-                        label="&preferencesCmd.label;"
-                        class="split-menuitem-item"
-                        flex="1"
-                        oncommand="openPreferences();"/>
-              <menu class="split-menuitem-menu"
-                    label="&preferencesCmd.label;">
-                <menupopup id="appmenu_customizeMenu"
-                           onpopupshowing="onViewToolbarsPopupShowing(event, document.getElementById('appmenu_toggleTabsOnTop').previousSibling);">
-                  <menuitem id="appmenu_preferences"
-#ifdef XP_UNIX
-                            label="&preferencesCmdUnix.label;"
-#else
-                            label="&preferencesCmd.label;"
-#endif
-                            oncommand="openPreferences();"/>
-                  <menuseparator/>
-                  <menuseparator/>
-                  <menuitem id="appmenu_toggleTabsOnTop"
-                            label="&viewTabsOnTop.label;"
-                            type="checkbox"
-                            command="cmd_ToggleTabsOnTop"/>
-                  <menuitem id="appmenu_toolbarLayout"
-                            label="&appMenuToolbarLayout.label;"
-                            command="cmd_CustomizeToolbars"/>
-                </menupopup>
-              </menu>
-            </hbox>
-            <hbox class="split-menuitem">
-              <menuitem id="appmenu_help"
-                        class="split-menuitem-item"
-                        flex="1"
-                        label="&helpMenu.label;"
-                        oncommand="openHelpLink('firefox-help')"/>
-              <menu class="split-menuitem-menu">
-                <menupopup id="appmenu_helpMenupopup">
-                  <menuitem id="appmenu_openHelp"
-                            label="&helpMenu.label;"
-                            oncommand="openHelpLink('firefox-help')"
-                            onclick="checkForMiddleClick(this, event);"/>
-                  <menuitem id="appmenu_gettingStarted"
-                            label="&appMenuGettingStarted.label;"
-                            oncommand="gBrowser.loadOneTab('http://www.mozilla.com/firefox/central/', {inBackground: false});"
-                            onclick="checkForMiddleClick(this, event);"/>
-                  <menuitem id="appmenu_troubleshootingInfo"
-                            label="&helpTroubleshootingInfo.label;"
-                            oncommand="openTroubleshootingPage()"
-                            onclick="checkForMiddleClick(this,event);"/>
-                  <menuitem id="appmenu_feedbackPage"
-                            label="&helpFeedbackPage.label;"
-                            oncommand="openFeedbackPage()"
-                            onclick="checkForMiddleClick(this, event);"/>
-                  <menuseparator/>
-                  <menuitem id="appmenu_safeMode"
-                            accesskey="&appMenuSafeMode.accesskey;"
-                            label="&appMenuSafeMode.label;"
-                            oncommand="safeModeRestart();"/>
-                  <menuseparator/>
-                  <menuitem id="appmenu_about"
-                            label="&aboutProduct.label;"
-                            oncommand="openAboutDialog();"/>
-                </menupopup>
-              </menu>
-            </hbox>
-#ifdef MOZ_SERVICES_SYNC
-            <spacer flex="1"/>
-            <!-- only one of sync-setup or sync-syncnow will be showing at once -->
-            <menuitem id="sync-setup-appmenu"
-                      label="&syncSetup.label;"
-                      observes="sync-setup-state"
-                      oncommand="gSyncUI.openSetup()"/>
-            <menuitem id="sync-syncnowitem-appmenu"
-                      label="&syncSyncNowItem.label;"
-                      observes="sync-syncnow-state"
-                      oncommand="gSyncUI.doSync(event);"/>
-#endif
-        </vbox>
-      </hbox>
-    </menupopup>
-  </button>
+    <hbox id="appmenu-button-container" align="start">
+      <button id="appmenu-button"
+              type="menu"
+              label="&brandShortName;"
+              style="-moz-user-focus: ignore;">
+#include browser-appmenu.inc
+      </button>
+    </hbox>
+    <spacer id="titlebar-spacer" flex="1"/>
+    <hbox id="titlebar-buttonbox">
+      <toolbarbutton class="titlebar-button" id="titlebar-min" oncommand="window.minimize();"/>
+      <toolbarbutton class="titlebar-button" id="titlebar-max" oncommand="onTitlebarMaxClick();"/>
+      <toolbarbutton class="titlebar-button" id="titlebar-close" command="cmd_closeWindow"/>
+    </hbox>
   </hbox>
-  <spacer id="titlebar-spacer" flex="1"/>
-  <hbox id="titlebar-buttonbox">
-    <toolbarbutton class="titlebar-button" id="titlebar-min" oncommand="window.minimize();"/>
-    <toolbarbutton class="titlebar-button" id="titlebar-max" oncommand="onTitlebarMaxClick();"/>
-    <toolbarbutton class="titlebar-button" id="titlebar-close" command="cmd_closeWindow"/>
-  </hbox>
-  </hbox>
-  </vbox>
+</vbox>
 #endif
 
 <deck flex="1" id="tab-view-deck">
 <vbox flex="1">
 
   <toolbox id="navigator-toolbox"
            defaultmode="icons" mode="icons"
 #ifdef WINCE
@@ -939,23 +571,26 @@
                    class="urlbar-icon"
                    onclick="PlacesStarButton.onClick(event);"/>
             <image id="go-button"
                    class="urlbar-icon"
                    tooltiptext="&goEndCap.tooltip;"
                    onclick="gURLBar.handleCommand(event);"/>
           </hbox>
           <toolbarbutton id="urlbar-go-button"
+                         class="chromeclass-toolbar-additional"
                          onclick="gURLBar.handleCommand(event);"
                          tooltiptext="&goEndCap.tooltip;"/>
           <toolbarbutton id="urlbar-reload-button"
+                         class="chromeclass-toolbar-additional"
                          command="Browser:ReloadOrDuplicate"
                          onclick="checkForMiddleClick(this, event);"
                          tooltiptext="&reloadButton.tooltip;"/>
           <toolbarbutton id="urlbar-stop-button"
+                         class="chromeclass-toolbar-additional"
                          command="Browser:Stop"
                          tooltiptext="&stopButton.tooltip;"/>
         </textbox>
       </toolbaritem>
 
       <toolbarbutton id="reload-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
                      label="&reloadCmd.label;" removable="true"
                      command="Browser:ReloadOrDuplicate"
@@ -1011,21 +646,27 @@
             <menuitem id="BMB_bookmarkThisPage"
 #ifndef XP_MACOSX
                       class="menuitem-iconic"
 #endif
                       label="&bookmarkThisPageCmd.label;"
                       command="Browser:AddBookmarkAs"
                       key="addBookmarkAsKb"/>
             <menuitem id="BMB_subscribeToPageMenuitem"
+#ifndef XP_MACOSX
+                      class="menuitem-iconic"
+#endif
                       label="&subscribeToPageMenuitem.label;"
                       oncommand="return FeedHandler.subscribeToFeed(null, event);"
                       onclick="checkForMiddleClick(this, event);"
                       observes="singleFeedMenuitemState"/>
             <menu id="BMB_subscribeToPageMenupopup"
+#ifndef XP_MACOSX
+                  class="menu-iconic"
+#endif
                   label="&subscribeToPageMenupopup.label;"
                   observes="multipleFeedsMenuState">
               <menupopup id="BMB_subscribeToPageSubmenuMenupopup"
                          onpopupshowing="return FeedHandler.buildFeedList(event.target);"
                          oncommand="return FeedHandler.subscribeToFeed(null, event);"
                          onclick="checkForMiddleClick(this, event);"/>
             </menu>
             <menuseparator/>
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -519,18 +519,20 @@
                     !(this.mBrowser.docShell.loadType & Ci.nsIDocShell.LOAD_CMD_PUSHSTATE))
                   this.mBrowser.mIconURL = null;
 
                 let browserHistory = this.mTabBrowser.mBrowserHistory;
                 if (this.mBrowser.registeredOpenURI) {
                   browserHistory.unregisterOpenPage(this.mBrowser.registeredOpenURI);
                   delete this.mBrowser.registeredOpenURI;
                 }
-                browserHistory.registerOpenPage(aLocation);
-                this.mBrowser.registeredOpenURI = aLocation;
+                if (aLocation.spec != "about:blank") {
+                  browserHistory.registerOpenPage(aLocation);
+                  this.mBrowser.registeredOpenURI = aLocation;
+                }
               }
 
               if (!this.mBlank) {
                 this._callProgressListeners("onLocationChange",
                                             [aWebProgress, aRequest, aLocation]);
               }
 
               if (topLevel)
@@ -825,41 +827,58 @@
                                           true, false);
             }
 
             // TabSelect events are suppressed during preview mode to avoid confusing extensions and other bits of code
             // that might rely upon the other changes suppressed.
             // Focus is suppressed in the event that the main browser window is minimized - focusing a tab would restore the window
             if (!this._previewMode) {
               // We've selected the new tab, so go ahead and notify listeners.
-              var event = document.createEvent("Events");
+              let event = document.createEvent("Events");
               event.initEvent("TabSelect", true, false);
               this.mCurrentTab.dispatchEvent(event);
 
               this._tabAttrModified(oldTab);
               this._tabAttrModified(this.mCurrentTab);
 
-              // Change focus to the new browser unless the findbar is focused.
-              if (!gFindBarInitialized ||
-                  gFindBar.hidden ||
-                  gFindBar.getElement("findbar-textbox").getAttribute("focused") != "true") {
-
-                var fm = Components.classes["@mozilla.org/focus-manager;1"].
-                           getService(Components.interfaces.nsIFocusManager);
-                var newFocusedElement = fm.getFocusedElementForWindow(window.content, true, {});
+              // Adjust focus
+              do {
+                // Focus the location bar if it was previously focused for that tab.
+                // In full screen mode, only bother making the location bar visible
+                // if the tab is a blank one.
+                oldBrowser._urlbarFocused = (gURLBar && gURLBar.focused);
+                if (newBrowser._urlbarFocused && gURLBar) {
+                  if (!window.fullScreen) {
+                    gURLBar.focus();
+                    break;
+                  } else if (isTabEmpty(this.mCurrentTab)) {
+                    focusAndSelectUrlBar();
+                    break;
+                  }
+                }
+
+                // If the find bar is focused, keep it focused.
+                if (gFindBarInitialized &&
+                    !gFindBar.hidden &&
+                    gFindBar.getElement("findbar-textbox").getAttribute("focused") == "true")
+                  break;
+
+                // Otherwise, focus the content area.
+                let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
+                let newFocusedElement = fm.getFocusedElementForWindow(window.content, true, {});
 
                 // for anchors, use FLAG_SHOWRING so that it is clear what link was
                 // last clicked when switching back to that tab
-                var focusFlags = fm.FLAG_NOSCROLL;
+                let focusFlags = fm.FLAG_NOSCROLL;
                 if (newFocusedElement &&
                     (newFocusedElement instanceof HTMLAnchorElement ||
                      newFocusedElement.getAttributeNS("http://www.w3.org/1999/xlink", "type") == "simple"))
                   focusFlags |= fm.FLAG_SHOWRING;
                 fm.setFocus(newBrowser, focusFlags);
-              }
+              } while (false);
             }
           ]]>
         </body>
       </method>
 
       <method name="_tabAttrModified">
         <parameter name="aTab"/>
         <body><![CDATA[
--- a/browser/base/content/tabview/groupitems.js
+++ b/browser/base/content/tabview/groupitems.js
@@ -76,16 +76,18 @@ function GroupItem(listOfEls, options) {
   this.isAGroupItem = true;
   this.id = options.id || GroupItems.getNextID();
   this._isStacked = false;
   this._stackAngles = [0];
   this.expanded = null;
   this.locked = (options.locked ? Utils.copy(options.locked) : {});
   this.topChild = null;
   this.hidden = false;
+  this.fadeAwayUndoButtonDelay = 15000;
+  this.fadeAwayUndoButtonDuration = 300;
 
   this.keepProportional = false;
 
   // Variable: _activeTab
   // The <TabItem> for the groupItem's active tab.
   this._activeTab = null;
 
   // Variables: xDensity, yDensity
@@ -272,16 +274,17 @@ function GroupItem(listOfEls, options) {
   if (this.locked.bounds)
     $container.css({cursor: 'default'});
 
   if (this.locked.close)
     $close.hide();
 
   // ___ Undo Close
   this.$undoContainer = null;
+  this._undoButtonTimeoutId = null;
 
   // ___ Superclass initialization
   this._init($container[0]);
 
   if (this.$debug)
     this.$debug.css({zIndex: -1000});
 
   // ___ Children
@@ -632,46 +635,25 @@ GroupItem.prototype = Utils.extend(new I
         easing: "tabviewBounce",
         duration: 170,
         complete: function() {
           self._sendToSubscribers("groupHidden", { groupItemId: self.id });
         }
       });
     }, 50);
 
-    let remove = function() {
-      // close all children
-      let toClose = self._children.concat();
-      toClose.forEach(function(child) {
-        child.removeSubscriber(self, "close");
-        child.close();
-      });
- 
-      // remove all children
-      self.removeAll();
-      GroupItems.unregister(self);
-      self._sendToSubscribers("close");
-      self.removeTrenches();
-
-      iQ(self.container).remove();
-      self.$undoContainer.remove();
-      self.$undoContainer = null;
-      Items.unsquish();
-
-      self.deleteData();
-    };
-
     this.$undoContainer.click(function(e) {
       // Only do this for clicks on this actual element.
       if (e.target.nodeName != self.$undoContainer[0].nodeName)
         return;
 
       self.$undoContainer.fadeOut(function() {
         iQ(this).remove();
         self.hidden = false;
+        self._cancelFadeAwayUndoButtonTimer();
         self.$undoContainer = null;
 
         iQ(self.container).show().animate({
           "-moz-transform": "scale(1)",
           "opacity": 1
         }, {
           duration: 170,
           complete: function() {
@@ -681,41 +663,102 @@ GroupItem.prototype = Utils.extend(new I
           }
         });
 
         self._sendToSubscribers("groupShown", { groupItemId: self.id });
       });
     });
 
     undoClose.click(function() {
-      self.$undoContainer.fadeOut(remove);
+      self._cancelFadeAwayUndoButtonTimer();
+      self.$undoContainer.fadeOut(function() { self._removeHiddenGroupItem(); });
     });
 
-    // After 15 seconds, fade away.
-    const WAIT = 15000;
-    const FADE = 300;
+    this.setupFadeAwayUndoButtonTimer();
+    // Cancel the fadeaway if you move the mouse over the undo
+    // button, and restart the countdown once you move out of it.
+    this.$undoContainer.mouseover(function() { 
+      self._cancelFadeAwayUndoButtonTimer();
+    });
+    this.$undoContainer.mouseout(function() {
+      self.setupFadeAwayUndoButtonTimer();
+    });
+  },
+
+  // ----------
+  // Sets up fade away undo button timeout. 
+  setupFadeAwayUndoButtonTimer: function() {
+    let self = this;
 
-    let fadeaway = function() {
-      if (self.$undoContainer)
+    if (!this._undoButtonTimeoutId) {
+      this._undoButtonTimeoutId = setTimeout(function() { 
+        self._fadeAwayUndoButton(); 
+      }, this.fadeAwayUndoButtonDelay);
+    }
+  },
+  
+  // ----------
+  // Cancels the fade away undo button timeout. 
+  _cancelFadeAwayUndoButtonTimer: function() {
+    clearTimeout(this._undoButtonTimeoutId);
+    this._undoButtonTimeoutId = null;
+  }, 
+
+  // ----------
+  // Fades away the undo button
+  _fadeAwayUndoButton: function() {
+    let self = this;
+
+    if (this.$undoContainer) {
+      // if there is one or more orphan tabs or there is more than one group 
+      // and other groupS are not empty, fade away the undo button.
+      let shouldFadeAway = GroupItems.getOrphanedTabs().length > 0;
+      
+      if (!shouldFadeAway && GroupItems.groupItems.length > 1) {
+        shouldFadeAway = 
+          GroupItems.groupItems.some(function(groupItem) {
+            return (groupItem != self && groupItem.getChildren().length > 0);
+          });
+      }
+      if (shouldFadeAway) {
         self.$undoContainer.animate({
           color: "transparent",
           opacity: 0
         }, {
-          duration: FADE,
-          complete: remove
+          duration: this.fadeAwayUndoButtonDuration,
+          complete: function() { self._removeHiddenGroupItem(); }
         });
-    };
+      }
+    }
+  },
+
+  // ----------
+  // Removes the group item, its children and its container.
+  _removeHiddenGroupItem: function() {
+    let self = this;
 
-    let timeoutId = setTimeout(fadeaway, WAIT);
-    // Cancel the fadeaway if you move the mouse over the undo
-    // button, and restart the countdown once you move out of it.
-    this.$undoContainer.mouseover(function() clearTimeout(timeoutId));
-    this.$undoContainer.mouseout(function() {
-      timeoutId = setTimeout(fadeaway, WAIT);
+    // close all children
+    let toClose = this._children.concat();
+    toClose.forEach(function(child) {
+      child.removeSubscriber(self, "close");
+      child.close();
     });
+ 
+    // remove all children
+    this.removeAll();
+    GroupItems.unregister(this);
+    this._sendToSubscribers("close");
+    this.removeTrenches();
+
+    iQ(this.container).remove();
+    this.$undoContainer.remove();
+    this.$undoContainer = null;
+    Items.unsquish();
+
+    this.deleteData();
   },
 
   // ----------
   // Function: add
   // Adds an item to the groupItem.
   // Parameters:
   //
   //   a - The item to add. Can be an <Item>, a DOM element or an iQ object.
deleted file mode 100644
--- a/browser/base/content/tabview/infoitems.js
+++ /dev/null
@@ -1,252 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is infoitems.js.
- *
- * The Initial Developer of the Original Code is
- * the Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2010
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Ian Gilman <ian@iangilman.com>
- * Aza Raskin <aza@mozilla.com>
- * Michael Yoshitaka Erlewine <mitcho@mitcho.com>
- * Ehsan Akhgari <ehsan@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 ***** */
-
-// **********
-// Title: infoitems.js
-
-// ##########
-// Class: InfoItem
-// An <Item> in TabView used for displaying information, such as the welcome video.
-// Note that it implements the <Subscribable> interface.
-//
-// ----------
-// Constructor: InfoItem
-//
-// Parameters:
-//   bounds - a <Rect> for where the item should be located
-//   options - various options for this infoItem (see below)
-//
-// Possible options:
-//   locked - see <Item.locked>; default is {}
-//   dontPush - true if this infoItem shouldn't push away on creation; default is false
-//   immediately - place the item immediately, without animation
-function InfoItem(bounds, options) {
-  try {
-    Utils.assertThrow(Utils.isRect(bounds), 'bounds');
-
-    if (typeof options == 'undefined')
-      options = {};
-
-    this._inited = false;
-    this.isAnInfoItem = true;
-    this.defaultSize = bounds.size();
-    this.locked = (options.locked ? Utils.copy(options.locked) : {});
-    this.bounds = new Rect(bounds);
-    this.isDragging = false;
-
-    var self = this;
-
-    var $container = iQ('<div>')
-      .addClass('info-item')
-      .css(this.bounds)
-      .appendTo('body');
-
-    this.$contents = iQ('<div>')
-      .appendTo($container);
-
-    var $close = iQ('<div>')
-      .addClass('close')
-      .click(function() {
-        self.close();
-      })
-      .appendTo($container);
-
-    // ___ locking
-    if (this.locked.bounds)
-      $container.css({cursor: 'default'});
-
-    if (this.locked.close)
-      $close.hide();
-
-    // ___ Superclass initialization
-    this._init($container[0]);
-
-    if (this.$debug)
-      this.$debug.css({zIndex: -1000});
-
-    // ___ Finish Up
-    if (!this.locked.bounds)
-      this.draggable();
-
-    // ___ Position
-    if (!options.dontPush)
-      this.snap(options.immediately);
-
-    this._inited = true;
-    this.save();
-  } catch(e) {
-    Utils.log(e);
-  }
-};
-
-// ----------
-InfoItem.prototype = Utils.extend(new Item(), new Subscribable(), {
-
-  // ----------
-  // Function: getStorageData
-  // Returns all of the info worth storing about this item.
-  getStorageData: function InfoItem_getStorageData() {
-    var data = null;
-
-    try {
-      data = {
-        bounds: this.getBounds(),
-        locked: Utils.copy(this.locked)
-      };
-    } catch(e) {
-      Utils.log(e);
-    }
-
-    return data;
-  },
-
-  // ----------
-  // Function: save
-  // Saves this item to persistent storage.
-  save: function InfoItem_save() {
-    try {
-      if (!this._inited) // too soon to save now
-        return;
-
-      var data = this.getStorageData();
-
-    } catch(e) {
-      Utils.log(e);
-    }
-  },
-
-  // ----------
-  // Function: setBounds
-  // Sets the bounds with the given <Rect>, animating unless "immediately" is false.
-  setBounds: function InfoItem_setBounds(rect, immediately) {
-    try {
-      Utils.assertThrow(Utils.isRect(rect), 'InfoItem.setBounds: rect must be a real rectangle!');
-
-      // ___ Determine what has changed
-      var css = {};
-
-      if (rect.left != this.bounds.left)
-        css.left = rect.left;
-
-      if (rect.top != this.bounds.top)
-        css.top = rect.top;
-
-      if (rect.width != this.bounds.width)
-        css.width = rect.width;
-
-      if (rect.height != this.bounds.height)
-        css.height = rect.height;
-
-      if (Utils.isEmptyObject(css))
-        return;
-
-      this.bounds = new Rect(rect);
-      Utils.assertThrow(Utils.isRect(this.bounds), 
-          'InfoItem.setBounds: this.bounds must be a real rectangle!');
-
-      // ___ Update our representation
-      if (immediately) {
-        iQ(this.container).css(css);
-      } else {
-        TabItems.pausePainting();
-        iQ(this.container).animate(css, {
-          duration: 350,
-          easing: "tabviewBounce",
-          complete: function() {
-            TabItems.resumePainting();
-          }
-        });
-      }
-
-      this._updateDebugBounds();
-      this.setTrenches(rect);
-      this.save();
-    } catch(e) {
-      Utils.log(e);
-    }
-  },
-
-  // ----------
-  // Function: setZ
-  // Set the Z order for the item's container.
-  setZ: function InfoItem_setZ(value) {
-    try {
-      Utils.assertThrow(typeof value == 'number', 'value must be a number');
-
-      this.zIndex = value;
-
-      iQ(this.container).css({zIndex: value});
-
-      if (this.$debug)
-        this.$debug.css({zIndex: value + 1});
-    } catch(e) {
-      Utils.log(e);
-    }
-  },
-
-  // ----------
-  // Function: close
-  // Closes the item.
-  close: function InfoItem_close() {
-    try {
-      this._sendToSubscribers("close");
-      this.removeTrenches();
-      iQ(this.container).fadeOut(function() {
-        iQ(this).remove();
-        Items.unsquish();
-      });
-
-    } catch(e) {
-      Utils.log(e);
-    }
-  },
-
-  // ----------
-  // Function: html
-  // Sets the item's container's html to the specified value.
-  html: function InfoItem_html(value) {
-    try {
-      Utils.assertThrow(typeof value == 'string', 'value must be a string');
-      this.$contents.html(value);
-    } catch(e) {
-      Utils.log(e);
-    }
-  }
-});
--- a/browser/base/content/tabview/tabview.js
+++ b/browser/base/content/tabview/tabview.js
@@ -47,13 +47,10 @@ XPCOMUtils.defineLazyGetter(this, "gPriv
 
 #include iq.js
 #include storage.js
 #include items.js
 #include groupitems.js
 #include tabitems.js
 #include drag.js
 #include trench.js
-#include infoitems.js
 #include ui.js
 #include search.js
-
-
--- a/browser/base/content/tabview/ui.js
+++ b/browser/base/content/tabview/ui.js
@@ -244,26 +244,29 @@ let UI = {
     this._reorderTabsOnHide = null;
     this._frameInitialized = false;
   },
   
   // Function: reset
   // Resets the Panorama view to have just one group with all tabs
   // and, if firstTime == true, add the welcome video/tab
   reset: function UI_reset(firstTime) {
-    let padding = 10;
-    let infoWidth = 350;
-    let infoHeight = 232;
+    let padding = Trenches.defaultRadius;
+    let welcomeWidth = 300;
     let pageBounds = Items.getPageBounds();
     pageBounds.inset(padding, padding);
 
+    let $actions = iQ("#actions");
+    if ($actions)
+      pageBounds.width -= $actions.width();
+
     // ___ make a fresh groupItem
     let box = new Rect(pageBounds);
-    box.width = 
-      Math.min(box.width * 0.667, pageBounds.width - (infoWidth + padding));
+    box.width = Math.min(box.width * 0.667,
+                         pageBounds.width - (welcomeWidth + padding));
     box.height = box.height * 0.667;
 
     GroupItems.groupItems.forEach(function(group) {
       group.close();
     });
     
     let options = {
       bounds: box,
@@ -275,27 +278,28 @@ let UI = {
       if (item.parent)
         item.parent.remove(item);
       groupItem.add(item, null, {immediately: true});
     });
     
     if (firstTime) {
       gPrefBranch.setBoolPref("experienced_first_run", true);
 
-      // ___ make info item
-      let video = 
-        "http://videos-cdn.mozilla.net/firefox4beta/tabcandy_howto.webm";
-      let html =
-        "<div class='intro'>"
-          + "<video src='" + video + "' width='100%' preload controls>"
-        + "</div>";
-      let infoBox = new Rect(box.right + padding, box.top,
-                         infoWidth, infoHeight);
-      let infoItem = new InfoItem(infoBox);
-      infoItem.html(html);
+      let url = gPrefBranch.getCharPref("welcome_url");
+      let newTab = gBrowser.loadOneTab(url, {inBackground: true});
+      let newTabItem = newTab.tabItem;
+      let parent = newTabItem.parent;
+      Utils.assert(parent, "should have a parent");
+
+      newTabItem.parent.remove(newTabItem);
+      let aspect = TabItems.tabHeight / TabItems.tabWidth;
+      let welcomeBounds = new Rect(box.right + padding, box.top,
+                                   welcomeWidth, welcomeWidth * aspect);
+      newTabItem.setBounds(welcomeBounds, true);
+      GroupItems.setActiveGroupItem(groupItem);
     }
   },
 
   // Function: blurAll
   // Blurs any currently focused element
   //
   blurAll: function UI_blurAll() {
     iQ(":focus").each(function(element) {
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -140,16 +140,17 @@ endif
                  browser_bug555224.js \
                  browser_bug555767.js \
                  browser_bug556061.js \
                  browser_bug559991.js \
                  browser_bug561623.js \
                  browser_bug561636.js \
                  browser_bug562649.js \
                  browser_bug563588.js \
+                 browser_bug565575.js \
                  browser_bug575561.js \
                  browser_bug577121.js \
                  browser_bug579872.js \
                  browser_bug580956.js \
                  browser_bug581242.js \
                  browser_bug581253.js \
                  browser_bug581947.js \
                  browser_bug585785.js \
@@ -216,16 +217,17 @@ endif
                  dummy_page.html \
                  browser_tabMatchesInAwesomebar.js \
                  file_bug550565_popup.html \
                  file_bug550565_favicon.ico \
                  browser_overLinkInLocationBar.js \
                  browser_aboutHome.js \
                  app_bug575561.html \
                  app_subframe_bug575561.html \
+                 browser_contentAreaClick.js \
                  $(NULL)
 
 # compartment-disabled
 #                 browser_popupUI.js \
 #                 browser_tab_dragdrop.js \
 
 ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 _BROWSER_FILES += \
--- a/browser/base/content/test/browser_aboutHome.js
+++ b/browser/base/content/test/browser_aboutHome.js
@@ -89,16 +89,42 @@ let gTests = [
     ok(snippetsElt, "Found default snippets element")
     ok(Array.some(snippetsElt.getElementsByTagName("span"), function(elt) {
       return !elt.hidden;
     }), "A default snippet is visible.");
     executeSoon(runNextTest);
   }
 },
 
+{
+  desc: "Check default snippets are shown if snippets are invalid xml",
+  setup: function ()
+  {
+    let storage = getStorage();
+    // This must be some incorrect xhtml code.
+    storage.setItem("snippets", "<p><b></p></b>");
+  },
+  run: function ()
+  {
+    let doc = gBrowser.selectedTab.linkedBrowser.contentDocument;
+
+    let snippetsElt = doc.getElementById("snippets");
+    ok(snippetsElt, "Found snippets element");
+    ok(snippetsElt.hidden, "Snippets element is hidden");
+
+    let defaultsElt = doc.getElementById("defaultSnippets");
+    ok(defaultsElt, "Found default snippets element")
+    ok(Array.some(defaultsElt.getElementsByTagName("span"), function(elt) {
+      return !elt.hidden;
+    }), "A default snippet is visible.");
+
+    executeSoon(runNextTest);
+  }
+},
+
 ];
 
 function test()
 {
   waitForExplicitFinish();
 
   // browser-chrome test harness inits browser specifying an hardcoded page
   // and this causes nsIBrowserHandler.defaultArgs to not be evaluated since
--- a/browser/base/content/test/browser_bug553455.js
+++ b/browser/base/content/test/browser_bug553455.js
@@ -28,36 +28,31 @@ function wait_for_notification(aCallback
     aCallback(PopupNotifications.panel);
   }, false);
 }
 
 function wait_for_install_dialog(aCallback) {
   info("Waiting for install dialog");
   Services.wm.addListener({
     onOpenWindow: function(aXULWindow) {
-      info("Install dialog opened, waiting for load");
+      info("Install dialog opened, waiting for focus");
       Services.wm.removeListener(this);
 
       var domwindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                                 .getInterface(Ci.nsIDOMWindowInternal);
-      domwindow.addEventListener("load", function() {
-        domwindow.removeEventListener("load", arguments.callee, false);
-
+      waitForFocus(function() {
+        info("Saw install dialog");
         is(domwindow.document.location.href, XPINSTALL_URL, "Should have seen the right window open");
 
-        // Allow other window load listeners to execute before passing to callback
-        executeSoon(function() {
-          info("Saw install dialog");
-          // Override the countdown timer on the accept button
-          var button = domwindow.document.documentElement.getButton("accept");
-          button.disabled = false;
+        // Override the countdown timer on the accept button
+        var button = domwindow.document.documentElement.getButton("accept");
+        button.disabled = false;
 
-          aCallback(domwindow);
-        });
-      }, false);
+        aCallback(domwindow);
+      }, domwindow);
     },
 
     onCloseWindow: function(aXULWindow) {
     },
 
     onWindowTitleChange: function(aXULWindow, aNewTitle) {
     }
   });
@@ -592,17 +587,17 @@ var XPInstallObserver = {
     info("Observed " + aTopic + " for " + installInfo.installs.length + " installs");
     installInfo.installs.forEach(function(aInstall) {
       info("Install of " + aInstall.sourceURI.spec + " was in state " + aInstall.state);
     });
   }
 };
 
 function test() {
-  requestLongerTimeout(2);
+  requestLongerTimeout(4);
   waitForExplicitFinish();
 
   Services.prefs.setBoolPref("extensions.logging.enabled", true);
 
   Services.obs.addObserver(XPInstallObserver, "addon-install-started", false);
   Services.obs.addObserver(XPInstallObserver, "addon-install-blocked", false);
   Services.obs.addObserver(XPInstallObserver, "addon-install-failed", false);
   Services.obs.addObserver(XPInstallObserver, "addon-install-complete", false);
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_bug565575.js
@@ -0,0 +1,13 @@
+function test() {
+  gBrowser.selectedBrowser.focus();
+  BrowserOpenTab();
+  ok(gURLBar.focused, "location bar is focused for a new tab");
+
+  gBrowser.selectedTab = gBrowser.tabs[0];
+  ok(!gURLBar.focused, "location bar isn't focused for the previously selected tab");
+
+  gBrowser.selectedTab = gBrowser.tabs[1];
+  ok(gURLBar.focused, "location bar is re-focused when selecting the new tab");
+
+  gBrowser.removeCurrentTab();
+}
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/browser_contentAreaClick.js
@@ -0,0 +1,296 @@
+/* ***** 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 Firefox Browser Test Code.
+ *
+ * The Initial Developer of the Original Code is the Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Marco Bonardo <mak77@bonardo.net>
+ *
+ * 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 ***** */
+ 
+/**
+ * Test for bug 549340.
+ * Test for browser.js::contentAreaClick() util.
+ *
+ * The test opens a new browser window, then replaces browser.js methods invoked
+ * by contentAreaClick with a mock function that tracks which methods have been
+ * called.
+ * Each sub-test synthesizes a mouse click event on links injected in content,
+ * the event is collected by a click handler that ensures that contentAreaClick
+ * correctly prevent default events, and follows the correct code path.
+ */
+
+let gTests = [
+
+  {
+    desc: "Simple left click",
+    setup: function() {},
+    clean: function() {},
+    event: {},
+    target: "commonlink",
+    expectedInvokedMethods: [],
+    preventDefault: false,
+  },
+
+  {
+    desc: "Ctrl/Cmd left click",
+    setup: function() {},
+    clean: function() {},
+    event: { ctrlKey: true,
+             metaKey: true },
+    target: "commonlink",
+    expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
+    preventDefault: true,
+  },
+
+  // The next test was once handling feedService.forcePreview().  Now it should
+  // just be like Alt click.
+  {
+    desc: "Shift+Alt left click",
+    setup: function() {},
+    clean: function() {},
+    event: { shiftKey: true,
+             altKey: true },
+    target: "commonlink",
+    expectedInvokedMethods: [ "gatherTextUnder", "saveURL" ],
+    preventDefault: true,
+  },
+
+  {
+    desc: "Shift click",
+    setup: function() {},
+    clean: function() {},
+    event: { shiftKey: true },
+    target: "commonlink",
+    expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
+    preventDefault: true,
+  },
+
+  {
+    desc: "Alt click",
+    setup: function() {},
+    clean: function() {},
+    event: { altKey: true },
+    target: "commonlink",
+    expectedInvokedMethods: [ "gatherTextUnder", "saveURL" ],
+    preventDefault: true,
+  },
+
+  {
+    desc: "Panel click",
+    setup: function() {},
+    clean: function() {},
+    event: {},
+    target: "panellink",
+    expectedInvokedMethods: [ "urlSecurityCheck", "getShortcutOrURI", "loadURI" ],
+    preventDefault: true,
+  },
+
+  {
+    desc: "Simple middle click opentab",
+    setup: function() {},
+    clean: function() {},
+    event: { button: 1 },
+    target: "commonlink",
+    expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
+    preventDefault: true,
+  },
+
+  {
+    desc: "Simple middle click openwin",
+    setup: function() {
+      gPrefService.setBoolPref("browser.tabs.opentabfor.middleclick", false);
+    },
+    clean: function() {
+      try {
+        gPrefService.clearUserPref("browser.tabs.opentabfor.middleclick");
+      } catch(ex) {}
+    },
+    event: { button: 1 },
+    target: "commonlink",
+    expectedInvokedMethods: [ "urlSecurityCheck", "openLinkIn" ],
+    preventDefault: true,
+  },
+
+  {
+    desc: "Middle mouse paste",
+    setup: function() {
+      gPrefService.setBoolPref("middlemouse.contentLoadURL", true);
+      gPrefService.setBoolPref("general.autoScroll", false);
+    },
+    clean: function() {
+      try {
+        gPrefService.clearUserPref("middlemouse.contentLoadURL");
+      } catch(ex) {}
+      try {
+        gPrefService.clearUserPref("general.autoScroll");
+      } catch(ex) {}
+    },
+    event: { button: 1 },
+    target: "emptylink",
+    expectedInvokedMethods: [ "middleMousePaste" ],
+    preventDefault: true,
+  },
+
+];
+
+// Array of method names that will be replaced in the new window.
+let gReplacedMethods = [
+  "middleMousePaste",
+  "urlSecurityCheck",
+  "loadURI",
+  "gatherTextUnder",
+  "saveURL",
+  "openLinkIn",
+  "getShortcutOrURI",
+];
+
+// Reference to the new window.
+let gTestWin = null;
+
+// List of methods invoked by a specific call to contentAreaClick.
+let gInvokedMethods = [];
+
+// The test currently running.
+let gCurrentTest = null;
+
+function test() {
+  waitForExplicitFinish();
+
+  gTestWin = openDialog(location, "", "chrome,all,dialog=no", "about:blank");
+  gTestWin.addEventListener("load", function (event) {
+    info("Window loaded.");
+    gTestWin.removeEventListener("load", arguments.callee, false);
+    waitForFocus(function() {
+      info("Setting up browser...");
+      setupTestBrowserWindow();
+      info("Running tests...");
+      executeSoon(runNextTest);
+    }, gTestWin.content, true);
+  }, false);
+}
+
+// Click handler used to steal click events.
+let gClickHandler = {
+  handleEvent: function (event) {
+    let linkId = event.target.id;
+    is(event.type, "click",
+       gCurrentTest.desc + ":Handler received a click event on " + linkId);
+
+    let isPanelClick = linkId == "panellink";
+    let returnValue = gTestWin.contentAreaClick(event, isPanelClick);
+    let prevent = event.getPreventDefault();
+    is(prevent, gCurrentTest.preventDefault,
+       gCurrentTest.desc + ": event.getPreventDefault() is correct (" + prevent + ")")
+
+    // Check that all required methods have been called.
+    gCurrentTest.expectedInvokedMethods.forEach(function(aExpectedMethodName) {
+      isnot(gInvokedMethods.indexOf(aExpectedMethodName), -1,
+            gCurrentTest.desc + ":" + aExpectedMethodName + " was invoked");
+    });
+    
+    if (gInvokedMethods.length != gCurrentTest.expectedInvokedMethods.length) {
+      is(false, "More than the expected methods have been called");
+      gInvokedMethods.forEach(function (method) info(method + " was invoked"));
+    }
+
+    event.preventDefault();
+    event.stopPropagation();
+
+    executeSoon(runNextTest);
+  }
+}
+
+// Wraps around the methods' replacement mock function.
+function wrapperMethod(aInvokedMethods, aMethodName) {
+  return function () {
+    aInvokedMethods.push(aMethodName);
+    // At least getShortcutOrURI requires to return url that is the first param.
+    return arguments[0];
+  }
+}
+
+function setupTestBrowserWindow() {
+  // Steal click events and don't propagate them.
+  gTestWin.addEventListener("click", gClickHandler, true);
+
+  // Replace methods.
+  gReplacedMethods.forEach(function (aMethodName) {
+    gTestWin["old_" + aMethodName] = gTestWin[aMethodName];
+    gTestWin[aMethodName] = wrapperMethod(gInvokedMethods, aMethodName);
+  });
+
+  // Inject links in content.
+  let doc = gTestWin.content.document;
+  let mainDiv = doc.createElement("div");
+  mainDiv.innerHTML =
+    '<a id="commonlink" href="http://mochi.test/moz/">Common link</a>' +
+    '<a id="panellink" href="http://mochi.test/moz/">Panel link</a>' +
+    '<a id="emptylink">Empty link</a>';
+  doc.body.appendChild(mainDiv);
+}
+
+function runNextTest() {
+  if (gCurrentTest) {
+    info(gCurrentTest.desc + ": cleaning up...")
+    gCurrentTest.clean();
+    gInvokedMethods.length = 0;
+  }
+
+  if (gTests.length > 0) {
+    gCurrentTest = gTests.shift();
+
+    info(gCurrentTest.desc + ": starting...");
+    // Prepare for test.
+    gCurrentTest.setup();
+
+    // Fire click event.
+    let target = gTestWin.content.document.getElementById(gCurrentTest.target);
+    ok(target, gCurrentTest.desc + ": target is valid (" + target.id + ")");
+    EventUtils.synthesizeMouse(target, 2, 2, gCurrentTest.event, gTestWin.content);
+  }
+  else {
+    // No more tests to run.
+    finishTest()
+  }
+}
+
+function finishTest() {
+  info("Restoring browser...");
+  gTestWin.removeEventListener("click", gClickHandler, true);
+
+  // Restore original methods.
+  gReplacedMethods.forEach(function (aMethodName) {
+    gTestWin[aMethodName] = gTestWin["old_" + aMethodName];
+    delete gTestWin["old_" + aMethodName];
+  });
+
+  gTestWin.close();
+  finish();
+}
--- a/browser/base/content/test/browser_tabMatchesInAwesomebar.js
+++ b/browser/base/content/test/browser_tabMatchesInAwesomebar.js
@@ -116,17 +116,17 @@ var gTestSteps = [
         }, true);
         tab.linkedBrowser.contentDocument.querySelector("iframe").src = "http://test2.example.org/";
       });
     }, true);
     tab.linkedBrowser.loadURI('data:text/html,<body><iframe src=""></iframe></body>');
   },
   function() {
     info("Running step 7 - remove tab immediately");
-    let tab = gBrowser.addTab("about:blank");
+    let tab = gBrowser.addTab("about:logo");
     gBrowser.removeTab(tab);
     ensure_opentabs_match_db();
     nextStep();
   },
   function() {
     info("Running step 8 - check swapBrowsersAndCloseOther preserves registered switch-to-tab result");
     let tabToKeep = gBrowser.addTab();
     let tab = gBrowser.addTab();
@@ -204,16 +204,18 @@ function ensure_opentabs_match_db() {
     let browserWin = winEnum.getNext();
     // skip closed-but-not-destroyed windows
     if (browserWin.closed)
       continue;
 
     for (let i = 0; i < browserWin.gBrowser.tabContainer.childElementCount; i++) {
       let browser = browserWin.gBrowser.getBrowserAtIndex(i);
       let url = browser.currentURI.spec;
+      if (url == "about:blank")
+        continue;
       if (!(url in tabs))
         tabs[url] = 1;
       else
         tabs[url]++;
     }
   }
 
   var db = PlacesUtils.history.QueryInterface(Ci.nsPIPlacesDatabase)
@@ -244,16 +246,20 @@ function ensure_opentabs_match_db() {
   } finally {
     stmt.finalize();
   }
 
   for (let url in tabs) {
     ok(dbtabs.indexOf(url) > -1,
        "tab is open (" + tabs[url] + " times) and should recorded in db: " + url);
   }
+  dbtabs.forEach(function (url) {
+    ok(url in tabs,
+       "db-recorded tab should actually exist: " + url);
+  });
 }
 
 /**
  * Clears history invoking callback when done.
  */
 function waitForClearHistory(aCallback) {
   const TOPIC_EXPIRATION_FINISHED = "places-expiration-finished";
   let observer = {
--- a/browser/base/content/test/browser_tabfocus.js
+++ b/browser/base/content/test/browser_tabfocus.js
@@ -39,21 +39,18 @@ function test() {
     is(focusedWindow.value, browser1.contentWindow, "initial frame focus in tab 1");
     is(fm.getFocusedElementForWindow(browser2.contentWindow, false, focusedWindow), null, "initial focus in tab 2");
     is(focusedWindow.value, browser2.contentWindow, "initial frame focus in tab 2");
 
     expectFocusShift(function () gBrowser.selectedTab = tab2,
                      browser2.contentWindow, null, true,
                      "focusedElement after tab change, focus in new tab");
 
-    // switching tabs when the urlbar is focused and nothing in the new tab is focused
+    // switching tabs when nothing in the new tab is focused
     // should focus the browser
-    expectFocusShift(function () gURLBar.focus(),
-                     window, gURLBar.inputField, true,
-                     "url field focused");
     expectFocusShift(function () gBrowser.selectedTab = tab1,
                      browser1.contentWindow, null, true,
                      "focusedElement after tab change, focus in new tab");
 
     // focusing a button in the current tab should focus it
     var button1 = browser1.contentDocument.getElementById("button1");
     expectFocusShift(function () button1.focus(),
                      browser1.contentWindow, button1, true,
@@ -84,16 +81,19 @@ function test() {
 
     // focusing the url field should switch active focus away from the tab but
     // not clear what would be the focus in the tab 
     button1.focus();
     expectFocusShift(function () gURLBar.focus(),
                      window, gURLBar.inputField, true,
                      "focusedWindow after url field focused");
     is(fm.getFocusedElementForWindow(browser2.contentWindow, false, {}), button2, "url field focused, button in tab");
+    expectFocusShift(function () gURLBar.blur(),
+                     window, null, true,
+                     "focusedWindow after browser focused");
 
     // when a chrome element is focused, switching tabs to a tab with a button
     // with the current focus should focus the button
     expectFocusShift(function () gBrowser.selectedTab = tab1,
                      browser1.contentWindow, button1, true,
                      "focusedWindow after tab change, focus in url field, button focused in new tab");
     is(fm.getFocusedElementForWindow(browser2.contentWindow, false, {}), button2, "after switch tab, focus in unfocused tab");
 
--- a/browser/base/content/test/tabview/Makefile.in
+++ b/browser/base/content/test/tabview/Makefile.in
@@ -48,16 +48,17 @@ include $(topsrcdir)/config/rules.mk
                  browser_tabview_bug580412.js \
                  browser_tabview_bug587043.js \
                  browser_tabview_bug587990.js \
                  browser_tabview_bug590606.js \
                  browser_tabview_bug591706.js \
                  browser_tabview_bug594176.js \
                  browser_tabview_bug595191.js \
                  browser_tabview_bug595518.js \
+                 browser_tabview_bug595521.js \
                  browser_tabview_bug595804.js \
                  browser_tabview_bug595930.js \
                  browser_tabview_bug595943.js \
                  browser_tabview_bug598600.js \
                  browser_tabview_dragdrop.js \
                  browser_tabview_exit_button.js \
                  browser_tabview_group.js \
                  browser_tabview_launch.js \
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/tabview/browser_tabview_bug595521.js
@@ -0,0 +1,101 @@
+/* ***** 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 a test for bug 595521.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Raymond Lee <raymond@appcoast.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+let fadeAwayUndoButtonDelay;
+let fadeAwayUndoButtonDuration;
+
+function test() {
+  waitForExplicitFinish();
+
+  window.addEventListener("tabviewshown", testCloseLastGroup, false);
+  TabView.toggle();
+}
+
+function testCloseLastGroup() {
+  window.removeEventListener("tabviewshown", testCloseLastGroup, false);
+  ok(TabView.isVisible(), "Tab View is visible");
+
+  let contentWindow = document.getElementById("tab-view").contentWindow;
+
+  is(contentWindow.GroupItems.groupItems.length, 1, "Has one group only");
+
+  let groupItem = contentWindow.GroupItems.groupItems[0];
+  
+  let checkExistence = function() {
+    is(contentWindow.GroupItems.groupItems.length, 1, 
+       "Still has one group after delay");
+
+    EventUtils.sendMouseEvent(
+      { type: "click" }, groupItem.$undoContainer[0], contentWindow);
+  };
+
+  groupItem.addSubscriber(groupItem, "groupHidden", function() {
+    groupItem.removeSubscriber(groupItem, "groupHidden");
+    // it should still stay after 3 ms.
+    setTimeout(checkExistence, 3);
+  });
+
+  groupItem.addSubscriber(groupItem, "groupShown", function() {
+    groupItem.removeSubscriber(groupItem, "groupShown");
+
+    let endGame = function() {
+      window.removeEventListener("tabviewhidden", endGame, false);
+      ok(!TabView.isVisible(), "Tab View is hidden");
+
+      groupItem.fadeAwayUndoButtonDelay = fadeAwayUndoButtonDelay;
+      groupItem.fadeAwayUndoButtonDuration = fadeAwayUndoButtonDuration;
+
+      finish();
+    };
+    window.addEventListener("tabviewhidden", endGame, false);
+
+    TabView.toggle();
+  });
+
+  let closeButton = groupItem.container.getElementsByClassName("close");
+  ok(closeButton, "Group item close button exists");
+
+  // store the original values
+  fadeAwayUndoButtonDelay = groupItem.fadeAwayUndoButtonDelay;
+  fadeAwayUndoButtonDuration = groupItem.fadeAwayUndoButtonDuration;
+
+  // set both fade away delay and duration to 1ms
+  groupItem.fadeAwayUndoButtonDelay = 1;
+  groupItem.fadeAwayUndoButtonDuration = 1;
+
+  EventUtils.sendMouseEvent({ type: "click" }, closeButton[0], contentWindow);
+}
--- a/browser/base/content/test/tabview/browser_tabview_bug598600.js
+++ b/browser/base/content/test/tabview/browser_tabview_bug598600.js
@@ -30,25 +30,18 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 let newWin;
-let prefService;
-
 function test() {
   let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
-  prefService = 
-    Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService).
-      getBranch("browser.panorama.");
-  // make sure we don't trigger the 'first run' behavior
-  prefService.setBoolPref("experienced_first_run", true);
 
   waitForExplicitFinish();
 
   // open a new window and setup the window state.
   newWin = openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no");
   newWin.addEventListener("load", function(event) {
     this.removeEventListener("load", arguments.callee, false);
 
@@ -99,17 +92,16 @@ function test() {
       newWin.removeEventListener("tabviewshown", onTabViewShow, false);
 
       let contentWindow = newWin.document.getElementById("tab-view").contentWindow;
 
       is(contentWindow.GroupItems.groupItems.length, 2, "Has two group items");
       is(contentWindow.GroupItems.getOrphanedTabs().length, 0, "No orphan tabs");
 
       // clean up and finish
-      prefService.setBoolPref("experienced_first_run", false);
       newWin.close();
 
       finish();
     }
     newWin.addEventListener("tabviewshown", onTabViewShow, false);
     newWin.TabView.toggle();
   }, false);
 }
--- a/browser/base/content/test/tabview/browser_tabview_firstrun_pref.js
+++ b/browser/base/content/test/tabview/browser_tabview_firstrun_pref.js
@@ -39,52 +39,64 @@ var prefsBranch = Cc["@mozilla.org/prefe
                   getService(Ci.nsIPrefService).
                   getBranch("browser.panorama.");
 
 function test() {
   waitForExplicitFinish();
 
   ok(!TabView.isVisible(), "Main window TabView is hidden");
 
+  ok(experienced(), "should start as experienced");
+
   prefsBranch.setBoolPref("experienced_first_run", false);
-  ok(!experienced(), "not experienced");
+  ok(!experienced(), "set to not experienced");
 
   newWindowWithTabView(checkFirstRun, part2);
 }
 
 function experienced() {
   return prefsBranch.prefHasUserValue("experienced_first_run") &&
     prefsBranch.getBoolPref("experienced_first_run");
 }
 
 function checkFirstRun(win) {
   let contentWindow = win.document.getElementById("tab-view").contentWindow;
   
-  let infoItems = contentWindow.iQ(".info-item");
-  is(infoItems.length, 1, "There should be an info item");
-
+  is(win.gBrowser.tabs.length, 2, "There should be two tabs");
+  
   let groupItems = contentWindow.GroupItems.groupItems;
   is(groupItems.length, 1, "There should be one group");
+  is(groupItems[0].getChildren().length, 1, "...with one child");
+
+  let orphanTabCount = contentWindow.GroupItems.getOrphanedTabs().length;
+  is(orphanTabCount, 1, "There should also be an orphaned tab");
   
   ok(experienced(), "we're now experienced");
 }
 
 function part2() {
   newWindowWithTabView(checkNotFirstRun, endGame);
 }
 
 function checkNotFirstRun(win) {
   let contentWindow = win.document.getElementById("tab-view").contentWindow;
   
-  let infoItems = contentWindow.iQ(".info-item");
-  is(infoItems.length, 0, "There should be no info items");
+  is(win.gBrowser.tabs.length, 1, "There should be one tab");
+  
+  let groupItems = contentWindow.GroupItems.groupItems;
+  is(groupItems.length, 1, "There should be one group");
+  is(groupItems[0].getChildren().length, 1, "...with one child");
+
+  let orphanTabCount = contentWindow.GroupItems.getOrphanedTabs().length;
+  is(orphanTabCount, 0, "There should also be no orphaned tabs");
 }
 
 function endGame() {
   ok(!TabView.isVisible(), "Main window TabView is still hidden");
+  ok(experienced(), "should finish as experienced");
   finish();
 }
 
 function newWindowWithTabView(callback, completeCallback) {
   let charsetArg = "charset=" + window.content.document.characterSet;
   let win = window.openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no,height=800,width=800",
                               "about:blank", charsetArg, null, null, true);
   let onLoad = function() {
--- a/browser/base/content/test/tabview/browser_tabview_launch.js
+++ b/browser/base/content/test/tabview/browser_tabview_launch.js
@@ -50,23 +50,38 @@ function test() {
   ok(button, "Tab View button exists");
   button.doCommand();
 }
 
 // ----------
 function onTabViewLoadedAndShown() {
   window.removeEventListener("tabviewshown", onTabViewLoadedAndShown, false);
   
-  ok(TabView.isVisible(), "Tab View is visible. Count: " + tabViewShownCount);
-  tabViewShownCount++;
+  // Evidently sometimes isVisible (which is based on the selectedIndex of the
+  // tabview deck) isn't updated immediately when called from button.doCommand,
+  // so we add a little timeout here to get outside of the doCommand call.
+  // If the initial timeout isn't enough, we keep waiting in case it's taking
+  // longer than expected.
+  // See bug 594909.
+  let deck = document.getElementById("tab-view-deck");
+  function waitForSwitch() {
+    if (deck.selectedIndex == 1) {
+      ok(TabView.isVisible(), "Tab View is visible. Count: " + tabViewShownCount);
+      tabViewShownCount++;
+      
+      // kick off the series
+      window.addEventListener("tabviewshown", onTabViewShown, false);
+      window.addEventListener("tabviewhidden", onTabViewHidden, false);
+      TabView.toggle();
+    } else {
+      setTimeout(waitForSwitch, 10);
+    }
+  }
   
-  // kick off the series
-  window.addEventListener("tabviewshown", onTabViewShown, false);
-  window.addEventListener("tabviewhidden", onTabViewHidden, false);
-  TabView.toggle();
+  setTimeout(waitForSwitch, 1);
 }
 
 // ----------
 function onTabViewShown() {
   // add the count to the message so we can track things more easily.
   ok(TabView.isVisible(), "Tab View is visible. Count: " + tabViewShownCount);
   tabViewShownCount++;
   TabView.toggle();
--- a/browser/base/content/urlbarBindings.xml
+++ b/browser/base/content/urlbarBindings.xml
@@ -156,17 +156,17 @@
           insertLocation = insertLocation.nextSibling;
         if (insertLocation) {
           pasteAndGo = document.createElement("menuitem");
           let label = Services.strings.createBundle("chrome://browser/locale/browser.properties").
                                    GetStringFromName("pasteAndGo.label");
           pasteAndGo.setAttribute("label", label);
           pasteAndGo.setAttribute("anonid", "paste-and-go");
           pasteAndGo.setAttribute("oncommand",
-              "gURLBar.value = ''; goDoCommand('cmd_paste'); gURLBar.handleCommand();");
+              "gURLBar.select(); goDoCommand('cmd_paste'); gURLBar.handleCommand();");
           cxmenu.insertBefore(pasteAndGo, insertLocation.nextSibling);
         }
       ]]></constructor>
 
       <destructor><![CDATA[
         this._prefs.removeObserver("", this);
         this._prefs = null;
         this.inputField.controllers.removeController(this._copyCutController);
@@ -243,18 +243,23 @@
 
           var url = this.value;
           var postData = null;
 
           var action = this._parseActionUrl(url);
           if (action) {
             url = action.param;
             if (!(aTriggeringEvent && aTriggeringEvent.altKey)) {
-              if (action.type == "switchtab")
-                switchToTabHavingURI(url);
+              if (action.type == "switchtab") {
+                this.handleRevert();
+                let prevTab = gBrowser.selectedTab;
+                if (switchToTabHavingURI(url) &&
+                    isTabEmpty(prevTab))
+                  gBrowser.removeTab(prevTab);
+              }
               return;
             }
           }
           else {
             [url, postData] = this._canonizeURL(aTriggeringEvent);
             if (!url)
               return;
           }
@@ -267,18 +272,23 @@
             // Things may go wrong when adding url to session history,
             // but don't let that interfere with the loading of the url.
             Cu.reportError(ex);
           }
 
           if (aTriggeringEvent instanceof MouseEvent) {
             // We have a mouse event (from the go button), so use the standard
             // UI link behaviors
-            openUILink(url, aTriggeringEvent, false, false,
-                       true /* allow third party fixup */, postData);
+            let where = whereToOpenLink(aTriggeringEvent, false, false);
+            if (where != "current") {
+              this.handleRevert();
+              content.focus();
+            }
+            openUILinkIn(url, where,
+                        { allowThirdPartyFixup: true, postData: postData });
             return;
           }
 
           if (aTriggeringEvent && aTriggeringEvent.altKey) {
             this.handleRevert();
             content.focus();
             gBrowser.loadOneTab(url, {
                                 postData: postData,
--- a/browser/base/content/utilityOverlay.js
+++ b/browser/base/content/utilityOverlay.js
@@ -407,19 +407,18 @@ function isBidiEnabled() {
   } catch (e) {}
 
   return rv;
 }
 
 function openAboutDialog() {
   var enumerator = Services.wm.getEnumerator("Browser:About");
   while (enumerator.hasMoreElements()) {
+    // Only open one about window (Bug 599573)
     let win = enumerator.getNext();
-    if (win.opener != window)
-      continue;
     win.focus();
     return;
   }
 
 #ifdef XP_MACOSX
   var features = "chrome,resizable=no,minimizable=no";
 #else
   var features = "chrome,centerscreen,dependent";
@@ -481,117 +480,22 @@ function openTroubleshootingPage()
 /**
  * Opens the feedback page for this version of the application.
  */
 function openFeedbackPage()
 {
   openUILinkIn("http://input.mozilla.com/feedback", "tab");
 }
 
-
-#ifdef MOZ_UPDATER
-/**
- * Opens the update manager and checks for updates to the application.
- */
-function checkForUpdates()
-{
-  var um = 
-      Components.classes["@mozilla.org/updates/update-manager;1"].
-      getService(Components.interfaces.nsIUpdateManager);
-  var prompter = 
-      Components.classes["@mozilla.org/updates/update-prompt;1"].
-      createInstance(Components.interfaces.nsIUpdatePrompt);
-
-  // If there's an update ready to be applied, show the "Update Downloaded"
-  // UI instead and let the user know they have to restart the browser for
-  // the changes to be applied. 
-  if (um.activeUpdate && um.activeUpdate.state == "pending")
-    prompter.showUpdateDownloaded(um.activeUpdate);
-  else
-    prompter.checkForUpdates();
-}
-#endif
-
-#ifdef MOZ_UPDATER
-/**
- * Updates an element to reflect the state of available update services.
- */
-function setupCheckForUpdates(checkForUpdates, aStringBundle)
-{
-  var updates = 
-      Components.classes["@mozilla.org/updates/update-service;1"].
-      getService(Components.interfaces.nsIApplicationUpdateService);
-  var um = 
-      Components.classes["@mozilla.org/updates/update-manager;1"].
-      getService(Components.interfaces.nsIUpdateManager);
-
-  // Disable the UI if the update enabled pref has been locked by the 
-  // administrator or if we cannot update for some other reason
-  var canCheckForUpdates = updates.canCheckForUpdates;
-  checkForUpdates.setAttribute("disabled", !canCheckForUpdates);
-  if (!canCheckForUpdates)
-    return; 
-
-  var activeUpdate = um.activeUpdate;
-
-  // If there's an active update, substitute its name into the label
-  // we show for this item, otherwise display a generic label.
-  function getStringWithUpdateName(key) {
-    if (activeUpdate && activeUpdate.name)
-      return aStringBundle.formatStringFromName(key, [activeUpdate.name], 1);
-    return aStringBundle.GetStringFromName(key + "Fallback");
-  }
-
-  // By default, show "Check for Updates..."
-  var key = "default";
-  if (activeUpdate) {
-    switch (activeUpdate.state) {
-    case "downloading":
-      // If we're downloading an update at present, show the text:
-      // "Downloading Firefox x.x..." otherwise we're paused, and show
-      // "Resume Downloading Firefox x.x..."
-      key = updates.isDownloading ? "downloading" : "resume";
-      break;
-    case "pending":
-      // If we're waiting for the user to restart, show: "Apply Downloaded
-      // Updates Now..."
-      key = "pending";
-      break;
-    }
-  }
-  checkForUpdates.label = getStringWithUpdateName("updatesItem_" + key);
-  checkForUpdates.accessKey = aStringBundle.
-                              GetStringFromName("updatesItem_" + key + ".accesskey");
-  if (um.activeUpdate && updates.isDownloading)
-    checkForUpdates.setAttribute("loading", "true");
-  else
-    checkForUpdates.removeAttribute("loading");
-}
-#endif
-
 function buildHelpMenu()
 {
   // Enable/disable the "Report Web Forgery" menu item.  safebrowsing object
   // may not exist in OSX
   if (typeof safebrowsing != "undefined")
     safebrowsing.setReportPhishingMenu();
-
-#ifdef XP_MACOSX
-#ifdef MOZ_UPDATER
-  var checkForUpdates = document.getElementById("checkForUpdates");
-  var browserBundle = document.getElementById("bundle_browser").stringBundle;
-  setupCheckForUpdates(checkForUpdates, browserBundle);
-#else  
-  // Needed by safebrowsing for inserting its menuitem so just hide it
-  document.getElementById("updateSeparator").hidden = true;
-#endif
-#else
-  // Needed by safebrowsing for inserting its menuitem so just hide it
-  document.getElementById("updateSeparator").hidden = true;
-#endif
 }
 
 function isElementVisible(aElement)
 {
   if (!aElement)
     return false;
 
   // If aElement or a direct or indirect parent is hidden or collapsed,
--- a/browser/branding/nightly/pref/firefox-branding.js
+++ b/browser/branding/nightly/pref/firefox-branding.js
@@ -1,10 +1,11 @@
 pref("startup.homepage_override_url","http://www.mozilla.org/projects/%APP%/%VERSION%/whatsnew/");
 pref("startup.homepage_welcome_url","http://www.mozilla.org/projects/%APP%/%VERSION%/firstrun/");
+pref("browser.panorama.welcome_url", "http://www.mozilla.com/firefox/panorama/");
 // The time interval between checks for a new version (in seconds)
 // nightly=8 hours, official=24 hours
 pref("app.update.interval", 28800);
 // The time interval between the downloading of mar file chunks in the
 // background (in seconds)
 pref("app.update.download.backgroundInterval", 60);
 // URL user can browse to manually if for some reason all update installation
 // attempts fail.
--- a/browser/branding/unofficial/pref/firefox-branding.js
+++ b/browser/branding/unofficial/pref/firefox-branding.js
@@ -1,10 +1,11 @@
 pref("startup.homepage_override_url","http://www.mozilla.org/projects/%APP%/%VERSION%/whatsnew/");
 pref("startup.homepage_welcome_url","http://www.mozilla.org/projects/%APP%/%VERSION%/firstrun/");
+pref("browser.panorama.welcome_url", "http://www.mozilla.com/firefox/panorama/");
 // The time interval between checks for a new version (in seconds)
 // nightly=8 hours, official=24 hours
 pref("app.update.interval", 28800);
 // The time interval between the downloading of mar file chunks in the
 // background (in seconds)
 pref("app.update.download.backgroundInterval", 60);
 // URL user can browse to manually if for some reason all update installation
 // attempts fail.
--- a/browser/components/nsBrowserContentHandler.js
+++ b/browser/components/nsBrowserContentHandler.js
@@ -569,48 +569,53 @@ nsBrowserContentHandler.prototype = {
 
   helpInfo : "  -browser           Open a browser window.\n",
 
   /* nsIBrowserHandler */
 
   get defaultArgs() {
     var prefb = Components.classes["@mozilla.org/preferences-service;1"]
                           .getService(nsIPrefBranch);
-    var formatter = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
-                              .getService(Components.interfaces.nsIURLFormatter);
 
     var overridePage = "";
     var haveUpdateSession = false;
     try {
       let override = needHomepageOverride(prefb);
       if (override != OVERRIDE_NONE) {
         // Setup the default search engine to about:home page.
         AboutHomeUtils.loadDefaultSearchEngine();
         AboutHomeUtils.loadSnippetsURL();
 
         switch (override) {
           case OVERRIDE_NEW_PROFILE:
             // New profile.
-            overridePage = formatter.formatURLPref("startup.homepage_welcome_url");
+            overridePage = Services.urlFormatter.formatURLPref("startup.homepage_welcome_url");
             break;
           case OVERRIDE_NEW_MSTONE:
             // Existing profile, new milestone build.
             copyPrefOverride();
 
             // Check whether we have a session to restore. If we do, we assume
             // that this is an "update" session.
             var ss = Components.classes["@mozilla.org/browser/sessionstartup;1"]
                                .getService(Components.interfaces.nsISessionStartup);
             haveUpdateSession = ss.doRestore();
-            overridePage = formatter.formatURLPref("startup.homepage_override_url");
+            overridePage = Services.urlFormatter.formatURLPref("startup.homepage_override_url");
             if (prefb.prefHasUserValue("app.update.postupdate"))
               overridePage = getPostUpdateOverridePage(overridePage);
             break;
         }
       }
+      else {
+        // No need to override homepage, but update snippets url if the pref has
+        // been manually changed.
+        if (Services.prefs.prefHasUserValue(AboutHomeUtils.SNIPPETS_URL_PREF)) {
+          AboutHomeUtils.loadSnippetsURL();
+        }
+      }
     } catch (ex) {}
 
     // formatURLPref might return "about:blank" if getting the pref fails
     if (overridePage == "about:blank")
       overridePage = "";
 
     var startPage = "";
     try {
@@ -877,16 +882,17 @@ nsDefaultCommandLineHandler.prototype = 
                  gBrowserContentHandler.defaultArgs, NO_EXTERNAL_URIS);
     }
   },
 
   helpInfo : "",
 };
 
 let AboutHomeUtils = {
+  SNIPPETS_URL_PREF: "browser.aboutHomeSnippets.updateUrl",
   get _storage() {
     let aboutHomeURI = Services.io.newURI("moz-safe-about:home", null, null);
     let principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"].
                     getService(Components.interfaces.nsIScriptSecurityManager).
                     getCodebasePrincipal(aboutHomeURI);
     let dsm = Components.classes["@mozilla.org/dom/storagemanager;1"].
               getService(Components.interfaces.nsIDOMStorageManager);
     return dsm.getLocalStorageForPrincipal(principal, "");
@@ -903,18 +909,18 @@ let AboutHomeUtils = {
     , searchUrl: submission.uri.spec
     }
     this._storage.setItem("search-engine", JSON.stringify(engine));
   },
 
   loadSnippetsURL: function AHU_loadSnippetsURL()
   {
     const STARTPAGE_VERSION = 1;
-    const SNIPPETS_URL = "http://snippets.mozilla.com/" + STARTPAGE_VERSION + "/%NAME%/%VERSION%/%APPBUILDID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/";
-    let updateURL = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"].
-                    getService(Components.interfaces.nsIURLFormatter).
-                    formatURL(SNIPPETS_URL);
+    let updateURL = Services.prefs
+                            .getCharPref(this.SNIPPETS_URL_PREF)
+                            .replace("%STARTPAGE_VERSION%", STARTPAGE_VERSION);
+    updateURL = Services.urlFormatter.formatURL(updateURL);
     this._storage.setItem("snippets-update-url", updateURL);
   },
 };
 
 var components = [nsBrowserContentHandler, nsDefaultCommandLineHandler];
 var NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
--- a/browser/components/places/content/browserPlacesViews.js
+++ b/browser/components/places/content/browserPlacesViews.js
@@ -494,20 +494,20 @@ PlacesViewBase.prototype = {
     // Here we need the <menu>.
     if (elt.localName == "menupopup")
       elt = elt.parentNode;
 
     if (!aNewTitle && elt.localName != "toolbarbutton") {
       // Many users consider toolbars as shortcuts containers, so explicitly
       // allow empty labels on toolbarbuttons.  For any other element try to be
       // smarter, guessing a title from the uri.
-      elt.label = PlacesUIUtils.getBestTitle(aPlacesNode);
+      elt.setAttribute("label", PlacesUIUtils.getBestTitle(aPlacesNode));
     }
     else {
-      elt.label = aNewTitle;
+      elt.setAttribute("label", aNewTitle);
     }
   },
 
   nodeRemoved:
   function PVB_nodeRemoved(aParentPlacesNode, aPlacesNode, aIndex) {
     let parentElt = aParentPlacesNode._DOMElement;
     let elt = aPlacesNode._DOMElement;
 
--- a/browser/components/places/src/PlacesUIUtils.jsm
+++ b/browser/components/places/src/PlacesUIUtils.jsm
@@ -715,17 +715,17 @@ var PlacesUIUtils = {
   },
 
   /**
    * By calling this before visiting an URL, any visit in frames will be
    * associated to a TRANSITION_FRAMED_LINK transition.
    * This is actually used to distinguish user-initiated visits in frames
    * so automatic visits can be correctly ignored.
    */
-  markPageAsFollowedLink: function PUIU_markPageAsUserClicked(aURL) {
+  markPageAsFollowedLink: function PUIU_markPageAsFollowedLink(aURL) {
     PlacesUtils.history.QueryInterface(Ci.nsIBrowserHistory)
                .markPageAsFollowedLink(this.createFixedURI(aURL));
   },
 
   /**
    * Allows opening of javascript/data URI only if the given node is
    * bookmarked (see bug 224521).
    * @param aURINode
--- a/browser/components/places/tests/browser/Makefile.in
+++ b/browser/components/places/tests/browser/Makefile.in
@@ -60,12 +60,16 @@ include $(topsrcdir)/config/rules.mk
 	browser_forgetthissite_single.js \
 	browser_library_left_pane_commands.js \
 	browser_drag_bookmarks_on_toolbar.js \
 	browser_library_middleclick.js \
 	browser_library_views_liveupdate.js \
 	browser_views_liveupdate.js \
 	browser_sidebarpanels_click.js \
 	browser_library_infoBox.js \
+	browser_markPageAsFollowedLink.js \
+	framedPage.html \
+	frameLeft.html \
+	frameRight.html \
 	$(NULL)
 
 libs:: $(_BROWSER_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/browser/components/places/tests/browser/browser_markPageAsFollowedLink.js
@@ -0,0 +1,89 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+/**
+ * Tests that visits across frames are correctly represented in the database.
+ */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+const BASE_URL = "http://mochi.test:8888/browser/browser/components/places/tests/browser";
+const PAGE_URL = BASE_URL + "/framedPage.html";
+const LEFT_URL = BASE_URL + "/frameLeft.html";
+const RIGHT_URL = BASE_URL + "/frameRight.html";
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+let gTabLoaded = false;
+let gLeftFrameVisited = false;
+
+let observer = {
+  observe: function(aSubject, aTopic, aData)
+  {
+    let url = aSubject.QueryInterface(Ci.nsIURI).spec;
+    if (url == LEFT_URL ) {
+      is(getTransitionForUrl(url), PlacesUtils.history.TRANSITION_EMBED,
+         "Frames should get a EMBED transition.");
+      gLeftFrameVisited = true;
+      maybeClickLink();
+    }
+    else if (url == RIGHT_URL ) {
+      is(getTransitionForUrl(url), PlacesUtils.history.TRANSITION_FRAMED_LINK,
+         "User activated visits should get a FRAMED_LINK transition.");
+      finish();
+    }
+  },
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver])
+};
+Services.obs.addObserver(observer, "uri-visit-saved", false);
+
+function test()
+{
+  waitForExplicitFinish();
+  gBrowser.selectedTab = gBrowser.addTab(PAGE_URL);
+  let frameCount = 0;
+  gBrowser.selectedTab.linkedBrowser.addEventListener("DOMContentLoaded",
+    function (event)
+    {
+      // Wait for all the frames.
+      if (frameCount++ < 2)
+        return;
+      gBrowser.selectedTab.linkedBrowser.removeEventListener("DOMContentLoaded", arguments.callee, false)
+      gTabLoaded = true;
+      maybeClickLink();
+    }, false
+  );
+}
+
+function maybeClickLink() {
+  if (gTabLoaded && gLeftFrameVisited) {
+    // Click on the link in the left frame to cause a page load in the
+    // right frame.
+    EventUtils.sendMouseEvent({type: "click"}, "clickme", content.frames[0]);
+  }
+}
+
+function getTransitionForUrl(aUrl)
+{
+  let dbConn = PlacesUtils.history
+                          .QueryInterface(Ci.nsPIPlacesDatabase).DBConnection;
+  let stmt = dbConn.createStatement(
+    "SELECT visit_type FROM moz_historyvisits_view WHERE place_id = " +
+      "(SELECT id FROM moz_places_view WHERE url = :page_url)");
+  stmt.params.page_url = aUrl;
+  try {
+    ok(stmt.executeStep(), "Found the visit in the database");
+    return stmt.row.visit_type;
+  }
+  finally {
+    stmt.finalize();
+  }
+}
+
+registerCleanupFunction(function ()
+{
+  gBrowser.removeTab(gBrowser.selectedTab);
+  Services.obs.removeObserver(observer, "uri-visit-saved");
+})
--- a/browser/components/places/tests/browser/browser_views_liveupdate.js
+++ b/browser/components/places/tests/browser/browser_views_liveupdate.js
@@ -286,18 +286,18 @@ var bookmarksObserver = {
         let cellText = tree.view.getCellText(aElementOrTreeIndex,
                                              tree.columns.getColumnAt(0));
         if (!aNewValue)
           return cellText == PlacesUIUtils.getBestTitle(tree.view.nodeForTreeIndex(aElementOrTreeIndex));
         return cellText == aNewValue;
       }
       else {
         if (!aNewValue && aElementOrTreeIndex.localName != "toolbarbutton")
-          return aElementOrTreeIndex.label == PlacesUIUtils.getBestTitle(aElementOrTreeIndex._placesNode);
-        return aElementOrTreeIndex.label == aNewValue;
+          return aElementOrTreeIndex.getAttribute("label") == PlacesUIUtils.getBestTitle(aElementOrTreeIndex._placesNode);
+        return aElementOrTreeIndex.getAttribute("label") == aNewValue;
       }
     };
 
     for (var i = 0; i < views.length; i++) {
       var [node, index, valid] = searchItemInView(aItemId, views[i], validator);
       isnot(node, null, "Found changed Places node in " + views[i]);
       is(node.title, aNewValue, "Node has correct title: " + aNewValue);
       ok(valid, "Node element has correct label: " + aNewValue);
new file mode 100644
--- /dev/null
+++ b/browser/components/places/tests/browser/frameLeft.html
@@ -0,0 +1,8 @@
+<html>
+  <head>
+    <title>Left frame</title>
+  </head>
+  <body>
+    <a id="clickme" href="frameRight.html" target="right">Open page in the right frame.</a>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/components/places/tests/browser/frameRight.html
@@ -0,0 +1,8 @@
+<html>
+  <head>
+    <title>Right Frame</title>
+  </head>
+  <body>
+    This is the right frame.
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/browser/components/places/tests/browser/framedPage.html
@@ -0,0 +1,9 @@
+<html>
+  <head>
+    <title>Framed page</title>
+  </head>
+  <frameset cols="*,*">
+    <frame name="left" src="frameLeft.html">
+    <frame name="right" src="about:robots">
+  </frameset>
+</html>
--- a/browser/components/privatebrowsing/content/aboutPrivateBrowsing.xhtml
+++ b/browser/components/privatebrowsing/content/aboutPrivateBrowsing.xhtml
@@ -40,22 +40,20 @@
   <!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 % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
   %browserDTD;
-#ifdef XP_WIN
-  <!ENTITY basePBMenu.label   "<span class='appMenuButton'>&brandShortName;</span><span class='toolsMenu'>&toolsMenu.label;</span>">
-#elifdef XP_MACOSX
+#ifdef XP_MACOSX
   <!ENTITY basePBMenu.label   "&toolsMenu.label;">
 #else
-  <!ENTITY basePBMenu.label   "<span class='appMenuButton'>&appMenuButton.label;</span><span class='toolsMenu'>&toolsMenu.label;</span>">
+  <!ENTITY basePBMenu.label   "<span class='appMenuButton'>&brandShortName;</span><span class='toolsMenu'>&toolsMenu.label;</span>">
 #endif
   <!ENTITY % privatebrowsingpageDTD SYSTEM "chrome://browser/locale/aboutPrivateBrowsing.dtd">
   %privatebrowsingpageDTD;
 ]>
 
 <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
     <link rel="stylesheet" href="chrome://global/skin/netError.css" type="text/css" media="all"/>
--- a/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js
+++ b/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js
@@ -464,18 +464,20 @@ PrivateBrowsingService.prototype = {
   },
 
   // nsICommandLineHandler
 
   handle: function PBS_handle(aCmdLine) {
     if (aCmdLine.handleFlag("private", false))
       ; // It has already been handled
     else if (aCmdLine.handleFlag("private-toggle", false)) {
+      if (this._autoStarted) {
+        throw Cr.NS_ERROR_ABORT;
+      }
       this.privateBrowsingEnabled = !this.privateBrowsingEnabled;
-      this._autoStarted = false;
       this._lastChangedByCommandLine = true;
     }
   },
 
   get helpInfo() {
     return "  -private           Enable private browsing mode.\n" +
            "  -private-toggle    Toggle private browsing mode.\n";
   },
--- a/browser/components/safebrowsing/content/report-phishing-overlay.xul
+++ b/browser/components/safebrowsing/content/report-phishing-overlay.xul
@@ -47,21 +47,21 @@
   <broadcasterset id="mainBroadcasterSet">
     <broadcaster id="reportPhishingBroadcaster" disabled="true"/>
     <broadcaster id="reportPhishingErrorBroadcaster" disabled="true"/>
   </broadcasterset>
   <menupopup id="menu_HelpPopup">
     <menuitem id="menu_HelpPopup_reportPhishingtoolmenu"
               label="&reportPhishSiteMenu.title2;"
               accesskey="&reportPhishSiteMenu.accesskey;"
-              insertbefore="updateSeparator"
+              insertbefore="aboutSeparator"
               observes="reportPhishingBroadcaster"
               oncommand="openUILink(safebrowsing.getReportURL('Phish'), event);"
               onclick="checkForMiddleClick(this, event);"/>
     <menuitem id="menu_HelpPopup_reportPhishingErrortoolmenu"
               label="&safeb.palm.notforgery.label2;"
               accesskey="&reportPhishSiteMenu.accesskey;"
-              insertbefore="updateSeparator"
+              insertbefore="aboutSeparator"
               observes="reportPhishingErrorBroadcaster"
               oncommand="openUILinkIn(safebrowsing.getReportURL('Error'), 'tab');"
               onclick="checkForMiddleClick(this, event);"/>
   </menupopup>
 </overlay>
--- a/browser/components/search/content/search.xml
+++ b/browser/components/search/content/search.xml
@@ -600,17 +600,17 @@
                  insertLocation.getAttribute("cmd") != "cmd_paste")
             insertLocation = insertLocation.nextSibling;
           if (insertLocation) {
             element = document.createElementNS(kXULNS, "menuitem");
             label = this._stringBundle.getString("cmd_pasteAndSearch");
             element.setAttribute("label", label);
             element.setAttribute("anonid", "paste-and-search");
             element.setAttribute("oncommand",
-                "BrowserSearch.searchBar.value = ''; goDoCommand('cmd_paste'); BrowserSearch.searchBar.handleSearchCommand();");
+                "BrowserSearch.searchBar.select(); goDoCommand('cmd_paste'); BrowserSearch.searchBar.handleSearchCommand();");
             cxmenu.insertBefore(element, insertLocation.nextSibling);
             pasteAndSearch = element;
           }
 
           element = document.createElementNS(kXULNS, "menuitem");
           label = this._stringBundle.getString("cmd_clearHistory");
           akey = this._stringBundle.getString("cmd_clearHistory_accesskey");
           element.setAttribute("label", label);
--- a/browser/components/sessionstore/src/nsSessionStore.js
+++ b/browser/components/sessionstore/src/nsSessionStore.js
@@ -740,34 +740,69 @@ SessionStoreService.prototype = {
       let followUp = this._statesToRestore[aWindow.__SS_restoreID].windows.length == 1;
       this.restoreWindow(aWindow, this._statesToRestore[aWindow.__SS_restoreID], true, followUp);
     }
     else if (this._restoreLastWindow && aWindow.toolbar.visible &&
              this._closedWindows.length &&
              !this._inPrivateBrowsing) {
       // default to the most-recently closed window
       // don't use popup windows
-      let state = null;
-      let newClosedWindows = this._closedWindows.filter(function(aWinState) {
-        if (!state && !aWinState.isPopup) {
-          state = aWinState;
-          return false;
+      let closedWindowState = null;
+      let closedWindowIndex;
+      for (let i = 0; i < this._closedWindows.length; i++) {
+        // Take the first non-popup, point our object at it, and break out.
+        if (!this._closedWindows[i].isPopup) {
+          closedWindowState = this._closedWindows[i];
+          closedWindowIndex = i;
+          break;
         }
-        return true;
-      });
-      if (state) {
-        delete state.hidden;
+      }
+
+      if (closedWindowState) {
+        let newWindowState;
 #ifndef XP_MACOSX
-        if (!this._doResumeSession())
+        if (!this._doResumeSession()) {
 #endif
-          state.tabs = state.tabs.filter(function (tab) tab.pinned);
-        if (state.tabs.length > 0) {
-          this._closedWindows = newClosedWindows;
+          // We want to split the window up into pinned tabs and unpinned tabs.
+          // Pinned tabs should be restored. If there are any remaining tabs,
+          // they should be added back to _closedWindows.
+          // We'll cheat a little bit and reuse _prepDataForDeferredRestore
+          // even though it wasn't built exactly for this.
+          let [appTabsState, normalTabsState] =
+            this._prepDataForDeferredRestore(JSON.stringify({ windows: [closedWindowState] }));
+
+          // These are our pinned tabs, which we should restore
+          if (appTabsState.windows.length) {
+            newWindowState = appTabsState.windows[0];
+            delete newWindowState.__lastSessionWindowID;
+          }
+
+          // In case there were no unpinned tabs, remove the window from _closedWindows
+          if (!normalTabsState.windows.length) {
+            this._closedWindows.splice(closedWindowIndex, 1);
+          }
+          // Or update _closedWindows with the modified state
+          else {
+            delete normalTabsState.windows[0].__lastSessionWindowID;
+            this._closedWindows[closedWindowIndex] = normalTabsState.windows[0];
+          }
+#ifndef XP_MACOSX
+        }
+        else {
+          // If we're just restoring the window, make sure it gets removed from
+          // _closedWindows.
+          this._closedWindows.splice(closedWindowIndex, 1);
+          newWindowState = closedWindowState;
+          delete newWindowState.hidden;
+        }
+#endif
+        if (newWindowState) {
+          // Ensure that the window state isn't hidden
           this._restoreCount = 1;
-          state = { windows: [state] };
+          let state = { windows: [newWindowState] };
           this.restoreWindow(aWindow, state, this._isCmdLineEmpty(aWindow, state));
         }
       }
       // we actually restored the session just now.
       this._prefBranch.setBoolPref("sessionstore.resume_session_once", false);
     }
     if (this._restoreLastWindow && aWindow.toolbar.visible) {
       // always reset (if not a popup window)
--- a/browser/components/sessionstore/test/browser/Makefile.in
+++ b/browser/components/sessionstore/test/browser/Makefile.in
@@ -115,16 +115,17 @@ include $(topsrcdir)/config/rules.mk
 	browser_524745.js \
 	browser_528776.js \
 	browser_579868.js \
 	browser_579879.js \
 	browser_580512.js \
 	browser_581593.js \
 	browser_586147.js \
 	browser_586068-cascaded_restore.js \
+	browser_589246.js \
 	browser_590268.js \
 	browser_600545.js \
 	$(NULL)
 
 ifneq ($(OS_ARCH),Darwin)
 _BROWSER_TEST_FILES += \
 	browser_597071.js \
 	$(NULL)
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser/browser_589246.js
@@ -0,0 +1,276 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is sessionstore test code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Paul O’Shannessy <paul@oshannessy.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 ***** */
+
+// Mirrors WINDOW_ATTRIBUTES IN nsSessionStore.js
+const WINDOW_ATTRIBUTES = ["width", "height", "screenX", "screenY", "sizemode"];
+
+Cu.import("resource://gre/modules/Services.jsm");
+let ss = Cc["@mozilla.org/browser/sessionstore;1"].
+         getService(Ci.nsISessionStore);
+
+let stateBackup = ss.getBrowserState();
+
+let originalWarnOnClose = gPrefService.getBoolPref("browser.tabs.warnOnClose");
+let originalStartupPage = gPrefService.getIntPref("browser.startup.page");
+let originalWindowType = document.documentElement.getAttribute("windowtype");
+
+let gotLastWindowClosedTopic = false;
+let shouldPinTab = false;
+let shouldOpenTabs = false;
+let shouldCloseTab = false;
+let testNum = 0;
+let afterTestCallback;
+
+// Set state so we know the closed windows content
+let testState = {
+  windows: [
+    { tabs: [{ entries: [{ url: "http://example.org" }] }] }
+  ],
+  _closedWindows: []
+};
+
+// We'll push a set of conditions and callbacks into this array
+// Ideally we would also test win/linux under a complete set of conditions, but
+// the tests for osx mirror the other set of conditions possible on win/linux.
+let tests = [];
+
+// the third & fourth test share a condition check, keep it DRY
+function checkOSX34Generator(num) {
+  return function(aPreviousState, aCurState) {
+    // In here, we should have restored the pinned tab, so only the unpinned tab
+    // should be in aCurState. So let's shape our expectations.
+    let expectedState = JSON.parse(aPreviousState);
+    expectedState[0].tabs.shift();
+    // size attributes are stripped out in _prepDataForDeferredRestore in nsSessionStore.
+    // This isn't the best approach, but neither is comparing JSON strings
+    WINDOW_ATTRIBUTES.forEach(function (attr) delete expectedState[0][attr]);
+
+    is(aCurState, JSON.stringify(expectedState),
+       "test #" + num + ": closedWindowState is as expected");
+  };
+}
+function checkNoWindowsGenerator(num) {
+  return function(aPreviousState, aCurState) {
+    is(aCurState, "[]", "test #" + num + ": there should be no closedWindowsLeft");
+  };
+}
+
+// The first test has 0 pinned tabs and 1 unpinned tab
+tests.push({
+  pinned: false,
+  extra: false,
+  close: false,
+  checkWinLin: checkNoWindowsGenerator(1),
+  checkOSX: function(aPreviousState, aCurState) {
+    is(aCurState, aPreviousState, "test #1: closed window state is unchanged");
+  }
+});
+
+// The second test has 1 pinned tab and 0 unpinned tabs.
+tests.push({
+  pinned: true,
+  extra: false,
+  close: false,
+  checkWinLin: checkNoWindowsGenerator(2),
+  checkOSX: checkNoWindowsGenerator(2)
+});
+
+// The third test has 1 pinned tab and 2 unpinned tabs.
+tests.push({
+  pinned: true,
+  extra: true,
+  close: false,
+  checkWinLin: checkNoWindowsGenerator(3),
+  checkOSX: checkOSX34Generator(3)
+});
+
+// The fourth test has 1 pinned tab, 2 unpinned tabs, and closes one unpinned tab.
+tests.push({
+  pinned: true,
+  extra: true,
+  close: "one",
+  checkWinLin: checkNoWindowsGenerator(4),
+  checkOSX: checkOSX34Generator(4)
+});
+
+// The fifth test has 1 pinned tab, 2 unpinned tabs, and closes both unpinned tabs.
+tests.push({
+  pinned: true,
+  extra: true,
+  close: "both",
+  checkWinLin: checkNoWindowsGenerator(5),
+  checkOSX: checkNoWindowsGenerator(5)
+});
+
+
+function test() {
+  /** Test for Bug 589246 - Closed window state getting corrupted when closing
+      and reopening last browser window without exiting browser **/
+  waitForExplicitFinish();
+  // windows opening & closing, so extending the timeout
+  requestLongerTimeout(2);
+
+  // We don't want the quit dialog pref
+  gPrefService.setBoolPref("browser.tabs.warnOnClose", false);
+  // Ensure that we would restore the session (important for Windows)
+  gPrefService.setIntPref("browser.startup.page", 3);
+
+  runNextTestOrFinish();
+}
+
+function runNextTestOrFinish() {
+  if (tests.length) {
+    setupForTest(tests.shift())
+  }
+  else {
+    // some state is cleaned up at the end of each test, but not all
+    ["browser.tabs.warnOnClose", "browser.startup.page"].forEach(function(p) {
+      if (gPrefService.prefHasUserValue(p))
+        gPrefService.clearUserPref(p);
+    });
+
+    ss.setBrowserState(stateBackup);
+    executeSoon(finish);
+  }
+}
+
+function setupForTest(aConditions) {
+  // reset some checks
+  gotLastWindowClosedTopic = false;
+  shouldPinTab = aConditions.pinned;
+  shouldOpenTabs = aConditions.extra;
+  shouldCloseTab = aConditions.close;
+  testNum++;
+
+  // set our test callback
+  afterTestCallback = /Mac/.test(navigator.platform) ? aConditions.checkOSX
+                                                     : aConditions.checkWinLin;
+
+  // Add observers
+  Services.obs.addObserver(onLastWindowClosed, "browser-lastwindow-close-granted", false);
+
+  // Set the state
+  Services.obs.addObserver(onStateRestored, "sessionstore-browser-state-restored", false);
+  ss.setBrowserState(JSON.stringify(testState));
+}
+
+function onStateRestored(aSubject, aTopic, aData) {
+  info("test #" + testNum + ": onStateRestored");
+  Services.obs.removeObserver(onStateRestored, "sessionstore-browser-state-restored", false);
+
+  // change this window's windowtype so that closing a new window will trigger
+  // browser-lastwindow-close-granted.
+  document.documentElement.setAttribute("windowtype", "navigator:testrunner");
+
+  let newWin = openDialog(location, "_blank", "chrome,all,dialog=no", "http://example.com");
+  newWin.addEventListener("load", function(aEvent) {
+    newWin.removeEventListener("load", arguments.callee, false);
+
+    newWin.gBrowser.selectedBrowser.addEventListener("load", function() {
+      newWin.gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
+
+      // pin this tab
+      if (shouldPinTab)
+        newWin.gBrowser.pinTab(newWin.gBrowser.selectedTab);
+
+      newWin.addEventListener("unload", onWindowUnloaded, false);
+      // Open a new tab as well. On Windows/Linux this will be restored when the
+      // new window is opened below (in onWindowUnloaded). On OS X we'll just
+      // restore the pinned tabs, leaving the unpinned tab in the closedWindowsData.
+      if (shouldOpenTabs) {
+        let newTab = newWin.gBrowser.addTab("about:config");
+        let newTab2 = newWin.gBrowser.addTab("about:buildconfig");
+
+        newTab.linkedBrowser.addEventListener("load", function() {
+          newTab.linkedBrowser.removeEventListener("load", arguments.callee, true);
+
+          if (shouldCloseTab == "one") {
+            newWin.gBrowser.removeTab(newTab2);
+          }
+          else if (shouldCloseTab == "both") {
+            newWin.gBrowser.removeTab(newTab);
+            newWin.gBrowser.removeTab(newTab2);
+          }
+          newWin.BrowserTryToCloseWindow();
+        }, true);
+      }
+      else {
+        newWin.BrowserTryToCloseWindow();
+      }
+    }, true);
+  }, false);
+}
+
+// This will be called before the window is actually closed
+function onLastWindowClosed(aSubject, aTopic, aData) {
+  info("test #" + testNum + ": onLastWindowClosed");
+  Services.obs.removeObserver(onLastWindowClosed, "browser-lastwindow-close-granted", false);
+  gotLastWindowClosedTopic = true;
+}
+
+// This is the unload event listener on the new window (from onStateRestored).
+// Unload is fired after the window is closed, so sessionstore has already
+// updated _closedWindows (which is important). We'll open a new window here
+// which should actually trigger the bug.
+function onWindowUnloaded() {
+  info("test #" + testNum + ": onWindowClosed");
+  ok(gotLastWindowClosedTopic, "test #" + testNum + ": browser-lastwindow-close-granted was notified prior");
+
+  let previousClosedWindowData = ss.getClosedWindowData();
+
+  // Now we want to open a new window
+  let newWin = openDialog(location, "_blank", "chrome,all,dialog=no", "about:robots");
+  newWin.addEventListener("load", function(aEvent) {
+    newWin.removeEventListener("load", arguments.callee, false);
+
+    newWin.gBrowser.selectedBrowser.addEventListener("load", function () {
+      // Good enough for checking the state
+      afterTestCallback(previousClosedWindowData, ss.getClosedWindowData());
+      afterTestCleanup(newWin);
+    }, true);
+
+  }, false);
+}
+
+function afterTestCleanup(aNewWin) {
+  executeSoon(function() {
+    aNewWin.close();
+    document.documentElement.setAttribute("windowtype", originalWindowType);
+    runNextTestOrFinish();
+  });
+}
+
--- a/browser/components/wintaskbar/WindowsJumpLists.jsm
+++ b/browser/components/wintaskbar/WindowsJumpLists.jsm
@@ -255,20 +255,17 @@ var WinTaskbarJumpList =
    *       _pendingStatements object, using a different LIST_TYPE entry for
    *       each statement. Once finished they must remove it and call
    *       commitBuild().  When there will be no more _pendingStatements,
    *       commitBuild() will commit for real.
    */
 
   _pendingStatements: {},
   _hasPendingStatements: function WTBJL__hasPendingStatements() {
-    for (let listType in this._pendingStatements) {
-      return true;
-    }
-    return false;
+    return Object.keys(this._pendingStatements).length > 0;
   },
 
   _buildList: function WTBJL__buildList() {
     if (this._hasPendingStatements()) {
       // We were requested to update the list while another update was in
       // progress, this could happen at shutdown, idle or privatebrowsing.
       // Abort the current list building.
       for (let listType in this._pendingStatements) {
@@ -339,16 +336,21 @@ var WinTaskbarJumpList =
   },
 
   _buildCustom: function WTBJL__buildCustom(title, items) {
     if (items.length > 0)
       this._builder.addListToBuild(this._builder.JUMPLIST_CATEGORY_CUSTOMLIST, items, title);
   },
 
   _buildFrequent: function WTBJL__buildFrequent() {
+    // If history is empty, just bail out.
+    if (!PlacesUtils.history.hasHistoryEntries) {
+      return;
+    }
+
     // Windows supports default frequent and recent lists,
     // but those depend on internal windows visit tracking
     // which we don't populate. So we build our own custom
     // frequent and recent lists using our nav history data.
 
     var items = Cc["@mozilla.org/array;1"].
                 createInstance(Ci.nsIMutableArray);
     // track frequent items so that we don't add them to
@@ -372,16 +374,21 @@ var WinTaskbarJumpList =
         items.appendElement(shortcut, false);
         this._frequentHashList.push(aResult.uri);
       },
       this
     );
   },
 
   _buildRecent: function WTBJL__buildRecent() {
+    // If history is empty, just bail out.
+    if (!PlacesUtils.history.hasHistoryEntries) {
+      return;
+    }
+
     var items = Cc["@mozilla.org/array;1"].
                 createInstance(Ci.nsIMutableArray);
     // Frequent items will be skipped, so we select a double amount of
     // entries and stop fetching results at _maxItemCount.
     var count = 0;
 
     this._pendingStatements[LIST_TYPE.RECENT] = this._getHistoryResults(
       Ci.nsINavHistoryQueryOptions.SORT_BY_DATE_DESCENDING,
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -208,16 +208,17 @@
 @BINPATH@/components/necko_file.xpt
 @BINPATH@/components/necko_ftp.xpt
 @BINPATH@/components/necko_http.xpt
 @BINPATH@/components/necko_res.xpt
 @BINPATH@/components/necko_socket.xpt
 @BINPATH@/components/necko_strconv.xpt
 @BINPATH@/components/necko_viewsource.xpt
 @BINPATH@/components/necko_wifi.xpt
+@BINPATH@/components/necko_wyciwyg.xpt
 @BINPATH@/components/necko.xpt
 @BINPATH@/components/loginmgr.xpt
 @BINPATH@/components/parentalcontrols.xpt
 @BINPATH@/components/places.xpt
 @BINPATH@/components/plugin.xpt
 @BINPATH@/components/pref.xpt
 @BINPATH@/components/prefetch.xpt
 @BINPATH@/components/profile.xpt
@@ -379,18 +380,16 @@
 #endif
 @BINPATH@/components/nsINIProcessor.manifest
 @BINPATH@/components/nsINIProcessor.js
 @BINPATH@/components/nsPrompter.manifest
 @BINPATH@/components/nsPrompter.js
 #ifdef MOZ_SERVICES_SYNC
 @BINPATH@/components/SyncComponents.manifest
 @BINPATH@/components/Weave.js
-@BINPATH@/components/WeaveCrypto.manifest
-@BINPATH@/components/WeaveCrypto.js
 #endif
 
 ; Modules
 @BINPATH@/modules/*
 
 ; Safe Browsing
 @BINPATH@/components/nsSafebrowsingApplication.manifest
 @BINPATH@/components/nsSafebrowsingApplication.js
--- a/browser/installer/removed-files.in
+++ b/browser/installer/removed-files.in
@@ -62,16 +62,18 @@ components/nsCloseAllWindows.js
 components/nsDictionary.js
 components/nsExtensionManager.js
 components/nsInterfaceInfoToIDL.js
 components/nsScriptableIO.js
 components/nsUrlClassifierTable.js
 components/nsXmlRpcClient.js
 components/pluginGlue.js
 components/sidebar.xpt
+components/WeaveCrypto.js
+components/WeaveCrypto.manifest
 components/xmlextras.xpt
 components/xpcom.xpt
 components/xpti.dat
 components/xptitemp.dat
 defaults/pref/all.js
 defaults/pref/bug259708.js
 defaults/pref/bug307259.js
 defaults/pref/reporter.js
@@ -616,17 +618,16 @@ xpicleanup@BIN_SUFFIX@
   components/nsUrlClassifierLib.js
   components/nsUrlClassifierListManager.js
   components/nsURLFormatter.js
   components/nsWebHandlerApp.js
   components/PlacesProtocolHandler.js
   components/storage-Legacy.js
   components/storage-mozStorage.js
   components/txEXSLTRegExFunctions.js
-  components/WeaveCrypto.js
   components/Weave.js
   components/WebContentConverter.js
   defaults/autoconfig/platform.js
   defaults/autoconfig/prefcalls.js
   defaults/pref/firefox-branding.js
   defaults/pref/firefox.js
   defaults/pref/firefox-l10n.js
   defaults/pref/services-sync.js
--- a/browser/locales/all-locales
+++ b/browser/locales/all-locales
@@ -1,56 +1,61 @@
 af
 ak
 ar
 as
+ast
 be
 bg
 bn-BD
 bn-IN
 br
 bs
 ca
 cs
 cy
 da
 de
 el
 en-GB
 en-ZA
 eo
 es-AR
+es-CL
 es-ES
 es-MX
 et
 eu
 fa
 fi
 fr
 fy-NL
 ga-IE
+gd
 gl
 gu-IN
 he
 hi-IN
 hr
 hu
 hy-AM
 id
 is
 it
 ja
 ja-JP-mac
 ka
+km
 kn
 ko
 ku
 lg
 lt
 lv
+mai
 mk
 ml
 mn
 mr
 nb-NO
 nl
 nn-NO
 nso
@@ -66,15 +71,16 @@ ru
 si
 sk
 sl
 son
 sq
 sr
 sv-SE
 ta
+ta-LK
 te
 th
 tr
 uk
 vi
 zh-CN
 zh-TW
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -66,17 +66,17 @@ can reach it easily. -->
 <!ENTITY menubarCmd.label "Menu Bar">
 <!ENTITY menubarCmd.accesskey "M">
 <!ENTITY navbarCmd.label "Navigation Toolbar">
 <!ENTITY navbarCmd.accesskey "N">
 <!ENTITY personalbarCmd.label "Bookmarks Toolbar">
 <!ENTITY personalbarCmd.accesskey "B">
 <!ENTITY bookmarksToolbarItem.label "Bookmarks Toolbar Items">
 <!ENTITY addonBarCmd.label "Add-on Bar">
-<!ENTITY addonBarCmd.accesskey "B">
+<!ENTITY addonBarCmd.accesskey "A">
 
 <!ENTITY pageSourceCmd.label "Page Source">
 <!ENTITY pageSourceCmd.accesskey "o">
 <!ENTITY pageSourceCmd.commandkey "u">
 <!ENTITY pageInfoCmd.label "Page Info">
 <!ENTITY pageInfoCmd.accesskey "I">
 <!ENTITY pageInfoCmd.commandkey "i">
 <!ENTITY fullScreenCmd.label "Full Screen">
--- a/browser/locales/shipped-locales
+++ b/browser/locales/shipped-locales
@@ -12,41 +12,45 @@ de
 el
 en-GB
 en-US
 en-ZA
 eo
 es-AR
 es-ES
 et
+eu
 fi
 fr
 fy-NL
 ga-IE
+gd
 he
 hu
 hy-AM
 id
 is
 it
 ja linux win32
 ja-JP-mac osx
 ko
 ku
 lg
 lt
 lv
+mk
 nb-NO
 nl
 nn-NO
 nso
 pa-IN
 pl
 pt-BR
 pt-PT
+rm
 ro
 ru
 sk
 son
 sq
 sv-SE
 tr
 uk
--- a/browser/themes/gnomestripe/browser/browser.css
+++ b/browser/themes/gnomestripe/browser/browser.css
@@ -228,17 +228,17 @@ menuitem.bookmark-item {
   list-style-image: url("moz-icon://stock/gtk-directory?size=menu");
 }
 
 .bookmark-item[query][hostContainer][open] {
   list-style-image: url("moz-icon://stock/gtk-directory?size=menu");
 }
 
 /* Stock icons for the menu bar items */
-menuitem:not([type]) {
+menuitem:not([type]):not(.menuitem-tooltip):not(.menuitem-iconic-tooltip) {
   -moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem-iconic");
 }
 
 #placesContext_open\:newwindow,
 #menu_newNavigator,
 #context-openlink,
 #context-openframe {
   list-style-image: url("chrome://browser/skin/Toolbar-small.png");
@@ -467,16 +467,23 @@ menuitem:not([type]) {
   -moz-image-region: rect(0px 32px 16px 16px);
 }
 
 #bookmarksShowAll {
   list-style-image: url("chrome://browser/skin/Toolbar-small.png");
   -moz-image-region: rect(0px 48px 16px 32px);
 }
 
+#subscribeToPageMenuitem:not([disabled]),
+#subscribeToPageMenupopup,
+#BMB_subscribeToPageMenuitem:not([disabled]),
+#BMB_subscribeToPageMenupopup {
+  list-style-image: url("chrome://browser/skin/page-livemarks.png");
+}
+
 #bookmarksToolbarFolderMenu,
 #BMB_bookmarksToolbar {
   list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png");
 }
 
 #BMB_bookmarkThisPage {
   list-style-image: url("chrome://browser/skin/places/starPage.png");
 }
--- a/browser/themes/gnomestripe/browser/sanitizeDialog.css
+++ b/browser/themes/gnomestripe/browser/sanitizeDialog.css
@@ -31,17 +31,17 @@
 #sanitizeEverythingWarningBox {
   background-color: Window;
   border: 1px solid ThreeDDarkShadow;
   border-radius: 5px;
   padding: 16px;
 }
 
 #sanitizeEverythingWarningIcon {
-  list-style-image: url("chrome://global/skin/icons/warning-large.png");
+  list-style-image: url("moz-icon://stock/gtk-dialog-warning?size=dialog");
   padding: 0;
   margin: 0;
 }
 
 #sanitizeEverythingWarningDescBox {
   padding: 0 16px;
   margin: 0;
 }
--- a/browser/themes/gnomestripe/browser/syncCommon.css
+++ b/browser/themes/gnomestripe/browser/syncCommon.css
@@ -9,21 +9,21 @@
   max-width: 16px;
 }
 
 .statusIcon[status="active"] {
   list-style-image: url("chrome://global/skin/icons/loading_16.png");
 }
 
 .statusIcon[status="error"] {
-  list-style-image: url("chrome://global/skin/icons/error-16.png");
+  list-style-image: url("moz-icon://stock/gtk-dialog-error?size=menu");
 }
 
 .statusIcon[status="success"] {
-  list-style-image: url("chrome://global/skin/icons/information-16.png");
+  list-style-image: url("moz-icon://stock/gtk-dialog-info?size=menu");
 }
 
 /* .data is only used by syncGenericChange.xul, but it seems unnecessary to have
    a separate stylesheet for it. */
 .data {
   font-size: 90%;
   font-weight: bold;
 }
--- a/browser/themes/pinstripe/browser/browser.css
+++ b/browser/themes/pinstripe/browser/browser.css
@@ -350,18 +350,26 @@ toolbar:not([mode="icons"]) #restore-but
 }
 
 .toolbarbutton-1[disabled="true"] > .toolbarbutton-icon,
 .toolbarbutton-1[type="menu-button"] > .toolbarbutton-menubutton-button[disabled="true"] > .toolbarbutton-icon,
 #restore-button[disabled="true"] > .toolbarbutton-icon {
   opacity: .4;
 }
 
+.toolbarbutton-1 > .toolbarbutton-menu-dropmarker,
 .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
   list-style-image: url(chrome://browser/skin/toolbarbutton-dropmarker.png);
+}
+
+.toolbarbutton-1 > .toolbarbutton-menu-dropmarker {
+  -moz-margin-end: 1px;
+}
+
+.toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
   width: 14px;
   padding-top: 2px;
   -moz-border-start: none !important;
 }
 
 toolbar:not([mode="icons"]) .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker {
   width: auto;
   padding-top: 0;
@@ -1932,17 +1940,16 @@ toolbarbutton.chevron > .toolbarbutton-m
   -moz-appearance: none;
   background-color: #fffcd6;
   border: 1px solid #dad8b6;
   padding: 5px 5px 5px 5px;
   font-weight: bold;
 }
 
 #notification-popup {
-  color: #fff;
   margin-left: -16px;
   margin-right: -16px;
 }
 
 #notification-popup-box {
   margin: 0 3px;
 }
 
--- a/browser/themes/winstripe/browser/browser.css
+++ b/browser/themes/winstripe/browser/browser.css
@@ -297,24 +297,16 @@
 #appmenu_privateBrowsing {
   list-style-image: url("chrome://browser/skin/Privacy-16.png");
 }
 
 #appmenu_addons {
   list-style-image: url("chrome://mozapps/skin/extensions/extensionGeneric-16.png");
 }
 
-#BMB_subscribeToPage:not([disabled]),
-#BMB_subscribeToPageMenu,
-#appmenu_subscribeToPage:not([disabled]),
-#appmenu_subscribeToPageMenu {
-  list-style-image: url("chrome://browser/skin/feeds/feed-icons-16.png");
-  -moz-image-region: rect(0px 16px 16px 0px);
-}
-
 #BMB_bookmarkThisPage,
 #appmenu_bookmarkThisPage {
   list-style-image: url("chrome://browser/skin/places/bookmark.png");
   -moz-image-region: rect(0 16px 16px 0);
 }
 
 /* ::::: titlebar ::::: */
 
@@ -1867,17 +1859,17 @@ toolbarbutton.bookmark-item[dragover="tr
   -moz-margin-end: 10px;
 }
 
 .popup-notification-icon[popupid="geolocation"] {
   list-style-image: url(chrome://browser/skin/Geolocation-64.png);
 }
 
 .geolocation-text-link {
-  padding-top: 5px;
+  margin-top: 17px;
 }
 
 .popup-notification-icon[popupid="xpinstall-disabled"],
 .popup-notification-icon[popupid="addon-install-blocked"],
 .popup-notification-icon[popupid="addon-install-failed"],
 .popup-notification-icon[popupid="addon-install-complete"] {
   list-style-image: url(chrome://mozapps/skin/extensions/extensionGeneric.png);
   width: 32px;
@@ -1931,16 +1923,25 @@ toolbarbutton.bookmark-item[dragover="tr
 }
 
 #download-monitor {
   list-style-image: url("chrome://browser/skin/Toolbar.png");
   -moz-image-region: rect(0, 108px, 18px, 90px);
 }
 
 /* Bookmarks roots menu-items */
+#appmenu_subscribeToPage:not([disabled]),
+#appmenu_subscribeToPageMenu,
+#subscribeToPageMenuitem:not([disabled]),
+#subscribeToPageMenupopup,
+#BMB_subscribeToPageMenuitem:not([disabled]),
+#BMB_subscribeToPageMenupopup {
+  list-style-image: url("chrome://browser/skin/feeds/feedIcon16.png");
+}
+
 #bookmarksToolbarFolderMenu,
 #appmenu_bookmarksToolbar,
 #BMB_bookmarksToolbar {
   list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png");
   -moz-image-region: auto;
 }
 
 #appmenu_unsortedBookmarks,
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -355,16 +355,17 @@ user_pref("javascript.options.jitprofili
 user_pref("gfx.color_management.force_srgb", true);
 user_pref("network.manage-offline-status", false);
 user_pref("test.mousescroll", true);
 user_pref("security.default_personal_cert", "Select Automatically"); // Need to client auth test be w/o any dialogs
 user_pref("network.http.prompt-temp-redirect", false);
 user_pref("media.cache_size", 100);
 user_pref("security.warn_viewing_mixed", false);
 user_pref("app.update.enabled", false);
+user_pref("browser.panorama.experienced_first_run", true); // Assume experienced
 
 // Only load extensions from the application and user profile
 // AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_APPLICATION
 user_pref("extensions.enabledScopes", 5);
 // Disable metadata caching for installed add-ons by default
 user_pref("extensions.getAddons.cache.enabled", false);
 
 user_pref("extensions.testpilot.runStudies", false);
--- a/build/automationutils.py
+++ b/build/automationutils.py
@@ -110,33 +110,45 @@ def checkForCrashes(dumpDir, symbolsPath
     except:
       testName = "unknown"
 
   foundCrash = False
   dumps = glob.glob(os.path.join(dumpDir, '*.dmp'))
   for d in dumps:
     log.info("PROCESS-CRASH | %s | application crashed (minidump found)", testName)
     if symbolsPath and stackwalkPath and os.path.exists(stackwalkPath):
-      nullfd = open(os.devnull, 'w')
-      # eat minidump_stackwalk errors
-      subprocess.call([stackwalkPath, d, symbolsPath], stderr=nullfd)
-      nullfd.close()
+      p = subprocess.Popen([stackwalkPath, d, symbolsPath],
+                           stdout=subprocess.PIPE,
+                           stderr=subprocess.PIPE)
+      (out, err) = p.communicate()
+      if len(out) > 3:
+        # minidump_stackwalk is chatty, so ignore stderr when it succeeds.
+        print out
+      else:
+        print "stderr from minidump_stackwalk:"
+        print err
+      if p.returncode != 0:
+        print "minidump_stackwalk exited with return code %d" % p.returncode
     elif stackwalkCGI and symbolsPath and isURL(symbolsPath):
       f = None
       try:
         f = open(d, "rb")
         sys.path.append(os.path.join(os.path.dirname(__file__), "poster.zip"))
         from poster.encode import multipart_encode
         from poster.streaminghttp import register_openers
         import urllib2
         register_openers()
         datagen, headers = multipart_encode({"minidump": f,
                                              "symbols": symbolsPath})
         request = urllib2.Request(stackwalkCGI, datagen, headers)
-        print urllib2.urlopen(request).read()
+        result = urllib2.urlopen(request).read()
+        if len(result) > 3:
+          print result
+        else:
+          print "stackwalkCGI returned nothing."
       finally:
         if f:
           f.close()
     else:
       if not symbolsPath:
         print "No symbols path given, can't process dump."
       if not stackwalkPath and not stackwalkCGI:
         print "Neither MINIDUMP_STACKWALK nor MINIDUMP_STACKWALK_CGI is set, can't process dump."
--- a/build/mobile/sutagent/android/AndroidManifest.xml
+++ b/build/mobile/sutagent/android/AndroidManifest.xml
@@ -60,9 +60,12 @@
 
 <uses-permission android:name="android.permission.VIBRATE"></uses-permission>
 
 
 
 <uses-permission android:name="android.permission.SET_TIME"></uses-permission>
 
 
+
+<uses-permission android:name="android.permission.SET_TIME_ZONE"></uses-permission>
+
 </manifest> 
\ No newline at end of file
--- a/build/mobile/sutagent/android/DoCommand.java
+++ b/build/mobile/sutagent/android/DoCommand.java
@@ -46,27 +46,31 @@ import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.PrintWriter;
+import java.lang.reflect.Field;
 import java.net.Socket;
 import java.net.SocketException;
 import java.net.UnknownHostException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Calendar;
+import java.util.Collections;
 import java.util.Date;
 import java.util.GregorianCalendar;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.TimeZone;
 import java.util.Timer;
 import java.util.zip.Adler32;
 import java.util.zip.CheckedInputStream;
 import java.util.zip.CheckedOutputStream;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 import java.util.zip.ZipInputStream;
@@ -82,30 +86,33 @@ import org.apache.http.client.ClientProt
 import org.apache.http.client.HttpClient;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.impl.client.DefaultHttpClient;
 
 import com.mozilla.SUTAgentAndroid.SUTAgentAndroid;
 
 import android.app.Activity;
 import android.app.ActivityManager;
+import android.app.AlarmManager;
 import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Configuration;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Debug;
 import android.os.Environment;
 import android.os.StatFs;
 import android.os.SystemClock;
+import android.provider.Settings;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.WindowManager;
 
 public class DoCommand {
 	
 	String lineSep = System.getProperty("line.separator");
 	Process	pProc;
@@ -113,23 +120,23 @@ public class DoCommand {
 	InputStream	sutErr;
 	InputStream	sutOut;
 	AlertLooperThread alrt = null;
 	ContextWrapper	contextWrapper = null;
 	
 	String	currentDir = "/";
 	String	sErrorPrefix = "##AGENT-WARNING## ";
 	
-	private final String prgVersion = "SUTAgentAndroid Version 0.85";
+	private final String prgVersion = "SUTAgentAndroid Version 0.87";
 	
 	public enum Command
 		{
 		RUN ("run"),
 		EXEC ("exec"),
-		ARUN ("arun"),
+		ENVRUN ("envrun"),
 		KILL ("kill"),
 		PS ("ps"),
 		DEVINFO ("info"),
 		OS ("os"),
 		ID ("id"),
 		UPTIME ("uptime"),
 		SETTIME ("settime"),
 		SYSTIME ("systime"),
@@ -168,16 +175,18 @@ public class DoCommand {
 		HELP ("help"),
 		FTPG ("ftpg"),
 		FTPP ("ftpp"),
 		INST ("inst"),
 		UPDT ("updt"),
 		UNINST ("uninst"),
 		TEST ("test"),
 		VER ("ver"),
+		TZGET ("tzget"),
+		TZSET ("tzset"),
 		UNKNOWN ("unknown");
 		
 		private final String theCmd;
 		
 		Command(String theCmd) { this.theCmd = theCmd; }
 
 		public String theCmd() {return theCmd;}
 		
@@ -202,32 +211,43 @@ public class DoCommand {
 		}
 	
 	public String processCommand(String theCmdLine, PrintWriter out, BufferedInputStream in, OutputStream cmdOut)
 		{
 		String 	strReturn = "";
 		Command	cCmd = null;
 		Command cSubCmd = null;
 		
-		String [] Argv = parseCmdLine(theCmdLine);
+		String [] Argv = parseCmdLine2(theCmdLine);
 		
 		int Argc = Argv.length;
 		
 		cCmd = Command.getCmd(Argv[0]);
 		
 		switch(cCmd)
 			{
 			case VER:
 				strReturn = prgVersion;
 				break;
 				
 			case CLOK:
 				strReturn = GetClok();
 				break;
 				
+			case TZGET:
+				strReturn = GetTimeZone();
+				break;
+				
+			case TZSET:
+				if (Argc == 2)
+					strReturn = SetTimeZone(Argv[1]);
+				else
+					strReturn = sErrorPrefix + "Wrong number of arguments for settz command!";
+				break;
+				
 			case UPDT:
 				strReturn = StartUpdateOMatic(Argv[1], Argv[2]);
 				break;
 			
 			case SETTIME:
 				strReturn = SetSystemTime(Argv[1], Argv[2], cmdOut);
 				break;
 			
@@ -322,26 +342,16 @@ public class DoCommand {
 					}
 				else
 					{
 					strReturn = sErrorPrefix + "Wrong number of arguments for alrt command!";
 					}
 				break;
 				
 			case REBT:
-//				try {
-//					reboot(null);
-//					Power.reboot(null);
-//					Power.shutdown();
-//					}
-//				catch (IOException e)
-//					{
-					// TODO Auto-generated catch block
-//					e.printStackTrace();
-//					}
 				RunReboot(cmdOut);
 				break;
 				
 			case TMPD:
 				strReturn = GetTmpDir();
 				break;
 				
 			case DEVINFO:
@@ -493,16 +503,35 @@ public class DoCommand {
 			case QUIT:
 			case EXIT:
 				strReturn = Argv[0];
 				break;
 				
 			case TEST:
 //				boolean bRet = false;
 /*				
+				Configuration userConfig = new Configuration();
+				Settings.System.getConfiguration( contextWrapper.getContentResolver(), userConfig );
+				Calendar cal = Calendar.getInstance( userConfig.locale);
+				TimeZone ctz = cal.getTimeZone();
+				String sctzLongName = ctz.getDisplayName();
+				String pstzName = TimeZone.getDefault().getDisplayName();
+*/
+				String sTimeZoneName = GetTimeZone();
+				
+				TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
+				TimeZone tz2 = TimeZone.getTimeZone("GMT-08:00");
+				int	nOffset = (-8 * 3600000);
+				String [] zoneNames = TimeZone.getAvailableIDs(nOffset);
+				int nNumMatches = zoneNames.length;
+				TimeZone.setDefault(tz);
+				
+				String sOldTZ = System.setProperty("persist.sys.timezone", "America/Los_Angeles");
+				
+/*				
 				byte[] buffer = new byte [4096];
 				int	nRead = 0;
 				long lTotalRead = 0;
 
 				Context ctx = SUTAgentAndroid.me.getApplicationContext();
 
 				FTPClient ftp = new FTPClient();
 				try 
@@ -586,17 +615,17 @@ public class DoCommand {
 				catch (IOException e)
 					{
 					// TODO Auto-generated catch block
 					strReturn = e.getMessage();
 					e.printStackTrace();
 					}
 */				
 //				strReturn = InstallApplication();
-				strReturn = InstallApp(Argv[1], cmdOut);
+//				strReturn = InstallApp(Argv[1], cmdOut);
 				
 //				strReturn = UninstallApplication();
 //				String sPingCheck = SendPing("www.mozilla.org",null);
 //				if (sPingCheck.contains("3 received"))
 //					strReturn = sPingCheck;
 //				RunReboot(cmdOut);
 /*
 				try 
@@ -648,16 +677,34 @@ public class DoCommand {
 				catch (IOException e) 
 					{
 					// TODO Auto-generated catch block
 					e.printStackTrace();
 					}
 */
 				break;
 				
+			case ENVRUN:
+				if (Argc >= 2)
+					{
+					String [] theArgs = new String [Argc - 1];
+			
+					for (int lcv = 1; lcv < Argc; lcv++)
+						{
+						theArgs[lcv - 1] = Argv[lcv];
+						}
+			
+					strReturn = StartPrg2(theArgs, cmdOut);
+					}
+				else
+					{
+					strReturn = sErrorPrefix + "Wrong number of arguments for " + Argv[0] + " command!";
+					}
+				break;
+				
 			case EXEC:
 			case RUN:
 				if (Argc >= 2)
 					{
 					String [] theArgs = new String [Argc - 1];
 				
 					for (int lcv = 1; lcv < Argc; lcv++)
 						{
@@ -823,32 +870,175 @@ public class DoCommand {
 				}
 			// Kill the thread
 			alrt.quit();
 			alrt = null;
 			System.gc();
 			}
 		}
 
-	public String [] parseCmdLine(String theCmdLine) {
+	public String [] parseCmdLine2(String theCmdLine)
+		{
+		String	cmdString;
 		String	workingString;
 		String	workingString2;
+		String	workingString3;
 		List<String> lst = new ArrayList<String>();
-		int nLength = theCmdLine.length();
-		int nFirstSpace = theCmdLine.indexOf(' ');
+		int nLength = 0;
+		int nFirstSpace = -1;
+		
+		// Null cmd line
+		if (theCmdLine == null)
+			{
+			String [] theArgs = new String [1];
+			theArgs[0] = new String("");
+			return(theArgs);
+			}
+		else
+			{
+			nLength = theCmdLine.length();
+			nFirstSpace = theCmdLine.indexOf(' ');
+			}
 		
 		if (nFirstSpace == -1)
 			{
 			String [] theArgs = new String [1];
 			theArgs[0] = new String(theCmdLine);
 			return(theArgs);
 			}
 		
 		// Get the command
-		lst.add(new String(theCmdLine.substring(0, nFirstSpace)));
+		cmdString = new String(theCmdLine.substring(0, nFirstSpace)); 
+		lst.add(cmdString);
+		
+		// Jump past the command and trim
+		workingString = (theCmdLine.substring(nFirstSpace + 1, nLength)).trim();
+		
+		while ((nLength = workingString.length()) > 0)
+			{
+			int nEnd = 0;
+			int	nStart = 0;
+			
+			// if we have a quote
+			if (workingString.startsWith("\""))
+				{
+				// point to the first non quote char
+				nStart = 1;
+				// find the matching quote
+				nEnd = workingString.indexOf('"', nStart);
+				
+				char prevChar;
+				
+				while(nEnd != -1)
+					{
+					// check to see if the quotation mark has been escaped
+					prevChar = workingString.charAt(nEnd - 1);
+					if (prevChar == '\\')
+						{
+						// if escaped, point past this quotation mark and find the next
+						nEnd++;
+						if (nEnd < nLength)
+							nEnd = workingString.indexOf('"', nEnd);
+						else
+							nEnd = -1;
+						}
+					else
+						break;
+					}
+				
+				// there isn't one
+				if (nEnd == -1)
+					{
+					// point at the quote
+					nStart = 0;
+					// so find the next space
+					nEnd = workingString.indexOf(' ', nStart);
+					// there isn't one of those either
+					if (nEnd == -1)
+						nEnd = nLength;	// Just grab the rest of the cmdline
+					}
+				}
+			else // no quote so find the next space
+				{
+				nEnd = workingString.indexOf(' ', nStart);
+				// there isn't one of those
+				if (nEnd == -1)
+					nEnd = nLength;	// Just grab the rest of the cmdline
+				}
+			
+			// get the substring
+			workingString2 = workingString.substring(nStart, nEnd);
+
+			// if we have escaped quotes
+			if (workingString2.contains("\\\""))
+				{
+				do
+					{
+					// replace escaped quote with embedded quote
+					workingString3 = workingString2.replace("\\\"", "\"");
+					workingString2 = workingString3;
+					}
+				while(workingString2.contains("\\\""));
+				}
+
+			// add it to the list
+			lst.add(new String(workingString2));
+			
+			// if we are dealing with a quote
+			if (nStart > 0)
+				nEnd++; //  point past the end one
+			
+			// jump past the substring and trim it
+			workingString = (workingString.substring(nEnd)).trim();
+			}
+		
+		// ok we're done package up the results
+		int nItems = lst.size();
+		
+		String [] theArgs = new String [nItems];
+		
+		for (int lcv = 0; lcv < nItems; lcv++)
+			{
+			theArgs[lcv] = lst.get(lcv);
+			}
+	
+		return(theArgs);
+		}
+	
+	public String [] parseCmdLine(String theCmdLine) {
+		String	cmdString;
+		String	workingString;
+		String	workingString2;
+		List<String> lst = new ArrayList<String>();
+		int nLength = 0;
+		int nFirstSpace = -1;
+		
+		// Null cmd line
+		if (theCmdLine == null)
+			{
+			String [] theArgs = new String [1];
+			theArgs[0] = new String("");
+			return(theArgs);
+			}
+		else
+			{
+			nLength = theCmdLine.length();
+			nFirstSpace = theCmdLine.indexOf(' ');
+			}
+		
+		if (nFirstSpace == -1)
+			{
+			String [] theArgs = new String [1];
+			theArgs[0] = new String(theCmdLine);
+			return(theArgs);
+			}
+		
+		// Get the command
+		cmdString = new String(theCmdLine.substring(0, nFirstSpace)); 
+		lst.add(cmdString);
 		
 		// Jump past the command and trim
 		workingString = (theCmdLine.substring(nFirstSpace + 1, nLength)).trim();
 		
 		while ((nLength = workingString.length()) > 0)
 			{
 			int nEnd = 0;
 			int	nStart = 0;
@@ -866,34 +1056,39 @@ public class DoCommand {
 					// point at the quote
 					nStart = 0;
 					// so find the next space
 					nEnd = workingString.indexOf(' ', nStart);
 					// there isn't one of those either
 					if (nEnd == -1)
 						nEnd = nLength;	// Just grab the rest of the cmdline
 					}
+				else
+					{
+					nStart = 0;
+					nEnd++;
+					}
 				}
 			else // no quote so find the next space
 				{
 				nEnd = workingString.indexOf(' ', nStart);
 				// there isn't one of those
 				if (nEnd == -1)
 					nEnd = nLength;	// Just grab the rest of the cmdline
 				}
 			
 			// get the substring
 			workingString2 = workingString.substring(nStart, nEnd);
 			
 			// add it to the list
 			lst.add(new String(workingString2));
 			
 			// if we are dealing with a quote
-			if (nStart > 0)
-				nEnd++; //  point past the end one
+//			if (nStart > 0)
+//				nEnd++; //  point past the end one
 			
 			// jump past the substring and trim it
 			workingString = (workingString.substring(nEnd)).trim();
 			}
 		
 		int nItems = lst.size();
 		
 		String [] theArgs = new String [nItems];
@@ -1111,17 +1306,16 @@ public class DoCommand {
 			}
 		
 		return(sRet);
 		}
 	
 	public String StatProcess(String string)
 		{
 		String sRet = "";
-//		ActivityManager aMgr = (ActivityManager) SUTAgentAndroid.me.getSystemService(Activity.ACTIVITY_SERVICE);
 		ActivityManager aMgr = (ActivityManager) contextWrapper.getSystemService(Activity.ACTIVITY_SERVICE);
 		int	[] nPids = new int [1];
 		
 		nPids[0] = Integer.parseInt(string);
 		
 		android.os.Debug.MemoryInfo[] mi = aMgr.getProcessMemoryInfo(nPids);
 		
 		sRet  = "Dalvik Private Dirty pages         " + mi[0].dalvikPrivateDirty     + " kb\n";
@@ -1155,17 +1349,16 @@ public class DoCommand {
 			}
 		
 		return(sRet);
 		}
 	
 	public String GetAppRoot(String AppName)
 		{
 		String sRet = "";
-//		Context ctx = SUTAgentAndroid.me.getApplicationContext();
 		Context ctx = contextWrapper.getApplicationContext();
 		
 		if (ctx != null)
 			{
 			try {
 				Context appCtx = ctx.createPackageContext(AppName, 0);
 				ContextWrapper appCtxW = new ContextWrapper(appCtx);
 				sRet = appCtxW.getPackageResourcePath();
@@ -1229,18 +1422,18 @@ public class DoCommand {
 		byte[] 			buffer 		= new byte [4096];
 		int				nRead 		= 0;
 		long 			lTotalRead 	= 0;
 		MessageDigest	digest 		= null;
 		
 		try {
 			digest = java.security.MessageDigest.getInstance("MD5");
 			}
-		catch (NoSuchAlgorithmException e) {
-			// TODO Auto-generated catch block
+		catch (NoSuchAlgorithmException e)
+			{
 			e.printStackTrace();
 			}
 		
 		try {
 			FileInputStream srcFile  = new FileInputStream(sTmpFileName);
 			while((nRead = srcFile.read(buffer)) != -1)
 				{
 				digest.update(buffer, 0, nRead);
@@ -1415,22 +1608,20 @@ public class DoCommand {
 
 			if (lTotalWritten == lTotalRead)
 				sRet = sTmpSrcFileName + " copied to " + sTmpDstFileName;
 			else
 				sRet = sErrorPrefix + "Failed to copy " + sTmpSrcFileName + " [length = " + lTotalWritten + "] to " + sTmpDstFileName + " [length = " + lTotalRead + "]";
 			}
 		catch (FileNotFoundException e)
 			{
-			// TODO Auto-generated catch block
 			e.printStackTrace();
 			} 
 		catch (IOException e)
 			{
-			// TODO Auto-generated catch block
 			e.printStackTrace();
 			}
 
 		return (sRet);
 		}
 	
 	public String IsDirWritable(String sDir)
 		{
@@ -1529,22 +1720,16 @@ public class DoCommand {
 							strRet = "\r" + lTotalRead + " of " + lFtpSize + " bytes received " + ((lTotalRead * 100) / lFtpSize) + "% completed";
 							out.write(strRet.getBytes());
 							out.flush();
 							}
 						ftpIn.close();
 						@SuppressWarnings("unused")
 						boolean bRet = ftp.completePendingCommand();
 						outStream.flush();
-				    	/*				    	
-				    	if (ftp.retrieveFile("pub/mozilla.org/firefox/releases/3.6b4/wince-arm/en-US/firefox-3.6b4.cab", outStream))
-				    		{
-				    		outStream.flush();
-				    		}
-				    	 */				    		
 			    		outStream.close();
 						strRet = ftp.getReplyString();
 						reply = ftp.getReplyCode();
 				    	}
 					strRet = ftp.getReplyString();
 					reply = ftp.getReplyCode();
 				    ftp.logout();
 				    ftp.disconnect();
@@ -1559,26 +1744,24 @@ public class DoCommand {
 		    else
 		    	{
 		        ftp.disconnect();
 		        System.err.println("FTP server refused connection.");
 		        }
 			}
 		catch (SocketException e)
 			{
-			// TODO Auto-generated catch block
 			sRet = e.getMessage();
 			strRet = ftp.getReplyString();
 			reply = ftp.getReplyCode();
 			sRet += "\n" + strRet;
 			e.printStackTrace();
 			}
 		catch (IOException e)
 			{
-			// TODO Auto-generated catch block
 			sRet = e.getMessage();
 			strRet = ftp.getReplyString();
 			reply = ftp.getReplyCode();
 			sRet += "\n" + strRet;
 			e.printStackTrace();
 			}
 		return (sRet);
 	}
@@ -1647,26 +1830,24 @@ public class DoCommand {
 		{
 		String [] theArgs = new String [3];
 		
 		theArgs[0] = "su";
 		theArgs[1] = "-c";
 		theArgs[2] = "kill";
 
 		String sRet = sErrorPrefix + "Unable to kill " + sProcName + "\n";
-//		ActivityManager aMgr = (ActivityManager) SUTAgentAndroid.me.getSystemService(Activity.ACTIVITY_SERVICE);
 		ActivityManager aMgr = (ActivityManager) contextWrapper.getSystemService(Activity.ACTIVITY_SERVICE);
 		List <ActivityManager.RunningAppProcessInfo> lProcesses = aMgr.getRunningAppProcesses();
 		int lcv = 0;
 		String strProcName = "";
 		int	nPID = 0;
 		
 		for (lcv = 0; lcv < lProcesses.size(); lcv++)
 			{
-//			if (lProcesses.get(lcv).processName.contentEquals(sProcName))
 			if (lProcesses.get(lcv).processName.contains(sProcName))
 				{
 				strProcName = lProcesses.get(lcv).processName;
 				nPID = lProcesses.get(lcv).pid;
 				sRet = sErrorPrefix + "Failed to kill " + nPID + " " + strProcName + "\n";
 
 				theArgs[2] += " " + nPID;
 				
@@ -1679,85 +1860,74 @@ public class DoCommand {
 					}
 				catch (IOException e) 
 					{
 					sRet = e.getMessage();
 					e.printStackTrace();
 					} 
 				catch (InterruptedException e)
 					{
-					// TODO Auto-generated catch block
 					e.printStackTrace();
 					}
 
-//				SUTAgentAndroid.me.finishActivity(SUTAgentAndroid.START_PRG);
-
 				// Give the messages a chance to be processed
 				try {
 					Thread.sleep(2000);
 					}
 				catch (InterruptedException e)
 					{
 					e.printStackTrace();
 					}
-//				aMgr.restartPackage(strProcName);
 				break;
 				}
 			}
 		
 		if (nPID > 0)
 			{
 			sRet = "Successfully killed " + nPID + " " + strProcName + "\n";
 			lProcesses = aMgr.getRunningAppProcesses();
 			for (lcv = 0; lcv < lProcesses.size(); lcv++)
 				{
-//				if (lProcesses.get(lcv).processName.contentEquals(sProcName))
 				if (lProcesses.get(lcv).processName.contains(sProcName))
 					{
 					sRet = sErrorPrefix + "Unable to kill " + nPID + " " + strProcName + "\n";
 					break;
 					}
 				}
 			}
 		
 		return (sRet);
 		}
 
 	public boolean IsProcessDead(String sProcName)
 		{
 		boolean bRet = false;
-//		ActivityManager aMgr = (ActivityManager) SUTAgentAndroid.me.getSystemService(Activity.ACTIVITY_SERVICE);
 		ActivityManager aMgr = (ActivityManager) contextWrapper.getSystemService(Activity.ACTIVITY_SERVICE);
 		List <ActivityManager.ProcessErrorStateInfo> lProcesses = aMgr.getProcessesInErrorState();
 		int lcv = 0;
-//		String strProcName = "";
-//		int	nPID = 0;
 		
 		if (lProcesses != null)
 			{
 			for (lcv = 0; lcv < lProcesses.size(); lcv++)
 				{
 				if (lProcesses.get(lcv).processName.contentEquals(sProcName) && 
 					lProcesses.get(lcv).condition != ActivityManager.ProcessErrorStateInfo.NO_ERROR)
 					{
-//					strProcName = lProcesses.get(lcv).processName;
-//					nPID = lProcesses.get(lcv).pid;
 					bRet = true;
 					break;
 					}
 				}
 			}
 	
 		return (bRet);
 		}
 
 	public String GetProcessInfo()
 		{
 		String sRet = "";
-//		ActivityManager aMgr = (ActivityManager) SUTAgentAndroid.me.getSystemService(Activity.ACTIVITY_SERVICE);
 		ActivityManager aMgr = (ActivityManager) contextWrapper.getSystemService(Activity.ACTIVITY_SERVICE);
 		List <ActivityManager.RunningAppProcessInfo> lProcesses = aMgr.getRunningAppProcesses();
 		int	nProcs = lProcesses.size();
 		int lcv = 0;
 		String strProcName = "";
 		int	nPID = 0;
 		int nUser = 0;
 		
@@ -1812,22 +1982,20 @@ public class DoCommand {
 	public String GetMemoryInfo()
 		{
 		String sRet = "PA:" + GetMemoryConfig();
 		return (sRet);
 		}
 
 	public long GetMemoryConfig()
 		{
-//		ActivityManager aMgr = (ActivityManager) SUTAgentAndroid.me.getSystemService(Activity.ACTIVITY_SERVICE);
 		ActivityManager aMgr = (ActivityManager) contextWrapper.getSystemService(Activity.ACTIVITY_SERVICE);
 		ActivityManager.MemoryInfo outInfo = new ActivityManager.MemoryInfo();
 		aMgr.getMemoryInfo(outInfo);
 		long lMem = outInfo.availMem;
-//		float fMem = (float) lMem / (float)(1024.0 * 1024.0);
 
 		return (lMem);
 		}
 	
 	public String RegisterTheDevice(String sSrvr, String sPort, String sData)
 		{
 		String sRet = "";
 		String line = "";
@@ -1861,22 +2029,20 @@ public class DoCommand {
 				socket.close();
 				}
 			catch(NumberFormatException e)
 				{
 				e.printStackTrace();
 				} 
 			catch (UnknownHostException e)
 				{
-				// TODO Auto-generated catch block
 				e.printStackTrace();
 				}
 			catch (IOException e)
 				{
-				// TODO Auto-generated catch block
 				sRet += "reg exception thrown";
 				e.printStackTrace();
 				}
 			}
 		return(sRet);
 		}
 	
 	public String GetInternetData(String sHost, String sPort, String sURL)
@@ -1906,79 +2072,118 @@ public class DoCommand {
 			    byte [] data = new byte [2048];
 			    int nRead = content.read(data);
 			    sRet = new String(data, 0, nRead);
 			    content.close(); // this will also close the connection
 				}
 			}
 		catch (IllegalArgumentException e)
 			{
-			// TODO Auto-generated catch block
 			sRet = e.getLocalizedMessage();
 			e.printStackTrace();
 			}
 		catch (ClientProtocolException e)
 			{
-			// TODO Auto-generated catch block
 			sRet = e.getLocalizedMessage();
 			e.printStackTrace();
 			}
 		catch (IOException e)
 			{
-			// TODO Auto-generated catch block
 			sRet = e.getLocalizedMessage();
 			e.printStackTrace();
 			}
 		
 		return(sRet);
 		}
+	
+	public String GetTimeZone()
+		{
+		String	sRet = "";
+		TimeZone tz;
+		
+		tz = TimeZone.getDefault();
+		Date now = new Date();
+		sRet = tz.getDisplayName(tz.inDaylightTime(now), TimeZone.LONG);
+		
+		return(sRet);
+		}
+	
+	public String SetTimeZone(String sTimeZone)
+		{
+		String			sRet = "Unable to set timezone to " + sTimeZone;
+		TimeZone 		tz = null;
+		AlarmManager 	amgr = null;
+		
+		if ((sTimeZone.length() > 0) && (sTimeZone.startsWith("GMT")))
+			{
+			amgr = (AlarmManager) contextWrapper.getSystemService(Context.ALARM_SERVICE);
+			if (amgr != null)
+				amgr.setTimeZone(sTimeZone);
+			}
+		else
+			{
+			String [] zoneNames = TimeZone.getAvailableIDs();
+			int nNumMatches = zoneNames.length;
+			int	lcv = 0;
+			
+			for (lcv = 0; lcv < nNumMatches; lcv++)
+				{
+				if (zoneNames[lcv].equalsIgnoreCase(sTimeZone))
+					break;
+				}
+
+			if (lcv < nNumMatches)
+				{
+				amgr = (AlarmManager) contextWrapper.getSystemService(Context.ALARM_SERVICE);
+				if (amgr != null)
+					amgr.setTimeZone(zoneNames[lcv]);
+				}
+			}
+		
+		if (amgr != null)
+			{
+			tz = TimeZone.getDefault();
+			Date now = new Date();
+			sRet = tz.getDisplayName(tz.inDaylightTime(now), TimeZone.LONG);
+			}
+		
+		return(sRet);
+		}
 
 	public String GetSystemTime()
 		{
 		String sRet = "";
 		Calendar cal = Calendar.getInstance();
 		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss:SSS");
 		sRet = sdf.format(cal.getTime());
 	
 		return (sRet);
 		}
 	
 	public String SetSystemTime(String sDate, String sTime, OutputStream out)
 		{
-//		Debug.waitForDebugger();
 		String sRet = "";
 		
-//		Intent	prgIntent = new Intent(android.provider.Settings.ACTION_DATE_SETTINGS);
-//		prgIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-//		contextWrapper.startActivity(prgIntent);
-		
-		// 2010/09/22 
-		// 15:41:00
-		// 0123456789012345678
-		
 		if (((sDate != null) && (sTime != null)) && 
 			(sDate.contains("/") || sDate.contains(".")) &&
 			(sTime.contains(":")))
 			{
 			int year = Integer.parseInt(sDate.substring(0,4));
 			int month = Integer.parseInt(sDate.substring(5,7));
 			int day = Integer.parseInt(sDate.substring(8,10));
 			
 			int hour = Integer.parseInt(sTime.substring(0,2));
 			int mins = Integer.parseInt(sTime.substring(3,5));
 			int secs = Integer.parseInt(sTime.substring(6,8));
 
-			Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
+			Calendar cal = new GregorianCalendar(TimeZone.getDefault());
 			cal.set(year, month - 1, day, hour, mins, secs);
 			long lMillisecs = cal.getTime().getTime();
 			
-//			boolean bRet = SystemClock.setCurrentTimeMillis(lMillisecs);
 			String sM = Long.toString(lMillisecs);
-//			long lm = 1285175618316L;
-			String sTest = cal.getTime().toGMTString();
 			String sMillis = sM.substring(0, sM.length() - 3) + "." + sM.substring(sM.length() - 3);
 			String [] theArgs = new String [3];
 		
 			theArgs[0] = "su";
 			theArgs[1] = "-c";
 			theArgs[2] = "date -u " + sMillis;
 		
 			try 
@@ -1991,17 +2196,16 @@ public class DoCommand {
 				}
 			catch (IOException e) 
 				{
 				sRet = e.getMessage();
 				e.printStackTrace();
 				} 
 			catch (InterruptedException e)
 				{
-				// TODO Auto-generated catch block
 				e.printStackTrace();
 				}
 			}
 		else
 			{
 			sRet = "Invalid argument(s)";
 			}
 
@@ -2040,34 +2244,16 @@ public class DoCommand {
 			lHold %= 60L * 1000L;
 			nSecs = (int)(lHold / 1000L);
 			nMilliseconds = (int)(lHold % 1000);
 			sRet = "" + nDays + " days " + nHours + " hours " + nMinutes + " minutes " + nSecs + " seconds " + nMilliseconds + " ms";
 			}
 
 		return (sRet);
 		}
-/*	
-	private boolean IsProcRunning(Process pProc)
-		{
-		boolean bRet = false;
-		int nExitCode = 0;
-		
-		try
-			{
-			nExitCode = pProc.exitValue();
-			}
-		catch (IllegalThreadStateException z)
-			{	
-			bRet = true;
-			}
-
-		return(bRet);
-		}
-*/
 
 	public String NewKillProc(String sProcId, OutputStream out)
 		{
 		String sRet = "";
 		String [] theArgs = new String [3];
 		
 		theArgs[0] = "su";
 		theArgs[1] = "-c";
@@ -2102,43 +2288,38 @@ public class DoCommand {
 		theArgs[0] = "ping";
 		theArgs[1] = "-c";
 		theArgs[2] = "3";
 		theArgs[3] = sIPAddr;
 		
 		try 
 			{
 			pProc = Runtime.getRuntime().exec(theArgs);
-//			sutErr = pProc.getErrorStream(); // Stderr
-//			sutIn = pProc.getOutputStream(); // Stdin
-//			sutOut = pProc.getInputStream(); // Stdout
 			RedirOutputThread outThrd = new RedirOutputThread(pProc, out);
 			outThrd.start();
 			outThrd.join(5000);
 			if (out == null)
 				sRet = outThrd.strOutput;
 			}
 		catch (IOException e) 
 			{
 			sRet = e.getMessage();
 			e.printStackTrace();
 			} 
 		catch (InterruptedException e)
 			{
-			// TODO Auto-generated catch block
 			e.printStackTrace();
 			}
 	
 		return (sRet);
 		}
 	
 	public String GetTmpDir()
 	{
 		String 	sRet = "";
-//		Context ctx = SUTAgentAndroid.me.getApplicationContext();
 		Context ctx = contextWrapper.getApplicationContext();
         File dir = ctx.getFilesDir();
         ctx = null;
         try {
 			sRet = dir.getCanonicalPath();
 			} 
         catch (IOException e)
         	{
@@ -2240,17 +2421,16 @@ public class DoCommand {
 			}
 		catch (IOException e) 
 			{
 			sRet = e.getMessage();
 			e.printStackTrace();
 			} 
 		catch (InterruptedException e)
 			{
-			// TODO Auto-generated catch block
 			e.printStackTrace();
 			}
 
 		return (sRet);
 		}
 	
 	public String UnInstallApp(String sApp, OutputStream out)
 		{
@@ -2264,17 +2444,16 @@ public class DoCommand {
 		try 
 			{
 			pProc = Runtime.getRuntime().exec(theArgs);
 		
 			RedirOutputThread outThrd = new RedirOutputThread(pProc, out);
 			outThrd.start();
 			outThrd.join(60000);
 			int nRet = pProc.exitValue();
-//			boolean bRet = outThrd.isAlive();
 			sRet = "\nuninst complete [" + nRet + "]";
 			}
 		catch (IOException e) 
 			{
 			sRet = e.getMessage();
 			e.printStackTrace();
 			} 
 		catch (InterruptedException e)
@@ -2398,17 +2577,16 @@ public class DoCommand {
 
 		return (sRet);
 		}
 
 	public String StartUpdateOMatic(String sPkgName, String sPkgFileName)
 		{
 		String sRet = "";
 	
-//		Context ctx = SUTAgentAndroid.me.getApplicationContext();
 		Context ctx = contextWrapper.getApplicationContext();
 		PackageManager pm = ctx.getPackageManager();
 
 		Intent prgIntent = new Intent();
 		prgIntent.setPackage("com.mozilla.UpdateOMatic");
 		prgIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
 		try {
@@ -2430,40 +2608,34 @@ public class DoCommand {
 			}
 		
 		prgIntent.putExtra("pkgName", sPkgName);
 		prgIntent.putExtra("pkgFileName", sPkgFileName);
 
 		try 
 			{
 			contextWrapper.startActivity(prgIntent);
-//			Thread.sleep(5000);
 			sRet = "exit";
 			}
 		catch(ActivityNotFoundException anf)
 			{
 			anf.printStackTrace();
 			} 
-//		catch (InterruptedException e)
-//			{
-//			e.printStackTrace();
-//			}
 	
 		ctx = null;
 		return (sRet);
 		}
 
 	public String StartJavaPrg(String [] sArgs)
 		{
 		String sRet = "";
 		String sArgList = "";
 		String sUrl = "";
 		String sRedirFileName = "";
 		
-//		Context ctx = SUTAgentAndroid.me.getApplicationContext();
 		Context ctx = contextWrapper.getApplicationContext();
 		PackageManager pm = ctx.getPackageManager();
 
 		Intent prgIntent = new Intent();
 		prgIntent.setPackage(sArgs[0]);
 		prgIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
 		try {
@@ -2481,17 +2653,17 @@ public class DoCommand {
 			}
 		catch (NameNotFoundException e)
 			{
 			e.printStackTrace();
 			}
 		
 		if (sArgs.length > 1)
 			{
-			if (sArgs[0].contains("android.browser"))
+//			if (sArgs[0].contains("android.browser"))
 				prgIntent.setAction(Intent.ACTION_VIEW);
 			
 			if (sArgs[0].contains("fennec"))
 				{
 				sArgList = "";
 				sUrl = "";
 				
 				for (int lcv = 1; lcv < sArgs.length; lcv++)
@@ -2525,20 +2697,17 @@ public class DoCommand {
 				prgIntent.setData(Uri.parse(sArgList.trim()));
 				}
 			}
 		else
 			prgIntent.setData(Uri.parse("about:blank"));
 
 		try 
 			{
-//			ctx.startActivity(prgIntent);
 			contextWrapper.startActivity(prgIntent);
-//			SUTAgentAndroid.me.startActivity(prgIntent);
-//			SUTAgentAndroid.me.startActivityForResult(prgIntent, SUTAgentAndroid.START_PRG);
 			}
 		catch(ActivityNotFoundException anf)
 			{
 			anf.printStackTrace();
 			}
 		
 		ctx = null;
 		return (sRet);
@@ -2546,31 +2715,169 @@ public class DoCommand {
 
 	public String StartPrg(String [] progArray, OutputStream out)
 		{
 		String sRet = "";
 		
 		try 
 			{
 			pProc = Runtime.getRuntime().exec(progArray);
-			sutErr = pProc.getErrorStream(); // Stderr
-			sutIn = pProc.getOutputStream(); // Stdin
-			sutOut = pProc.getInputStream(); // Stdout
 			RedirOutputThread outThrd = new RedirOutputThread(pProc, out);
 			outThrd.start();
 			outThrd.join(10000);
+			int nRetCode = pProc.exitValue();
+			sRet = "return code [" + nRetCode + "]";
 			}
 		catch (IOException e) 
 			{
 			e.printStackTrace();
 			}
 		catch (InterruptedException e)
 			{
-			// TODO Auto-generated catch block
 			e.printStackTrace();
+			sRet = "Timed out!";
+			}
+
+		return (sRet);
+		}
+/*	
+	@SuppressWarnings("unchecked")
+	public static void set(String key, String value) throws Exception
+		{
+	    Class[] classes = Collections.class.getDeclaredClasses();
+	    Map env = System.getenv();
+	    for(Class cl : classes)
+	    	{
+	        if("java.util.Collections$UnmodifiableMap".equals(cl.getName()))
+	        	{
+	            Field field = cl.getDeclaredField("m");
+	            field.setAccessible(true);
+	            Object obj = field.get(env);
+	            Map<String, String> map = (Map<String, String>) obj;
+	            map.put(key, value);
+	        	}
+	    	}
+		}
+
+*/	
+	public String StartPrg2(String [] progArray, OutputStream out)
+		{
+		String sRet = "";
+		
+		int	nArraySize = 0;
+		int	nArgs = progArray.length - 1; // 1st arg is the environment string
+		int	lcv	= 0;
+		int	temp = 0;
+
+		String sEnvString = progArray[0];
+
+		// Set up command line args stripping off the environment string
+		String [] theArgs = new String [nArgs];
+		for (lcv = 0; lcv < nArgs; lcv++)
+			{
+			theArgs[lcv] = progArray[lcv + 1];
+			}
+		
+		try 
+			{
+			String [] envStrings = sEnvString.split(",");
+			Map<String, String> newEnv = new HashMap<String, String>();
+			
+			for (lcv = 0; lcv < envStrings.length; lcv++)
+				{
+				temp = envStrings[lcv].indexOf("=");
+				if (temp > 0)
+					{
+					newEnv.put(	envStrings[lcv].substring(0, temp), 
+								envStrings[lcv].substring(temp + 1, envStrings[lcv].length()));
+					}
+				}
+			
+			Map<String, String> sysEnv = System.getenv();
+			
+			nArraySize = sysEnv.size();
+			
+			for (Map.Entry<String, String> entry : newEnv.entrySet())
+				{
+				if (!sysEnv.containsKey(entry.getKey()))
+					{
+					nArraySize++;
+					}
+				}
+			
+			String[] envArray = new String[nArraySize];
+				
+			int		i = 0;
+			int		offset;
+			String	sKey = "";
+			String 	sValue = "";
+			
+	        for (Map.Entry<String, String> entry : sysEnv.entrySet())
+	        	{
+	        	sKey = entry.getKey();
+	        	if (newEnv.containsKey(sKey))
+	        		{
+	        		sValue = newEnv.get(sKey);
+	        		if ((offset = sValue.indexOf("$" + sKey)) != -1)
+	        			{
+	        			envArray[i++] = sKey + 
+	        							"=" + 
+	        							sValue.substring(0, offset) + 
+	        							entry.getValue() + 
+	        							sValue.substring(offset + sKey.length() + 1);
+	        			}
+	        		else
+	        			envArray[i++] = sKey + "=" + sValue;
+	        		newEnv.remove(sKey);
+	        		}
+	        	else
+	        		envArray[i++] = entry.getKey() + "=" + entry.getValue();
+	        	}
+	        
+			for (Map.Entry<String, String> entry : newEnv.entrySet())
+				{
+        		envArray[i++] = entry.getKey() + "=" + entry.getValue();
+				}
+	        
+			pProc = Runtime.getRuntime().exec(theArgs, envArray);
+
+			RedirOutputThread outThrd = new RedirOutputThread(pProc, out);
+			outThrd.start();
+			outThrd.join(10000);
+			int nRetCode = pProc.exitValue();
+			sRet = "return code [" + nRetCode + "]";
+			}
+		catch(UnsupportedOperationException e)
+			{
+			if (e != null)
+				e.printStackTrace();
+			}
+		catch(ClassCastException e)
+			{
+			if (e != null)
+				e.printStackTrace();
+			}
+		catch(IllegalArgumentException e)
+			{
+			if (e != null)
+				e.printStackTrace();
+			}
+		catch(NullPointerException e)
+			{
+			if (e != null)
+				e.printStackTrace();
+			}
+		catch (IOException e) 
+			{
+			e.printStackTrace();
+			}
+		catch (InterruptedException e)
+			{
+			e.printStackTrace();
+			sRet = "Timed out!";
 			}
 
 		return (sRet);
 		}
 /*	
 	public String InstallApplication()
 		{
 		String sRet = "";
@@ -2598,60 +2905,63 @@ public class DoCommand {
 	
 		SUTAgentAndroid.me.startActivity(unInstIntent);
 
 		return(sRet);
 		}
 */
 	private String PrintUsage()
 		{
-		String sRet = "run [executable] [args]  - start program no wait\n" +
-			"exec [executable] [args] - start program wait\n" +
-			"fire [executable] [args] - start program no wait\n" +
-			"arun [executable] [args] - start program no wait\n" +
-			"kill [program name]      - kill program no path\n" +
-			"killall                  - kill all processes started\n" +
-			"ps                       - list of running processes\n" +
-			"info                     - list of device info\n" +
-			"        [os]             - os version for device\n" +
-			"        [id]             - unique identifier for device\n" +
-			"        [uptime]         - uptime for device\n" +
-			"        [systime]        - current system time on device\n" +
-			"        [screen]         - width, height and bits per pixel for device\n" +
-			"        [memory]         - physical, free, available, storage memory for device\n" +
-			"        [processes]      - list of running processes see 'ps'\n" +
-			"deadman timeout          - set the duration for the deadman timer\n" +
-			"alrt [on/off]            - start or stop sysalert behavior\n" +
-			"disk [arg]               - prints disk space info\n" +
-			"cp file1 file2           - copy file1 to file2 on device\n" +
-			"time file                - timestamp for file on device\n" +
-			"hash file                - generate hash for file on device\n" +
-			"cd directory             - change cwd on device\n" +
-			"cat file                 - cat file on device\n" +
-			"cwd                      - display cwd on device\n" +
-			"mv file1 file2           - move file1 to file2 on device\n" +
-			"push filename            - push file to device\n" +
-			"rm file                  - delete file on device\n" +
-			"rmdr directory           - delete directory on device even if not empty\n" +
-			"mkdr directory           - create directory on device\n" +
-			"dirw directory           - tests whether the directory is writable on the device\n" +
-			"stat processid           - stat process on device\n" +
-			"dead processid           - print whether the process is alive or hung on device\n" +
-			"mems                     - dump memory stats on device\n" +
-			"ls                       - print directory on device\n" +
-			"tmpd                     - print temp directory on device\n" +
-			"ping [hostname/ipaddr]   - ping a network device\n" +
-			"unzp zipfile destdir     - unzip the zipfile into the destination dir\n" +
-			"zip zipfile src          - zip the source file/dir into zipfile\n" +
-			"rebt                     - reboot device\n" +
-			"inst /path/filename.apk  - install the referenced apk file\n" +
-			"uninst packagename       - uninstall the referenced package\n" +
-			"updt pkgname pkgfile     - unpdate the referenced package\n" +
-			"clok                     - the current device time expressed as the number of millisecs since epoch\n" +
-			"settime date time        - sets the device date and time (YYYY/MM/DD HH:MM:SS)\n" +
-			"rebt                     - reboot device\n" +
-			"quit                     - disconnect SUTAgent\n" +
-			"exit                     - close SUTAgent\n" +
-			"ver                      - SUTAgent version\n" +
-			"help                     - you're reading it";
+		String sRet = 
+			"run [executable] [args]      - start program no wait\n" +
+			"exec [executable] [args]     - start program wait\n" +
+			"fire [executable] [args]     - start program no wait\n" +
+			"envrun [env pairs] [cmdline] - start program no wait\n" +
+			"kill [program name]          - kill program no path\n" +
+			"killall                      - kill all processes started\n" +
+			"ps                           - list of running processes\n" +
+			"info                         - list of device info\n" +
+			"        [os]                 - os version for device\n" +
+			"        [id]                 - unique identifier for device\n" +
+			"        [uptime]             - uptime for device\n" +
+			"        [systime]            - current system time on device\n" +
+			"        [screen]             - width, height and bits per pixel for device\n" +
+			"        [memory]             - physical, free, available, storage memory for device\n" +
+			"        [processes]          - list of running processes see 'ps'\n" +
+			"deadman timeout              - set the duration for the deadman timer\n" +
+			"alrt [on/off]                - start or stop sysalert behavior\n" +
+			"disk [arg]                   - prints disk space info\n" +
+			"cp file1 file2               - copy file1 to file2 on device\n" +
+			"time file                    - timestamp for file on device\n" +
+			"hash file                    - generate hash for file on device\n" +
+			"cd directory                 - change cwd on device\n" +
+			"cat file                     - cat file on device\n" +
+			"cwd                          - display cwd on device\n" +
+			"mv file1 file2               - move file1 to file2 on device\n" +
+			"push filename                - push file to device\n" +
+			"rm file                      - delete file on device\n" +
+			"rmdr directory               - delete directory on device even if not empty\n" +
+			"mkdr directory               - create directory on device\n" +
+			"dirw directory               - tests whether the directory is writable on the device\n" +
+			"stat processid               - stat process on device\n" +
+			"dead processid               - print whether the process is alive or hung on device\n" +
+			"mems                         - dump memory stats on device\n" +
+			"ls                           - print directory on device\n" +
+			"tmpd                         - print temp directory on device\n" +
+			"ping [hostname/ipaddr]       - ping a network device\n" +
+			"unzp zipfile destdir         - unzip the zipfile into the destination dir\n" +
+			"zip zipfile src              - zip the source file/dir into zipfile\n" +
+			"rebt                         - reboot device\n" +
+			"inst /path/filename.apk      - install the referenced apk file\n" +
+			"uninst packagename           - uninstall the referenced package\n" +
+			"updt pkgname pkgfile         - unpdate the referenced package\n" +
+			"clok                         - the current device time expressed as the number of millisecs since epoch\n" +
+			"settime date time            - sets the device date and time (YYYY/MM/DD HH:MM:SS)\n" +
+			"tzset timezone               - sets the device timezone format is GMTxhh:mm x = +/- or a recognized Olsen string\n" +
+			"tzget                        - returns the current timezone set on the device\n" +
+			"rebt                         - reboot device\n" +
+			"quit                         - disconnect SUTAgent\n" +
+			"exit                         - close SUTAgent\n" +
+			"ver                          - SUTAgent version\n" +
+			"help                         - you're reading it";
 		return (sRet);
 		}
 }
--- a/build/mobile/sutagent/android/SUTAgentAndroid.java
+++ b/build/mobile/sutagent/android/SUTAgentAndroid.java
@@ -386,17 +386,17 @@ public class SUTAgentAndroid extends Act
 					else if (nChargeLevel > 80)
 						sb.append("HIGH");
 					}
 				
 				if (BatteryManager.BATTERY_HEALTH_OVERHEAT == health)
 					{
 					sb.append("Overheated ");
 					sb.append((((float)(nBatteryTemp))/10));
-					sb.append("(C)");
+					sb.append("(C)");
 					}
 				else
 					{
 					switch(status)
 						{
 						case BatteryManager.BATTERY_STATUS_UNKNOWN:
 							// old emulator; maybe also when plugged in with no battery
 							if (present == true)
--- a/chrome/src/nsChromeRegistryChrome.cpp
+++ b/chrome/src/nsChromeRegistryChrome.cpp
@@ -452,28 +452,28 @@ EnumerateOverride(nsIURI* aURIKey,
     chromeURI, overrideURI
   };
   overrides->AppendElement(override);
   return (PLDHashOperator)PL_DHASH_NEXT;
 }
 
 struct EnumerationArgs
 {
-  nsTArray<ChromePackage>& packages;
+  InfallibleTArray<ChromePackage>& packages;
   const nsCString& selectedLocale;
   const nsCString& selectedSkin;
 };
 
 void
 nsChromeRegistryChrome::SendRegisteredChrome(
     mozilla::dom::PContentParent* aParent)
 {
-  nsTArray<ChromePackage> packages;
-  nsTArray<ResourceMapping> resources;
-  nsTArray<OverrideMapping> overrides;
+  InfallibleTArray<ChromePackage> packages;
+  InfallibleTArray<ResourceMapping> resources;
+  InfallibleTArray<OverrideMapping> overrides;
 
   EnumerationArgs args = {
     packages, mSelectedLocale, mSelectedSkin
   };
   PL_DHashTableEnumerate(&mPackagesHash, CollectPackages, &args);
 
   nsCOMPtr<nsIIOService> io (do_GetIOService());
   NS_ENSURE_TRUE(io, );
--- a/client.mk
+++ b/client.mk
@@ -64,18 +64,17 @@
 #   MOZ_PREFLIGHT      }   MOZ_BUILD_PROJECTS, before each project, after
 #   MOZ_POSTFLIGHT     }   each project, and after all projects; these
 #   MOZ_POSTFLIGHT_ALL }   variables contain space-separated lists
 #   MOZ_UNIFY_BDATE      - Set to use the same bdate for each project in
 #                          MOZ_BUILD_PROJECTS
 #
 #######################################################################
 # Defines
-#
-CVS = cvs
+
 comma := ,
 
 CWD := $(CURDIR)
 ifneq (1,$(words $(CWD)))
 $(error The mozilla directory cannot be located in a path with spaces.)
 endif
 
 ifeq "$(CWD)" "/"
@@ -102,17 +101,16 @@ endif
 MKDIR := mkdir
 SH := /bin/sh
 ifndef MAKE
 MAKE := gmake
 endif
 PERL ?= perl
 PYTHON ?= python
 
-RUN_AUTOCONF_LOCALLY = 1
 CONFIG_GUESS_SCRIPT := $(wildcard $(TOPSRCDIR)/build/autoconf/config.guess)
 ifdef CONFIG_GUESS_SCRIPT
   CONFIG_GUESS = $(shell $(CONFIG_GUESS_SCRIPT))
 endif
 
 
 ####################################
 # Sanity checks
@@ -165,17 +163,16 @@ MOZ_MAKE = $(MAKE) $(MOZ_MAKE_FLAGS) -C 
 endif # MOZ_BUILD_PROJECTS
 
 # 'configure' scripts generated by autoconf.
 CONFIGURES := $(TOPSRCDIR)/configure
 CONFIGURES += $(TOPSRCDIR)/js/src/configure
 
 #######################################################################
 # Rules
-# 
 
 # The default rule is build
 build::
 
 # Print out any options loaded from mozconfig.
 all build clean depend distclean export libs install realclean::
 	@if test -f .mozconfig.out; then \
 	  cat .mozconfig.out; \
@@ -267,51 +264,44 @@ else
 # individual project in a multi-project build.
 
 ####################################
 # Configure
 
 CONFIG_STATUS = $(wildcard $(OBJDIR)/config.status)
 CONFIG_CACHE  = $(wildcard $(OBJDIR)/config.cache)
 
-ifdef RUN_AUTOCONF_LOCALLY
 EXTRA_CONFIG_DEPS := \
 	$(TOPSRCDIR)/aclocal.m4 \
 	$(wildcard $(TOPSRCDIR)/build/autoconf/*.m4) \
 	$(TOPSRCDIR)/js/src/aclocal.m4 \
 	$(NULL)
 
 $(CONFIGURES): %: %.in $(EXTRA_CONFIG_DEPS)
 	@echo Generating $@ using autoconf
 	cd $(@D); $(AUTOCONF)
-endif
 
 CONFIG_STATUS_DEPS := \
 	$(wildcard $(CONFIGURES)) \
 	$(TOPSRCDIR)/allmakefiles.sh \
 	$(TOPSRCDIR)/.mozconfig.mk \
 	$(wildcard $(TOPSRCDIR)/nsprpub/configure) \
 	$(wildcard $(TOPSRCDIR)/config/milestone.txt) \
-	$(wildcard $(TOPSRCDIR)/config/chrome-versions.sh) \
-  $(wildcard $(addsuffix confvars.sh,$(wildcard $(TOPSRCDIR)/*/))) \
+	$(wildcard $(addsuffix confvars.sh,$(wildcard $(TOPSRCDIR)/*/))) \
 	$(NULL)
 
 # configure uses the program name to determine @srcdir@. Calling it without
 #   $(TOPSRCDIR) will set @srcdir@ to "."; otherwise, it is set to the full
 #   path of $(TOPSRCDIR).
 ifeq ($(TOPSRCDIR),$(OBJDIR))
   CONFIGURE = ./configure
 else
   CONFIGURE = $(TOPSRCDIR)/configure
 endif
 
-ifdef MOZ_TOOLS
-  CONFIGURE = $(TOPSRCDIR)/configure
-endif
-
 configure-files: $(CONFIGURES)
 
 configure:: configure-files
 ifdef MOZ_BUILD_PROJECTS
 	@if test ! -d $(MOZ_OBJDIR); then $(MKDIR) $(MOZ_OBJDIR); else true; fi
 endif
 	@if test ! -d $(OBJDIR); then $(MKDIR) $(OBJDIR); else true; fi
 	@echo cd $(OBJDIR);
@@ -412,9 +402,9 @@ cleansrcdir:
 echo-variable-%:
 	@echo $($*)
 
 # This makefile doesn't support parallel execution. It does pass
 # MOZ_MAKE_FLAGS to sub-make processes, so they will correctly execute
 # in parallel.
 .NOTPARALLEL:
 
-.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
+.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 upload sdk
--- a/config/JarMaker.py
+++ b/config/JarMaker.py
@@ -39,16 +39,17 @@
 processing jar.mn files.
 
 See the documentation for jar.mn on MDC for further details on the format.
 '''
 
 import sys
 import os
 import os.path
+import errno
 import re
 import logging
 from time import localtime
 from optparse import OptionParser
 from MozZipFile import ZipFile
 from cStringIO import StringIO
 from datetime import datetime
 
@@ -440,17 +441,17 @@ class JarMaker(object):
     def getDestModTime(self, aPath):
       return getModTime(os.path.join(self.basepath, aPath))
     def getOutput(self, name):
       out = self.ensureDirFor(name)
       # remove previous link or file
       try:
         os.remove(out)
       except OSError, e:
-        if e.errno != 2:
+        if e.errno != errno.ENOENT:
           raise
       return open(out, 'wb')
     def ensureDirFor(self, name):
       out = os.path.join(self.basepath, name)
       outdir = os.path.dirname(out)
       if not os.path.isdir(outdir):
         os.makedirs(outdir)
       return out
@@ -460,17 +461,17 @@ class JarMaker(object):
     creating a symlink including creating the parent directories.
     '''
     def symlink(self, src, dest):
       out = self.ensureDirFor(dest)
       # remove previous link or file
       try:
         os.remove(out)
       except OSError, e:
-        if e.errno != 2:
+        if e.errno != errno.ENOENT:
           raise
       os.symlink(src, out)
 
 def main():
   jm = JarMaker()
   p = jm.getCommandLineParser()
   (options, args) = p.parse_args()
   jm.processIncludes(options.I)
--- a/config/Makefile.in
+++ b/config/Makefile.in
@@ -127,16 +127,17 @@ export::
 		-DMOZ_TREE_CAIRO=$(MOZ_TREE_CAIRO) \
 		-DMOZ_ENABLE_LIBXUL=$(MOZ_ENABLE_LIBXUL) \
 		-DMOZ_NATIVE_HUNSPELL=$(MOZ_NATIVE_HUNSPELL) \
 		-DMOZ_NATIVE_BZ2=$(MOZ_NATIVE_BZ2) \
 		-DMOZ_NATIVE_ZLIB=$(MOZ_NATIVE_ZLIB) \
 		-DMOZ_NATIVE_PNG=$(MOZ_NATIVE_PNG) \
 		-DMOZ_NATIVE_JPEG=$(MOZ_NATIVE_JPEG) \
 		-DMOZ_NATIVE_LIBEVENT=$(MOZ_NATIVE_LIBEVENT) \
+		-DMOZ_NATIVE_LIBVPX=$(MOZ_NATIVE_LIBVPX) \
 		$(srcdir)/system-headers | $(PERL) $(topsrcdir)/nsprpub/config/make-system-wrappers.pl system_wrappers
 	$(INSTALL) system_wrappers $(DIST)
 
 GARBAGE_DIRS += system_wrappers
 endif
 
 ifdef WRAP_STL_INCLUDES
 ifdef GNU_CXX
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -96,17 +96,16 @@ MOZ_JS_LIBS		   = @MOZ_JS_LIBS@
 
 MOZ_DEBUG	= @MOZ_DEBUG@
 MOZ_DEBUG_SYMBOLS = @MOZ_DEBUG_SYMBOLS@
 MOZ_DEBUG_ENABLE_DEFS		= @MOZ_DEBUG_ENABLE_DEFS@
 MOZ_DEBUG_DISABLE_DEFS	= @MOZ_DEBUG_DISABLE_DEFS@
 MOZ_DEBUG_FLAGS	= @MOZ_DEBUG_FLAGS@
 MOZ_DEBUG_LDFLAGS=@MOZ_DEBUG_LDFLAGS@
 MOZ_EXTENSIONS  = @MOZ_EXTENSIONS@
-MOZ_IMG_ENCODERS= @MOZ_IMG_ENCODERS@
 MOZ_JSDEBUGGER  = @MOZ_JSDEBUGGER@
 MOZ_IPC 	= @MOZ_IPC@
 MOZ_IPDL_TESTS 	= @MOZ_IPDL_TESTS@
 MOZ_LEAKY	= @MOZ_LEAKY@
 MOZ_MEMORY      = @MOZ_MEMORY@
 MOZ_PROFILING   = @MOZ_PROFILING@
 MOZ_JPROF       = @MOZ_JPROF@
 MOZ_SHARK       = @MOZ_SHARK@
@@ -161,17 +160,21 @@ MOZ_RAW = @MOZ_RAW@
 MOZ_SYDNEYAUDIO = @MOZ_SYDNEYAUDIO@
 MOZ_WAVE = @MOZ_WAVE@
 MOZ_MEDIA = @MOZ_MEDIA@
 MOZ_VORBIS = @MOZ_VORBIS@
 MOZ_TREMOR = @MOZ_TREMOR@
 MOZ_WEBM = @MOZ_WEBM@
 VPX_AS = @VPX_AS@
 VPX_ASFLAGS = @VPX_ASFLAGS@
+VPX_DASH_C_FLAG = @VPX_DASH_C_FLAG@
+VPX_AS_CONVERSION = @VPX_AS_CONVERSION@
+VPX_ASM_SUFFIX = @VPX_ASM_SUFFIX@
 VPX_X86_ASM = @VPX_X86_ASM@
+VPX_ARM_ASM = @VPX_ARM_ASM@
 NS_PRINTING = @NS_PRINTING@
 MOZ_CRASHREPORTER = @MOZ_CRASHREPORTER@
 MOZ_HELP_VIEWER = @MOZ_HELP_VIEWER@
 MOC= @MOC@
 MOZ_NSS_PATCH = @MOZ_NSS_PATCH@
 MOZ_WEBGL = @MOZ_WEBGL@
 
 MOZ_JAVAXPCOM = @MOZ_JAVAXPCOM@
@@ -227,16 +230,20 @@ MOZ_AUTH_EXTENSION = @MOZ_AUTH_EXTENSION
 MOZ_NATIVE_HUNSPELL = @SYSTEM_HUNSPELL@
 MOZ_HUNSPELL_LIBS = @MOZ_HUNSPELL_LIBS@
 MOZ_HUNSPELL_CFLAGS = @MOZ_HUNSPELL_CFLAGS@
 
 MOZ_NATIVE_LIBEVENT = @MOZ_NATIVE_LIBEVENT@
 MOZ_LIBEVENT_LIBS = @MOZ_LIBEVENT_LIBS@
 MOZ_LIBEVENT_INCLUDES = @MOZ_LIBEVENT_INCLUDES@
 
+MOZ_NATIVE_LIBVPX = @MOZ_NATIVE_LIBVPX@
+MOZ_LIBVPX_LIBS = @MOZ_LIBVPX_LIBS@
+MOZ_LIBVPX_INCLUDES = @MOZ_LIBVPX_INCLUDES@
+
 MOZ_NATIVE_ZLIB	= @SYSTEM_ZLIB@
 MOZ_NATIVE_BZ2	= @SYSTEM_BZ2@
 MOZ_NATIVE_JPEG	= @SYSTEM_JPEG@
 MOZ_NATIVE_PNG	= @SYSTEM_PNG@
 MOZ_TREE_CAIRO = @MOZ_TREE_CAIRO@
 MOZ_TREE_PIXMAN = @MOZ_TREE_PIXMAN@
 
 MOZ_UPDATE_XTERM = @MOZ_UPDATE_XTERM@
@@ -600,17 +607,16 @@ OS_TEST=@OS_TEST@
 SOLARIS_SUNPRO_CC = @SOLARIS_SUNPRO_CC@
 SOLARIS_SUNPRO_CXX = @SOLARIS_SUNPRO_CXX@
 
 # For AIX build
 AIX_OBJMODEL = @AIX_OBJMODEL@
 
 # For OS/2 build
 MOZ_OS2_TOOLS = @MOZ_OS2_TOOLS@
-MOZ_OS2_USE_DECLSPEC = @MOZ_OS2_USE_DECLSPEC@
 MOZ_OS2_HIGH_MEMORY = @MOZ_OS2_HIGH_MEMORY@
 
 HAVE_XIE=@HAVE_XIE@
 
 MOZ_PSM=@MOZ_PSM@
 
 # Gssapi (krb5) libraries and headers for the Negotiate auth method
 GSSAPI_INCLUDES = @GSSAPI_INCLUDES@
@@ -691,8 +697,21 @@ MOZ_APP_EXTRA_LIBS = @MOZ_APP_EXTRA_LIBS
 ANDROID_NDK       = @ANDROID_NDK@
 ANDROID_TOOLCHAIN = @ANDROID_TOOLCHAIN@
 ANDROID_PLATFORM  = @ANDROID_PLATFORM@
 ANDROID_SDK       = @ANDROID_SDK@
 ANDROID_TOOLS     = @ANDROID_TOOLS@
 ANDROID_VERSION   = @ANDROID_VERSION@
 
 JS_SHARED_LIBRARY = @JS_SHARED_LIBRARY@
+
+# We only want to do the pymake sanity on Windows, other os's can cope
+ifeq (,$(filter-out WINNT WINCE,$(HOST_OS_ARCH)))
+# Ensure invariants between GNU Make and pymake
+# Checked here since we want the sane error in a file that
+# actually can be found regardless of path-style.
+ifeq (_:,$(.PYMAKE)_$(findstring :,$(srcdir)))
+$(error Windows-style srcdir being used with GNU make. Did you mean to run $(topsrcdir)/build/pymake/make.py instead? [see-also: https://developer.mozilla.org/en/Gmake_vs._Pymake])
+endif
+ifeq (1_a,$(.PYMAKE)_$(firstword a$(subst /, ,$(srcdir))))
+$(error MSYS-style srcdir being used with Pymake. Did you mean to run GNU Make instead? [see-also: https://developer.mozilla.org/en/Gmake_vs._Pymake])
+endif
+endif # Windows
--- a/config/config.mk
+++ b/config/config.mk
@@ -229,17 +229,17 @@ OS_LDFLAGS += -OPT:NOICF
 endif
 
 #
 # Handle trace-malloc in optimized builds.
 # No opt to give sane callstacks.
 #
 ifdef NS_TRACE_MALLOC
 MOZ_OPTIMIZE_FLAGS=-Zi -Od -UDEBUG -DNDEBUG
-OS_LDFLAGS = -DEBUG -PDB:NONE -OPT:REF -OPT:nowin98
+OS_LDFLAGS = -DEBUG -PDB:NONE -OPT:REF
 endif # NS_TRACE_MALLOC
 
 endif # MOZ_DEBUG
 endif # WINNT && !GNU_CC
 
 #
 # Build using PIC by default
 # Do not use PIC if not building a shared lib (see exceptions below)
--- a/config/nsStaticComponents.cpp.in
+++ b/config/nsStaticComponents.cpp.in
@@ -54,20 +54,18 @@
 
 %MODULE_LIST%
 #line 57 "nsStaticComponents.cpp.in"
 
 #undef MODULE
 
 
 #define MODULE(_name) \
-    NSMODULE_NAME(_name),
+    &NSMODULE_NAME(_name),
 
 /**
  * The nsStaticModuleInfo
  */
-static const mozilla::Module *const kStaticModules[] = {
+const mozilla::Module *const *const kPStaticModules[] = {
 	%MODULE_LIST%
 #line 70 "nsStaticComponents.cpp.in"
         NULL
 };
-
-mozilla::Module const *const *const kPStaticModules = kStaticModules;
--- a/config/nsStaticComponents.h
+++ b/config/nsStaticComponents.h
@@ -38,11 +38,11 @@
 #ifndef nsStaticComponents_h__
 #define nsStaticComponents_h__
 
 #include "mozilla/Module.h"
 
 // These symbols are provided by nsStaticComponents.cpp, and also by other
 // static component providers such as nsStaticXULComponents (libxul).
 
-extern mozilla::Module const *const *const kPStaticModules;
+extern mozilla::Module const *const *const kPStaticModules[];
 
 #endif
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -166,58 +166,58 @@ define _INSTALL_TESTS
 
 endef # do not remove the blank line!
 
 SOLO_FILE ?= $(error Specify a test filename in SOLO_FILE when using check-interactive or check-one)
 
 libs::
 	$(foreach dir,$(XPCSHELL_TESTS),$(_INSTALL_TESTS))
 	$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py \
-          $(testxpcobjdir)/all-test-dirs.list \
-          $(addprefix $(relativesrcdir)/,$(XPCSHELL_TESTS))
+	  $(testxpcobjdir)/all-test-dirs.list \
+	  $(addprefix $(relativesrcdir)/,$(XPCSHELL_TESTS))
 
 testxpcsrcdir = $(topsrcdir)/testing/xpcshell
 
 # Execute all tests in the $(XPCSHELL_TESTS) directories.
 # See also testsuite-targets.mk 'xpcshell-tests' target for global execution.
 xpcshell-tests:
 	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-          -I$(topsrcdir)/build \
-          $(testxpcsrcdir)/runxpcshelltests.py \
-          --symbols-path=$(DIST)/crashreporter-symbols \
-          $(EXTRA_TEST_ARGS) \
-          $(DIST)/bin/xpcshell \
-          $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
+	  -I$(topsrcdir)/build \
+	  $(testxpcsrcdir)/runxpcshelltests.py \
+	  --symbols-path=$(DIST)/crashreporter-symbols \
+	  $(EXTRA_TEST_ARGS) \
+	  $(DIST)/bin/xpcshell \
+	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
 
 # Execute a single test, specified in $(SOLO_FILE), but don't automatically
 # start the test. Instead, present the xpcshell prompt so the user can
 # attach a debugger and then start the test.
 check-interactive:
 	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-          -I$(topsrcdir)/build \
-          $(testxpcsrcdir)/runxpcshelltests.py \
-          --symbols-path=$(DIST)/crashreporter-symbols \
-          --test-path=$(SOLO_FILE) \
-          --profile-name=$(MOZ_APP_NAME) \
-          --interactive \
-          $(DIST)/bin/xpcshell \
-          $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
+	  -I$(topsrcdir)/build \
+	  $(testxpcsrcdir)/runxpcshelltests.py \
+	  --symbols-path=$(DIST)/crashreporter-symbols \
+	  --test-path=$(SOLO_FILE) \
+	  --profile-name=$(MOZ_APP_NAME) \
+	  --interactive \
+	  $(DIST)/bin/xpcshell \
+	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
 
 # Execute a single test, specified in $(SOLO_FILE)
 check-one:
 	$(PYTHON) -u $(topsrcdir)/config/pythonpath.py \
-          -I$(topsrcdir)/build \
-          $(testxpcsrcdir)/runxpcshelltests.py \
-          --symbols-path=$(DIST)/crashreporter-symbols \
-          --test-path=$(SOLO_FILE) \
-          --profile-name=$(MOZ_APP_NAME) \
-          --verbose \
-          $(EXTRA_TEST_ARGS) \
-          $(DIST)/bin/xpcshell \
-          $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
+	  -I$(topsrcdir)/build \
+	  $(testxpcsrcdir)/runxpcshelltests.py \
+	  --symbols-path=$(DIST)/crashreporter-symbols \
+	  --test-path=$(SOLO_FILE) \
+	  --profile-name=$(MOZ_APP_NAME) \
+	  --verbose \
+	  $(EXTRA_TEST_ARGS) \
+	  $(DIST)/bin/xpcshell \
+	  $(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
 
 endif # XPCSHELL_TESTS
 
 ifdef CPP_UNIT_TESTS
 
 # Compile the tests to $(DIST)/bin.  Make lots of niceties available by default
 # through TestHarness.h, by modifying the list of includes and the libs against
 # which stuff links.
@@ -841,17 +841,17 @@ ifdef LIBRARY_NAME
 ifdef EXPORT_LIBRARY
 ifdef IS_COMPONENT
 ifdef BUILD_STATIC_LIBS
 	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_COMPS) $(STATIC_LIBRARY_NAME)
 ifdef MODULE_NAME
 	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_COMP_NAMES) $(MODULE_NAME)
 endif
 endif # BUILD_STATIC_LIBS
-else  # !IS_COMPONENT
+else # !IS_COMPONENT
 	$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_LIBS) $(STATIC_LIBRARY_NAME)
 endif # IS_COMPONENT
 endif # EXPORT_LIBRARY
 endif # LIBRARY_NAME
 
 # Create dependencies on static (and shared EXTRA_DSO_LIBS) libraries
 LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(LIBS))
 HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(HOST_LIBS))
@@ -869,17 +869,17 @@ vpath $(LIB_PREFIX)%.$(LIB_SUFFIX) $(_LI
 ifdef IMPORT_LIB_SUFFIX
 vpath $(LIB_PREFIX)%.$(IMPORT_LIB_SUFFIX) $(_LIBDIRS)
 endif # IMPORT_LIB_SUFFIX
 vpath $(DLL_PREFIX)%$(DLL_SUFFIX) $(_LIBDIRS)
 endif # _LIBDIRS
 
 endif # _LIBNAME_RELATIVE_PATHS
 
-# Dependancies which, if modified, should cause everything to rebuild
+# Dependencies which, if modified, should cause everything to rebuild
 GLOBAL_DEPS += Makefile Makefile.in $(DEPTH)/config/autoconf.mk $(topsrcdir)/config/config.mk
 
 ##############################################
 ifdef PARALLEL_DIRS
 libs:: $(PARALLEL_DIRS_libs)
 
 $(PARALLEL_DIRS_libs): %_libs: %/Makefile
 	+@$(call SUBMAKE,libs,$*)
@@ -1193,17 +1193,17 @@ else
 ifneq (,$(filter OSF1 BSD_OS FreeBSD NetBSD OpenBSD SunOS Darwin,$(OS_ARCH)))
 CLEANUP1	:= | egrep -v '(________64ELEL_|__.SYMDEF)'
 CLEANUP2	:= rm -f ________64ELEL_ __.SYMDEF
 else
 CLEANUP2	:= true
 endif
 SUB_LOBJS	= $(shell for lib in $(SHARED_LIBRARY_LIBS); do $(AR_LIST) $${lib} $(CLEANUP1); done;)
 endif # EXPAND_FAKELIBS
-endif # SHARED_LIBARY_LIBS
+endif # SHARED_LIBRARY_LIBS
 endif
 ifdef MOZILLA_PROBE_LIBS
 PROBE_LOBJS	= $(shell for lib in $(MOZILLA_PROBE_LIBS); do $(AR_LIST) $${lib} $(CLEANUP1); done;)
 endif
 ifdef DTRACE_PROBE_OBJ
 EXTRA_DEPS += $(DTRACE_PROBE_OBJ)
 endif
 
@@ -1244,36 +1244,20 @@ endif
 ifeq ($(OS_ARCH),OS2)
 $(DEF_FILE): $(OBJS) $(SHARED_LIBRARY_LIBS)
 	rm -f $@
 	echo LIBRARY $(SHARED_LIBRARY_NAME) INITINSTANCE TERMINSTANCE > $@
 	echo PROTMODE >> $@
 	echo CODE    LOADONCALL MOVEABLE DISCARDABLE >> $@
 	echo DATA    PRELOAD MOVEABLE MULTIPLE NONSHARED >> $@
 	echo EXPORTS >> $@
-ifeq ($(IS_COMPONENT),1)
-ifeq ($(HAS_EXTRAEXPORTS),1)
-ifndef MOZ_OS2_USE_DECLSPEC
-	$(FILTER) $(OBJS) $(SHARED_LIBRARY_LIBS) >> $@
-endif	
-else
-	echo    _NSModule >> $@
-endif
-else
-ifndef MOZ_OS2_USE_DECLSPEC
-	$(FILTER) $(OBJS) $(SHARED_LIBRARY_LIBS) >> $@
-endif	
-endif
+
 	$(ADD_TO_DEF_FILE)
 
-ifdef MOZ_OS2_USE_DECLSPEC
 $(IMPORT_LIBRARY): $(SHARED_LIBRARY)
-else
-$(IMPORT_LIBRARY): $(DEF_FILE)
-endif
 	rm -f $@
 	$(IMPLIB) $@ $^
 	$(RANLIB) $@
 endif # OS/2
 
 $(HOST_LIBRARY): $(HOST_OBJS) Makefile
 	rm -f $@
 	$(HOST_AR) $(HOST_AR_FLAGS) $(HOST_OBJS)
@@ -1573,17 +1557,17 @@ SPACE := $(EMPTY) $(EMPTY)
 # and class paths to be in the DOS form (i.e. e:/builds/...).  This function
 # does the appropriate conversion on Windows, but is a noop on other systems.
 ifeq (,$(filter-out WINNT WINCE, $(HOST_OS_ARCH)))
 ifdef CYGWIN_WRAPPER
 normalizepath = $(foreach p,$(1),$(shell cygpath -m $(p)))
 else
 # assume MSYS
 #  We use 'pwd -W' to get DOS form of the path.  However, since the given path
-#  could be a file or a nonexistent path, we cannot call 'pwd -W' directly
+#  could be a file or a non-existent path, we cannot call 'pwd -W' directly
 #  on the path.  Instead, we extract the root path (i.e. "c:/"), call 'pwd -W'
 #  on it, then merge with the rest of the path.
 root-path = $(shell echo $(1) | sed -e "s|\(/[^/]*\)/\?\(.*\)|\1|")
 non-root-path = $(shell echo $(1) | sed -e "s|\(/[^/]*\)/\?\(.*\)|\2|")
 normalizepath = $(foreach p,$(1),$(if $(filter /%,$(1)),$(patsubst %/,%,$(shell cd $(call root-path,$(1)) && pwd -W))/$(call non-root-path,$(1)),$(1)))
 endif
 else
 normalizepath = $(1)
--- a/config/system-headers
+++ b/config/system-headers
@@ -1046,8 +1046,12 @@ proxy.h
 contentaction/contentaction.h
 #endif
 #ifndef MOZ_TREE_PIXMAN
 pixman.h
 #endif
 #if MOZ_ENABLE_MEEGOTOUCHSHARE
 shareuiinterface.h
 #endif
+#if MOZ_NATIVE_LIBVPX==1
+vpx/vpx_decoder.h
+vpx/vp8dx.h
+#endif
--- a/configure.in
+++ b/configure.in
@@ -987,17 +987,17 @@ AC_MSG_CHECKING([for full perl installat
 _perl_res=$?
 if test "$_perl_res" != 0; then
     AC_MSG_RESULT([no])
     AC_MSG_ERROR([Cannot find Config.pm or \$Config{archlib}.  A full perl installation is required.])
 else
     AC_MSG_RESULT([yes])    
 fi
 
-MOZ_PATH_PROGS(PYTHON, $PYTHON python2.6 python2.5 python2.4 python)
+MOZ_PATH_PROGS(PYTHON, $PYTHON python2.7 python2.6 python2.5 python)
 if test -z "$PYTHON"; then
     AC_MSG_ERROR([python was not found in \$PATH])
 fi
 
 if test -z "$COMPILE_ENVIRONMENT"; then
     NSINSTALL_BIN='$(PYTHON) $(topsrcdir)/config/nsinstall.py'
 fi
 AC_SUBST(NSINSTALL_BIN)
@@ -1841,18 +1841,16 @@ dnl ====================================
 case "$host" in
 *-beos*)
     HOST_CFLAGS="$HOST_CFLAGS -DXP_BEOS -DBeOS -DBEOS -D_POSIX_SOURCE -DNO_X11"
     HOST_NSPR_MDCPUCFG='\"md/_beos.cfg\"'
     HOST_OPTIMIZE_FLAGS="${HOST_OPTIMIZE_FLAGS=-O3}"
     ;;
 
 *cygwin*|*mingw*|*mks*|*msvc*|*wince|*winmo)
-    # we need Python 2.5 on Windows
-    PYTHON_VERSION=2.5
     if test -n "$_WIN32_MSVC"; then
         HOST_AR=lib
         HOST_AR_FLAGS='-NOLOGO -OUT:"$@"'
         HOST_CFLAGS="$HOST_CFLAGS -TC -nologo -Fd\$(HOST_PDBFILE)"
         HOST_RANLIB='echo ranlib'
     else
         HOST_CFLAGS="$HOST_CFLAGS -mno-cygwin"
     fi
@@ -1916,18 +1914,17 @@ case "$host" in
     ;;
 
 *)
     HOST_CFLAGS="$HOST_CFLAGS -DXP_UNIX"
     HOST_OPTIMIZE_FLAGS="${HOST_OPTIMIZE_FLAGS=-O2}"
     ;;
 esac
 
-dnl We require version 2.4 or newer of Python to build,
-dnl and 2.5 or newer on Windows.
+dnl We require version 2.5 or newer of Python to build.
 AC_MSG_CHECKING([for minimum required Python version >= $PYTHON_VERSION])
 changequote(,)
 $PYTHON -c "import sys; sys.exit(sys.version[:3] < sys.argv[1])" $PYTHON_VERSION
 _python_res=$?
 changequote([,])
 if test "$_python_res" != 0; then
     AC_MSG_ERROR([Python $PYTHON_VERSION or higher is required.])
 fi
@@ -2640,17 +2637,17 @@ ia64*-hpux*)
     DSO_PIC_CFLAGS=
     AR=emxomfar
     AR_FLAGS='r $@'
     CFLAGS="$CFLAGS -Zomf"
     CXXFLAGS="$CXXFLAGS -Zomf"
     DSO_LDOPTS='-Zdll'
     BIN_FLAGS='-Zlinker /ST:0x100000'
     IMPLIB='emximp -o'
-    FILTER='emxexp -o'
+    FILTER='true'
     LDFLAGS='-Zmap'
     WARNINGS_AS_ERRORS='-Werror'
     MOZ_DEBUG_FLAGS="-g -fno-inline"
     MOZ_OPTIMIZE_FLAGS="-O2"
     MOZ_OPTIMIZE_LDFLAGS="-s -Zlinker /EXEPACK:2 -Zlinker /PACKCODE -Zlinker /PACKDATA"
     DYNAMIC_XPCOM_LIBS='-L$(LIBXUL_DIST)/lib $(LIBXUL_DIST)/lib/xpcom.lib $(LIBXUL_DIST)/lib/xpcom_core.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
     LIBXUL_LIBS='-L$(LIBXUL_DIST)/lib $(LIBXUL_DIST)/lib/xpcom.lib $(LIBXUL_DIST)/lib/xul.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
     TARGET_MD_ARCH=os2
@@ -2676,19 +2673,18 @@ ia64*-hpux*)
     _DEFINES_CXXFLAGS="$_DEFINES_CXXFLAGS -Uunix -U__unix -U__unix__"
 
     AC_CACHE_CHECK(for __declspec(dllexport),
         ac_os2_declspec,
         [AC_TRY_COMPILE([__declspec(dllexport) void ac_os2_declspec(void) {}],
                         [return 0;],
                         ac_os2_declspec="yes",
                         ac_os2_declspec="no")])
-    if test "$ac_os2_declspec" = "yes"; then
-        FILTER='true'
-        MOZ_OS2_USE_DECLSPEC='1'
+    if test "$ac_os2_declspec" != "yes"; then
+        AC_MSG_ERROR([Compiler does not support __declspec(dllexport), install GCC-4.3.2 or newer])
     fi
     ;;
 
 alpha*-*-osf*)
     if test "$GNU_CC"; then
       MKSHLIB='$(CXX) $(CXXFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-soname,$@ -o $@'
       MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-soname,$@ -o $@'
 
@@ -3403,21 +3399,19 @@ dnl against libSystem causes issues when
 case $target in
 *-darwin*)
     ;;
 *-beos*)
     ;;
 *-os2*)
     ;;
 *)
-    AC_CHECK_LIB(m, atan)
-    AC_CHECK_LIB(dl, dlopen,
-    AC_CHECK_HEADER(dlfcn.h, 
-        LIBS="-ldl $LIBS"
-        AC_DEFINE(HAVE_LIBDL)))
+    AC_SEARCH_LIBS(dlopen, dl, 
+        AC_CHECK_HEADER(dlfcn.h, 
+        AC_DEFINE(HAVE_DLOPEN)))
     ;;
 esac
 
 _SAVE_CFLAGS="$CFLAGS"
 CFLAGS="$CFLAGS -D_GNU_SOURCE"
 AC_CHECK_FUNCS(dladdr)
 CFLAGS="$_SAVE_CFLAGS"
 
@@ -4723,20 +4717,20 @@ dnl Detect yasm
 dnl ======================
 
 AC_MSG_CHECKING([for YASM assembler])
 AC_CHECK_PROGS(YASM, yasm, "")
 
 if test -n "$YASM"; then
   dnl Pull out yasm's version string
   changequote(,)
-  _YASM_VER_FILTER='s|.* ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*|\1|p'
+  _YASM_VER_FILTER='s|.* \([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\).*|\1|p'
   changequote([,])
 
-  YASM_VERSION=`yasm --version | sed -nre "$_YASM_VER_FILTER"`
+  YASM_VERSION=`yasm --version | sed -ne "$_YASM_VER_FILTER"`
   _YASM_MAJOR_VERSION=`echo ${YASM_VERSION} | $AWK -F\. '{ print $1 }'`
   _YASM_MINOR_VERSION=`echo ${YASM_VERSION} | $AWK -F\. '{ print $2 }'`
   _YASM_RELEASE=`      echo ${YASM_VERSION} | $AWK -F\. '{ print $3 }'`
   _YASM_BUILD=`        echo ${YASM_VERSION} | $AWK -F\. '{ print $4 }'`
 fi
 
 if test -z "$SKIP_LIBRARY_CHECKS"; then
 dnl system JPEG support
@@ -4937,17 +4931,16 @@ dnl ====================================
 MOZ_ARG_HEADER(Application)
 
 BUILD_STATIC_LIBS=
 ENABLE_TESTS=1
 MOZ_ACTIVEX_SCRIPTING_SUPPORT=
 MOZ_BRANDING_DIRECTORY=
 MOZ_OFFICIAL_BRANDING=
 MOZ_FEEDS=1
-MOZ_IMG_ENCODERS_DEFAULT="png jpeg"
 MOZ_INSTALLER=1
 MOZ_IPC=1
 MOZ_JAVAXPCOM=
 MOZ_JSDEBUGGER=1
 MOZ_JSLOADER=1
 MOZ_MATHML=1
 MOZ_MORK=
 MOZ_MORKREADER=1
@@ -4959,17 +4952,21 @@ MOZ_RAW=
 MOZ_SYDNEYAUDIO=
 MOZ_VORBIS=
 MOZ_TREMOR=
 MOZ_WAVE=1
 MOZ_MEDIA=
 MOZ_WEBM=1
 VPX_AS=
 VPX_ASFLAGS=
+VPX_AS_DASH_C_FLAG=
+VPX_AS_CONVERSION=
+VPX_ASM_SUFFIX=
 VPX_X86_ASM=
+VPX_ARM_ASM=
 MOZ_PANGO=1
 MOZ_PERMISSIONS=1
 MOZ_PLACES=1
 MOZ_PLAINTEXT_EDITOR_ONLY=
 MOZ_PLUGINS=1
 MOZ_PREF_EXTENSIONS=1
 MOZ_PROFILELOCKING=1
 MOZ_PSM=1
@@ -5989,33 +5986,77 @@ fi
 dnl ========================================================
 dnl = Disable VP8 decoder support
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(webm,
 [  --disable-webm          Disable support for WebM media (VP8 video and Vorbis audio)],
     MOZ_WEBM=,
     MOZ_WEBM=1)
 
+dnl system libvpx Support
+dnl ========================================================
+MOZ_ARG_WITH_STRING(system-libvpx,
+[  --with-system-libvpx=[PFX]
+                          Use system libvpx [installed at prefix PFX]],
+    LIBVPX_DIR=$withval)
+
+MOZ_NATIVE_LIBVPX=
+MOZ_LIBVPX_INCLUDES=
+MOZ_LIBVPX_LIBS=
+
 if test -n "$MOZ_WEBM"; then
     AC_DEFINE(MOZ_WEBM)
+
+    if test -n "$LIBVPX_DIR" -a "$LIBVPX_DIR" != no; then
+        _SAVE_CFLAGS=$CFLAGS
+        _SAVE_LDFLAGS=$LDFLAGS
+        _SAVE_LIBS=$LIBS
+        if test "${LIBVPX_DIR}" = "yes"; then
+            LIBVPX_DIR=/usr
+        fi
+        CFLAGS="-I${LIBVPX_DIR}/include $CFLAGS"
+        LDFLAGS="-L${LIBVPX_DIR}/lib $LDFLAGS"
+        AC_CHECK_HEADER(vpx/vpx_decoder.h,
+                        [if test ! -f "${LIBVPX_DIR}/include/vpx/vpx_decoder.h"; then
+                             AC_MSG_ERROR([vpx/vpx_decoder.h found, but is not in ${LIBVPX_DIR}/include])
+                         fi],
+                        AC_MSG_ERROR([--with-system-libvpx requested but vpx/vpx_decoder.h not found]))
+        AC_CHECK_LIB(vpx, vpx_codec_dec_init_ver,
+                     [MOZ_NATIVE_LIBVPX=1
+                      MOZ_LIBVPX_INCLUDES="-I${LIBVPX_DIR}/include"
+                      MOZ_LIBVPX_LIBS="-L${LIBVPX_DIR}/lib -lvpx"],
+                     ([--with-system-libvpx requested but symbol vpx_codec_dec_init_ver not found]))
+        CFLAGS=$_SAVE_CFLAGS
+        LDFLAGS=$_SAVE_LDFLAGS
+        LIBS=$_SAVE_LIBS
+    fi
+fi
+
+AC_SUBST(MOZ_NATIVE_LIBVPX)
+AC_SUBST(MOZ_LIBVPX_INCLUDES)
+AC_SUBST(MOZ_LIBVPX_LIBS)
+
+if test -n "$MOZ_WEBM" -a -z "$MOZ_NATIVE_LIBVPX"; then
     MOZ_SYDNEYAUDIO=1
     MOZ_MEDIA=1
     case "$target_cpu" in
     arm*)
         MOZ_TREMOR=1
     ;;
     *)
         MOZ_VORBIS=1
     ;;
     esac
 
 
     dnl Detect if we can use an assembler to compile optimized assembly for libvpx.
-    dnl We currently require yasm on all platforms and require yasm 1.1.0 on Win32.
+    dnl We currently require yasm on all x86 platforms and require yasm 1.1.0 on Win32.
+    dnl We currently require gcc on all arm platforms.
     VPX_AS=$YASM
+    VPX_ASM_SUFFIX=asm
 
     dnl See if we have assembly on this platform.  
     case "$OS_ARCH:$CPU_ARCH" in
     Linux:x86)
       VPX_ASFLAGS="-f elf32 -rnasm -pnasm"
       VPX_X86_ASM=1
     ;;
     Linux:x86_64)
@@ -6052,24 +6093,37 @@ if test -n "$MOZ_WEBM"; then
         elif test -n "$COMPILE_ENVIRONMENT" -a "$_YASM_MAJOR_VERSION" -lt "1" -o \( "$_YASM_MAJOR_VERSION" -eq "1" -a "$_YASM_MINOR_VERSION" -lt "1" \) ; then
           AC_MSG_ERROR([yasm 1.1 or greater is required to build libvpx on Win32, but you appear to have version $_YASM_MAJOR_VERSION.$_YASM_MINOR_VERSION.  Upgrade to the newest version (included in MozillaBuild 1.5.1 and newer) or configure with --disable-webm (which disables the WebM video format). See https://developer.mozilla.org/en/YASM for more details.])
         else
           VPX_ASFLAGS="-f win32 -rnasm -pnasm -DPIC"
           VPX_X86_ASM=1
         fi
       fi
     ;;
+    *:arm*)
+      if test -n "$GNU_AS" ; then
+        VPX_AS=$AS
+        dnl These flags are a lie; they're just used to enable the requisite
+        dnl opcodes; actual arch detection is done at runtime.
+        VPX_ASFLAGS="-march=armv7-a -mfpu=neon"
+        VPX_DASH_C_FLAG="-c"
+        VPX_AS_CONVERSION="$PERL ${srcdir}/media/libvpx/build/make/ads2gas.pl"
+        VPX_ASM_SUFFIX="$ASM_SUFFIX"
+        VPX_ARM_ASM=1
+      fi
     esac
 
     if test -n "$COMPILE_ENVIRONMENT" -a -n "$VPX_X86_ASM" -a -z "$VPX_AS"; then
       AC_MSG_ERROR([yasm is a required build tool for this architecture when webm is enabled. You may either install yasm or --disable-webm (which disables the WebM video format). See https://developer.mozilla.org/en/YASM for more details.])
     fi
 
     if test -n "$VPX_X86_ASM"; then
       AC_DEFINE(VPX_X86_ASM)
+    elif test -n "$VPX_ARM_ASM"; then
+      AC_DEFINE(VPX_ARM_ASM)
     else
       AC_MSG_WARN([No assembler or assembly support for libvpx. Using unoptimized C routines.])
     fi
 fi
 
 dnl ========================================================
 dnl = Disable Wave decoder support
 dnl ========================================================
@@ -6362,25 +6416,21 @@ if test `echo "$MOZ_EXTENSIONS" | grep -
 fi
 
 dnl cookie must be built before tridentprofile. put it at list's end.
 if test `echo "$MOZ_EXTENSIONS" | grep -c tridentprofile` -ne 0; then
   MOZ_EXTENSIONS=`echo $MOZ_EXTENSIONS | sed -e 's|tridentprofile||'`
   MOZ_EXTENSIONS="$MOZ_EXTENSIONS tridentprofile"
 fi
 
-dnl xforms requires xtf and schema-validation
+dnl xforms requires xtf
 if test -z "$MOZ_XTF" -a `echo "$MOZ_EXTENSIONS" | grep -c xforms` -ne 0; then
     AC_MSG_WARN([Cannot build XForms without XTF support.  Removing XForms from MOZ_EXTENSIONS.])
     MOZ_EXTENSIONS=`echo $MOZ_EXTENSIONS | sed -e 's|xforms||g'`
 fi
-if test `echo "$MOZ_EXTENSIONS" | grep -c xforms` -ne 0 && test `echo "$MOZ_EXTENSIONS" | grep -c schema-validation` -eq 0; then
-    AC_MSG_WARN([Cannot build XForms without schema validation.  Removing XForms from MOZ_EXTENSIONS.])
-    MOZ_EXTENSIONS=`echo $MOZ_EXTENSIONS | sed -e 's|xforms||g'`
-fi
 
 if test `echo "$MOZ_EXTENSIONS" | grep -c auth` -ne 0; then
     AC_MSG_WARN([auth is no longer an extension, use --disable-negotiateauth to disable.])
     MOZ_EXTENSIONS=`echo $MOZ_EXTENSIONS | sed -e 's|auth||g'`
 fi
 
 if test `echo "$MOZ_EXTENSIONS" | grep -c 'cookie\|permissions'` -ne 0; then
     AC_MSG_WARN([cookie and permissions are no longer extensions, use --disable-permissions to disable.])
@@ -6414,43 +6464,16 @@ dnl Ensure every extension exists, to av
 dnl when trying to build a nonexistent extension.
 for extension in $MOZ_EXTENSIONS; do
     if test ! -d "${srcdir}/extensions/${extension}"; then
         AC_MSG_ERROR([Unrecognized extension provided to --enable-extensions: ${extension}.])
     fi
 done
 
 dnl ========================================================
-dnl Image encoders
-dnl ========================================================
-MOZ_ARG_ENABLE_STRING(image-encoders,
-[  --enable-image-encoders[={mod1,mod2,default,all,none}]
-                          Enable specific image encoders],
-[ for option in `echo $enableval | sed 's/,/ /g'`; do
-    if test "$option" = "yes" -o "$option" = "all"; then
-        addencoder="$MOZ_IMG_ENCODERS_DEFAULT"
-    elif test "$option" = "no" -o "$option" = "none"; then
-        MOZ_IMG_ENCODERS=""
-        addencoder=""
-    elif test "$option" = "default"; then
-        addencoder="$MOZ_IMG_ENCODERS_DEFAULT"
-    elif test `echo "$option" | grep -c \^-` != 0; then
-        option=`echo $option | sed 's/^-//'`
-        addencoder=`echo "$MOZ_IMG_ENCODERS" | sed "s/ ${option}//"`
-    else
-        addencoder="$option"
-    fi
-    MOZ_IMG_ENCODERS="$MOZ_IMG_ENCODERS $addencoder"
-done],
-    MOZ_IMG_ENCODERS="$MOZ_IMG_ENCODERS_DEFAULT")
-
-dnl Remove dupes
-MOZ_IMG_ENCODERS=`${PERL} ${srcdir}/build/unix/uniq.pl ${MOZ_IMG_ENCODERS}`
-
-dnl ========================================================
 dnl MathML on by default
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(mathml,
 [  --disable-mathml        Disable MathML support],
     MOZ_MATHML=,
     MOZ_MATHML=1 )
 if test "$MOZ_MATHML"; then
   AC_DEFINE(MOZ_MATHML)
@@ -8568,17 +8591,17 @@ if test "$MOZ_TREE_CAIRO"; then
     AC_SUBST(PNG_FUNCTIONS_FEATURE)
     AC_SUBST(QT_SURFACE_FEATURE)
 
     MOZ_CAIRO_LIBS='$(call EXPAND_LIBNAME_PATH,mozcairo,$(DEPTH)/gfx/cairo/cairo/src)'" $CAIRO_FT_LIBS"
 
     if test "$MOZ_TREE_PIXMAN"; then
         MOZ_CAIRO_LIBS="$MOZ_CAIRO_LIBS"' $(call EXPAND_LIBNAME_PATH,mozlibpixman,$(DEPTH)/gfx/cairo/libpixman/src)'
     else
-        PKG_CHECK_MODULES(PIXMAN, pixman-1 >= 0.17.3)
+        PKG_CHECK_MODULES(PIXMAN, pixman-1 >= 0.19.2)
         MOZ_CAIRO_CFLAGS="$MOZ_CAIRO_CFLAGS $PIXMAN_CFLAGS"
         MOZ_CAIRO_LIBS="$MOZ_CAIRO_LIBS $PIXMAN_LIBS"
     fi
 
     if test "$MOZ_X11"; then
         MOZ_CAIRO_LIBS="$MOZ_CAIRO_LIBS $XLDFLAGS -lXrender -lfreetype -lfontconfig"
     fi
 
@@ -8843,17 +8866,16 @@ AC_SUBST(MOZ_PSM)
 AC_SUBST(MOZ_DEBUG)
 AC_SUBST(MOZ_DEBUG_SYMBOLS)
 AC_SUBST(MOZ_DEBUG_ENABLE_DEFS)
 AC_SUBST(MOZ_DEBUG_DISABLE_DEFS)
 AC_SUBST(MOZ_DEBUG_FLAGS)
 AC_SUBST(MOZ_DEBUG_LDFLAGS)
 AC_SUBST(WARNINGS_AS_ERRORS)
 AC_SUBST(MOZ_EXTENSIONS)
-AC_SUBST(MOZ_IMG_ENCODERS)
 AC_SUBST(MOZ_JSDEBUGGER)
 AC_SUBST(MOZ_PLUGINS)
 AC_SUBST(MOZ_LOG_REFCNT)
 AC_SUBST(MOZ_LEAKY)
 AC_SUBST(MOZ_JPROF)
 AC_SUBST(MOZ_SHARK)
 AC_SUBST(MOZ_CALLGRIND)
 AC_SUBST(MOZ_VTUNE)
@@ -8906,17 +8928,16 @@ AC_SUBST(XPCOM_LIBS)
 AC_SUBST(XPCOM_FROZEN_LDOPTS)
 AC_SUBST(XPCOM_GLUE_LDOPTS)
 AC_SUBST(XPCOM_STANDALONE_GLUE_LDOPTS)
 
 AC_SUBST(USE_DEPENDENT_LIBS)
 
 AC_SUBST(MOZ_BUILD_ROOT)
 AC_SUBST(MOZ_OS2_TOOLS)
-AC_SUBST(MOZ_OS2_USE_DECLSPEC)
 
 AC_SUBST(MOZ_POST_DSO_LIB_COMMAND)
 AC_SUBST(MOZ_POST_PROGRAM_COMMAND)
 AC_SUBST(MOZ_TIMELINE)
 AC_SUBST(OGLES_SDK_DIR)
 
 AC_SUBST(MOZ_APP_NAME)
 AC_SUBST(MOZ_APP_DISPLAYNAME)
@@ -9073,17 +9094,21 @@ AC_SUBST(MOZ_SYDNEYAUDIO)
 AC_SUBST(MOZ_WAVE)
 AC_SUBST(MOZ_VORBIS)
 AC_SUBST(MOZ_TREMOR)
 AC_SUBST(MOZ_WEBM)
 AC_SUBST(MOZ_OGG)
 AC_SUBST(MOZ_ALSA_LIBS)
 AC_SUBST(VPX_AS)
 AC_SUBST(VPX_ASFLAGS)
+AC_SUBST(VPX_DASH_C_FLAG)
+AC_SUBST(VPX_AS_CONVERSION)
+AC_SUBST(VPX_ASM_SUFFIX)
 AC_SUBST(VPX_X86_ASM)
+AC_SUBST(VPX_ARM_ASM)
 
 if test "$USING_HCC"; then
    CC='${topsrcdir}/build/hcc'
    CC="$CC '$_OLDCC'"
    CXX='${topsrcdir}/build/hcpp'
    CXX="$CXX '$_OLDCXX'"
    AC_SUBST(CC)
    AC_SUBST(CXX)
new file mode 100644
--- /dev/null
+++ b/content/base/public/FromParser.h
@@ -0,0 +1,57 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Ms2ger <Ms2ger@gmail.com>.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef mozilla_dom_FromParser_h
+#define mozilla_dom_FromParser_h
+
+namespace mozilla {
+namespace dom {
+
+/**
+ * Constants for passing as aFromParser
+ */
+enum FromParser {
+  NOT_FROM_PARSER = 0,
+  FROM_PARSER_NETWORK = 1,
+  FROM_PARSER_DOCUMENT_WRITE = 1 << 1,
+  FROM_PARSER_FRAGMENT = 1 << 2,
+  FROM_PARSER_XSLT = 1 << 3
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_FromParser_h
--- a/content/base/public/Makefile.in
+++ b/content/base/public/Makefile.in
@@ -79,18 +79,19 @@ nsLineBreaker.h \
 nsReferencedElement.h \
 nsXMLNameSpaceMap.h \
 nsDOMEventTargetWrapperCache.h \
 $(NULL)
 
 EXPORTS_NAMESPACES = mozilla/dom
 
 EXPORTS_mozilla/dom = \
-Element.h \
-$(NULL)
+		Element.h \
+		FromParser.h \
+		$(NULL)
 
 ifndef DISABLE_XFORMS_HOOKS
 EXPORTS += nsIXFormsUtilityService.h
 endif
 
 SDK_XPIDLSRCS   = \
 		nsISelection.idl  \
 		$(NULL)
--- a/content/base/public/nsContentCreatorFunctions.h
+++ b/content/base/public/nsContentCreatorFunctions.h
@@ -37,41 +37,35 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsContentCreatorFunctions_h__
 #define nsContentCreatorFunctions_h__
 
 #include "nscore.h"
 #include "nsCOMPtr.h"
+#include "mozilla/dom/FromParser.h"
 
 /**
  * Functions to create content, to be used only inside Gecko
  * (mozilla/content and mozilla/layout).
  */
 
 class nsAString;
 class nsIContent;
 class nsIDocument;
 class nsINodeInfo;
 class imgIRequest;
 class nsNodeInfoManager;
 class nsGenericHTMLElement;
 
-/**
- * Constants for passing as aFromParser
- */
-#define NS_NOT_FROM_PARSER 0
-#define NS_FROM_PARSER_NETWORK 1
-#define NS_FROM_PARSER_DOCUMENT_WRITE (1 << 1)
-#define NS_FROM_PARSER_FRAGMENT (1 << 2)
-
 nsresult
 NS_NewElement(nsIContent** aResult, PRInt32 aElementType,
-              already_AddRefed<nsINodeInfo> aNodeInfo, PRUint32 aFromParser);
+              already_AddRefed<nsINodeInfo> aNodeInfo,
+              mozilla::dom::FromParser aFromParser);
 
 nsresult
 NS_NewXMLElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo);
 
 /**
  * aNodeInfoManager must not be null.
  */
 nsresult
@@ -104,23 +98,23 @@ NS_NewXMLStylesheetProcessingInstruction
  * aNodeInfoManager must not be null.
  */
 nsresult
 NS_NewXMLCDATASection(nsIContent** aInstancePtrResult,
                       nsNodeInfoManager *aNodeInfoManager);
 
 nsresult
 NS_NewHTMLElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo,
-                  PRUint32 aFromParser);
+                  mozilla::dom::FromParser aFromParser);
 
 // First argument should be nsHTMLTag, but that adds dependency to parser
 // for a bunch of files.
 already_AddRefed<nsGenericHTMLElement>
 CreateHTMLElement(PRUint32 aNodeType, already_AddRefed<nsINodeInfo> aNodeInfo,
-                  PRUint32 aFromParser);
+                  mozilla::dom::FromParser aFromParser);
 
 #ifdef MOZ_MATHML
 nsresult
 NS_NewMathMLElement(nsIContent** aResult,
                      already_AddRefed<nsINodeInfo> aNodeInfo);
 #endif
 
 #ifdef MOZ_XUL
@@ -129,17 +123,17 @@ NS_NewXULElement(nsIContent** aResult, a
 
 void
 NS_TrustedNewXULElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo);
 #endif
 
 #ifdef MOZ_SVG
 nsresult
 NS_NewSVGElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo,
-                 PRUint32 aFromParser);
+                 mozilla::dom::FromParser aFromParser);
 #endif
 
 nsresult
 NS_NewGenConImageContent(nsIContent** aResult,
                          already_AddRefed<nsINodeInfo> aNodeInfo,
                          imgIRequest* aImageRequest);
 
 nsresult
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1695,16 +1695,24 @@ public:
    * A sub document isn't tabbable when it's a zombie document.
    *
    * @param aElement element to test.
    *
    * @return Whether the subdocument is tabbable.
    */
   static bool IsSubDocumentTabbable(nsIContent* aContent);
 
+  /**
+   * Flushes the layout tree (recursively)
+   *
+   * @param aWindow the window the flush should start at
+   *
+   */
+  static void FlushLayoutForTree(nsIDOMWindow* aWindow);
+
 private:
 
   static PRBool InitializeEventTable();
 
   static nsresult EnsureStringBundle(PropertiesFile aFile);
 
   static nsIDOMScriptObjectFactory *GetDOMScriptObjectFactory();
 
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -116,18 +116,18 @@ class Loader;
 namespace dom {
 class Link;
 class Element;
 } // namespace dom
 } // namespace mozilla
 
 
 #define NS_IDOCUMENT_IID      \
-{ 0x7fb1e97d, 0xbd2c, 0x47cf, \
-  { 0xa3, 0x05, 0x5b, 0x31, 0xd4, 0x1d, 0x3a, 0x52 } }
+{ 0xc38a7935, 0xc854, 0x4df7, \
+  { 0x8f, 0xd4, 0xa2, 0x6f, 0x0d, 0x27, 0x9f, 0x31 } }
 
 // Flag for AddStyleSheet().
 #define NS_STYLESHEET_FROM_CATALOG                (1 << 0)
 
 // Document states
 
 // RTL locale: specific to the XUL localedir attribute
 #define NS_DOCUMENT_STATE_RTL_LOCALE              NS_DEFINE_EVENT_STATE_MACRO(0)
@@ -1275,16 +1275,21 @@ public:
   PRBool HasAnimationController()  { return !!mAnimationController; }
 
   // Getter for this document's SMIL Animation Controller. Performs lazy
   // initialization, if this document supports animation and if
   // mAnimationController isn't yet initialized.
   virtual nsSMILAnimationController* GetAnimationController() = 0;
 #endif // MOZ_SMIL
 
+  // Makes the images on this document capable of having their animation
+  // active or suspended. An Image will animate as long as at least one of its
+  // owning Documents needs it to animate; otherwise it can suspend.
+  virtual void SetImagesNeedAnimating(PRBool aAnimating) = 0;
+
   /**
    * Prevents user initiated events from being dispatched to the document and
    * subdocuments.
    */
   virtual void SuppressEventHandling(PRUint32 aIncrease = 1) = 0;
 
   /**
    * Unsuppress event handling.
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -733,17 +733,17 @@ public:
    * observer that is already observing the node must not be added without
    * being removed first.
    */
   void AddMutationObserver(nsIMutationObserver* aMutationObserver)
   {
     nsSlots* s = GetSlots();
     if (s) {
       NS_ASSERTION(s->mMutationObservers.IndexOf(aMutationObserver) ==
-                   nsTArray_base::NoIndex,
+                   nsTArray<int>::NoIndex,
                    "Observer already in the list");
       s->mMutationObservers.AppendElement(aMutationObserver);
     }
   }
 
   /**
    * Same as above, but only adds the observer if its not observing
    * the node already.
--- a/content/base/public/nsIScriptElement.h
+++ b/content/base/public/nsIScriptElement.h
@@ -53,25 +53,28 @@
 
 /**
  * Internal interface implemented by script elements
  */
 class nsIScriptElement : public nsIScriptLoaderObserver {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCRIPTELEMENT_IID)
 
-  nsIScriptElement(PRUint32 aFromParser)
+  nsIScriptElement(mozilla::dom::FromParser aFromParser)
     : mLineNumber(0),
       mAlreadyStarted(PR_FALSE),
       mMalformed(PR_FALSE),
       mDoneAddingChildren(PR_TRUE),
       mFrozen(PR_FALSE),
       mDefer(PR_FALSE),
       mAsync(PR_FALSE),
-      mParserCreated((PRUint8)aFromParser),
+      mParserCreated(aFromParser == mozilla::dom::FROM_PARSER_FRAGMENT ?
+                     mozilla::dom::NOT_FROM_PARSER : aFromParser),
+                     // Fragment parser-created scripts (if executable)
+                     // behave like script-created scripts.
       mCreatorParser(nsnull)
   {
   }
 
   /**
    * Content type identifying the scripting language. Can be empty, in
    * which case javascript will be assumed.
    */
@@ -115,20 +118,19 @@ public:
    */
   PRBool GetScriptAsync()
   {
     NS_PRECONDITION(mFrozen, "Not ready for this call yet!");
     return mAsync;  
   }
 
   /**
-   * Returns a constant defined in nsContentCreatorFunctions.h. Non-zero
-   * values mean parser-created and zero means not parser-created.
+   * Returns how the element was created.
    */
-  PRUint32 GetParserCreated()
+  mozilla::dom::FromParser GetParserCreated()
   {
     return mParserCreated;
   }
 
   void SetScriptLineNumber(PRUint32 aLineNumber)
   {
     mLineNumber = aLineNumber;
   }
@@ -151,17 +153,17 @@ public:
     mAlreadyStarted = PR_TRUE;
   }
 
   void LoseParserInsertedness()
   {
     mFrozen = PR_FALSE;
     mUri = nsnull;
     mCreatorParser = nsnull;
-    mParserCreated = NS_NOT_FROM_PARSER;
+    mParserCreated = mozilla::dom::NOT_FROM_PARSER;
   }
 
   void SetCreatorParser(nsIParser* aParser)
   {
     mCreatorParser = getter_AddRefs(NS_GetWeakReference(aParser));
   }
 
   /**
@@ -229,17 +231,17 @@ protected:
   /**
    * The effective asyncness.
    */
   PRPackedBool mAsync;
   
   /**
    * Whether this element was parser-created.
    */
-  PRUint8 mParserCreated;
+  mozilla::dom::FromParser mParserCreated;
 
   /**
    * The effective src (or null if no src).
    */
   nsCOMPtr<nsIURI> mUri;
   
   /**
    * The creator parser of a non-defer, non-async parser-inserted script.
--- a/content/base/src/CSPUtils.jsm
+++ b/content/base/src/CSPUtils.jsm
@@ -80,47 +80,44 @@ var gPrefObserver = {
       this._debugEnabled = this._branch.getBoolPref("debug");
   },
 
 };
 
 
 function CSPWarning(aMsg) {
   var textMessage = 'CSP WARN:  ' + aMsg + "\n";
-  dump(textMessage);
 
   var consoleMsg = Components.classes["@mozilla.org/scripterror;1"]
                     .createInstance(Components.interfaces.nsIScriptError);
   consoleMsg.init('CSP: ' + aMsg, null, null, 0, 0,
                   Components.interfaces.nsIScriptError.warningFlag,
                   "Content Security Policy");
   Components.classes["@mozilla.org/consoleservice;1"]
                     .getService(Components.interfaces.nsIConsoleService)
                     .logMessage(consoleMsg);
 }
 
 function CSPError(aMsg) {
   var textMessage = 'CSP ERROR:  ' + aMsg + "\n";
-  dump(textMessage);
 
   var consoleMsg = Components.classes["@mozilla.org/scripterror;1"]
                     .createInstance(Components.interfaces.nsIScriptError);
   consoleMsg.init('CSP: ' + aMsg, null, null, 0, 0,
                   Components.interfaces.nsIScriptError.errorFlag,
                   "Content Security Policy");
   Components.classes["@mozilla.org/consoleservice;1"]
                     .getService(Components.interfaces.nsIConsoleService)
                     .logMessage(consoleMsg);
 }
 
 function CSPdebug(aMsg) {
   if (!gPrefObserver.debugEnabled) return;
 
   aMsg = 'CSP debug: ' + aMsg + "\n";
-  dump(aMsg);
   Components.classes["@mozilla.org/consoleservice;1"]
                     .getService(Components.interfaces.nsIConsoleService)
                     .logStringMessage(aMsg);
 }
 
 //:::::::::::::::::::::::: CLASSES ::::::::::::::::::::::::::// 
 
 /**
--- a/content/base/src/nsAttrValue.h
+++ b/content/base/src/nsAttrValue.h
@@ -53,18 +53,19 @@
 #include "nsCOMPtr.h"
 
 typedef PRUptrdiff PtrBits;
 class nsAString;
 class nsIAtom;
 class nsICSSStyleRule;
 class nsISVGValue;
 class nsIDocument;
-template<class E> class nsTArray;
-template<class E> class nsTPtrArray;
+template<class E, class A> class nsTArray;
+template<class E, class A> class nsTPtrArray;
+struct nsTArrayDefaultAllocator;
 
 #define NS_ATTRVALUE_MAX_STRINGLENGTH_ATOM 12
 
 #define NS_ATTRVALUE_BASETYPE_MASK (PtrBits(3))
 #define NS_ATTRVALUE_POINTERVALUE_MASK (~NS_ATTRVALUE_BASETYPE_MASK)
 
 #define NS_ATTRVALUE_INTEGERTYPE_BITS 4
 #define NS_ATTRVALUE_INTEGERTYPE_MASK (PtrBits((1 << NS_ATTRVALUE_INTEGERTYPE_BITS) - 1))
@@ -376,17 +377,17 @@ private:
   // aStrict is set PR_TRUE if stringifying the return value equals with
   // aValue.
   PRInt32 StringToInteger(const nsAString& aValue,
                           PRBool* aStrict,
                           PRInt32* aErrorCode,
                           PRBool aCanBePercent = PR_FALSE,
                           PRBool* aIsPercent = nsnull) const;
 
-  static nsTPtrArray<const EnumTable>* sEnumTableArray;
+  static nsTPtrArray<const EnumTable, nsTArrayDefaultAllocator>* sEnumTableArray;
 
   PtrBits mBits;
 };
 
 /**
  * Implementation of inline methods
  */
 
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -4798,18 +4798,22 @@ static void ProcessViewportToken(nsIDocu
   while ((tip != end) && (*tip != '='))
     ++tip;
 
   /* If we didn't find an '=', punt. */
   if (tip == end)
     return;
 
   /* Extract the key and value. */
-  const nsAString &key = Substring(tail, tip);
-  const nsAString &value = Substring(++tip, end);
+  const nsAString &key =
+    nsContentUtils::TrimWhitespace<nsCRT::IsAsciiSpace>(Substring(tail, tip),
+                                                        PR_TRUE);
+  const nsAString &value =
+    nsContentUtils::TrimWhitespace<nsCRT::IsAsciiSpace>(Substring(++tip, end),
+                                                        PR_TRUE);
 
   /* Check for known keys. If we find a match, insert the appropriate
    * information into the document header. */
   nsCOMPtr<nsIAtom> key_atom = do_GetAtom(key);
   if (key_atom == nsGkAtoms::height)
     aDocument->SetHeaderData(nsGkAtoms::viewport_height, value);
   else if (key_atom == nsGkAtoms::width)
     aDocument->SetHeaderData(nsGkAtoms::viewport_width, value);
@@ -4818,50 +4822,63 @@ static void ProcessViewportToken(nsIDocu
   else if (key_atom == nsGkAtoms::minimum_scale)
     aDocument->SetHeaderData(nsGkAtoms::viewport_minimum_scale, value);
   else if (key_atom == nsGkAtoms::maximum_scale)
     aDocument->SetHeaderData(nsGkAtoms::viewport_maximum_scale, value);
   else if (key_atom == nsGkAtoms::user_scalable)
     aDocument->SetHeaderData(nsGkAtoms::viewport_user_scalable, value);
 }
 
-#define IS_SEPARATOR(c) ((c == ' ') || (c == ',') || (c == ';'))
+#define IS_SEPARATOR(c) ((c == '=') || (c == ',') || (c == ';') || \
+                         (c == '\t') || (c == '\n') || (c == '\r'))
+
 /* static */
 nsresult
 nsContentUtils::ProcessViewportInfo(nsIDocument *aDocument,
                                     const nsAString &viewportInfo) {
 
   /* We never fail. */
   nsresult rv = NS_OK;
 
   /* Iterators. */
   nsAString::const_iterator tip, tail, end;
   viewportInfo.BeginReading(tip);
   tail = tip;
   viewportInfo.EndReading(end);
 
   /* Read the tip to the first non-separator character. */
-  while ((tip != end) && IS_SEPARATOR(*tip))
+  while ((tip != end) && (IS_SEPARATOR(*tip) || nsCRT::IsAsciiSpace(*tip)))
     ++tip;
 
   /* Read through and find tokens separated by separators. */
   while (tip != end) {
-    
+
     /* Synchronize tip and tail. */
     tail = tip;
 
     /* Advance tip past non-separator characters. */
     while ((tip != end) && !IS_SEPARATOR(*tip))
       ++tip;
 
+    /* Allow white spaces that surround the '=' character */
+    if ((tip != end) && (*tip == '=')) {
+      ++tip;
+
+      while ((tip != end) && nsCRT::IsAsciiSpace(*tip))
+        ++tip;
+
+      while ((tip != end) && !(IS_SEPARATOR(*tip) || nsCRT::IsAsciiSpace(*tip)))
+        ++tip;
+    }
+
     /* Our token consists of the characters between tail and tip. */
     ProcessViewportToken(aDocument, Substring(tail, tip));
 
     /* Skip separators. */
-    while ((tip != end) && IS_SEPARATOR(*tip))
+    while ((tip != end) && (IS_SEPARATOR(*tip) || nsCRT::IsAsciiSpace(*tip)))
       ++tip;
   }
 
   return rv;
 
 }
 
 #undef IS_SEPARATOR
@@ -6281,16 +6298,50 @@ nsContentUtils::IsSubDocumentTabbable(ns
   contentViewer->GetPreviousViewer(getter_AddRefs(zombieViewer));
 
   // If there are 2 viewers for the current docshell, that
   // means the current document is a zombie document.
   // Only navigate into the subdocument if it's not a zombie.
   return !zombieViewer;
 }
 
+void
+nsContentUtils::FlushLayoutForTree(nsIDOMWindow* aWindow)
+{
+    nsCOMPtr<nsPIDOMWindow> piWin = do_QueryInterface(aWindow);
+    if (!piWin)
+        return;
+
+    // Note that because FlushPendingNotifications flushes parents, this
+    // is O(N^2) in docshell tree depth.  However, the docshell tree is
+    // usually pretty shallow.
+
+    nsCOMPtr<nsIDOMDocument> domDoc;
+    aWindow->GetDocument(getter_AddRefs(domDoc));
+    nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
+    if (doc) {
+        doc->FlushPendingNotifications(Flush_Layout);
+    }
+
+    nsCOMPtr<nsIDocShellTreeNode> node =
+        do_QueryInterface(piWin->GetDocShell());
+    if (node) {
+        PRInt32 i = 0, i_end;
+        node->GetChildCount(&i_end);
+        for (; i < i_end; ++i) {
+            nsCOMPtr<nsIDocShellTreeItem> item;
+            node->GetChildAt(i, getter_AddRefs(item));
+            nsCOMPtr<nsIDOMWindow> win = do_GetInterface(item);
+            if (win) {
+                FlushLayoutForTree(win);
+            }
+        }
+    }
+}
+
 void nsContentUtils::RemoveNewlines(nsString &aString)
 {
   // strip CR/LF and null
   static const char badChars[] = {'\r', '\n', 0};
   aString.StripChars(badChars);
 }
 
 void
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -200,16 +200,18 @@ static NS_DEFINE_CID(kDOMEventGroupCID, 
 #include "nsHTMLStyleSheet.h"
 #include "nsHTMLCSSStyleSheet.h"
 
 #include "mozilla/dom/Link.h"
 #include "nsIHTMLDocument.h"
 
 using namespace mozilla::dom;
 
+typedef nsTArray<Link*> LinkArray;
+
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo* gDocumentLeakPRLog;
 static PRLogModuleInfo* gCspPRLog;
 #endif
 
 #define NAME_NOT_VALID ((nsBaseContentList*)1)
 
@@ -3897,17 +3899,17 @@ nsDocument::InternalAllowXULXBL()
   return PR_FALSE;
 }
 
 // Note: We don't hold a reference to the document observer; we assume
 // that it has a live reference to the document.
 void
 nsDocument::AddObserver(nsIDocumentObserver* aObserver)
 {
-  NS_ASSERTION(mObservers.IndexOf(aObserver) == nsTArray_base::NoIndex,
+  NS_ASSERTION(mObservers.IndexOf(aObserver) == nsTArray<int>::NoIndex,
                "Observer already in the list");
   mObservers.AppendElement(aObserver);
   AddMutationObserver(aObserver);
 }
 
 PRBool
 nsDocument::RemoveObserver(nsIDocumentObserver* aObserver)
 {
@@ -4366,17 +4368,18 @@ nsDocument::CreateElementNS(const nsAStr
   nsresult rv = nsContentUtils::GetNodeInfoFromQName(aNamespaceURI,
                                                      aQualifiedName,
                                                      mNodeInfoManager,
                                                      getter_AddRefs(nodeInfo));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIContent> content;
   PRInt32 ns = nodeInfo->NamespaceID();
-  rv = NS_NewElement(getter_AddRefs(content), ns, nodeInfo.forget(), PR_FALSE);
+  rv = NS_NewElement(getter_AddRefs(content), ns, nodeInfo.forget(),
+                     NOT_FROM_PARSER);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return CallQueryInterface(content, aReturn);
 }
 
 NS_IMETHODIMP
 nsDocument::CreateTextNode(const nsAString& aData, nsIDOMText** aReturn)
 {
@@ -5537,16 +5540,21 @@ nsDocument::GetAnimationController()
   if (mAnimationController && shell) {
     nsPresContext *context = shell->GetPresContext();
     if (context &&
         context->ImageAnimationMode() == imgIContainer::kDontAnimMode) {
       mAnimationController->Pause(nsSMILTimeContainer::PAUSE_USERPREF);
     }
   }
 
+  // If we're hidden (or being hidden), notify the animation controller.
+  if (!mIsShowing) {
+    mAnimationController->OnPageHide();
+  }
+
   return mAnimationController;
 }
 #endif // MOZ_SMIL
 
 struct DirTable {
   const char* mName;
   PRUint8     mValue;
 };
@@ -6843,17 +6851,18 @@ nsDocument::CreateElem(const nsAString& 
   PRInt32 elementType = aDocumentDefaultType ? mDefaultElementType :
     aNamespaceID;
 
   nsCOMPtr<nsINodeInfo> nodeInfo;
   mNodeInfoManager->GetNodeInfo(aName, aPrefix, aNamespaceID,
                                 getter_AddRefs(nodeInfo));
   NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
 
-  return NS_NewElement(aResult, elementType, nodeInfo.forget(), PR_FALSE);
+  return NS_NewElement(aResult, elementType, nodeInfo.forget(),
+                       NOT_FROM_PARSER);
 }
 
 PRBool
 nsDocument::IsSafeToFlush() const
 {
   nsCOMPtr<nsIPresShell> shell = GetShell();
   if (!shell)
     return PR_TRUE;
@@ -7534,33 +7543,33 @@ nsDocument::DestroyElementMaps()
   mStyledLinks.Clear();
   mIdentifierMap.Clear();
 }
 
 static
 PLDHashOperator
 EnumerateStyledLinks(nsPtrHashKey<Link>* aEntry, void* aArray)
 {
-  nsTArray<Link*>* array = static_cast<nsTArray<Link*>*>(aArray);
+  LinkArray* array = static_cast<LinkArray*>(aArray);
   (void)array->AppendElement(aEntry->GetKey());
   return PL_DHASH_NEXT;
 }
 
 void
 nsDocument::RefreshLinkHrefs()
 {
   // Get a list of all links we know about.  We will reset them, which will
   // remove them from the document, so we need a copy of what is in the
   // hashtable.
-  nsTArray<Link*> linksToNotify(mStyledLinks.Count());
+  LinkArray linksToNotify(mStyledLinks.Count());
   (void)mStyledLinks.EnumerateEntries(EnumerateStyledLinks, &linksToNotify);
 
   // Reset all of our styled links.
   MOZ_AUTO_DOC_UPDATE(this, UPDATE_CONTENT_STATE, PR_TRUE);
-  for (nsTArray_base::size_type i = 0; i < linksToNotify.Length(); i++) {
+  for (LinkArray::size_type i = 0; i < linksToNotify.Length(); i++) {
     linksToNotify[i]->ResetLinkState(true);
   }
 }
 
 NS_IMETHODIMP
 nsDocument::GetScriptTypeID(PRUint32 *aScriptType)
 {
     NS_ERROR("No default script type here - ask some element");
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -914,16 +914,18 @@ public:
   nsTArray<nsCString> mFileDataUris;
 
 #ifdef MOZ_SMIL
   // Returns our (lazily-initialized) animation controller.
   // If HasAnimationController is true, this is guaranteed to return non-null.
   nsSMILAnimationController* GetAnimationController();
 #endif // MOZ_SMIL
 
+  void SetImagesNeedAnimating(PRBool aAnimating);
+
   virtual void SuppressEventHandling(PRUint32 aIncrease);
 
   virtual void UnsuppressEventHandlingAndFireEvents(PRBool aFireEvents);
   
   void DecreaseEventSuppression() { --mEventsSuppressed; }
 
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDocument,
                                                          nsIDocument)
@@ -1247,22 +1249,16 @@ private:
 
   // Tracking for images in the document.
   nsDataHashtable< nsPtrHashKey<imgIRequest>, PRUint32> mImageTracker;
 
 #ifdef DEBUG
 protected:
   PRBool mWillReparent;
 #endif
-
-protected:
-  // Makes the images on this document capable of having their animation
-  // active or suspended. An Image will animate as long as at least one of its
-  // owning Documents needs it to animate; otherwise it can suspend.
-  void SetImagesNeedAnimating(PRBool aAnimating);
 };
 
 #define NS_DOCUMENT_INTERFACE_TABLE_BEGIN(_class)                             \
   NS_NODE_OFFSET_AND_INTERFACE_TABLE_BEGIN(_class)                            \
   NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsIDOMDocument, nsDocument)      \
   NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsIDOMNSDocument, nsDocument)    \
   NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsIDOMDocumentEvent, nsDocument) \
   NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsIDOMDocumentView, nsDocument)  \
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -648,17 +648,28 @@ nsFrameLoader::Show(PRInt32 marginWidth,
 #ifdef MOZ_IPC
   if (mRemoteFrame) {
     return ShowRemoteFrame(GetSubDocumentSize(frame));
   }
 #endif
 
   nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(mDocShell);
   NS_ASSERTION(baseWindow, "Found a nsIDocShell that isn't a nsIBaseWindow.");
-  baseWindow->InitWindow(nsnull, view->GetWidget(), 0, 0, 10, 10);
+  nsIntSize size;
+  if (!(frame->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
+    // We have a useful size already; use it, since we might get no
+    // more size updates.
+    size = GetSubDocumentSize(frame);
+  } else {
+    // Pick some default size for now.  Using 10x10 because that's what the
+    // code here used to do.
+    size.SizeTo(10, 10);
+  }
+  baseWindow->InitWindow(nsnull, view->GetWidget(), 0, 0,
+                         size.width, size.height);
   // This is kinda whacky, this "Create()" call doesn't really
   // create anything, one starts to wonder why this was named
   // "Create"...
   baseWindow->Create();
   baseWindow->SetVisibility(PR_TRUE);
 
   // Trigger editor re-initialization if midas is turned on in the
   // sub-document. This shouldn't be necessary, but given the way our
@@ -707,18 +718,17 @@ nsFrameLoader::ShowRemoteFrame(const nsI
 
   // FIXME/bug 589337: Show()/Hide() is pretty expensive for
   // cross-process layers; need to figure out what behavior we really
   // want here.  For now, hack.
   if (!mRemoteBrowserShown) {
     mRemoteBrowser->Show(size);
     mRemoteBrowserShown = PR_TRUE;
 
-    nsCOMPtr<nsIChromeFrameMessageManager> dummy;
-    GetMessageManager(getter_AddRefs(dummy)); // Initialize message manager.
+    EnsureMessageManager();
   } else {
     mRemoteBrowser->Move(size);
   }
 
   return true;
 }
 #endif
 
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -229,17 +229,17 @@ nsFrameMessageManager::SendSyncMessage()
   NS_ASSERTION(!IsWindowLevel(), "Should not call SendSyncMessage in chrome");
   NS_ASSERTION(!mParentManager, "Should not have parent manager in content!");
   if (mSyncCallback) {
     NS_ENSURE_TRUE(mCallbackData, NS_ERROR_NOT_INITIALIZED);
     nsString messageName;
     nsString json;
     nsresult rv = GetParamsForMessage(messageName, json);
     NS_ENSURE_SUCCESS(rv, rv);
-    nsTArray<nsString> retval;
+    InfallibleTArray<nsString> retval;
     if (mSyncCallback(mCallbackData, messageName, json, &retval)) {
       nsAXPCNativeCallContext* ncc = nsnull;
       rv = nsContentUtils::XPConnect()->GetCurrentNativeCallContext(&ncc);
       NS_ENSURE_SUCCESS(rv, rv);
       NS_ENSURE_STATE(ncc);
 
       JSContext* ctx = nsnull;
       rv = ncc->GetJSContext(&ctx);
@@ -321,17 +321,17 @@ nsFrameMessageManager::GetDocShell(nsIDo
   return NS_OK;
 }
 
 nsresult
 nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
                                       const nsAString& aMessage,
                                       PRBool aSync, const nsAString& aJSON,
                                       JSObject* aObjectsArray,
-                                      nsTArray<nsString>* aJSONRetVal,
+                                      InfallibleTArray<nsString>* aJSONRetVal,
                                       JSContext* aContext)
 {
   JSContext* ctx = mContext ? mContext : aContext;
   if (!ctx) {
     nsContentUtils::ThreadJSContextStack()->GetSafeJSContext(&ctx);
   }
   if (mListeners.Length()) {
     nsCOMPtr<nsIAtom> name = do_GetAtom(aMessage);
@@ -737,17 +737,17 @@ bool SendAsyncMessageToChildProcess(void
     return cp->SendAsyncMessage(nsString(aMessage), nsString(aJSON));
   }
   return true;
 }
 
 bool SendSyncMessageToParentProcess(void* aCallbackData,
                                     const nsAString& aMessage,
                                     const nsAString& aJSON,
-                                    nsTArray<nsString>* aJSONRetVal)
+                                    InfallibleTArray<nsString>* aJSONRetVal)
 {
   mozilla::dom::ContentChild* cc =
     mozilla::dom::ContentChild::GetSingleton();
   if (cc) {
     return
       cc->SendSyncMessage(nsString(aMessage), nsString(aJSON), aJSONRetVal);
   }
   return true;
--- a/content/base/src/nsFrameMessageManager.h
+++ b/content/base/src/nsFrameMessageManager.h
@@ -61,17 +61,17 @@ struct nsMessageListenerInfo
   nsCOMPtr<nsIFrameMessageListener> mListener;
   nsCOMPtr<nsIAtom> mMessage;
 };
 
 typedef bool (*nsLoadScriptCallback)(void* aCallbackData, const nsAString& aURL);
 typedef bool (*nsSyncMessageCallback)(void* aCallbackData,
                                       const nsAString& aMessage,
                                       const nsAString& aJSON,
-                                      nsTArray<nsString>* aJSONRetVal);
+                                      InfallibleTArray<nsString>* aJSONRetVal);
 typedef bool (*nsAsyncMessageCallback)(void* aCallbackData,
                                        const nsAString& aMessage,
                                        const nsAString& aJSON);
 
 class nsFrameMessageManager : public nsIContentFrameMessageManager,
                               public nsIChromeFrameMessageManager
 {
 public:
@@ -124,17 +124,17 @@ public:
   NS_DECL_NSIFRAMEMESSAGEMANAGER
   NS_DECL_NSISYNCMESSAGESENDER
   NS_DECL_NSICONTENTFRAMEMESSAGEMANAGER
   NS_DECL_NSICHROMEFRAMEMESSAGEMANAGER
 
   nsresult ReceiveMessage(nsISupports* aTarget, const nsAString& aMessage,
                           PRBool aSync, const nsAString& aJSON,
                           JSObject* aObjectsArray,
-                          nsTArray<nsString>* aJSONRetVal,
+                          InfallibleTArray<nsString>* aJSONRetVal,
                           JSContext* aContext = nsnull);
   void AddChildManager(nsFrameMessageManager* aManager,
                        PRBool aLoadScripts = PR_TRUE);
   void RemoveChildManager(nsFrameMessageManager* aManager)
   {
     mChildManagers.RemoveObject(aManager);
   }
 
--- a/content/base/src/nsInProcessTabChildGlobal.cpp
+++ b/content/base/src/nsInProcessTabChildGlobal.cpp
@@ -49,17 +49,17 @@
 #include "nsScriptLoader.h"
 #include "nsIJSContextStack.h"
 #include "nsFrameLoader.h"
 #include "nsIPrivateDOMEvent.h"
 
 bool SendSyncMessageToParent(void* aCallbackData,
                              const nsAString& aMessage,
                              const nsAString& aJSON,
-                             nsTArray<nsString>* aJSONRetVal)
+                             InfallibleTArray<nsString>* aJSONRetVal)
 {
   nsInProcessTabChildGlobal* tabChild =
     static_cast<nsInProcessTabChildGlobal*>(aCallbackData);
   nsCOMPtr<nsIContent> owner = tabChild->mOwner;
   nsTArray<nsCOMPtr<nsIRunnable> > asyncMessages;
   asyncMessages.SwapElements(tabChild->mASyncMessages);
   PRUint32 len = asyncMessages.Length();
   for (PRUint32 i = 0; i < len; ++i) {
--- a/content/base/src/nsNameSpaceManager.cpp
+++ b/content/base/src/nsNameSpaceManager.cpp
@@ -52,16 +52,18 @@
 
 #ifdef MOZ_XTF
 #include "nsIServiceManager.h"
 #include "nsIXTFService.h"
 #include "nsContentUtils.h"
 static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
 #endif
 
+using namespace mozilla::dom;
+
 #ifdef MOZ_SVG
 PRBool NS_SVGEnabled();
 #endif
 
 #define kXMLNSNameSpaceURI "http://www.w3.org/2000/xmlns/"
 #define kXMLNameSpaceURI "http://www.w3.org/XML/1998/namespace"
 #define kXHTMLNameSpaceURI "http://www.w3.org/1999/xhtml"
 #define kXLinkNameSpaceURI "http://www.w3.org/1999/xlink"
@@ -222,17 +224,17 @@ NameSpaceManagerImpl::GetNameSpaceID(con
     return nameSpaceID;
   }
 
   return kNameSpaceID_Unknown;
 }
 
 nsresult
 NS_NewElement(nsIContent** aResult, PRInt32 aElementType,
-              already_AddRefed<nsINodeInfo> aNodeInfo, PRUint32 aFromParser)
+              already_AddRefed<nsINodeInfo> aNodeInfo, FromParser aFromParser)
 {
   if (aElementType == kNameSpaceID_XHTML) {
     return NS_NewHTMLElement(aResult, aNodeInfo, aFromParser);
   }
 #ifdef MOZ_XUL
   if (aElementType == kNameSpaceID_XUL) {
     return NS_NewXULElement(aResult, aNodeInfo);
   }
--- a/content/base/src/nsReferencedElement.cpp
+++ b/content/base/src/nsReferencedElement.cpp
@@ -100,44 +100,55 @@ nsReferencedElement::Reset(nsIContent* a
   if (ref.IsEmpty())
     return;
 
   // Get the current document
   nsIDocument *doc = aFromContent->GetCurrentDoc();
   if (!doc)
     return;
 
-  // This will be the URI of the document the content belongs to
-  // (the URI of the XBL document if the content is anonymous
-  // XBL content)
-  nsCOMPtr<nsIURL> documentURL = do_QueryInterface(doc->GetDocumentURI());
   nsIContent* bindingParent = aFromContent->GetBindingParent();
-  PRBool isXBL = PR_FALSE;
   if (bindingParent) {
     nsXBLBinding* binding = doc->BindingManager()->GetBinding(bindingParent);
     if (binding) {
-      // XXX sXBL/XBL2 issue
-      // If this is an anonymous XBL element then the URI is
-      // relative to the binding document. A full fix requires a
-      // proper XBL2 implementation but for now URIs that are
-      // relative to the binding document should be resolve to the
-      // copy of the target element that has been inserted into the
-      // bound document.
-      documentURL = do_QueryInterface(binding->PrototypeBinding()->DocURI());
-      isXBL = PR_TRUE;
+      nsCOMPtr<nsIURL> bindingDocumentURL =
+        do_QueryInterface(binding->PrototypeBinding()->DocURI());
+      if (EqualExceptRef(url, bindingDocumentURL)) {
+        // XXX sXBL/XBL2 issue
+        // Our content is an anonymous XBL element from a binding inside the
+        // same document that the referenced URI points to. In order to avoid
+        // the risk of ID collisions we restrict ourselves to anonymous
+        // elements from this binding; specifically, URIs that are relative to
+        // the binding document should resolve to the copy of the target
+        // element that has been inserted into the bound document.
+        // If the URI points to a different document we don't need this
+        // restriction.
+        nsINodeList* anonymousChildren =
+          doc->BindingManager()->GetAnonymousNodesFor(bindingParent);
+
+        if (anonymousChildren) {
+          PRUint32 length;
+          anonymousChildren->GetLength(&length);
+          for (PRUint32 i = 0; i < length && !mElement; ++i) {
+            mElement =
+              nsContentUtils::MatchElementId(anonymousChildren->GetNodeAt(i), ref);
+          }
+        }
+
+        // We don't have watching working yet for XBL, so bail out here.
+        return;
+      }
     }
   }
+
+  nsCOMPtr<nsIURL> documentURL = do_QueryInterface(doc->GetDocumentURI());
   if (!documentURL)
     return;
 
   if (!EqualExceptRef(url, documentURL)) {
-    // Don't take the XBL codepath here, since we'll want to just
-    // normally set up our external resource document and then watch
-    // it as needed.
-    isXBL = PR_FALSE;
     nsRefPtr<nsIDocument::ExternalResourceLoad> load;
     doc = doc->RequestExternalResource(url, aFromContent, getter_AddRefs(load));
     if (!doc) {
       if (!load || !aWatch) {
         // Nothing will ever happen here
         return;
       }
 
@@ -146,34 +157,16 @@ nsReferencedElement::Reset(nsIContent* a
       mPendingNotification = observer;
       if (observer) {
         load->AddObserver(observer);
       }
       // Keep going so we set up our watching stuff a bit
     }
   }
 
-  // Get the element
-  if (isXBL) {
-    nsINodeList* anonymousChildren =
-      doc->BindingManager()-> GetAnonymousNodesFor(bindingParent);
-
-    if (anonymousChildren) {
-      PRUint32 length;
-      anonymousChildren->GetLength(&length);
-      for (PRUint32 i = 0; i < length && !mElement; ++i) {
-        mElement =
-          nsContentUtils::MatchElementId(anonymousChildren->GetNodeAt(i), ref);
-      }
-    }
-
-    // We don't have watching working yet for XBL, so bail out here.
-    return;
-  }
-
   if (aWatch) {
     nsCOMPtr<nsIAtom> atom = do_GetAtom(ref);
     if (!atom)
       return;
     atom.swap(mWatchID);
   }
 
   mReferencingImage = aReferenceImage;
--- a/content/base/src/nsScriptElement.cpp
+++ b/content/base/src/nsScriptElement.cpp
@@ -10,17 +10,17 @@
  * Software distributed under the License is distributed on an "AS IS" basis,
  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  * for the specific language governing rights and limitations under the
  * License.
  *
  * The Original Code is Mozilla Code.
  *
  * The Initial Developer of the Original Code is
- * Mozilla Corporation.
+ * the Mozilla Foundation.
  * Portions created by the Initial Developer are Copyright (C) 2006
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Jonas Sicking <jonas@sicking.cc> (original developer)
  *
  * 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
@@ -141,65 +141,35 @@ void
 nsScriptElement::ContentInserted(nsIDocument *aDocument,
                                  nsIContent* aContainer,
                                  nsIContent* aChild,
                                  PRInt32 aIndexInContainer)
 {
   MaybeProcessScript();
 }
 
-static PRBool
-InNonScriptingContainer(nsIContent* aNode)
-{
-  aNode = aNode->GetParent();
-  while (aNode) {
-    // XXX noframes and noembed are currently unconditionally not
-    // displayed and processed. This might change if we support either
-    // prefs or per-document container settings for not allowing
-    // frames or plugins.
-    if (aNode->IsHTML()) {
-      nsIAtom *localName = aNode->Tag();
-      if (localName == nsGkAtoms::iframe ||
-          localName == nsGkAtoms::noframes ||
-          localName == nsGkAtoms::noembed) {
-        return PR_TRUE;
-      }
-    }
-    aNode = aNode->GetParent();
-  }
-
-  return PR_FALSE;
-}
-
 nsresult
 nsScriptElement::MaybeProcessScript()
 {
   nsCOMPtr<nsIContent> cont =
     do_QueryInterface((nsIScriptElement*) this);
 
   NS_ASSERTION(cont->DebugGetSlots()->mMutationObservers.Contains(this),
                "You forgot to add self as observer");
 
   if (mAlreadyStarted || !mDoneAddingChildren || !cont->IsInDoc() ||
       mMalformed || !HasScriptContent()) {
     return NS_OK;
   }
 
   FreezeUriAsyncDefer();
 
-  if (InNonScriptingContainer(cont)) {
-    // Make