Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Fri, 23 Mar 2012 14:50:35 -0700
changeset 106086 70001f01a139bc441644a82a45e60a92377cf114
parent 106085 dec79c24caa37f43922e6adad91598c56f222908 (current diff)
parent 90212 6470fe2fc4de48077605605aa052448c6586b7a6 (diff)
child 106087 4c9a4636a9aa1ca3f22bde2601dcebaddde1e607
push id14706
push usereakhgari@mozilla.com
push dateTue, 11 Sep 2012 20:39:52 +0000
treeherdermozilla-inbound@d50bf1edaabe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone14.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge from mozilla-central.
accessible/public/nsIAccessibilityService.h
accessible/src/base/AccEvent.cpp
accessible/src/base/AccIterator.cpp
accessible/src/base/AccIterator.h
accessible/src/base/nsARIAMap.cpp
accessible/src/base/nsAccessibilityService.cpp
accessible/src/base/nsAccessibilityService.h
accessible/src/base/nsAccessible.cpp
accessible/src/base/nsDocAccessible.cpp
accessible/src/base/nsTextEquivUtils.cpp
accessible/src/html/nsHTMLTableAccessible.cpp
accessible/tests/mochitest/events.js
accessible/tests/mochitest/events/Makefile.in
b2g/confvars.sh
b2g/installer/package-manifest.in
browser/base/content/browser.js
build/mobile/devicemanagerADB.py
config/autoconf.mk.in
configure.in
content/base/public/nsIContent.h
content/base/public/nsIDocument.h
content/base/src/nsAttrAndChildArray.cpp
content/base/src/nsAttrAndChildArray.h
content/base/src/nsContentList.cpp
content/base/src/nsContentSink.cpp
content/base/src/nsCrossSiteListenerProxy.cpp
content/base/src/nsDocument.cpp
content/base/src/nsDocument.h
content/base/src/nsGenericElement.cpp
content/base/src/nsGkAtomList.h
content/base/src/nsMappedAttributeElement.cpp
content/base/src/nsMappedAttributeElement.h
content/base/src/nsNodeUtils.cpp
content/base/src/nsNodeUtils.h
content/base/src/nsObjectLoadingContent.cpp
content/base/src/nsObjectLoadingContent.h
content/base/src/nsRange.cpp
content/base/src/nsScriptLoader.cpp
content/base/src/nsStyledElement.cpp
content/base/src/nsStyledElement.h
content/base/src/nsXMLContentSerializer.h
content/base/src/nsXMLHttpRequest.cpp
content/base/test/Makefile.in
content/html/content/src/nsHTMLMediaElement.cpp
content/html/content/src/nsHTMLObjectElement.cpp
content/html/content/src/nsHTMLSharedObjectElement.cpp
content/html/document/src/MediaDocument.cpp
content/html/document/src/nsHTMLContentSink.cpp
content/smil/nsSMILAnimationFunction.cpp
content/smil/nsSMILTimedElement.cpp
content/xbl/src/nsBindingManager.cpp
content/xbl/src/nsXBLBinding.cpp
content/xbl/src/nsXBLContentSink.cpp
content/xbl/src/nsXBLDocumentInfo.cpp
content/xbl/src/nsXBLDocumentInfo.h
content/xbl/src/nsXBLPrototypeBinding.cpp
content/xbl/src/nsXBLService.cpp
content/xml/document/src/nsXMLDocument.cpp
content/xml/document/src/nsXMLFragmentContentSink.cpp
content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp
content/xslt/src/xslt/txMozillaTextOutput.cpp
content/xslt/src/xslt/txMozillaXMLOutput.cpp
content/xul/document/src/nsXULContentSink.cpp
content/xul/document/src/nsXULDocument.cpp
content/xul/templates/src/nsXULTemplateBuilder.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMWindowUtils.cpp
dom/interfaces/base/nsIDOMWindowUtils.idl
dom/system/nsDeviceMotion.cpp
dom/system/nsDeviceMotion.h
dom/workers/WorkerPrivate.cpp
editor/libeditor/html/nsHTMLDataTransfer.cpp
gfx/gl/GLContextProviderEGL.cpp
gfx/layers/basic/BasicLayers.cpp
gfx/layers/d3d10/CanvasLayerD3D10.cpp
gfx/layers/d3d10/CanvasLayerD3D10.h
gfx/layers/d3d9/CanvasLayerD3D9.cpp
gfx/layers/d3d9/CanvasLayerD3D9.h
gfx/layers/opengl/CanvasLayerOGL.cpp
gfx/layers/opengl/CanvasLayerOGL.h
gfx/layers/opengl/ImageLayerOGL.cpp
gfx/layers/opengl/LayerManagerOGL.h
gfx/thebes/gfxFont.h
gfx/thebes/gfxQtPlatform.cpp
gfx/thebes/gfxQtPlatform.h
gfx/ycbcr/QuellGccWarnings.patch
image/src/imgRequest.cpp
image/test/mochitest/Makefile.in
js/src/configure.in
js/src/jsapi.cpp
js/src/jsarray.cpp
js/src/jsgc.cpp
js/src/jsscript.cpp
js/src/jsscript.h
js/src/jstypedarray.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsCSSFrameConstructor.h
layout/base/nsDocumentViewer.cpp
layout/base/nsPresShell.cpp
layout/build/nsContentDLF.cpp
layout/generic/nsHTMLReflowMetrics.h
layout/printing/nsPrintEngine.cpp
layout/style/nsAnimationManager.cpp
layout/svg/base/src/nsSVGOuterSVGFrame.h
layout/tools/reftest/remotereftest.py
memory/jemalloc/jemalloc.c
memory/jemalloc/jemalloc.h
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoAppShell.java
mobile/android/base/Makefile.in
modules/libpref/public/Preferences.h
modules/libpref/src/Preferences.cpp
modules/libpref/src/init/all.js
mozglue/android/APKOpen.cpp
netwerk/cache/nsCacheService.cpp
netwerk/cache/nsCacheService.h
netwerk/cache/nsCacheSession.cpp
netwerk/protocol/ftp/nsFtpConnectionThread.cpp
netwerk/protocol/http/SpdySession.cpp
netwerk/protocol/http/SpdySession.h
netwerk/protocol/http/nsAHttpConnection.h
netwerk/protocol/http/nsAHttpTransaction.h
netwerk/protocol/http/nsHttp.cpp
netwerk/protocol/http/nsHttp.h
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpChannel.h
netwerk/protocol/http/nsHttpConnection.cpp
netwerk/protocol/http/nsHttpConnection.h
netwerk/protocol/http/nsHttpConnectionInfo.cpp
netwerk/protocol/http/nsHttpConnectionInfo.h
netwerk/protocol/http/nsHttpConnectionMgr.cpp
netwerk/protocol/http/nsHttpConnectionMgr.h
netwerk/protocol/http/nsHttpHandler.cpp
netwerk/protocol/http/nsHttpHandler.h
netwerk/protocol/http/nsHttpPipeline.cpp
netwerk/protocol/http/nsHttpPipeline.h
netwerk/protocol/http/nsHttpTransaction.cpp
netwerk/protocol/http/nsHttpTransaction.h
netwerk/protocol/wyciwyg/WyciwygChannelChild.cpp
netwerk/protocol/wyciwyg/nsWyciwygChannel.cpp
netwerk/wifi/nsWifiScannerWin.cpp
parser/html/nsHtml5StreamParser.cpp
parser/html/nsHtml5TreeOpExecutor.cpp
parser/html/nsHtml5TreeOpExecutor.h
parser/htmlparser/public/nsIHTMLContentSink.h
parser/htmlparser/public/nsIParser.h
parser/htmlparser/src/CNavDTD.h
parser/htmlparser/src/nsParser.cpp
parser/htmlparser/src/nsScanner.cpp
parser/xml/src/nsSAXXMLReader.cpp
testing/mochitest/runtestsremote.py
testing/xpcshell/xpcshell.ini
toolkit/components/downloads/nsDownloadManager.cpp
toolkit/components/downloads/nsDownloadManager.h
toolkit/components/places/nsNavHistoryQuery.cpp
widget/windows/nsWinGesture.h
widget/windows/nsWindowDefs.h
xpcom/base/nsStackWalk.cpp
xpfe/appshell/src/nsXULWindow.cpp
--- a/accessible/public/nsIAccessibilityService.h
+++ b/accessible/public/nsIAccessibilityService.h
@@ -158,22 +158,16 @@ public:
 
   /**
    * Notify the accessibility service that the given presshell is
    * being destroyed.
    */
   virtual void PresShellDestroyed(nsIPresShell *aPresShell) = 0;
 
   /**
-   * Recreate an accessible for the given content node in the presshell.
-   */
-  virtual void RecreateAccessible(nsIPresShell* aPresShell,
-                                  nsIContent* aContent) = 0;
-
-  /**
    * Fire accessible event of the given type for the given target.
    *
    * @param aEvent   [in] accessible event type
    * @param aTarget  [in] target of accessible event
    */
   virtual void FireAccessibleEvent(PRUint32 aEvent, nsAccessible* aTarget) = 0;
 };
 
--- a/accessible/src/base/AccEvent.cpp
+++ b/accessible/src/base/AccEvent.cpp
@@ -43,24 +43,27 @@
 #include "nsAccUtils.h"
 #include "nsApplicationAccessibleWrap.h"
 #include "nsDocAccessible.h"
 #include "nsIAccessibleText.h"
 #ifdef MOZ_XUL
 #include "nsXULTreeAccessible.h"
 #endif
 #include "nsAccEvent.h"
+#include "States.h"
 
 #include "nsIDOMDocument.h"
 #include "nsEventStateManager.h"
 #include "nsIServiceManager.h"
 #ifdef MOZ_XUL
 #include "nsIDOMXULMultSelectCntrlEl.h"
 #endif
 
+using namespace mozilla::a11y;
+
 ////////////////////////////////////////////////////////////////////////////////
 // AccEvent
 ////////////////////////////////////////////////////////////////////////////////
 
 ////////////////////////////////////////////////////////////////////////////////
 // AccEvent constructors
 
 AccEvent::AccEvent(PRUint32 aEventType, nsAccessible* aAccessible,
@@ -249,16 +252,20 @@ AccTextChangeEvent::
   : AccEvent(aIsInserted ?
              static_cast<PRUint32>(nsIAccessibleEvent::EVENT_TEXT_INSERTED) :
              static_cast<PRUint32>(nsIAccessibleEvent::EVENT_TEXT_REMOVED),
              aAccessible, aIsFromUserInput, eAllowDupes)
   , mStart(aStart)
   , mIsInserted(aIsInserted)
   , mModifiedText(aModifiedText)
 {
+  // XXX We should use IsFromUserInput here, but that isn't always correct
+  // when the text change isn't related to content insertion or removal.
+   mIsFromUserInput = mAccessible->State() &
+    (states::FOCUSED | states::EDITABLE);
 }
 
 already_AddRefed<nsAccEvent>
 AccTextChangeEvent::CreateXPCOMObject()
 {
   nsAccEvent* event = new nsAccTextChangeEvent(this);
   NS_IF_ADDREF(event);
   return event;
--- a/accessible/src/base/AccIterator.cpp
+++ b/accessible/src/base/AccIterator.cpp
@@ -272,18 +272,20 @@ XULDescriptionIterator::Next()
 
   return nsnull;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // IDRefsIterator
 ////////////////////////////////////////////////////////////////////////////////
 
-IDRefsIterator::IDRefsIterator(nsIContent* aContent, nsIAtom* aIDRefsAttr) :
-  mCurrIdx(0), mContent(aContent)
+IDRefsIterator::
+  IDRefsIterator(nsDocAccessible* aDoc, nsIContent* aContent,
+                 nsIAtom* aIDRefsAttr) :
+  mCurrIdx(0), mContent(aContent), mDoc(aDoc)
 {
   if (mContent->IsInDoc())
     mContent->GetAttr(kNameSpaceID_None, aIDRefsAttr, mIDs);
 }
 
 const nsDependentSubstring
 IDRefsIterator::NextID()
 {
@@ -363,17 +365,17 @@ IDRefsIterator::GetElem(const nsDependen
 
   return nsnull;
 }
 
 nsAccessible*
 IDRefsIterator::Next()
 {
   nsIContent* nextElm = NextElem();
-  return nextElm ? GetAccService()->GetAccessible(nextElm, nsnull) : nsnull;
+  return nextElm ? mDoc->GetAccessible(nextElm) : nsnull;
 }
 
 nsAccessible*
 SingleAccIterator::Next()
 {
   nsRefPtr<nsAccessible> nextAcc;
   mAcc.swap(nextAcc);
   return (nextAcc && !nextAcc->IsDefunct()) ? nextAcc : nsnull;
--- a/accessible/src/base/AccIterator.h
+++ b/accessible/src/base/AccIterator.h
@@ -259,17 +259,18 @@ private:
 /**
  * Used to iterate through IDs, elements or accessibles pointed by IDRefs
  * attribute. Note, any method used to iterate through IDs, elements, or
  * accessibles moves iterator to next position.
  */
 class IDRefsIterator : public AccIterable
 {
 public:
-  IDRefsIterator(nsIContent* aContent, nsIAtom* aIDRefsAttr);
+  IDRefsIterator(nsDocAccessible* aDoc, nsIContent* aContent,
+                 nsIAtom* aIDRefsAttr);
   virtual ~IDRefsIterator() { }
 
   /**
    * Return next ID.
    */
   const nsDependentSubstring NextID();
 
   /**
@@ -287,16 +288,17 @@ public:
 
 private:
   IDRefsIterator();
   IDRefsIterator(const IDRefsIterator&);
   IDRefsIterator operator = (const IDRefsIterator&);
 
   nsString mIDs;
   nsIContent* mContent;
+  nsDocAccessible* mDoc;
   nsAString::index_type mCurrIdx;
 };
 
 /**
  * Iterator that points to a single accessible returning it on the first call
  * to Next().
  */
 class SingleAccIterator : public AccIterable
--- a/accessible/src/base/nsARIAMap.cpp
+++ b/accessible/src/base/nsARIAMap.cpp
@@ -331,16 +331,25 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] 
     kUseMapRole,
     eNoValue,
     eClickAction,
     eNoLiveAttr,
     kNoReqStates,
     eARIACheckableBool
   },
   {
+    "note",
+    roles::NOTE,
+    kUseMapRole,
+    eNoValue,
+    eNoAction,
+    eNoLiveAttr,
+    kNoReqStates
+  },
+  {
     "option",
     roles::OPTION,
     kUseMapRole,
     eNoValue,
     eSelectAction,
     eNoLiveAttr,
     kNoReqStates,
     eARIASelectable,
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -671,20 +671,18 @@ nsAccessibilityService::PresShellActivat
   }
 }
 
 void
 nsAccessibilityService::RecreateAccessible(nsIPresShell* aPresShell,
                                            nsIContent* aContent)
 {
   nsDocAccessible* document = GetDocAccessible(aPresShell->GetDocument());
-  if (document) {
-    document->HandleNotification<nsDocAccessible, nsIContent>
-      (document, &nsDocAccessible::RecreateAccessible, aContent);
-  }
+  if (document)
+    document->RecreateAccessible(aContent);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessibleRetrieval
 
 NS_IMETHODIMP
 nsAccessibilityService::GetApplicationAccessible(nsIAccessible **aAccessibleApplication)
 {
--- a/accessible/src/base/nsAccessibilityService.h
+++ b/accessible/src/base/nsAccessibilityService.h
@@ -168,18 +168,20 @@ public:
 
   virtual void PresShellDestroyed(nsIPresShell* aPresShell);
 
   /**
    * Notify that presshell is activated.
    */
   virtual void PresShellActivated(nsIPresShell* aPresShell);
 
-  virtual void RecreateAccessible(nsIPresShell* aPresShell,
-                                  nsIContent* aContent);
+  /**
+   * Recreate an accessible for the given content node in the presshell.
+   */
+  void RecreateAccessible(nsIPresShell* aPresShell, nsIContent* aContent);
 
   virtual void FireAccessibleEvent(PRUint32 aEvent, nsAccessible* aTarget);
 
   // nsAccessibiltiyService
 
   /**
    * Return true if accessibility service has been shutdown.
    */
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -2010,51 +2010,51 @@ nsAccessible::RelationByType(PRUint32 aT
 {
   // Relationships are defined on the same content node that the role would be
   // defined on.
   switch (aType) {
     case nsIAccessibleRelation::RELATION_LABEL_FOR: {
       Relation rel(new RelatedAccIterator(Document(), mContent,
                                           nsGkAtoms::aria_labelledby));
       if (mContent->Tag() == nsGkAtoms::label)
-        rel.AppendIter(new IDRefsIterator(mContent, mContent->IsHTML() ?
+        rel.AppendIter(new IDRefsIterator(mDoc, mContent, mContent->IsHTML() ?
                                           nsGkAtoms::_for :
                                           nsGkAtoms::control));
 
       return rel;
     }
     case nsIAccessibleRelation::RELATION_LABELLED_BY: {
-      Relation rel(new IDRefsIterator(mContent,
+      Relation rel(new IDRefsIterator(mDoc, mContent,
                                       nsGkAtoms::aria_labelledby));
       if (mContent->IsHTML()) {
         rel.AppendIter(new HTMLLabelIterator(Document(), this));
       } else if (mContent->IsXUL()) {
         rel.AppendIter(new XULLabelIterator(Document(), mContent));
       }
 
       return rel;
     }
     case nsIAccessibleRelation::RELATION_DESCRIBED_BY: {
-      Relation rel(new IDRefsIterator(mContent,
-                                        nsGkAtoms::aria_describedby));
+      Relation rel(new IDRefsIterator(mDoc, mContent,
+                                      nsGkAtoms::aria_describedby));
       if (mContent->IsXUL())
         rel.AppendIter(new XULDescriptionIterator(Document(), mContent));
 
       return rel;
     }
     case nsIAccessibleRelation::RELATION_DESCRIPTION_FOR: {
       Relation rel(new RelatedAccIterator(Document(), mContent,
                                           nsGkAtoms::aria_describedby));
 
       // This affectively adds an optional control attribute to xul:description,
       // which only affects accessibility, by allowing the description to be
       // tied to a control.
       if (mContent->Tag() == nsGkAtoms::description &&
           mContent->IsXUL())
-        rel.AppendIter(new IDRefsIterator(mContent,
+        rel.AppendIter(new IDRefsIterator(mDoc, mContent,
                                           nsGkAtoms::control));
 
       return rel;
     }
     case nsIAccessibleRelation::RELATION_NODE_CHILD_OF: {
       Relation rel(new RelatedAccIterator(Document(), mContent,
                                           nsGkAtoms::aria_owns));
       
@@ -2086,23 +2086,23 @@ nsAccessible::RelationByType(PRUint32 aT
       }
 
       return rel;
     }
     case nsIAccessibleRelation::RELATION_CONTROLLED_BY:
       return Relation(new RelatedAccIterator(Document(), mContent,
                                              nsGkAtoms::aria_controls));
     case nsIAccessibleRelation::RELATION_CONTROLLER_FOR: {
-      Relation rel(new IDRefsIterator(mContent,
+      Relation rel(new IDRefsIterator(mDoc, mContent,
                                       nsGkAtoms::aria_controls));
       rel.AppendIter(new HTMLOutputIterator(Document(), mContent));
       return rel;
     }
     case nsIAccessibleRelation::RELATION_FLOWS_TO:
-      return Relation(new IDRefsIterator(mContent,
+      return Relation(new IDRefsIterator(mDoc, mContent,
                                          nsGkAtoms::aria_flowto));
     case nsIAccessibleRelation::RELATION_FLOWS_FROM:
       return Relation(new RelatedAccIterator(Document(), mContent,
                                              nsGkAtoms::aria_flowto));
     case nsIAccessibleRelation::RELATION_DEFAULT_BUTTON: {
       if (mContent->IsHTML()) {
         // HTML form controls implements nsIFormControl interface.
         nsCOMPtr<nsIFormControl> control(do_QueryInterface(mContent));
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -1462,24 +1462,18 @@ nsDocAccessible::ContentRemoved(nsIConte
 void
 nsDocAccessible::RecreateAccessible(nsIContent* aContent)
 {
   // XXX: we shouldn't recreate whole accessible subtree, instead we should
   // subclass hide and show events to handle them separately and implement their
   // coalescence with normal hide and show events. Note, in this case they
   // should be coalesced with normal show/hide events.
 
-  // Check if the node is in accessible document.
-  nsAccessible* container = GetContainerAccessible(aContent);
-  if (container) {
-    // Remove and reinsert.
-    UpdateTree(container, aContent, false);
-    container->UpdateChildren();
-    UpdateTree(container, aContent, true);
-  }
+  ContentRemoved(aContent->GetParent(), aContent);
+  ContentInserted(aContent->GetParent(), aContent, aContent->GetNextSibling());
 }
 
 void
 nsDocAccessible::ProcessInvalidationList()
 {
   // Invalidate children of container accessible for each element in
   // invalidation list. Allow invalidation list insertions while container
   // children are recached.
@@ -1618,17 +1612,17 @@ nsDocAccessible::AddDependentIDsFor(nsAc
 
     } else if (relAttr == nsGkAtoms::control) {
       if (!aRelProvider->GetContent()->IsXUL() ||
           (aRelProvider->GetContent()->Tag() != nsGkAtoms::label &&
            aRelProvider->GetContent()->Tag() != nsGkAtoms::description))
         continue;
     }
 
-    IDRefsIterator iter(aRelProvider->GetContent(), relAttr);
+    IDRefsIterator iter(this, aRelProvider->GetContent(), relAttr);
     while (true) {
       const nsDependentSubstring id = iter.NextID();
       if (id.IsEmpty())
         break;
 
       AttrRelProviderArray* providers = mDependentIDsHash.Get(id);
       if (!providers) {
         providers = new AttrRelProviderArray();
@@ -1669,17 +1663,17 @@ void
 nsDocAccessible::RemoveDependentIDsFor(nsAccessible* aRelProvider,
                                        nsIAtom* aRelAttr)
 {
   for (PRUint32 idx = 0; idx < kRelationAttrsLen; idx++) {
     nsIAtom* relAttr = *kRelationAttrs[idx];
     if (aRelAttr && aRelAttr != *kRelationAttrs[idx])
       continue;
 
-    IDRefsIterator iter(aRelProvider->GetContent(), relAttr);
+    IDRefsIterator iter(this, aRelProvider->GetContent(), relAttr);
     while (true) {
       const nsDependentSubstring id = iter.NextID();
       if (id.IsEmpty())
         break;
 
       AttrRelProviderArray* providers = mDependentIDsHash.Get(id);
       if (providers) {
         for (PRUint32 jdx = 0; jdx < providers->Length(); ) {
@@ -1712,43 +1706,39 @@ nsDocAccessible::UpdateAccessibleOnAttrC
     if (mContent == aElement) {
       SetRoleMapEntry(nsAccUtils::GetRoleMapEntry(aElement));
       return true;
     }
 
     // Recreate the accessible when role is changed because we might require a
     // different accessible class for the new role or the accessible may expose
     // a different sets of interfaces (COM restriction).
-    HandleNotification<nsDocAccessible, nsIContent>
-      (this, &nsDocAccessible::RecreateAccessible, aElement);
+    RecreateAccessible(aElement);
 
     return true;
   }
 
   if (aAttribute == nsGkAtoms::href ||
       aAttribute == nsGkAtoms::onclick) {
     // Not worth the expense to ensure which namespace these are in. It doesn't
     // kill use to recreate the accessible even if the attribute was used in
     // the wrong namespace or an element that doesn't support it.
 
-    // Recreate accessible asynchronously to allow the content to handle
-    // the attribute change.
-    mNotificationController->ScheduleNotification<nsDocAccessible, nsIContent>
-      (this, &nsDocAccessible::RecreateAccessible, aElement);
-
+    // Make sure the accessible is recreated asynchronously to allow the content
+    // to handle the attribute change.
+    RecreateAccessible(aElement);
     return true;
   }
 
   if (aAttribute == nsGkAtoms::aria_multiselectable &&
       aElement->HasAttr(kNameSpaceID_None, nsGkAtoms::role)) {
     // This affects whether the accessible supports SelectAccessible.
     // COM says we cannot change what interfaces are supported on-the-fly,
     // so invalidate this object. A new one will be created on demand.
-    HandleNotification<nsDocAccessible, nsIContent>
-      (this, &nsDocAccessible::RecreateAccessible, aElement);
+    RecreateAccessible(aElement);
 
     return true;
   }
 
   return false;
 }
 
 // nsDocAccessible public member
--- a/accessible/src/base/nsTextEquivUtils.cpp
+++ b/accessible/src/base/nsTextEquivUtils.cpp
@@ -89,17 +89,17 @@ nsTextEquivUtils::GetTextEquivFromIDRefs
 {
   aTextEquiv.Truncate();
 
   nsIContent* content = aAccessible->GetContent();
   if (!content)
     return NS_OK;
 
   nsIContent* refContent = nsnull;
-  IDRefsIterator iter(content, aIDRefsAttr);
+  IDRefsIterator iter(aAccessible->Document(), content, aIDRefsAttr);
   while ((refContent = iter.NextElem())) {
     if (!aTextEquiv.IsEmpty())
       aTextEquiv += ' ';
 
     nsresult rv = AppendTextEquivFromContent(aAccessible, refContent,
                                              &aTextEquiv);
     NS_ENSURE_SUCCESS(rv, rv);
   }
--- a/accessible/src/html/nsHTMLTableAccessible.cpp
+++ b/accessible/src/html/nsHTMLTableAccessible.cpp
@@ -329,17 +329,17 @@ nsHTMLTableCellAccessible::GetCellIndexe
   return cellLayout->GetCellIndexes(aRowIndex, aColIndex);
 }
 
 nsresult
 nsHTMLTableCellAccessible::GetHeaderCells(PRInt32 aRowOrColumnHeaderCell,
                                           nsIArray **aHeaderCells)
 {
   // Get header cells from @header attribute.
-  IDRefsIterator iter(mContent, nsGkAtoms::headers);
+  IDRefsIterator iter(mDoc, mContent, nsGkAtoms::headers);
   nsIContent* headerCellElm = iter.NextElem();
   if (headerCellElm) {
     nsresult rv = NS_OK;
     nsCOMPtr<nsIMutableArray> headerCells =
       do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
     roles::Role desiredRole = static_cast<roles::Role>(-1) ;
     if (aRowOrColumnHeaderCell == nsAccUtils::eRowHeaderCells)
--- a/accessible/src/html/nsHTMLTextAccessible.cpp
+++ b/accessible/src/html/nsHTMLTextAccessible.cpp
@@ -199,17 +199,17 @@ nsHTMLOutputAccessible::
 
 NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLOutputAccessible, nsHyperTextAccessible)
 
 Relation
 nsHTMLOutputAccessible::RelationByType(PRUint32 aType)
 {
   Relation rel = nsAccessibleWrap::RelationByType(aType);
   if (aType == nsIAccessibleRelation::RELATION_CONTROLLED_BY)
-    rel.AppendIter(new IDRefsIterator(mContent, nsGkAtoms::_for));
+    rel.AppendIter(new IDRefsIterator(mDoc, mContent, nsGkAtoms::_for));
 
   return rel;
 }
 
 role
 nsHTMLOutputAccessible::NativeRole()
 {
   return roles::SECTION;
--- a/accessible/tests/mochitest/events.js
+++ b/accessible/tests/mochitest/events.js
@@ -24,16 +24,19 @@ const EVENT_STATE_CHANGE = nsIAccessible
 const EVENT_TEXT_ATTRIBUTE_CHANGED = nsIAccessibleEvent.EVENT_TEXT_ATTRIBUTE_CHANGED;
 const EVENT_TEXT_CARET_MOVED = nsIAccessibleEvent.EVENT_TEXT_CARET_MOVED;
 const EVENT_TEXT_INSERTED = nsIAccessibleEvent.EVENT_TEXT_INSERTED;
 const EVENT_TEXT_REMOVED = nsIAccessibleEvent.EVENT_TEXT_REMOVED;
 const EVENT_TEXT_SELECTION_CHANGED = nsIAccessibleEvent.EVENT_TEXT_SELECTION_CHANGED;
 const EVENT_VALUE_CHANGE = nsIAccessibleEvent.EVENT_VALUE_CHANGE;
 const EVENT_VIRTUALCURSOR_CHANGED = nsIAccessibleEvent.EVENT_VIRTUALCURSOR_CHANGED;
 
+const kNotFromUserInput = 0;
+const kFromUserInput = 1;
+
 ////////////////////////////////////////////////////////////////////////////////
 // General
 
 Components.utils.import("resource://gre/modules/Services.jsm");
 
 /**
  * Set up this variable to dump events into DOM.
  */
@@ -1327,18 +1330,19 @@ function focusChecker(aTargetOrFunc, aTa
 function nofocusChecker(aID)
 {
   this.__proto__ = new focusChecker(aID);
   this.unexpected = true;
 }
 
 /**
  * Text inserted/removed events checker.
+ * @param aFromUser  [in, optional] kNotFromUserInput or kFromUserInput
  */
-function textChangeChecker(aID, aStart, aEnd, aTextOrFunc, aIsInserted)
+function textChangeChecker(aID, aStart, aEnd, aTextOrFunc, aIsInserted, aFromUser)
 {
   this.target = getNode(aID);
   this.type = aIsInserted ? EVENT_TEXT_INSERTED : EVENT_TEXT_REMOVED;
 
   this.check = function textChangeChecker_check(aEvent)
   {
     aEvent.QueryInterface(nsIAccessibleTextChangeEvent);
 
@@ -1348,16 +1352,19 @@ function textChangeChecker(aID, aStart, 
 
     is(aEvent.start, aStart, "Wrong start offset for " + prettyName(aID));
     is(aEvent.length, modifiedTextLen, "Wrong length for " + prettyName(aID));
     var changeInfo = (aIsInserted ? "inserted" : "removed");
     is(aEvent.isInserted(), aIsInserted,
        "Text was " + changeInfo + " for " + prettyName(aID));
     is(aEvent.modifiedText, modifiedText,
        "Wrong " + changeInfo + " text for " + prettyName(aID));
+    if (typeof aFromUser != "undefined")
+      is(aEvent.isFromUserInput, aFromUser,
+         "wrong value of isFromUserInput() for " + prettyName(aID));
   }
 }
 
 /**
  * Caret move events checker.
  */
 function caretMoveChecker(aCaretOffset, aTargetOrFunc, aTargetFuncArg)
 {
--- a/accessible/tests/mochitest/events/Makefile.in
+++ b/accessible/tests/mochitest/events/Makefile.in
@@ -73,16 +73,17 @@ include $(topsrcdir)/config/rules.mk
 		test_focus_general.html \
 		test_focus_general.xul \
 		test_focus_listcontrols.xul \
 		test_focus_menu.xul \
 		test_focus_name.html \
 		test_focus_selects.html \
 		test_focus_tabbox.xul \
 		test_focus_tree.xul \
+		test_fromUserInput.html \
 		test_menu.xul \
 		test_mutation.html \
 		test_mutation.xhtml \
 		test_scroll.xul \
 		test_selection_aria.html \
 		test_selection.html \
 		test_selection.xul \
 		test_statechange.html \
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/events/test_fromUserInput.html
@@ -0,0 +1,127 @@
+<html>
+
+<head>
+  <title>Testing of isFromUserInput in text events</title>
+
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+
+  <script type="application/javascript"
+          src="../common.js"></script>
+  <script type="application/javascript"
+          src="../events.js"></script>
+
+  <script type="application/javascript">
+
+    /**
+     * Remove text data from HTML input.
+     */
+    function removeTextFromInput(aID, aStart, aEnd, aText, aFromUser)
+    {
+      this.DOMNode = getNode(aID);
+
+      this.eventSeq = [
+        new textChangeChecker(aID, aStart, aEnd, aText, false, aFromUser)
+      ];
+
+      this.invoke = function removeTextFromInput_invoke()
+      {
+        const nsIDOMNSEditableElement =
+          Components.interfaces.nsIDOMNSEditableElement;
+
+        this.DOMNode.focus();
+        this.DOMNode.setSelectionRange(aStart, aEnd);
+
+        synthesizeKey("VK_DELETE", {});
+      }
+
+      this.getID = function removeTextFromInput_getID()
+      {
+        return "Remove text from " + aStart + " to " + aEnd + " for " +
+          prettyName(aID);
+      }
+    }
+
+    /**
+     * Remove text data from text node.
+     */
+    function removeTextFromContentEditable(aID, aStart, aEnd, aText, aFromUser)
+    {
+      this.DOMNode = getNode(aID);
+
+      this.eventSeq = [
+        new textChangeChecker(aID, aStart, aEnd, aText, false, aFromUser)
+      ];
+
+      this.invoke = function removeTextFromContentEditable_invoke()
+      {
+        const nsIDOMNSEditableElement =
+          Components.interfaces.nsIDOMNSEditableElement;
+
+        this.DOMNode.focus();
+        this.textNode = getNode(aID).firstChild;
+        var selection = window.getSelection();
+        var range = document.createRange();
+        range.setStart(this.textNode, aStart);
+        range.setEnd(this.textNode, aEnd-1);
+        selection.addRange(range);
+
+        synthesizeKey("VK_DELETE", {});
+      }
+
+      this.getID = function removeTextFromContentEditable_getID()
+      {
+        return "Remove text from " + aStart + " to " + aEnd + " for " +
+          prettyName(aID);
+      }
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    // Do tests
+    // gA11yEventDumpID = "eventdump"; // debug stuff
+
+    var gQueue = null;
+
+    function doTests()
+    {
+      gQueue = new eventQueue();
+
+      // Focused editable text node
+      gQueue.push(new removeTextFromContentEditable("div", 0, 3, "hel", true));
+
+      // Focused editable HTML input
+      gQueue.push(new removeTextFromInput("input", 1, 2, "n", true));
+
+      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=686909"
+     title="isFromUserInput flag on accessible text change events not correct">
+    Mozilla Bug 686909
+  </a>
+
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test"></pre>
+  <div id="eventdump"></div>
+
+  <div id="div" contentEditable="true">hello</div>
+  <input id="input" value="input">
+
+</body>
+
+</html>
--- a/accessible/tests/mochitest/test_aria_roles.html
+++ b/accessible/tests/mochitest/test_aria_roles.html
@@ -63,16 +63,17 @@ https://bugzilla.mozilla.org/show_bug.cg
       var abstract_roles = ["composite", "landmark", "structure", "widget",
                             "window", "input", "range", "select", "section",
                             "sectionhead"];
       for (a in abstract_roles)
         testRole(abstract_roles[a], ROLE_SECTION);
 
       //////////////////////////////////////////////////////////////////////////
       // misc roles
+      testRole("note", ROLE_NOTE);
       testRole("scrollbar", ROLE_SCROLLBAR);
       testRole("dir", ROLE_LIST);
 
       //////////////////////////////////////////////////////////////////////////
       // test document role map update
       var testDoc = getAccessible(document, [nsIAccessibleDocument]);
       testRole(testDoc, ROLE_DOCUMENT);
       document.body.setAttribute("role", "application");
@@ -149,16 +150,17 @@ https://bugzilla.mozilla.org/show_bug.cg
   <div role="input" id="input">input</div>
   <div role="range" id="range">range</div>
   <div role="select" id="select">select</div>
   <!-- test abstract structure roles -->
   <div role="section" id="section">section</div>
   <div role="sectionhead" id="sectionhead">sectionhead</div>
 
   <!-- misc roles -->
+  <div role="note" id="note">note</div>
   <div role="scrollbar" id="scrollbar">scrollbar</div>
 
   <div id="dir" role="directory">
     <div role="listitem">A</div>
     <div role="listitem">B</div>
     <div role="listitem">C</div>
   </div>
 </body>
--- a/accessible/tests/mochitest/treeupdate/test_imagemap.html
+++ b/accessible/tests/mochitest/treeupdate/test_imagemap.html
@@ -340,30 +340,66 @@
       }
 
       this.getID = function insertMap_getID()
       {
         return "insert map element";
       }
     }
 
+    function hideImageMap(aContainerID, aImageID)
+    {
+      this.container = getAccessible(aContainerID);
+      this.imageMap = null;
+      this.imageMapNode = getNode(aImageID);
+
+      function getImageMap(aThisObj)
+      {
+        return aThisObj.imageMap;
+      }
+
+      this.eventSeq = [
+        new invokerChecker(EVENT_HIDE, getImageMap, this),
+        new invokerChecker(EVENT_REORDER, aContainerID)
+      ];
+
+      this.invoke = function hideImageMap_invoke()
+      {
+        this.imageMap = getAccessible(this.imageMapNode);
+        this.imageMapNode.style.display = "none";
+      }
+
+      this.finalCheck = function hideImageMap_finalCheck()
+      {
+        var accTree =
+          { SECTION: [ ] };
+        testAccessibleTree(this.container, accTree);
+      }
+
+      this.getID = function hideImageMap_getID()
+      {
+        return "display:none image";
+      }
+    }
+
     //gA11yEventDumpToConsole = true;
 
     var gQueue = null;
     function doTest()
     {
       gQueue = new eventQueue();
 
       gQueue.push(new insertArea("imgmap", "map"));
       gQueue.push(new appendArea("imgmap", "map"));
       gQueue.push(new removeArea("imgmap", "map"));
       gQueue.push(new removeNameOnMap("container", "imgmap", "map"));
       gQueue.push(new restoreNameOnMap("container", "imgmap", "map"));
       gQueue.push(new removeMap("container", "imgmap", "map"));
       gQueue.push(new insertMap("container", "imgmap"));
+      gQueue.push(new hideImageMap("container", "imgmap"));
 
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
--- a/allmakefiles.sh
+++ b/allmakefiles.sh
@@ -117,16 +117,24 @@ if [ "$OS_ARCH" != "WINNT" -a "$OS_ARCH"
 fi
 
 if [ "$COMPILER_DEPEND" = "" -a "$MOZ_NATIVE_MAKEDEPEND" = "" ]; then
   add_makefiles "
     config/mkdepend/Makefile
   "
 fi
 
+if [ "$ENABLE_MARIONETTE" ]; then
+  add_makefiles "
+    testing/marionette/Makefile
+    testing/marionette/components/Makefile
+    testing/marionette/tests/Makefile
+  "
+fi
+
 if [ "$ENABLE_TESTS" ]; then
   add_makefiles "
     build/autoconf/test/Makefile
   "
   if [ ! "$LIBXUL_SDK" ]; then 
     add_makefiles "
       mozglue/tests/Makefile
     "
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -450,16 +450,20 @@ pref("media.volume.steps", 10);
 // navigator.settings API, or even in a database where we can look
 // it up automatically (bug 729440), but for this will have to do.
 pref("ril.data.enabled", false);
 pref("ril.data.roaming.enabled", false);
 pref("ril.data.apn", "");
 pref("ril.data.user", "");
 pref("ril.data.passwd", "");
 
+//Enable/disable marionette server, set listening port
+pref("marionette.defaultPrefs.enabled", true);
+pref("marionette.defaultPrefs.port", 2828);
+
 #ifdef MOZ_UPDATER
 pref("app.update.enabled", true);
 pref("app.update.auto", true);
 pref("app.update.silent", true);
 pref("app.update.mode", 0);
 pref("app.update.incompatible.mode", 0);
 pref("app.update.service.enabled", true);
 
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -62,17 +62,18 @@ function startupHttpd(baseDir, port) {
 
 // FIXME Bug 707625
 // until we have a proper security model, add some rights to
 // the pre-installed web applications
 // XXX never grant 'content-camera' to non-gaia apps
 function addPermissions(urls) {
   let permissions = [
     'indexedDB', 'indexedDB-unlimited', 'webapps-manage', 'offline-app',
-    'content-camera', 'webcontacts-manage', 'wifi-manage', 'desktop-notification'
+    'content-camera', 'webcontacts-manage', 'wifi-manage', 'desktop-notification',
+    'geolocation'
   ];
   urls.forEach(function(url) {
     let uri = Services.io.newURI(url, null, null);
     let allow = Ci.nsIPermissionManager.ALLOW_ACTION;
 
     permissions.forEach(function(permission) {
       Services.perms.add(uri, permission, allow);
     });
--- a/b2g/confvars.sh
+++ b/b2g/confvars.sh
@@ -41,17 +41,17 @@ MOZ_APP_VENDOR=Mozilla
 MOZ_APP_VERSION=14.0a1
 MOZ_APP_UA_NAME=Firefox
 
 MOZ_BRANDING_DIRECTORY=b2g/branding/unofficial
 MOZ_OFFICIAL_BRANDING_DIRECTORY=b2g/branding/official
 # MOZ_APP_DISPLAYNAME is set by branding/configure.sh
 
 MOZ_SAFE_BROWSING=
-MOZ_SERVICES_SYNC=
+MOZ_SERVICES_SYNC=1
 
 MOZ_WEBSMS_BACKEND=1
 MOZ_DISABLE_DOMCRYPTO=1
 MOZ_APP_STATIC_INI=1
 
 if test "$OS_TARGET" = "Android"; then
 MOZ_CAPTURE=1
 MOZ_RAW=1
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -612,14 +612,18 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DL
 
 [b2g]
 @BINPATH@/chrome/icons/
 @BINPATH@/chrome/chrome@JAREXT@
 @BINPATH@/chrome/chrome.manifest
 @BINPATH@/components/B2GComponents.manifest
 @BINPATH@/components/B2GComponents.xpt
 @BINPATH@/components/CameraContent.js
+@BINPATH@/chrome/marionette@JAREXT@
+@BINPATH@/chrome/marionette.manifest
+@BINPATH@/components/MarionetteComponents.manifest
+@BINPATH@/components/marionettecomponent.js
 @BINPATH@/components/AlertsService.js
 @BINPATH@/components/ContentPermissionPrompt.js
 #ifdef MOZ_UPDATER
 @BINPATH@/components/UpdatePrompt.js
 #endif
 @BINPATH@/components/MozKeyboard.js
--- a/build/autoconf/compiler-opts.m4
+++ b/build/autoconf/compiler-opts.m4
@@ -77,54 +77,8 @@ if test "$GNU_CC" -a "$GCC_USE_GNU_LD" -
         fi
         rm -rf conftest*])
     if test "$GC_SECTIONS_BREAKS_DEBUG_RANGES" = no; then
         DSO_LDOPTS="$DSO_LDOPTS -Wl,--gc-sections"
     fi
 fi
 
 ])
-
-dnl GCC and clang will fail if given an unknown warning option like -Wfoobar. 
-dnl But later versions won't fail if given an unknown negated warning option
-dnl like -Wno-foobar.  So when we are check for support of negated warning 
-dnl options, we actually test the positive form, but add the negated form to 
-dnl the flags variable.
-
-AC_DEFUN([MOZ_C_SUPPORTS_WARNING],
-[
-    AC_CACHE_CHECK(whether the C compiler supports $1$2, $3,
-        [
-            AC_LANG_SAVE
-            AC_LANG_C
-            _SAVE_CFLAGS="$CFLAGS"
-            CFLAGS="$CFLAGS -W$2"
-            AC_TRY_COMPILE([],
-                           [return(0);],
-                           $3="yes",
-                           $3="no")
-            CFLAGS="$_SAVE_CFLAGS"
-            AC_LANG_RESTORE
-        ])
-    if test "${$3}" = "yes"; then
-        _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} $1$2"
-    fi
-])
-
-AC_DEFUN([MOZ_CXX_SUPPORTS_WARNING],
-[
-    AC_CACHE_CHECK(whether the C++ compiler supports $1$2, $3,
-        [
-            AC_LANG_SAVE
-            AC_LANG_CPLUSPLUS
-            _SAVE_CXXFLAGS="$CXXFLAGS"
-            CXXFLAGS="$CXXFLAGS -W$2"
-            AC_TRY_COMPILE([],
-                           [return(0);],
-                           $3="yes",
-                           $3="no")
-            CXXFLAGS="$_SAVE_CXXFLAGS"
-            AC_LANG_RESTORE
-        ])
-    if test "${$3}" = "yes"; then
-        _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} $1$2"
-    fi
-])
--- a/build/mobile/devicemanagerADB.py
+++ b/build/mobile/devicemanagerADB.py
@@ -413,35 +413,36 @@ class DeviceManagerADB(DeviceManager):
     # TODO: add debug flags and allow for printing stdout
     # self.runCmd(["pull", remoteFile, localFile])
     try:
 
       # First attempt to pull file regularly
       outerr = self.runCmd(["pull",  remoteFile, localFile]).communicate()
 
       # Now check stderr for errors
-      errl = outerr[1].splitlines()
-      if (len(errl) == 1):
-        if (((errl[0].find("Permission denied") != -1)
-          or (errl[0].find("does not exist") != -1))
-          and self.useRunAs):
-          # If we lack permissions to read but have run-as, then we should try
-          # to copy the file to a world-readable location first before attempting
-          # to pull it again.
-          remoteTmpFile = self.getTempDir() + "/" + os.path.basename(remoteFile)
-          self.checkCmdAs(["shell", "dd", "if=" + remoteFile, "of=" + remoteTmpFile])
-          self.checkCmdAs(["shell", "chmod", "777", remoteTmpFile])
-          self.runCmd(["pull",  remoteTmpFile, localFile]).stdout.read()
-          # Clean up temporary file
-          self.checkCmdAs(["shell", "rm", remoteTmpFile])
+      if outerr[1]:
+        errl = outerr[1].splitlines()
+        if (len(errl) == 1):
+          if (((errl[0].find("Permission denied") != -1)
+            or (errl[0].find("does not exist") != -1))
+            and self.useRunAs):
+            # If we lack permissions to read but have run-as, then we should try
+            # to copy the file to a world-readable location first before attempting
+            # to pull it again.
+            remoteTmpFile = self.getTempDir() + "/" + os.path.basename(remoteFile)
+            self.checkCmdAs(["shell", "dd", "if=" + remoteFile, "of=" + remoteTmpFile])
+            self.checkCmdAs(["shell", "chmod", "777", remoteTmpFile])
+            self.runCmd(["pull",  remoteTmpFile, localFile]).stdout.read()
+            # Clean up temporary file
+            self.checkCmdAs(["shell", "rm", remoteTmpFile])
 
       f = open(localFile)
       ret = f.read()
       f.close()
-      return ret;      
+      return ret
     except:
       return None
 
   # copy directory structure from device (remoteDir) to host (localDir)
   # external function
   # checkDir exists so that we don't create local directories if the
   # remote directory doesn't exist but also so that we don't call isDir
   # twice when recursing.
--- a/build/mobile/robocop/FennecMochitestAssert.java.in
+++ b/build/mobile/robocop/FennecMochitestAssert.java.in
@@ -175,25 +175,27 @@ public class FennecMochitestAssert imple
         ok(pass, name, getNotEqualString(a,b,pass));
     }
 
     public void ispixel(int actual, int r, int g, int b, String name) {
         // When we read GL pixels the GPU has already processed them and they
         // are usually off by a little bit. For example a CSS-color pixel of color #64FFF5
         // was turned into #63FFF7 when it came out of glReadPixels. So in order to compare
         // against the expected value, we use a little fuzz factor. For the alpha we just
-        // make sure it is always 0xFF.
+        // make sure it is always 0xFF. There is also bug 691354 which crops up every so
+        // often just to make our lives difficult. However the individual color components
+        // should never be off by more than 8.
         int aAlpha = ((actual >> 24) & 0xFF);
         int aR = ((actual >> 16) & 0xFF);
         int aG = ((actual >> 8) & 0xFF);
         int aB = (actual & 0xFF);
         boolean pass = (aAlpha == 0xFF) /* alpha */
-                                && (Math.abs(aR - r) < 8) /* red */
-                                && (Math.abs(aG - g) < 8) /* green */
-                                && (Math.abs(aB - b) < 8); /* blue */
+                                && (Math.abs(aR - r) <= 8) /* red */
+                                && (Math.abs(aG - g) <= 8) /* green */
+                                && (Math.abs(aB - b) <= 8); /* blue */
         ok(pass, name, "Color rgba(" + aR + "," + aG + "," + aB + "," + aAlpha + ")" + (pass ? " " : " not") + " close enough to expected rgb(" + r + "," + g + "," + b + ")");
     }
 
     public void todo(boolean condition, String name, String diag) {
         testInfo test = new testInfo(condition, name, diag, true);
         _logMochitestResult(test, "TEST-UNEXPECTED-PASS", "TEST-KNOWN-FAIL");
         mTestList.add(test);
     }
--- a/build/mobile/robocop/FennecNativeActions.java.in
+++ b/build/mobile/robocop/FennecNativeActions.java.in
@@ -95,19 +95,19 @@ public class FennecNativeActions impleme
             parameters[0] = String.class;
             parameters[1] = mGel;
             mRegisterGEL = mGas.getMethod("registerGeckoEventListener", parameters);
             mUnregisterGEL = mGas.getMethod("unregisterGeckoEventListener", parameters);
             parameters = new Class[1];
             parameters[0] = mGe;
             mSendGE = mGas.getMethod("sendEventToGecko", parameters);
 
-            mGetLayerClient = activity.getClass().getMethod("getSoftwareLayerClient");
-            Class gslc = mClassLoader.loadClass("org.mozilla.gecko.gfx.GeckoSoftwareLayerClient");
-            mDrawListener = mClassLoader.loadClass("org.mozilla.gecko.gfx.GeckoSoftwareLayerClient$DrawListener");
+            mGetLayerClient = activity.getClass().getMethod("getLayerClient");
+            Class gslc = mClassLoader.loadClass("org.mozilla.gecko.gfx.GeckoLayerClient");
+            mDrawListener = mClassLoader.loadClass("org.mozilla.gecko.gfx.GeckoLayerClient$DrawListener");
             mSetDrawListener = gslc.getDeclaredMethod("setDrawListener", mDrawListener);
          } catch (ClassNotFoundException e) {
              e.printStackTrace();
          } catch (SecurityException e) {
              e.printStackTrace();
          } catch (NoSuchMethodException e) {
              e.printStackTrace();
          } catch (IllegalArgumentException e) {
--- a/build/mobile/robocop/FennecNativeDriver.java.in
+++ b/build/mobile/robocop/FennecNativeDriver.java.in
@@ -34,27 +34,29 @@
  * 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 ***** */
 
 package @ANDROID_PACKAGE_NAME@;
 
+import java.io.BufferedOutputStream;
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
+import java.io.DataOutputStream;
 import java.io.File;
 import java.io.FileReader;
 import java.io.FileWriter;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.OutputStream;
 import java.nio.IntBuffer;
 import java.util.HashMap;
 import java.util.List;
-import java.io.FileOutputStream;
-import java.io.DataOutputStream;
 
 import java.lang.Class;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.lang.reflect.InvocationHandler;
 import java.lang.Long;
 
@@ -279,27 +281,32 @@ public class FennecNativeDriver implemen
             e.printStackTrace();
         } catch (InvocationTargetException e) {
             e.printStackTrace();
         }
 
         return 0.0f;
     }
 
-    private GLSurfaceView getSurfaceView() {
-        for (View v : mSolo.getCurrentViews()) {
-            if (v instanceof GLSurfaceView) {
-                return (GLSurfaceView)v;
+    private View getSurfaceView() {
+        try {
+            Class c = Class.forName("org.mozilla.gecko.gfx.LayerView");
+            for (View v : mSolo.getCurrentViews()) {
+                if (c.isInstance(v)) {
+                    return v;
+                }
             }
+        } catch (ClassNotFoundException e) {
+            e.printStackTrace();
         }
         return null;
     }
 
     public PaintedSurface getPaintedSurface() {
-        GLSurfaceView view = getSurfaceView();
+        View view = getSurfaceView();
         if (view == null) {
             return null;
         }
         IntBuffer pixelBuffer;
         try {
             pixelBuffer = (IntBuffer)_getPixels.invoke(view);
         } catch (Exception e) {
             e.printStackTrace();
@@ -309,41 +316,48 @@ public class FennecNativeDriver implemen
         // now we need to (1) flip the image, because GL likes to do things up-side-down,
         // and (2) rearrange the bits from AGBR-8888 to ARGB-8888.
         int w = view.getWidth();
         int h = view.getHeight();
         pixelBuffer.position(0);
         String mapFile = "/mnt/sdcard/pixels.map";
 
         FileOutputStream fos = null;
+        BufferedOutputStream bos = null;
         DataOutputStream dos = null;
         try {
             fos = new FileOutputStream(mapFile);
-            dos = new DataOutputStream(fos);
+            bos = new BufferedOutputStream(fos);
+            dos = new DataOutputStream(bos);
 
             for (int y = h - 1; y >= 0; y--) {
                 for (int x = 0; x < w; x++) {
                     int agbr = pixelBuffer.get();
                     dos.writeInt((agbr & 0xFF00FF00) | ((agbr >> 16) & 0x000000FF) | ((agbr << 16) & 0x00FF0000));
                 }
             }
-            return new PaintedSurface(mapFile, w, h);
         } catch (IOException e) {
             throw new RoboCopException("exception with pixel writer on file: " + mapFile);
         } finally {
             try {
-                if (dos != null && fos != null) {
+                if (dos != null) {
                     dos.flush();
                     dos.close();
+                }
+                // closing dos automatically closes bos
+                if (fos != null) {
+                    fos.flush();
                     fos.close();
                 }
             } catch (IOException e) {
+                e.printStackTrace();
                 throw new RoboCopException("exception closing pixel writer on file: " + mapFile);
             }
         }
+        return new PaintedSurface(mapFile, w, h);
     }
 
     public int mHeight=0;
     public int mScrollHeight=0;
     public int mPageHeight=10;
 
     class scrollHandler implements InvocationHandler {
         public scrollHandler(){};
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -130,16 +130,17 @@ NS_TRACE_MALLOC = @NS_TRACE_MALLOC@
 USE_ELF_DYNSTR_GC = @USE_ELF_DYNSTR_GC@
 USE_ELF_HACK = @USE_ELF_HACK@
 STDCXX_COMPAT = @STDCXX_COMPAT@
 MOZ_LIBSTDCXX_TARGET_VERSION=@MOZ_LIBSTDCXX_TARGET_VERSION@
 MOZ_LIBSTDCXX_HOST_VERSION=@MOZ_LIBSTDCXX_HOST_VERSION@
 INCREMENTAL_LINKER = @INCREMENTAL_LINKER@
 MACOSX_DEPLOYMENT_TARGET = @MACOSX_DEPLOYMENT_TARGET@
 ENABLE_TESTS	= @ENABLE_TESTS@
+ENABLE_MARIONETTE = @ENABLE_MARIONETTE@
 IBMBIDI = @IBMBIDI@
 MOZ_UNIVERSALCHARDET = @MOZ_UNIVERSALCHARDET@
 ACCESSIBILITY = @ACCESSIBILITY@
 MOZ_BRANDING_DIRECTORY = @MOZ_BRANDING_DIRECTORY@
 XPCOM_USE_LEA = @XPCOM_USE_LEA@
 MOZ_INSTALLER	= @MOZ_INSTALLER@
 MOZ_MAINTENANCE_SERVICE	= @MOZ_MAINTENANCE_SERVICE@
 MOZ_VERIFY_MAR_SIGNATURE	= @MOZ_VERIFY_MAR_SIGNATURE@
--- a/configure.in
+++ b/configure.in
@@ -1691,54 +1691,46 @@ if test "$GNU_CC"; then
     fi
     WARNINGS_AS_ERRORS='-Werror -Wno-error=uninitialized'
     DSO_CFLAGS=''
     DSO_PIC_CFLAGS='-fPIC'
     ASFLAGS="$ASFLAGS -fPIC"
     _MOZ_RTTI_FLAGS_ON=-frtti
     _MOZ_RTTI_FLAGS_OFF=-fno-rtti
 
-    # Turn on GNU-specific warnings:
-    # -Wall - turn on a lot of warnings
-    # -pedantic - this is turned on below
-    # -Wpointer-arith - enabled with -pedantic, but good to have even if not
-    # -Werror=declaration-after-statement - MSVC doesn't like these
-    # -Werror=return-type - catches missing returns, zero false positives
-    # -Wtype-limits - catches overflow bugs, few false positives
-    # -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
-    #
-    _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wall -Wpointer-arith -Werror=declaration-after-statement"
-    MOZ_C_SUPPORTS_WARNING(-W, error=return-type, ac_c_has_werror_return_type)
-    MOZ_C_SUPPORTS_WARNING(-W, type-limits, ac_c_has_wtype_limits)
-    MOZ_C_SUPPORTS_WARNING(-W, empty-body, ac_c_has_wempty_body)
-    
-    # Turn off the following warnings that -Wall/-pedantic turn on:
-    # -Wno-overlength-strings - we exceed the minimum maximum length frequently
-    # -Wno-unused - lots of violations in third-party code
-    #
-    _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wno-overlength-strings -Wno-unused"
-
+    # Turn on GNU specific features
+    # -Wall - turn on all warnings
+    # -pedantic - make compiler warn about non-ANSI stuff, and
+    #             be a little bit stricter
+    # -Wdeclaration-after-statement - MSVC doesn't like these
+    # Warnings slamm took out for now (these were giving more noise than help):
+    # -Wbad-function-cast - warns when casting a function to a new return type
+    # -Wshadow - removed because it generates more noise than help --pete
+    _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wall -W -Wno-unused -Wpointer-arith -Wdeclaration-after-statement"
     if test -z "$INTEL_CC" -a -z "$CLANG_CC"; then
        # Don't use -Wcast-align with ICC or clang
        case "$CPU_ARCH" in
            # And don't use it on hppa, ia64, sparc, arm, since it's noisy there
            hppa | ia64 | sparc | arm)
            ;;
            *)
         _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wcast-align"
            ;;
        esac
     fi
 
     dnl Turn pedantic on but disable the warnings for long long
     _PEDANTIC=1
 
+    if test -z "$INTEL_CC"; then
+      _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -W"
+    fi
+
     _DEFINES_CFLAGS='-include $(DEPTH)/mozilla-config.h -DMOZILLA_CLIENT'
     _USE_CPP_INCLUDE_FLAG=1
-
 elif test "$SOLARIS_SUNPRO_CC"; then
     DSO_CFLAGS=''
     if test "$CPU_ARCH" = "sparc"; then
         # for Sun Studio on Solaris/SPARC
         DSO_PIC_CFLAGS='-xcode=pic32'
     else
         DSO_PIC_CFLAGS='-KPIC'
     fi
@@ -1756,41 +1748,18 @@ else
     DSO_CFLAGS=''
     DSO_PIC_CFLAGS='-KPIC'
     _DEFINES_CFLAGS='$(ACDEFINES) -D_MOZILLA_CONFIG_H_ -DMOZILLA_CLIENT'
 fi
 
 if test "$GNU_CXX"; then
     # FIXME: Let us build with strict aliasing. bug 414641.
     CXXFLAGS="$CXXFLAGS -fno-exceptions -fno-strict-aliasing"
-
-    # Turn on GNU-specific warnings:
-    # -Wall - turn on a lot of warnings
-    # -pedantic - this is turned on below
-    # -Wpointer-arith - enabled with -pedantic, but good to have even if not
-    # -Woverloaded-virtual - ???
-    # -Werror=return-type - catches missing returns, zero false positives
-    # -Wtype-limits - catches overflow bugs, few false positives
-    # -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
-    #
-    _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wall -Wpointer-arith -Woverloaded-virtual"
-    MOZ_CXX_SUPPORTS_WARNING(-W, error=return-type, ac_cxx_has_werror_return_type)
-    MOZ_CXX_SUPPORTS_WARNING(-W, type-limits, ac_cxx_has_wtype_limits)
-    MOZ_CXX_SUPPORTS_WARNING(-W, empty-body, ac_cxx_has_wempty_body)
-
-    # Turn off the following warnings that -Wall/-pedantic turn on:
-    # -Wno-overlength-strings - we exceed the minimum maximum length frequently 
-    # -Wno-ctor-dtor-privacy - ???
-    # -Wno-invalid-offsetof - we use offsetof on non-POD types frequently
-    # -Wno-variadic-macros - ???
-    #
-    _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-overlength-strings -Wno-ctor-dtor-privacy"
-    MOZ_CXX_SUPPORTS_WARNING(-Wno-, invalid-offsetof, ac_cxx_has_wno_invalid_offsetof)
-    MOZ_CXX_SUPPORTS_WARNING(-Wno-, variadic-macros, ac_cxx_has_wno_variadic_macros)
-
+    # Turn on GNU specific features
+    _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wall -Wpointer-arith -Woverloaded-virtual -Wsynth -Wno-ctor-dtor-privacy -Wno-non-virtual-dtor"
     if test -z "$INTEL_CXX" -a -z "$CLANG_CXX"; then
        # Don't use -Wcast-align with ICC or clang
        case "$CPU_ARCH" in
            # And don't use it on hppa, ia64, sparc, arm, since it's noisy there
            hppa | ia64 | sparc | arm)
            ;;
            *)
         _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wcast-align"
@@ -1804,17 +1773,91 @@ if test "$GNU_CXX"; then
     # Recent clang and gcc support C++11 deleted functions without warnings if
     # compiling with -std=c++0x or -std=gnu++0x (or c++11 or gnu++11 in very new
     # versions).  We can't use -std=c++0x yet, so gcc's support must remain
     # unused.  But clang's warning can be disabled, so when compiling with clang
     # we use it to opt out of the warning, enabling (macro-encapsulated) use of
     # deleted function syntax.
     if test "$CLANG_CXX"; then
         _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-c++0x-extensions"
-        MOZ_CXX_SUPPORTS_WARNING(-Wno-, extended-offsetof, ac_cxx_has_wno_extended_offsetof)
+    fi
+
+    AC_CACHE_CHECK(whether the compiler supports -Wno-extended-offsetof,
+                   ac_has_wno_extended_offsetof,
+        [
+            AC_LANG_SAVE
+            AC_LANG_CPLUSPLUS
+            _SAVE_CXXFLAGS="$CXXFLAGS"
+            CXXFLAGS="$CXXFLAGS -Wno-extended-offsetof"
+            AC_TRY_COMPILE([$configure_static_assert_macros
+                            #ifndef __has_warning
+                            #define __has_warning(x) 0
+                            #endif],
+                           [CONFIGURE_STATIC_ASSERT(__has_warning("-Wextended-offsetof"))],
+                           ac_has_wno_extended_offsetof="yes",
+                           ac_has_wno_extended_offsetof="no")
+            CXXFLAGS="$_SAVE_CXXFLAGS"
+            AC_LANG_RESTORE
+        ])
+    if test "$ac_has_wno_extended_offsetof" = "yes"; then
+        _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-extended-offsetof"
+    fi
+
+    AC_CACHE_CHECK(whether the compiler supports -Wno-invalid-offsetof,
+                   ac_has_wno_invalid_offsetof,
+        [
+            AC_LANG_SAVE
+            AC_LANG_CPLUSPLUS
+            _SAVE_CXXFLAGS="$CXXFLAGS"
+            CXXFLAGS="$CXXFLAGS -Wno-invalid-offsetof"
+            AC_TRY_COMPILE([],
+                           [return(0);],
+                           ac_has_wno_invalid_offsetof="yes",
+                           ac_has_wno_invalid_offsetof="no")
+            CXXFLAGS="$_SAVE_CXXFLAGS"
+            AC_LANG_RESTORE
+        ])
+    if test "$ac_has_wno_invalid_offsetof" = "yes"; then
+        _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-invalid-offsetof"
+    fi
+
+    AC_CACHE_CHECK(whether the compiler supports -Wno-variadic-macros,
+                   ac_has_wno_variadic_macros,
+        [
+            AC_LANG_SAVE
+            AC_LANG_CPLUSPLUS
+            _SAVE_CXXFLAGS="$CXXFLAGS"
+            CXXFLAGS="$CXXFLAGS -Wno-variadic-macros"
+            AC_TRY_COMPILE([],
+                           [return(0);],
+                           ac_has_wno_variadic_macros="yes",
+                           ac_has_wno_variadic_macros="no")
+            CXXFLAGS="$_SAVE_CXXFLAGS"
+            AC_LANG_RESTORE
+        ])
+    if test "$ac_has_wno_variadic_macros" = "yes"; then
+        _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-variadic-macros"
+    fi
+
+    AC_CACHE_CHECK(whether the compiler supports -Werror=return-type,
+                   ac_has_werror_return_type,
+        [
+            AC_LANG_SAVE
+            AC_LANG_CPLUSPLUS
+            _SAVE_CXXFLAGS="$CXXFLAGS"
+            CXXFLAGS="$CXXFLAGS -Werror=return-type"
+            AC_TRY_COMPILE([],
+                           [return(0);],
+                           ac_has_werror_return_type="yes",
+                           ac_has_werror_return_type="no")
+            CXXFLAGS="$_SAVE_CXXFLAGS"
+            AC_LANG_RESTORE
+        ])
+    if test "$ac_has_werror_return_type" = "yes"; then
+        _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=return-type"
     fi
 
 else
     _DEFINES_CXXFLAGS='-DMOZILLA_CLIENT -D_MOZILLA_CONFIG_H_ $(ACDEFINES)'
 fi
 
 dnl gcc can come with its own linker so it is better to use the pass-thru calls
 dnl MKSHLIB_FORCE_ALL is used to force the linker to include all object
@@ -2402,17 +2445,16 @@ ia64*-hpux*)
         AR_EXTRACT=
         RANLIB='echo not_ranlib'
         STRIP='echo not_strip'
         PKG_SKIP_STRIP=1
         XARGS=xargs
         ZIP=zip
         UNZIP=unzip
         DOXYGEN=:
-        GARBAGE='$(OBJDIR)/vc20.pdb $(OBJDIR)/vc40.pdb'
         ASM_SUFFIX=asm
         OBJ_SUFFIX=obj
         LIB_SUFFIX=lib
         DLL_PREFIX=
         LIB_PREFIX=
         IMPORT_LIB_SUFFIX=lib
         MKSHLIB='$(LD) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
         MKCSHLIB='$(LD) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
@@ -6242,49 +6284,42 @@ if test -n "$MOZ_TREE_FREETYPE"; then
    AC_DEFINE(HAVE_FT_GLYPHSLOT_EMBOLDEN)
    AC_DEFINE(HAVE_FT_LOAD_SFNT_TABLE)
    AC_SUBST(CAIRO_FT_CFLAGS)
 fi
 
 dnl ========================================================
 dnl Installer
 dnl ========================================================
-MOZ_ARG_DISABLE_BOOL(installer,
-[  --disable-installer     Disable building of installer],
-    MOZ_INSTALLER=,
-    MOZ_INSTALLER=1)
+dnl Abort Windows build if the required major version and
+dnl minimum minor version of Unicode NSIS isn't in the path.
 if test -n "$MOZ_INSTALLER" -a "$OS_ARCH" = "WINNT"; then
-    # Disable installer for Windows builds that use the new toolkit if the
-    # required major version and minimum minor version of Unicode NSIS isn't in
-    # the path.
     REQ_NSIS_MAJOR_VER=2
     MIN_NSIS_MINOR_VER=33
     MOZ_PATH_PROGS(MAKENSISU, $MAKENSISU makensisu-2.46 makensisu makensis)
     if test -z "$MAKENSISU" -o "$MAKENSISU" = ":"; then
-        AC_MSG_ERROR([To build the installer you must have the latest MozillaBuild or Unicode NSIS with a major version of $REQ_NSIS_MAJOR_VER and a minimum minor version of $MIN_NSIS_MINOR_VER in your path. To build without the installer reconfigure using --disable-installer.])
+        AC_MSG_ERROR([To build the installer you must have the latest MozillaBuild or Unicode NSIS with a major version of $REQ_NSIS_MAJOR_VER and a minimum minor version of $MIN_NSIS_MINOR_VER in your path.])
     fi
     changequote(,)
     MAKENSISU_VER=`"$MAKENSISU" -version 2>/dev/null | sed -e '/-Unicode/!s/.*//g' -e 's/^v\([0-9]\+\.[0-9]\+\)\-Unicode$/\1/g'`
     changequote([,])
     if test ! "$MAKENSISU_VER" = ""; then
         MAKENSISU_MAJOR_VER=`echo $MAKENSISU_VER | $AWK -F\. '{ print $1 }'`
         MAKENSISU_MINOR_VER=`echo $MAKENSISU_VER | $AWK -F\. '{ print $2 }'`
     fi
     AC_MSG_CHECKING([for Unicode NSIS with major version == $REQ_NSIS_MAJOR_VER and minor version >= $MIN_NSIS_MINOR_VER])
     if test "$MAKENSISU_VER" = "" ||
        test ! "$MAKENSISU_MAJOR_VER" = "$REQ_NSIS_MAJOR_VER" -o \
             ! "$MAKENSISU_MINOR_VER" -ge $MIN_NSIS_MINOR_VER; then
         AC_MSG_RESULT([no])
-        AC_MSG_ERROR([To build the installer you must have the latest MozillaBuild or Unicode NSIS with a major version of $REQ_NSIS_MAJOR_VER and a minimum minor version of $MIN_NSIS_MINOR_VER in your path. To build without the installer reconfigure using --disable-installer.])
+        AC_MSG_ERROR([To build the installer you must have the latest MozillaBuild or Unicode NSIS with a major version of $REQ_NSIS_MAJOR_VER and a minimum minor version of $MIN_NSIS_MINOR_VER in your path.])
     fi
     AC_MSG_RESULT([yes])
 fi
 
-AC_SUBST(MOZ_INSTALLER)
-
 AC_MSG_CHECKING([for tar archiver])
 AC_CHECK_PROGS(TAR, gnutar gtar tar, "")
 if test -z "$TAR"; then
     AC_MSG_ERROR([no tar archiver found in \$PATH])
 fi
 AC_MSG_RESULT([$TAR])
 AC_SUBST(TAR)
 
@@ -6390,16 +6425,24 @@ dnl ====================================
 dnl build the tests by default
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(tests,
 [  --disable-tests         Do not build test libraries & programs],
     ENABLE_TESTS=,
     ENABLE_TESTS=1 )
 
 dnl ========================================================
+dnl Marionette
+dnl ========================================================
+MOZ_ARG_ENABLE_BOOL(marionette,
+[  --enable-marionette     Enable Marionette for remote testing and control],
+    ENABLE_MARIONETTE=1,
+    ENABLE_MARIONETTE)
+
+dnl ========================================================
 dnl parental controls (for Windows Vista)
 dnl ========================================================
 MOZ_ARG_DISABLE_BOOL(parental-controls,
 [  --disable-parental-controls
                           Do not build parental controls],
    MOZ_DISABLE_PARENTAL_CONTROLS=1,
    MOZ_DISABLE_PARENTAL_CONTROLS=)
 if test -n "$MOZ_DISABLE_PARENTAL_CONTROLS"; then
@@ -7185,32 +7228,32 @@ dnl We need to wrap dlopen and related f
 dnl our own linker.
 if test "$OS_TARGET" = Android; then
     WRAP_LDFLAGS="${WRAP_LDFLAGS} -L$_objdir/dist/lib -lmozglue"
     if test "$MOZ_WIDGET_TOOLKIT" = android; then
         if test -n "$MOZ_OLD_LINKER"; then
             WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=dlopen,--wrap=dlclose,--wrap=dlerror,--wrap=dlsym,--wrap=dladdr"
         fi
         WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=getaddrinfo,--wrap=freeaddrinfo,--wrap=gai_strerror"
+        WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=fork,--wrap=pthread_atfork"
     fi
 fi
 
 dnl ========================================================
 dnl = Use malloc wrapper lib
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(wrap-malloc,
 [  --enable-wrap-malloc    Wrap malloc calls (gnu linker only)],
     _WRAP_MALLOC=1,
     _WRAP_MALLOC= )
 
 if test -n "$_WRAP_MALLOC"; then
     if test -n "$GNU_CC"; then
         WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=malloc,--wrap=calloc,--wrap=valloc,--wrap=free,--wrap=realloc,--wrap=memalign"
         WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=__builtin_new,--wrap=__builtin_vec_new,--wrap=__builtin_delete,--wrap=__builtin_vec_delete"
-        WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=PR_Free,--wrap=PR_Malloc,--wrap=PR_Calloc,--wrap=PR_Realloc"
         WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=strdup,--wrap=strndup"
         WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=posix_memalign,--wrap=malloc_usable_size"
     else
         AC_MSG_ERROR([--enable-wrap-malloc is not supported for non-GNU toolchains])
     fi
 fi
 
 dnl ========================================================
@@ -8307,16 +8350,17 @@ 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_INSTALLER)
 AC_SUBST(MOZ_JSDEBUGGER)
 AC_SUBST(MOZ_LOG_REFCNT)
 AC_SUBST(MOZ_LEAKY)
 AC_SUBST(MOZ_ENABLE_PROFILER_SPS)
 AC_SUBST(MOZ_JPROF)
 AC_SUBST(MOZ_SHARK)
 AC_SUBST(MOZ_CALLGRIND)
 AC_SUBST(MOZ_VTUNE)
@@ -8333,16 +8377,17 @@ AC_SUBST(MOZ_HELP_VIEWER)
 
 AC_SUBST(JAVA)
 AC_SUBST(JAVAC)
 AC_SUBST(JAR)
 
 AC_SUBST(MOZ_PROFILELOCKING)
 
 AC_SUBST(ENABLE_TESTS)
+AC_SUBST(ENABLE_MARIONETTE)
 AC_SUBST(IBMBIDI)
 AC_SUBST(MOZ_UNIVERSALCHARDET)
 AC_SUBST(ACCESSIBILITY)
 AC_SUBST(MOZ_SPELLCHECK)
 AC_SUBST(MOZ_JAVA_COMPOSITOR)
 AC_SUBST(MOZ_ONLY_TOUCH_EVENTS)
 AC_SUBST(MOZ_USER_DIR)
 AC_SUBST(MOZ_CRASHREPORTER)
--- a/content/base/public/nsIContent.h
+++ b/content/base/public/nsIContent.h
@@ -109,18 +109,19 @@ public:
    * the parent's child list and before nsIDocumentObserver notifications for
    * the addition are dispatched.
    * @param aDocument The new document for the content node.  Must match the
    *                  current document of aParent, if aParent is not null.
    *                  May not be null if aParent is null.
    * @param aParent The new parent for the content node.  May be null if the
    *                node is being bound as a direct child of the document.
    * @param aBindingParent The new binding parent for the content node.
-   *                       This is allowed to be null.  In that case, the
-   *                       binding parent of aParent, if any, will be used.
+   *                       This is must either be non-null if a particular
+   *                       binding parent is desired or match aParent's binding
+   *                       parent.
    * @param aCompileEventHandlers whether to initialize the event handlers in
    *        the document (used by nsXULElement)
    * @note either aDocument or aParent must be non-null.  If both are null,
    *       this method _will_ crash.
    * @note This method must not be called by consumers of nsIContent on a node
    *       that is already bound to a tree.  Call UnbindFromTree first.
    * @note This method will handle rebinding descendants appropriately (eg
    *       changing their binding parent as needed).
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -644,17 +644,19 @@ public:
    * StartDocumentLoad or Reset were never called)
    */
   virtual nsIChannel* GetChannel() const = 0;
 
   /**
    * Get this document's attribute stylesheet.  May return null if
    * there isn't one.
    */
-  virtual nsHTMLStyleSheet* GetAttributeStyleSheet() const = 0;
+  nsHTMLStyleSheet* GetAttributeStyleSheet() const {
+    return mAttrStyleSheet;
+  }
 
   /**
    * Get this document's inline style sheet.  May return null if there
    * isn't one
    */
   virtual nsHTMLCSSStyleSheet* GetInlineStyleSheet() const = 0;
 
   /**
@@ -1695,16 +1697,17 @@ protected:
   // A reference to the element last returned from GetRootElement().
   mozilla::dom::Element* mCachedRootElement;
 
   // We'd like these to be nsRefPtrs, but that'd require us to include
   // additional headers that we don't want to expose.
   // The cleanup is handled by the nsDocument destructor.
   nsNodeInfoManager* mNodeInfoManager; // [STRONG]
   mozilla::css::Loader* mCSSLoader; // [STRONG]
+  nsHTMLStyleSheet* mAttrStyleSheet;
 
   // The set of all object, embed, applet, video and audio elements for
   // which this is the owner document. (They might not be in the document.)
   // These are non-owning pointers, the elements are responsible for removing
   // themselves when they go away.
   nsAutoPtr<nsTHashtable<nsPtrHashKey<nsIContent> > > mFreezableElements;
   
   // The set of all links that need their status resolved.  Links must add themselves
--- a/content/base/src/nsAttrAndChildArray.cpp
+++ b/content/base/src/nsAttrAndChildArray.cpp
@@ -571,20 +571,21 @@ nsAttrAndChildArray::SetAndTakeMappedAtt
 
   rv = mapped->SetAndTakeAttr(aLocalName, aValue);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return MakeMappedUnique(mapped);
 }
 
 nsresult
-nsAttrAndChildArray::SetMappedAttrStyleSheet(nsHTMLStyleSheet* aSheet)
+nsAttrAndChildArray::DoSetMappedAttrStyleSheet(nsHTMLStyleSheet* aSheet)
 {
-  if (!mImpl || !mImpl->mMappedAttrs ||
-      aSheet == mImpl->mMappedAttrs->GetStyleSheet()) {
+  NS_PRECONDITION(mImpl && mImpl->mMappedAttrs,
+                  "Should have mapped attrs here!");
+  if (aSheet == mImpl->mMappedAttrs->GetStyleSheet()) {
     return NS_OK;
   }
 
   nsRefPtr<nsMappedAttributes> mapped;
   nsresult rv = GetModifiableMapped(nsnull, nsnull, false, 
                                     getter_AddRefs(mapped));
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/content/base/src/nsAttrAndChildArray.h
+++ b/content/base/src/nsAttrAndChildArray.h
@@ -119,17 +119,22 @@ public:
   const nsAttrName* GetSafeAttrNameAt(PRUint32 aPos) const;
 
   const nsAttrName* GetExistingAttrNameFromQName(const nsAString& aName) const;
   PRInt32 IndexOfAttr(nsIAtom* aLocalName, PRInt32 aNamespaceID = kNameSpaceID_None) const;
 
   nsresult SetAndTakeMappedAttr(nsIAtom* aLocalName, nsAttrValue& aValue,
                                 nsMappedAttributeElement* aContent,
                                 nsHTMLStyleSheet* aSheet);
-  nsresult SetMappedAttrStyleSheet(nsHTMLStyleSheet* aSheet);
+  nsresult SetMappedAttrStyleSheet(nsHTMLStyleSheet* aSheet) {
+    if (!mImpl || !mImpl->mMappedAttrs) {
+      return NS_OK;
+    }
+    return DoSetMappedAttrStyleSheet(aSheet);
+  }
   void WalkMappedAttributeStyleRules(nsRuleWalker* aRuleWalker);
 
   void Compact();
 
   bool CanFitMoreAttrs() const
   {
     return AttrSlotCount() < ATTRCHILD_ARRAY_MAX_ATTR_COUNT ||
            !AttrSlotIsTaken(ATTRCHILD_ARRAY_MAX_ATTR_COUNT - 1);
@@ -198,16 +203,21 @@ private:
   /**
    * Set *aPos to aChild and update sibling pointers as needed.  aIndex is the
    * index at which aChild is actually being inserted.  aChildCount is the
    * number of kids we had before the insertion.
    */
   inline void SetChildAtPos(void** aPos, nsIContent* aChild, PRUint32 aIndex,
                             PRUint32 aChildCount);
 
+  /**
+   * Guts of SetMappedAttrStyleSheet for the rare case when we have mapped attrs
+   */
+  nsresult DoSetMappedAttrStyleSheet(nsHTMLStyleSheet* aSheet);
+
   struct InternalAttr
   {
     nsAttrName mName;
     nsAttrValue mValue;
   };
 
   struct Impl {
     PRUint32 mAttrAndChildCount;
--- a/content/base/src/nsContentList.cpp
+++ b/content/base/src/nsContentList.cpp
@@ -76,17 +76,18 @@ nsBaseContentList::~nsBaseContentList()
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsBaseContentList)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsBaseContentList)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(mElements)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsBaseContentList)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
-  if (nsCCUncollectableMarker::sGeneration && tmp->IsBlack()) {
+  if (nsCCUncollectableMarker::sGeneration && tmp->IsBlack() &&
+      NS_LIKELY(!cb.WantAllTraces())) {
     return NS_SUCCESS_INTERRUPTED_TRAVERSE;
   }
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY_OF_NSCOMPTR(mElements)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsBaseContentList)
   NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
--- a/content/base/src/nsContentSink.cpp
+++ b/content/base/src/nsContentSink.cpp
@@ -53,17 +53,16 @@
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsCPrefetchService.h"
 #include "nsIURI.h"
 #include "nsNetUtil.h"
 #include "nsIHttpChannel.h"
 #include "nsIContent.h"
 #include "nsIScriptElement.h"
-#include "nsIParser.h"
 #include "nsContentErrors.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsIViewManager.h"
 #include "nsIContentViewer.h"
 #include "nsIAtom.h"
 #include "nsGkAtoms.h"
 #include "nsIDOMWindow.h"
--- a/content/base/src/nsCrossSiteListenerProxy.cpp
+++ b/content/base/src/nsCrossSiteListenerProxy.cpp
@@ -37,18 +37,16 @@
 
 #include "nsCrossSiteListenerProxy.h"
 #include "nsIChannel.h"
 #include "nsIHttpChannel.h"
 #include "nsDOMError.h"
 #include "nsContentUtils.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsNetUtil.h"
-#include "nsIParser.h"
-#include "nsParserCIID.h"
 #include "nsMimeTypes.h"
 #include "nsIStreamConverterService.h"
 #include "nsStringStream.h"
 #include "nsGkAtoms.h"
 #include "nsWhitespaceTokenizer.h"
 #include "nsIChannelEventSink.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
 #include "nsCharSeparatedTokenizer.h"
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -143,16 +143,17 @@
 #include "nsBindingManager.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIRequest.h"
 #include "nsILink.h"
 #include "nsBlobProtocolHandler.h"
 
 #include "nsCharsetAlias.h"
+#include "nsCharsetSource.h"
 #include "nsIParser.h"
 #include "nsIContentSink.h"
 
 #include "nsDateTimeFormatCID.h"
 #include "nsIDateTimeFormat.h"
 #include "nsEventDispatcher.h"
 #include "nsMutationEvent.h"
 #include "nsDOMCID.h"
@@ -1623,18 +1624,20 @@ nsDocument::~nsDocument()
   indx = mStyleSheets.Count();
   while (--indx >= 0) {
     mStyleSheets[indx]->SetOwningDocument(nsnull);
   }
   indx = mCatalogSheets.Count();
   while (--indx >= 0) {
     mCatalogSheets[indx]->SetOwningDocument(nsnull);
   }
-  if (mAttrStyleSheet)
+  if (mAttrStyleSheet) {
     mAttrStyleSheet->SetOwningDocument(nsnull);
+    NS_RELEASE(mAttrStyleSheet);
+  }
   if (mStyleAttrStyleSheet)
     mStyleAttrStyleSheet->SetOwningDocument(nsnull);
 
   if (mListenerManager) {
     mListenerManager->Disconnect();
     UnsetFlags(NODE_HAS_LISTENERMANAGER);
   }
 
@@ -1648,24 +1651,16 @@ nsDocument::~nsDocument()
     NS_RELEASE(mCSSLoader);
   }
 
   // XXX Ideally we'd do this cleanup in the nsIDocument destructor.
   if (mNodeInfoManager) {
     mNodeInfoManager->DropDocumentReference();
   }
 
-  if (mAttrStyleSheet) {
-    mAttrStyleSheet->SetOwningDocument(nsnull);
-  }
-  
-  if (mStyleAttrStyleSheet) {
-    mStyleAttrStyleSheet->SetOwningDocument(nsnull);
-  }
-
   delete mHeaderData;
 
   if (mBoxObjectTable) {
     mBoxObjectTable->EnumerateRead(ClearAllBoxObjects, nsnull);
     delete mBoxObjectTable;
   }
 
   mPendingTitleChangeEvent.Revoke();
@@ -2268,18 +2263,21 @@ nsDocument::ResetStylesheetsToURI(nsIURI
     // Remove this sheet from all style sets
     nsCOMPtr<nsIPresShell> shell = GetShell();
     if (shell) {
       shell->StyleSet()->RemoveStyleSheet(nsStyleSet::ePresHintSheet,
                                           mAttrStyleSheet);
     }
     mAttrStyleSheet->Reset(aURI);
   } else {
-    rv = NS_NewHTMLStyleSheet(getter_AddRefs(mAttrStyleSheet), aURI, this);
-    NS_ENSURE_SUCCESS(rv, rv);
+    rv = NS_NewHTMLStyleSheet(&mAttrStyleSheet, aURI, this);
+    if (NS_FAILED(rv)) {
+      NS_IF_RELEASE(mAttrStyleSheet);
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
   }
 
   // Don't use AddStyleSheet, since it'll put the sheet into style
   // sets in the document level, which is not desirable here.
   mAttrStyleSheet->SetOwningDocument(this);
   
   if (mStyleAttrStyleSheet) {
     // Remove this sheet from all style sets
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -624,24 +624,16 @@ public:
   virtual void AddCatalogStyleSheet(nsIStyleSheet* aSheet);
   virtual void EnsureCatalogStyleSheet(const char *aStyleSheetURI);
 
   virtual nsIChannel* GetChannel() const {
     return mChannel;
   }
 
   /**
-   * Get this document's attribute stylesheet.  May return null if
-   * there isn't one.
-   */
-  virtual nsHTMLStyleSheet* GetAttributeStyleSheet() const {
-    return mAttrStyleSheet;
-  }
-
-  /**
    * Get this document's inline style sheet.  May return null if there
    * isn't one
    */
   virtual nsHTMLCSSStyleSheet* GetInlineStyleSheet() const {
     return mStyleAttrStyleSheet;
   }
   
   /**
@@ -1195,17 +1187,16 @@ protected:
   bool mInFlush:1;
 
   PRUint8 mXMLDeclarationBits;
 
   nsInterfaceHashtable<nsPtrHashKey<nsIContent>, nsPIBoxObject> *mBoxObjectTable;
 
   // The channel that got passed to StartDocumentLoad(), if any
   nsCOMPtr<nsIChannel> mChannel;
-  nsRefPtr<nsHTMLStyleSheet> mAttrStyleSheet;
   nsRefPtr<nsHTMLCSSStyleSheet> mStyleAttrStyleSheet;
   nsRefPtr<nsXMLEventsManager> mXMLEventsManager;
 
   // Our update nesting level
   PRUint32 mUpdateNestLevel;
 
   // The application cache that this document is associated with, if
   // any.  This can change during the lifetime of the document.
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -154,16 +154,18 @@
 #include "nsCycleCollector.h"
 #include "xpcpublic.h"
 #include "xpcprivate.h"
 #include "nsLayoutStatics.h"
 #include "mozilla/Telemetry.h"
 
 #include "mozilla/CORSMode.h"
 
+#include "nsStyledElement.h"
+
 using namespace mozilla;
 using namespace mozilla::dom;
 
 NS_DEFINE_IID(kThisPtrOffsetsSID, NS_THISPTROFFSETS_SID);
 
 PRInt32 nsIContent::sTabFocusModel = eTabFocus_any;
 bool nsIContent::sTabFocusModelAppliesToXUL = false;
 PRUint32 nsMutationGuard::sMutationCount = 0;
@@ -1214,39 +1216,41 @@ bool UnoptimizableCCNode(nsINode* aNode)
          (aNode->IsElement() &&
           aNode->AsElement()->IsInNamespace(kNameSpaceID_XBL));
 }
 
 /* static */
 bool
 nsINode::Traverse(nsINode *tmp, nsCycleCollectionTraversalCallback &cb)
 {
-  nsIDocument *currentDoc = tmp->GetCurrentDoc();
-  if (currentDoc &&
-      nsCCUncollectableMarker::InGeneration(cb, currentDoc->GetMarkedCCGeneration())) {
-    return false;
-  }
-
-  if (nsCCUncollectableMarker::sGeneration) {
-    // If we're black no need to traverse.
-    if (tmp->IsBlack() || tmp->InCCBlackTree()) {
+  if (NS_LIKELY(!cb.WantAllTraces())) {
+    nsIDocument *currentDoc = tmp->GetCurrentDoc();
+    if (currentDoc &&
+        nsCCUncollectableMarker::InGeneration(currentDoc->GetMarkedCCGeneration())) {
       return false;
     }
 
-    if (!UnoptimizableCCNode(tmp)) {
-      // If we're in a black document, return early.
-      if ((currentDoc && currentDoc->IsBlack())) {
+    if (nsCCUncollectableMarker::sGeneration) {
+      // If we're black no need to traverse.
+      if (tmp->IsBlack() || tmp->InCCBlackTree()) {
         return false;
       }
-      // If we're not in anonymous content and we have a black parent,
-      // return early.
-      nsIContent* parent = tmp->GetParent();
-      if (parent && !UnoptimizableCCNode(parent) && parent->IsBlack()) {
-        NS_ABORT_IF_FALSE(parent->IndexOf(tmp) >= 0, "Parent doesn't own us?");
-        return false;
+
+      if (!UnoptimizableCCNode(tmp)) {
+        // If we're in a black document, return early.
+        if ((currentDoc && currentDoc->IsBlack())) {
+          return false;
+        }
+        // If we're not in anonymous content and we have a black parent,
+        // return early.
+        nsIContent* parent = tmp->GetParent();
+        if (parent && !UnoptimizableCCNode(parent) && parent->IsBlack()) {
+          NS_ABORT_IF_FALSE(parent->IndexOf(tmp) >= 0, "Parent doesn't own us?");
+          return false;
+        }
       }
     }
   }
 
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNodeInfo)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(GetParent())
 
   nsSlots *slots = tmp->GetExistingSlots();
@@ -3083,20 +3087,19 @@ nsGenericElement::BindToTree(nsIDocument
                   !aParent->HasFlag(NODE_FORCE_XBL_BINDINGS),
                   "Parent in document but flagged as forcing XBL");
   NS_PRECONDITION(aBindingParent != this,
                   "Content must not be its own binding parent");
   NS_PRECONDITION(!IsRootOfNativeAnonymousSubtree() ||
                   aBindingParent == aParent,
                   "Native anonymous content must have its parent as its "
                   "own binding parent");
-
-  if (!aBindingParent && aParent) {
-    aBindingParent = aParent->GetBindingParent();
-  }
+  NS_PRECONDITION(aBindingParent || !aParent ||
+                  aBindingParent == aParent->GetBindingParent(),
+                  "We should be passed the right binding parent");
 
 #ifdef MOZ_XUL
   // First set the binding parent
   nsXULElement* xulElem = nsXULElement::FromContent(this);
   if (xulElem) {
     xulElem->SetXULBindingParent(aBindingParent);
   }
   else 
@@ -3209,16 +3212,38 @@ nsGenericElement::BindToTree(nsIDocument
        child = child->GetNextSibling()) {
     rv = child->BindToTree(aDocument, this, aBindingParent,
                            aCompileEventHandlers);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   nsNodeUtils::ParentChainChanged(this);
 
+  if (aDocument && HasID() && !aBindingParent) {
+    aDocument->AddToIdTable(this, DoGetID());
+  }
+
+  if (MayHaveStyle() && !IsXUL()) {
+    // XXXbz if we already have a style attr parsed, this won't do
+    // anything... need to fix that.
+    // If MayHaveStyle() is true, we must be an nsStyledElement
+    static_cast<nsStyledElement*>(this)->ReparseStyleAttribute(false);
+  }
+
+  if (aDocument) {
+    // If we're in a document now, let our mapped attrs know what their new
+    // sheet is.  This is safe to run for non-mapped-attribute elements too;
+    // it'll just do a small bit of unnecessary work.  But most elements in
+    // practice are mapped-attribute elements.
+    nsHTMLStyleSheet* sheet = aDocument->GetAttributeStyleSheet();
+    if (sheet) {
+      mAttrsAndChildren.SetMappedAttrStyleSheet(sheet);
+    }
+  }
+
   // XXXbz script execution during binding can trigger some of these
   // postcondition asserts....  But we do want that, since things will
   // generally be quite broken when that happens.
   NS_POSTCONDITION(aDocument == GetCurrentDoc(), "Bound to wrong document");
   NS_POSTCONDITION(aParent == GetParent(), "Bound to wrong parent");
   NS_POSTCONDITION(aBindingParent == GetBindingParent(),
                    "Bound to wrong binding parent");
 
@@ -3226,16 +3251,19 @@ nsGenericElement::BindToTree(nsIDocument
 }
 
 void
 nsGenericElement::UnbindFromTree(bool aDeep, bool aNullParent)
 {
   NS_PRECONDITION(aDeep || (!GetCurrentDoc() && !GetBindingParent()),
                   "Shallow unbind won't clear document and binding parent on "
                   "kids!");
+
+  RemoveFromIdTable();
+
   // Make sure to unbind this node before doing the kids
   nsIDocument *document =
     HasFlag(NODE_FORCE_XBL_BINDINGS) ? OwnerDoc() : GetCurrentDoc();
 
   if (aNullParent) {
     if (IsFullScreenAncestor()) {
       // The element being removed is an ancestor of the full-screen element,
       // exit full-screen state.
@@ -3778,17 +3806,19 @@ nsINode::doInsertChildAt(nsIContent* aKi
   NS_ENSURE_SUCCESS(rv, rv);
   if (aIndex == 0) {
     mFirstChild = aKid;
   }
 
   nsIContent* parent =
     IsNodeOfType(eDOCUMENT) ? nsnull : static_cast<nsIContent*>(this);
 
-  rv = aKid->BindToTree(doc, parent, nsnull, true);
+  rv = aKid->BindToTree(doc, parent,
+                        parent ? parent->GetBindingParent() : nsnull,
+                        true);
   if (NS_FAILED(rv)) {
     if (GetFirstChild() == aKid) {
       mFirstChild = aKid->GetNextSibling();
     }
     aChildArray.RemoveChildAt(aIndex);
     aKid->UnbindFromTree();
     return rv;
   }
@@ -3998,17 +4028,24 @@ bool IsAllowedAsChild(nsIContent* aNewCh
   NS_PRECONDITION(!aIsReplace || aRefChild,
                   "Must have ref content for replace");
   NS_PRECONDITION(aParent->IsNodeOfType(nsINode::eDOCUMENT) ||
                   aParent->IsNodeOfType(nsINode::eDOCUMENT_FRAGMENT) ||
                   aParent->IsElement(),
                   "Nodes that are not documents, document fragments or "
                   "elements can't be parents!");
 
-  if (aParent && nsContentUtils::ContentIsDescendantOf(aParent, aNewChild)) {
+  // A common case is that aNewChild has no kids, in which case
+  // aParent can't be a descendant of aNewChild unless they're
+  // actually equal to each other.  Fast-path that case, since aParent
+  // could be pretty deep in the DOM tree.
+  if (aParent &&
+      (aNewChild == aParent ||
+       (aNewChild->GetFirstChild() &&
+        nsContentUtils::ContentIsDescendantOf(aParent, aNewChild)))) {
     return false;
   }
 
   // The allowed child nodes differ for documents and elements
   switch (aNewChild->NodeType()) {
   case nsIDOMNode::COMMENT_NODE :
   case nsIDOMNode::PROCESSING_INSTRUCTION_NODE :
     // OK in both cases
@@ -6058,17 +6095,17 @@ ParseSelectorList(nsINode* aNode,
     }
   } while (*slot);
   *aSelectorList = selectorList;
 
   return NS_OK;
 }
 
 // Actually find elements matching aSelectorList (which must not be
-// null) and which are descendants of aRoot and put them in Alist.  If
+// null) and which are descendants of aRoot and put them in aList.  If
 // onlyFirstMatch, then stop once the first one is found.
 template<bool onlyFirstMatch, class T>
 inline static nsresult FindMatchingElements(nsINode* aRoot,
                                             const nsAString& aSelector,
                                             T &aList)
 {
   nsAutoPtr<nsCSSSelectorList> selectorList;
   nsresult rv = ParseSelectorList(aRoot, aSelector,
@@ -6103,18 +6140,19 @@ inline static nsresult FindMatchingEleme
       doc->GetAllElementsForId(nsDependentAtomString(id));
 
     // XXXbz: Should we fall back to the tree walk if aRoot is not the
     // document and |elements| is long, for some value of "long"?
     if (elements) {
       for (PRInt32 i = 0; i < elements->Count(); ++i) {
         Element *element = static_cast<Element*>(elements->ElementAt(i));
         if (!aRoot->IsElement() ||
-            nsContentUtils::ContentIsDescendantOf(element, aRoot)) {
-          // We have an element with the right id and it's a descendant
+            (element != aRoot &&
+             nsContentUtils::ContentIsDescendantOf(element, aRoot))) {
+          // We have an element with the right id and it's a strict descendant
           // of aRoot.  Make sure it really matches the selector.
           if (nsCSSRuleProcessor::SelectorListMatches(element, matchingContext,
                                                       selectorList)) {
             aList.AppendElement(element);
             if (onlyFirstMatch) {
               return NS_OK;
             }
           }
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -1211,17 +1211,18 @@ GK_ATOM(font_style, "font-style")
 GK_ATOM(font_variant, "font-variant")
 GK_ATOM(foreignObject, "foreignObject")
 GK_ATOM(fractalNoise, "fractalNoise")
 GK_ATOM(fx, "fx")
 GK_ATOM(fy, "fy")
 GK_ATOM(G, "G")
 GK_ATOM(g, "g")
 GK_ATOM(gamma, "gamma")
-GK_ATOM(generic, "generic")
+// 'generic' conflicts with msvc11 winrt compiler extensions
+GK_ATOM(generic_, "generic")
 GK_ATOM(glyph, "glyph")
 GK_ATOM(glyphRef, "glyphRef")
 GK_ATOM(glyph_orientation_horizontal, "glyph-orientation-horizontal")
 GK_ATOM(glyph_orientation_vertical, "glyph-orientation-vertical")
 GK_ATOM(grad, "grad")
 GK_ATOM(gradientTransform, "gradientTransform")
 GK_ATOM(gradientUnits, "gradientUnits")
 GK_ATOM(hkern, "hkern")
--- a/content/base/src/nsMappedAttributeElement.cpp
+++ b/content/base/src/nsMappedAttributeElement.cpp
@@ -37,38 +37,16 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsMappedAttributeElement.h"
 #include "nsIDocument.h"
 
 nsresult
-nsMappedAttributeElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
-                                     nsIContent* aBindingParent,
-                                     bool aCompileEventHandlers)
-{
-  nsresult rv = nsMappedAttributeElementBase::BindToTree(aDocument, aParent,
-                                                         aBindingParent,
-                                                         aCompileEventHandlers);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (aDocument) {
-    // If we're in a document now, let our mapped attrs know what their new
-    // sheet is.
-    nsHTMLStyleSheet* sheet = aDocument->GetAttributeStyleSheet();
-    if (sheet) {
-      mAttrsAndChildren.SetMappedAttrStyleSheet(sheet);
-    }
-  }
-
-  return rv;
-}
-
-nsresult
 nsMappedAttributeElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
 {
   mAttrsAndChildren.WalkMappedAttributeStyleRules(aRuleWalker);
   return NS_OK;
 }
 
 bool
 nsMappedAttributeElement::SetMappedAttribute(nsIDocument* aDocument,
--- a/content/base/src/nsMappedAttributeElement.h
+++ b/content/base/src/nsMappedAttributeElement.h
@@ -60,20 +60,16 @@ class nsMappedAttributeElement : public 
 
 protected:
 
   nsMappedAttributeElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : nsMappedAttributeElementBase(aNodeInfo)
   {}
 
 public:
-  virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
-                              nsIContent* aBindingParent,
-                              bool aCompileEventHandlers);
-
   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
 
   static void MapNoAttributesInto(const nsMappedAttributes* aAttributes, 
                                   nsRuleData* aRuleData);
 
   NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
   virtual bool SetMappedAttribute(nsIDocument* aDocument,
                                     nsIAtom* aName,
--- a/content/base/src/nsNodeUtils.cpp
+++ b/content/base/src/nsNodeUtils.cpp
@@ -220,33 +220,16 @@ nsNodeUtils::AttributeChildRemoved(nsINo
         }
       }
     }
     aAttribute = aAttribute->GetNodeParent();
   } while (aAttribute);
 }
 
 void
-nsNodeUtils::ParentChainChanged(nsIContent *aContent)
-{
-  // No need to notify observers on the parents since their parent
-  // chain must have been changed too and so their observers were
-  // notified at that time.
-
-  nsINode::nsSlots* slots = aContent->GetExistingSlots();
-  if (slots && !slots->mMutationObservers.IsEmpty()) {
-    NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(
-        slots->mMutationObservers,
-        nsIMutationObserver,
-        ParentChainChanged,
-        (aContent));
-  }
-}
-
-void
 nsNodeUtils::LastRelease(nsINode* aNode)
 {
   nsINode::nsSlots* slots = aNode->GetExistingSlots();
   if (slots) {
     if (!slots->mMutationObservers.IsEmpty()) {
       NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(slots->mMutationObservers,
                                          nsIMutationObserver,
                                          NodeWillBeDestroyed, (aNode));
--- a/content/base/src/nsNodeUtils.h
+++ b/content/base/src/nsNodeUtils.h
@@ -34,16 +34,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsNodeUtils_h___
 #define nsNodeUtils_h___
 
 #include "nsINode.h"
+#include "nsIContent.h"
 
 struct CharacterDataChangeInfo;
 struct JSContext;
 struct JSObject;
 class nsIVariant;
 class nsIDOMNode;
 class nsIDOMUserDataHandler;
 template<class E> class nsCOMArray;
@@ -135,17 +136,26 @@ public:
    * @see nsIMutationObserver2::AttributeChildRemoved.
    */
   static void AttributeChildRemoved(nsINode* aAttribute, nsIContent* aChild);
   /**
    * Send ParentChainChanged notifications to nsIMutationObservers
    * @param aContent  The piece of content that had its parent changed.
    * @see nsIMutationObserver::ParentChainChanged
    */
-  static void ParentChainChanged(nsIContent *aContent);
+  static inline void ParentChainChanged(nsIContent *aContent)
+  {
+    nsINode::nsSlots* slots = aContent->GetExistingSlots();
+    if (slots && !slots->mMutationObservers.IsEmpty()) {
+      NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(slots->mMutationObservers,
+                                         nsIMutationObserver,
+                                         ParentChainChanged,
+                                         (aContent));
+    }
+  }
 
   /**
    * To be called when reference count of aNode drops to zero.
    * @param aNode The node which is going to be deleted.
    */
   static void LastRelease(nsINode* aNode);
 
   /**
--- a/content/base/src/nsRange.cpp
+++ b/content/base/src/nsRange.cpp
@@ -2166,21 +2166,32 @@ nsRange::SurroundContents(nsIDOMNode* aN
                     startGrandParent &&
                     startGrandParent == mEndParent) ||
                    (endIsText &&
                     endGrandParent &&
                     endGrandParent == mStartParent),
                    NS_ERROR_DOM_INVALID_STATE_ERR);
   }
 
+  // INVALID_NODE_TYPE_ERROR if aNewParent is something that can't be inserted
+  // (Document, DocumentType, DocumentFragment)
+  PRUint16 nodeType;
+  nsresult res = aNewParent->GetNodeType(&nodeType);
+  if (NS_FAILED(res)) return res;
+  if (nodeType == nsIDOMNode::DOCUMENT_NODE ||
+      nodeType == nsIDOMNode::DOCUMENT_TYPE_NODE ||
+      nodeType == nsIDOMNode::DOCUMENT_FRAGMENT_NODE) {
+    return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR;
+  }
+
   // Extract the contents within the range.
 
   nsCOMPtr<nsIDOMDocumentFragment> docFrag;
 
-  nsresult res = ExtractContents(getter_AddRefs(docFrag));
+  res = ExtractContents(getter_AddRefs(docFrag));
 
   if (NS_FAILED(res)) return res;
   if (!docFrag) return NS_ERROR_FAILURE;
 
   // Spec says we need to remove all of aNewParent's
   // children prior to insertion.
 
   nsCOMPtr<nsIDOMNodeList> children;
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -60,17 +60,16 @@
 #include "nsIScriptElement.h"
 #include "nsIDOMHTMLScriptElement.h"
 #include "nsIDocShell.h"
 #include "nsContentUtils.h"
 #include "nsUnicharUtils.h"
 #include "nsAutoPtr.h"
 #include "nsIXPConnect.h"
 #include "nsContentErrors.h"
-#include "nsIParser.h"
 #include "nsThreadUtils.h"
 #include "nsDocShellCID.h"
 #include "nsIContentSecurityPolicy.h"
 #include "prlog.h"
 #include "nsIChannelPolicy.h"
 #include "nsChannelPolicy.h"
 #include "nsCRT.h"
 #include "nsContentCreatorFunctions.h"
--- a/content/base/src/nsStyledElement.cpp
+++ b/content/base/src/nsStyledElement.cpp
@@ -215,50 +215,16 @@ nsStyledElementNotElementCSSInlineStyle:
 
   if (attrVal && attrVal->Type() == nsAttrValue::eCSSStyleRule) {
     return attrVal->GetCSSStyleRuleValue();
   }
 
   return nsnull;
 }
 
-nsresult
-nsStyledElementNotElementCSSInlineStyle::BindToTree(nsIDocument* aDocument,
-                                                    nsIContent* aParent,
-                                                    nsIContent* aBindingParent,
-                                                    bool aCompileEventHandlers)
-{
-  nsresult rv = nsStyledElementBase::BindToTree(aDocument, aParent,
-                                                aBindingParent,
-                                                aCompileEventHandlers);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (aDocument && HasID() && !GetBindingParent()) {
-    aDocument->AddToIdTable(this, DoGetID());
-  }
-
-  if (!IsXUL()) {
-    // XXXbz if we already have a style attr parsed, this won't do
-    // anything... need to fix that.
-    ReparseStyleAttribute(false);
-  }
-
-  return NS_OK;
-}
-
-void
-nsStyledElementNotElementCSSInlineStyle::UnbindFromTree(bool aDeep,
-                                                        bool aNullParent)
-{
-  RemoveFromIdTable();
-
-  nsStyledElementBase::UnbindFromTree(aDeep, aNullParent);
-}
-
-
 // ---------------------------------------------------------------
 // Others and helpers
 
 nsIDOMCSSStyleDeclaration*
 nsStyledElementNotElementCSSInlineStyle::GetStyle(nsresult* retval)
 {
   nsXULElement* xulElement = nsXULElement::FromContent(this);
   if (xulElement) {
--- a/content/base/src/nsStyledElement.h
+++ b/content/base/src/nsStyledElement.h
@@ -71,21 +71,16 @@ public:
   virtual nsIAtom* GetClassAttributeName() const;
   virtual nsIAtom* GetIDAttributeName() const;
   virtual nsIAtom* DoGetID() const;
   virtual const nsAttrValue* DoGetClasses() const;
 
   virtual mozilla::css::StyleRule* GetInlineStyleRule();
   NS_IMETHOD SetInlineStyleRule(mozilla::css::StyleRule* aStyleRule, bool aNotify);
 
-  virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
-                              nsIContent* aBindingParent,
-                              bool aCompileEventHandlers);
-  virtual void UnbindFromTree(bool aDeep, bool aNullParent);
-
   virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
                              bool aNotify);
   virtual nsresult AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
                                 const nsAttrValue* aValue, bool aNotify);
 
   nsIDOMCSSStyleDeclaration* GetStyle(nsresult* retval);
 
 protected:
@@ -99,16 +94,18 @@ protected:
    */
   void ParseStyleAttribute(const nsAString& aValue,
                            nsAttrValue& aResult,
                            bool aForceInDataDoc);
 
   virtual bool ParseAttribute(PRInt32 aNamespaceID, nsIAtom* aAttribute,
                                 const nsAString& aValue, nsAttrValue& aResult);
 
+  friend class nsGenericElement;
+
   /**
    * Create the style struct from the style attr.  Used when an element is
    * first put into a document.  Only has an effect if the old value is a
    * string.  If aForceInDataDoc is true, will reparse even if we're in a data
    * document.
    */
   nsresult  ReparseStyleAttribute(bool aForceInDataDoc);
 };
--- a/content/base/src/nsXMLContentSerializer.h
+++ b/content/base/src/nsXMLContentSerializer.h
@@ -46,17 +46,16 @@
 #define nsXMLContentSerializer_h__
 
 #include "nsIContent.h"
 #include "nsIContentSerializer.h"
 #include "nsISupportsUtils.h"
 #include "nsCOMPtr.h"
 #include "nsTArray.h"
 #include "nsString.h"
-#include "nsIParser.h"
 
 #define kIndentStr NS_LITERAL_STRING("  ")
 #define kEndTag NS_LITERAL_STRING("</")
 
 class nsIDOMNode;
 class nsIAtom;
 
 class nsXMLContentSerializer : public nsIContentSerializer {
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -2774,16 +2774,20 @@ nsXMLHttpRequest::Send(nsIVariant *aBody
   nsCOMPtr<nsIStreamListener> listener = this;
   if (mState & XML_HTTP_REQUEST_MULTIPART) {
     listener = new nsMultipartProxyListener(listener);
     if (!listener) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
+  // Blocking gets are common enough out of XHR that we should mark
+  // the channel slow by default for pipeline purposes
+  AddLoadFlags(mChannel, nsIRequest::INHIBIT_PIPELINE);
+
   if (!IsSystemXHR()) {
     // Always create a nsCORSListenerProxy here even if it's
     // a same-origin request right now, since it could be redirected.
     listener = new nsCORSListenerProxy(listener, mPrincipal, mChannel,
                                        withCredentials, true, &rv);
     NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
     NS_ENSURE_SUCCESS(rv, rv);
   }
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -565,16 +565,18 @@ include $(topsrcdir)/config/rules.mk
 		test_bug711047.html \
 		test_bug696301-1.html \
 		test_bug696301-2.html \
 		bug696301-script-1.js \
 		bug696301-script-1.js^headers^ \
 		bug696301-script-2.js \
 		test_bug737565.html \
 		test_bug737612.html \
+		test_bug738108.html \
+		test_bug366944.html \
 		$(NULL)
 
 _CHROME_FILES =	\
 		test_bug357450.js \
 		$(NULL)
 
 # This test fails on the Mac for some reason
 ifneq (,$(filter gtk2 windows,$(MOZ_WIDGET_TOOLKIT)))
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug366944.html
@@ -0,0 +1,49 @@
+<!doctype html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=366944
+-->
+<title>Test for Bug 366944</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=366944">Mozilla Bug 366944</a>
+<script>
+
+/** Test for Bug 366944 **/
+var testNodes = [document, document.doctype, document.createDocumentFragment()];
+for (var i = 0; i < testNodes.length; i++) {
+  var range = document.createRange();
+  // If a non-Text node is partially contained, we expect to throw for that
+  // first
+  range.setStart(document.head, 0);
+  range.setEnd(document.body, 0);
+  var threw = false;
+  var desc = " (surrounding a range with partially-contained Element "
+    + "with " + (i == 0 ? "document" : i == 1 ? "doctype" : "docfrag") + ")";
+  try {
+    range.surroundContents(testNodes[i]);
+  } catch(e) {
+    threw = true;
+    is(Object.getPrototypeOf(e), DOMException.prototype,
+       "Must throw DOMException" + desc);
+    is(e.name, "InvalidStateError", "Must throw InvalidStateError" + desc);
+  }
+  ok(threw, "Must throw" + desc);
+
+  range.setStart(document.body, 0);
+  range.setEnd(document.body, 1);
+  threw = false;
+  desc = " (surrounding a regular range "
+    + "with " + (i == 0 ? "document" : i == 1 ? "doctype" : "docfrag") + ")";
+  try {
+    range.surroundContents(testNodes[i]);
+  } catch(e) {
+    threw = true;
+    is(Object.getPrototypeOf(e), DOMException.prototype,
+       "Must throw DOMException" + desc);
+    is(e.name, "InvalidNodeTypeError",
+       "Must throw InvalidNodeTypeError" + desc);
+  }
+  ok(threw, "Must throw" + desc);
+}
+
+</script>
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug738108.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=738108
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 738108</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=738108">Mozilla Bug 738108</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  <div id="foo"></div>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 738108 **/
+is(document.querySelector("#foo"), $("foo"),
+   "querySelector on document should find element by id")
+is($("content").querySelector("#foo"), $("foo"),
+   "querySelector on parent element should find element by id")
+is($("foo").querySelector("#foo"), null,
+   "querySelector on element should not find the element itself by id")
+
+is(document.querySelectorAll("#foo").length, 1,
+   "querySelectorAll on document should find element by id")
+is($("content").querySelectorAll("#foo").length, 1,
+   "querySelectorAll on parent element should find element by id")
+is($("foo").querySelectorAll("#foo").length, 0,
+   "querySelectorall on element should not find the element itself by id")
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/canvas/src/ImageData.cpp
+++ b/content/canvas/src/ImageData.cpp
@@ -52,20 +52,20 @@ NS_IMETHODIMP
 ImageData::GetHeight(PRUint32* aHeight)
 {
   *aHeight = GetHeight();
   return NS_OK;
 }
 
 /* readonly attribute jsval data; */
 NS_IMETHODIMP
-ImageData::GetData(JS::Value* aData)
+ImageData::GetData(JSContext* aCx, JS::Value* aData)
 {
-  *aData = GetData();
-  return NS_OK;
+  *aData = JS::ObjectOrNullValue(GetDataObject());
+  return JS_WrapValue(aCx, aData) ? NS_OK : NS_ERROR_FAILURE;
 }
 
 void
 ImageData::HoldData()
 {
   NS_HOLD_JS_OBJECTS(this, ImageData);
 }
 
--- a/content/canvas/src/ImageData.h
+++ b/content/canvas/src/ImageData.h
@@ -46,20 +46,16 @@ public:
   uint32_t GetWidth()
   {
     return mWidth;
   }
   uint32_t GetHeight()
   {
     return mHeight;
   }
-  JS::Value GetData()
-  {
-    return JS::ObjectOrNullValue(GetDataObject());
-  }
   JSObject* GetDataObject()
   {
     xpc_UnmarkGrayObject(mData);
     return mData;
   }
 
 private:
   void HoldData();
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -52,16 +52,18 @@
 #include "nsIDOMDocument.h"
 #include "nsDOMError.h"
 #include "nsNodeInfoManager.h"
 #include "nsNetUtil.h"
 #include "nsXPCOMStrings.h"
 #include "nsThreadUtils.h"
 #include "nsIThreadInternal.h"
 #include "nsContentUtils.h"
+#include "nsIRequest.h"
+
 #include "nsFrameManager.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsIXPConnect.h"
 #include "jsapi.h"
 
 #include "nsITimer.h"
 
 #include "nsEventDispatcher.h"
@@ -2845,16 +2847,23 @@ nsresult nsHTMLMediaElement::GetBuffered
   return NS_OK;
 }
 
 void nsHTMLMediaElement::SetRequestHeaders(nsIHttpChannel* aChannel)
 {
   // Send Accept header for video and audio types only (Bug 489071)
   SetAcceptHeader(aChannel);
 
+  // Media elements are likely candidates for HTTP Pipeline head of line
+  // blocking problems, so disable pipelines.
+  nsLoadFlags loadflags;
+  aChannel->GetLoadFlags(&loadflags);
+  loadflags |= nsIRequest::INHIBIT_PIPELINE;
+  aChannel->SetLoadFlags(loadflags);
+
   // Apache doesn't send Content-Length when gzip transfer encoding is used,
   // which prevents us from estimating the video length (if explicit Content-Duration
   // and a length spec in the container are not present either) and from seeking.
   // So, disable the standard "Accept-Encoding: gzip,deflate" that we usually send.
   // See bug 614760.
   aChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept-Encoding"),
                              EmptyCString(), false);
 
--- a/content/html/document/src/MediaDocument.cpp
+++ b/content/html/document/src/MediaDocument.cpp
@@ -43,17 +43,17 @@
 #include "nsIPresShell.h"
 #include "nsIScrollable.h"
 #include "nsIViewManager.h"
 #include "nsITextToSubURI.h"
 #include "nsIURL.h"
 #include "nsIContentViewer.h"
 #include "nsIMarkupDocumentViewer.h"
 #include "nsIDocShell.h"
-#include "nsIParser.h" // kCharsetFrom* macro definition
+#include "nsCharsetSource.h" // kCharsetFrom* macro definition
 #include "nsNodeInfoManager.h"
 #include "nsContentUtils.h"
 
 namespace mozilla {
 namespace dom {
 
 MediaDocumentStreamListener::MediaDocumentStreamListener(MediaDocument *aDocument)
 {
--- a/content/html/document/src/nsHTMLContentSink.cpp
+++ b/content/html/document/src/nsHTMLContentSink.cpp
@@ -35,26 +35,31 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+/**
+ * This file is near-OBSOLETE. It is used for about:blank only and for the
+ * HTML element factory.
+ * Don't bother adding new stuff in this file.
+ */
+
 #include "mozilla/Util.h"
 
 #include "nsContentSink.h"
 #include "nsCOMPtr.h"
 #include "nsReadableUtils.h"
 #include "nsUnicharUtils.h"
 #include "nsIHTMLContentSink.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
-#include "nsIParser.h"
 #include "nsScriptLoader.h"
 #include "nsIURI.h"
 #include "nsNetUtil.h"
 #include "nsIContentViewer.h"
 #include "nsIMarkupDocumentViewer.h"
 #include "nsINodeInfo.h"
 #include "nsHTMLTokens.h"
 #include "nsIAppShell.h"
@@ -150,16 +155,20 @@ static const contentCreatorCallback sCon
 #undef HTML_HTMLELEMENT_TAG
 #undef HTML_OTHER
   NS_NewHTMLUnknownElement
 };
 
 class SinkContext;
 class HTMLContentSink;
 
+/**
+ * This class is near-OBSOLETE. It is used for about:blank only.
+ * Don't bother adding new stuff in this file.
+ */
 class HTMLContentSink : public nsContentSink,
 #ifdef DEBUG
                         public nsIDebugDumpContent,
 #endif
                         public nsIHTMLContentSink
 {
 public:
   friend class SinkContext;
--- a/content/smil/nsSMILAnimationFunction.cpp
+++ b/content/smil/nsSMILAnimationFunction.cpp
@@ -666,17 +666,17 @@ nsSMILAnimationFunction::ScaleSimpleProg
     return aProgress;
 
   PRUint32 numTimes = mKeyTimes.Length();
 
   if (numTimes < 2)
     return aProgress;
 
   PRUint32 i = 0;
-  for (; i < numTimes - 2 && aProgress >= mKeyTimes[i+1]; ++i) { }
+  for (; i < numTimes - 2 && aProgress >= mKeyTimes[i+1]; ++i);
 
   if (aCalcMode == CALC_DISCRETE) {
     // discrete calcMode behaviour differs in that each keyTime defines the time
     // from when the corresponding value is set, and therefore the last value
     // needn't be 1. So check if we're in the last 'interval', that is, the
     // space between the final value and 1.0.
     if (aProgress >= mKeyTimes[i+1]) {
       NS_ABORT_IF_FALSE(i == numTimes - 2,
--- a/content/smil/nsSMILTimedElement.cpp
+++ b/content/smil/nsSMILTimedElement.cpp
@@ -1762,17 +1762,17 @@ nsSMILTimedElement::GetNextInterval(cons
 
 nsSMILInstanceTime*
 nsSMILTimedElement::GetNextGreater(const InstanceTimeList& aList,
                                    const nsSMILTimeValue& aBase,
                                    PRInt32& aPosition) const
 {
   nsSMILInstanceTime* result = nsnull;
   while ((result = GetNextGreaterOrEqual(aList, aBase, aPosition)) &&
-         result->Time() == aBase) { }
+         result->Time() == aBase);
   return result;
 }
 
 nsSMILInstanceTime*
 nsSMILTimedElement::GetNextGreaterOrEqual(const InstanceTimeList& aList,
                                           const nsSMILTimeValue& aBase,
                                           PRInt32& aPosition) const
 {
--- a/content/xbl/src/nsBindingManager.cpp
+++ b/content/xbl/src/nsBindingManager.cpp
@@ -40,18 +40,16 @@
 
 #include "nsCOMPtr.h"
 #include "nsIXBLService.h"
 #include "nsIInputStream.h"
 #include "nsIURI.h"
 #include "nsIURL.h"
 #include "nsIChannel.h"
 #include "nsXPIDLString.h"
-#include "nsIParser.h"
-#include "nsParserCIID.h"
 #include "nsNetUtil.h"
 #include "plstr.h"
 #include "nsIContent.h"
 #include "nsIDOMElement.h"
 #include "nsIDocument.h"
 #include "mozilla/FunctionTimer.h"
 #include "nsContentUtils.h"
 #include "nsIPresShell.h"
--- a/content/xbl/src/nsXBLBinding.cpp
+++ b/content/xbl/src/nsXBLBinding.cpp
@@ -44,18 +44,16 @@
 #include "nsINameSpaceManager.h"
 #include "nsHashtable.h"
 #include "nsIURI.h"
 #include "nsIURL.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIChannel.h"
 #include "nsXPIDLString.h"
 #include "nsReadableUtils.h"
-#include "nsIParser.h"
-#include "nsParserCIID.h"
 #include "nsNetUtil.h"
 #include "plstr.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsContentUtils.h"
 #ifdef MOZ_XUL
 #include "nsIXULDocument.h"
 #endif
--- a/content/xbl/src/nsXBLContentSink.cpp
+++ b/content/xbl/src/nsXBLContentSink.cpp
@@ -37,17 +37,16 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/Util.h"
 
 #include "nsXBLContentSink.h"
 #include "nsIDocument.h"
 #include "nsBindingManager.h"
 #include "nsIDOMNode.h"
-#include "nsIParser.h"
 #include "nsGkAtoms.h"
 #include "nsINameSpaceManager.h"
 #include "nsHTMLTokens.h"
 #include "nsIURI.h"
 #include "nsTextFragment.h"
 #ifdef MOZ_XUL
 #include "nsXULElement.h"
 #endif
@@ -419,36 +418,39 @@ nsXBLContentSink::OnOpenContainer(const 
   if (aNameSpaceID != kNameSpaceID_XBL) {
     // Construct non-XBL nodes
     return true;
   }
 
   bool ret = true;
   if (aTagName == nsGkAtoms::bindings) {
     ENSURE_XBL_STATE(mState == eXBL_InDocument);
-      
-    mDocInfo = NS_NewXBLDocumentInfo(mDocument);
+
+    NS_ASSERTION(mDocument, "Must have a document!");
+    nsRefPtr<nsXBLDocumentInfo> info = new nsXBLDocumentInfo(mDocument);
+
+    // We keep a weak ref. We're creating a cycle between doc/binding manager/doc info.
+    mDocInfo = info;
+
     if (!mDocInfo) {
       mState = eXBL_Error;
       return true;
     }
 
     mDocument->BindingManager()->PutXBLDocumentInfo(mDocInfo);
 
     nsIURI *uri = mDocument->GetDocumentURI();
-      
+
     bool isChrome = false;
     bool isRes = false;
 
     uri->SchemeIs("chrome", &isChrome);
     uri->SchemeIs("resource", &isRes);
     mIsChromeOrResource = isChrome || isRes;
-      
-    nsXBLDocumentInfo* info = mDocInfo;
-    NS_RELEASE(info); // We keep a weak ref. We've created a cycle between doc/binding manager/doc info.
+
     mState = eXBL_InBindings;
   }
   else if (aTagName == nsGkAtoms::binding) {
     ENSURE_XBL_STATE(mState == eXBL_InBindings);
     mState = eXBL_InBinding;
   }
   else if (aTagName == nsGkAtoms::handlers) {
     ENSURE_XBL_STATE(mState == eXBL_InBinding && mBinding);
--- a/content/xbl/src/nsXBLDocumentInfo.cpp
+++ b/content/xbl/src/nsXBLDocumentInfo.cpp
@@ -677,17 +677,18 @@ nsXBLDocumentInfo::ReadPrototypeBindings
   nsContentUtils::GetSecurityManager()->
     GetSystemPrincipal(getter_AddRefs(principal));
 
   nsCOMPtr<nsIDOMDocument> domdoc;
   rv = NS_NewXBLDocument(getter_AddRefs(domdoc), aURI, nsnull, principal);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
-  nsRefPtr<nsXBLDocumentInfo> docInfo = NS_NewXBLDocumentInfo(doc);
+  NS_ASSERTION(doc, "Must have a document!");
+  nsRefPtr<nsXBLDocumentInfo> docInfo = new nsXBLDocumentInfo(doc);
 
   while (1) {
     PRUint8 flags;
     nsresult rv = stream->Read8(&flags);
     NS_ENSURE_SUCCESS(rv, rv);
     if (flags == XBLBinding_Serialize_NoMoreBindings)
       break;
 
@@ -778,19 +779,8 @@ nsXBLDocumentInfo::GetScriptGlobalObject
     if (!global)
       return nsnull;
 
     mGlobalObject = global;
   }
 
   return mGlobalObject;
 }
-
-nsXBLDocumentInfo* NS_NewXBLDocumentInfo(nsIDocument* aDocument)
-{
-  NS_PRECONDITION(aDocument, "Must have a document!");
-
-  nsXBLDocumentInfo* result;
-
-  result = new nsXBLDocumentInfo(aDocument);
-  NS_ADDREF(result);
-  return result;
-}
--- a/content/xbl/src/nsXBLDocumentInfo.h
+++ b/content/xbl/src/nsXBLDocumentInfo.h
@@ -96,11 +96,9 @@ private:
   // the binding table owns each nsXBLPrototypeBinding
   nsObjectHashtable* mBindingTable;
   // non-owning pointer to the first binding in the table
   nsXBLPrototypeBinding* mFirstBinding;
 
   nsRefPtr<nsXBLDocGlobalObject> mGlobalObject;
 };
 
-nsXBLDocumentInfo* NS_NewXBLDocumentInfo(nsIDocument* aDocument);
-
 #endif
--- a/content/xbl/src/nsXBLPrototypeBinding.cpp
+++ b/content/xbl/src/nsXBLPrototypeBinding.cpp
@@ -43,18 +43,16 @@
 #include "nsIInputStream.h"
 #include "nsINameSpaceManager.h"
 #include "nsIURI.h"
 #include "nsIURL.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIChannel.h"
 #include "nsXPIDLString.h"
 #include "nsReadableUtils.h"
-#include "nsIParser.h"
-#include "nsParserCIID.h"
 #include "nsNetUtil.h"
 #include "plstr.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsIDocument.h"
 #include "nsIXMLContentSink.h"
 #include "nsContentCID.h"
 #include "nsXMLDocument.h"
 #include "nsXBLService.h"
@@ -1321,17 +1319,18 @@ nsXBLPrototypeBinding::ConstructInsertio
       // Annotate the insertion point with our default content.
       xblIns->SetDefaultContent(child);
 
       // Reconnect back to our parent for access later.  This makes "inherits" easier
       // to work with on default content.
       // XXXbz this is somewhat screwed up, since it's sort of like anonymous
       // content... but not.
       nsresult rv =
-        child->BindToTree(parent->GetCurrentDoc(), parent, nsnull, false);
+        child->BindToTree(parent->GetCurrentDoc(), parent,
+                          parent->GetBindingParent(), false);
       if (NS_FAILED(rv)) {
         // Well... now what?  Just unbind and bail out, I guess...
         // XXXbz This really shouldn't be a void method!
         child->UnbindFromTree();
         return;
       }
     }
   }
@@ -1992,17 +1991,18 @@ nsXBLPrototypeBinding::ReadContentNode(n
     // If the insertion point has default content, read it.
     nsCOMPtr<nsIContent> defaultContent;
     rv = ReadContentNode(aStream, aDocument, aNim, getter_AddRefs(defaultContent));
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (defaultContent) {
       xblIns->SetDefaultContent(defaultContent);
 
-      rv = defaultContent->BindToTree(nsnull, content, nsnull, false);
+      rv = defaultContent->BindToTree(nsnull, content,
+                                      content->GetBindingParent(), false);
       if (NS_FAILED(rv)) {
         defaultContent->UnbindFromTree();
         return rv;
       }
     }
 
     if (!mInsertionPointTable) {
       mInsertionPointTable = new nsObjectHashtable(nsnull, nsnull,
@@ -2318,17 +2318,17 @@ bool CheckTagNameWhiteList(PRInt32 aName
   if (aNameSpaceID == kNameSpaceID_XUL) {
     for (i = 0; kValidXULTagNames[i]; ++i) {
       if (aTagName == *(kValidXULTagNames[i])) {
         return true;
       }
     }
   }
   else if (aNameSpaceID == kNameSpaceID_SVG &&
-           aTagName == nsGkAtoms::generic) {
+           aTagName == nsGkAtoms::generic_) {
     return true;
   }
 
   return false;
 }
 
 nsresult
 nsXBLPrototypeBinding::ResolveBaseBinding()
--- a/content/xbl/src/nsXBLService.cpp
+++ b/content/xbl/src/nsXBLService.cpp
@@ -48,18 +48,16 @@
 #include "nsIInputStream.h"
 #include "nsINameSpaceManager.h"
 #include "nsHashtable.h"
 #include "nsIURI.h"
 #include "nsIDOMElement.h"
 #include "nsIURL.h"
 #include "nsIChannel.h"
 #include "nsXPIDLString.h"
-#include "nsIParser.h"
-#include "nsParserCIID.h"
 #include "plstr.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsIXMLContentSink.h"
 #include "nsContentCID.h"
 #include "nsXMLDocument.h"
 #include "mozilla/FunctionTimer.h"
 #include "nsGkAtoms.h"
@@ -1103,21 +1101,17 @@ nsXBLService::LoadBindingDocumentInfo(ns
         if (bindingManager) {
           // Also put it in our binding manager's document table.
           bindingManager->PutXBLDocumentInfo(info);
         }
       }
     }
   }
 
-  if (!info)
-    return NS_OK;
- 
-  *aResult = info;
-  NS_IF_ADDREF(*aResult);
+  info.forget(aResult);
 
   return NS_OK;
 }
 
 nsresult
 nsXBLService::FetchBindingDocument(nsIContent* aBoundElement, nsIDocument* aBoundDocument,
                                    nsIURI* aDocumentURI, nsIURI* aBindingURI, 
                                    bool aForceSyncLoad, nsIDocument** aResult)
--- a/content/xml/document/src/nsXMLDocument.cpp
+++ b/content/xml/document/src/nsXMLDocument.cpp
@@ -34,17 +34,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 
 #include "nsXMLDocument.h"
 #include "nsParserCIID.h"
-#include "nsIParser.h"
+#include "nsCharsetSource.h"
 #include "nsIXMLContentSink.h"
 #include "nsPresContext.h" 
 #include "nsIContent.h"
 #include "nsIContentViewerContainer.h"
 #include "nsIContentViewer.h"
 #include "nsIDocShell.h"
 #include "nsIMarkupDocumentViewer.h"
 #include "nsHTMLParts.h"
--- a/content/xml/document/src/nsXMLFragmentContentSink.cpp
+++ b/content/xml/document/src/nsXMLFragmentContentSink.cpp
@@ -38,17 +38,16 @@
  * ***** END LICENSE BLOCK ***** */
 #include "nsCOMPtr.h"
 #include "nsXMLContentSink.h"
 #include "nsIFragmentContentSink.h"
 #include "nsIXMLContentSink.h"
 #include "nsContentSink.h"
 #include "nsIExpatSink.h"
 #include "nsIDTD.h"
-#include "nsIParser.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocumentFragment.h"
 #include "nsIContent.h"
 #include "nsGkAtoms.h"
 #include "nsINodeInfo.h"
 #include "nsNodeInfoManager.h"
 #include "nsNullPrincipal.h"
 #include "nsContentCreatorFunctions.h"
--- a/content/xslt/src/base/txExpandedNameMap.h
+++ b/content/xslt/src/base/txExpandedNameMap.h
@@ -97,26 +97,28 @@ protected:
 
         bool next()
         {
             return ++mCurrentPos < mMap.mItems.Length();
         }
 
         const txExpandedName key()
         {
-            NS_ASSERTION(mCurrentPos < mMap.mItems.Length(),
+            NS_ASSERTION(mCurrentPos >= 0 &&
+                         mCurrentPos < mMap.mItems.Length(),
                          "invalid position in txExpandedNameMap::iterator");
             return txExpandedName(mMap.mItems[mCurrentPos].mNamespaceID,
                                   mMap.mItems[mCurrentPos].mLocalName);
         }
 
     protected:
         void* itemValue()
         {
-            NS_ASSERTION(mCurrentPos < mMap.mItems.Length(),
+            NS_ASSERTION(mCurrentPos >= 0 &&
+                         mCurrentPos < mMap.mItems.Length(),
                          "invalid position in txExpandedNameMap::iterator");
             return mMap.mItems[mCurrentPos].mValue;
         }
 
     private:
         txExpandedNameMap_base& mMap;
         PRUint32 mCurrentPos;
     };
--- a/content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp
+++ b/content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp
@@ -45,16 +45,17 @@
 #include "nsIDocument.h"
 #include "nsIExpatSink.h"
 #include "nsIChannelEventSink.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsILoadGroup.h"
 #include "nsINameSpaceManager.h"
 #include "nsINodeInfo.h"
 #include "nsIParser.h"
+#include "nsCharsetSource.h"
 #include "nsIRequestObserver.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsContentPolicyUtils.h"
 #include "nsIStreamConverterService.h"
 #include "nsSyncLoadService.h"
 #include "nsIURI.h"
 #include "nsIPrincipal.h"
 #include "nsIWindowWatcher.h"
--- a/content/xslt/src/xslt/txMozillaTextOutput.cpp
+++ b/content/xslt/src/xslt/txMozillaTextOutput.cpp
@@ -39,17 +39,17 @@
 #include "txMozillaTextOutput.h"
 #include "nsContentCID.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMDocumentFragment.h"
 #include "nsIDocumentTransformer.h"
 #include "nsNetUtil.h"
-#include "nsIParser.h"
+#include "nsCharsetSource.h"
 #include "nsCharsetAlias.h"
 #include "nsIPrincipal.h"
 #include "txURIUtils.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsContentUtils.h"
 #include "nsGkAtoms.h"
 
 using namespace mozilla::dom;
--- a/content/xslt/src/xslt/txMozillaXMLOutput.cpp
+++ b/content/xslt/src/xslt/txMozillaXMLOutput.cpp
@@ -39,17 +39,17 @@
 #include "txMozillaXMLOutput.h"
 
 #include "nsIDocument.h"
 #include "nsIDocShell.h"
 #include "nsScriptLoader.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMDocumentType.h"
 #include "nsIScriptElement.h"
-#include "nsIParser.h"
+#include "nsCharsetSource.h"
 #include "nsIRefreshURI.h"
 #include "nsPIDOMWindow.h"
 #include "nsIContent.h"
 #include "nsContentCID.h"
 #include "nsNetUtil.h"
 #include "nsUnicharUtils.h"
 #include "nsGkAtoms.h"
 #include "txLog.h"
--- a/content/xul/document/src/nsXULContentSink.cpp
+++ b/content/xul/document/src/nsXULContentSink.cpp
@@ -57,17 +57,16 @@
 #include "nsIDOMEventListener.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIDOMXULDocument.h"
 #include "nsIDocument.h"
 #include "nsIFormControl.h"
 #include "nsHTMLStyleSheet.h"
 #include "nsINameSpaceManager.h"
 #include "nsINodeInfo.h"
-#include "nsIParser.h"
 #include "nsIScriptContext.h"
 #include "nsIScriptRuntime.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIServiceManager.h"
 #include "nsIURL.h"
 #include "nsIViewManager.h"
 #include "nsIXULDocument.h"
 #include "nsIScriptSecurityManager.h"
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -106,16 +106,17 @@
 #include "nsIScriptGlobalObject.h"
 #include "nsIScriptGlobalObjectOwner.h"
 #include "nsIScriptRuntime.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsNodeInfoManager.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsContentUtils.h"
 #include "nsIParser.h"
+#include "nsCharsetSource.h"
 #include "nsIParserService.h"
 #include "nsCSSStyleSheet.h"
 #include "mozilla/css/Loader.h"
 #include "nsIScriptError.h"
 #include "nsIStyleSheetLinkingElement.h"
 #include "nsEventDispatcher.h"
 #include "nsContentErrors.h"
 #include "nsIObserverService.h"
--- a/content/xul/templates/src/nsXULTemplateBuilder.cpp
+++ b/content/xul/templates/src/nsXULTemplateBuilder.cpp
@@ -279,16 +279,21 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
     }
     for (PRUint32 i = 0; i < tmp->mQuerySets.Length(); ++i) {
         nsTemplateQuerySet* qs = tmp->mQuerySets[i];
         delete qs;
     }
     tmp->mQuerySets.Clear();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULTemplateBuilder)
+    if (tmp->mObservedDocument && !cb.WantAllTraces()) {
+        // The global observer service holds us alive.
+        return NS_SUCCESS_INTERRUPTED_TRAVERSE;
+    }
+
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDataSource)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDB)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCompDB)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mRoot)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mRootResult)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mListeners)
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mQueryProcessor)
     if (tmp->mMatchMap.IsInitialized())
--- a/docshell/base/nsIWebShellServices.h
+++ b/docshell/base/nsIWebShellServices.h
@@ -33,17 +33,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #ifndef nsIWebShellServices_h___
 #define nsIWebShellServices_h___
 
 #include "nsISupports.h"
-#include "nsIParser.h"
+#include "nsCharsetSource.h"
 
 // Interface ID for nsIWebShellServices
 
 /* 0c628af0-5638-4703-8f99-ed6134c9de18 */
 #define NS_IWEB_SHELL_SERVICES_IID \
 { 0x0c628af0, 0x5638, 0x4703, {0x8f, 0x99, 0xed, 0x61, 0x34, 0xc9, 0xde, 0x18} }
 
 //----------------------------------------------------------------------
--- a/dom/base/Webapps.jsm
+++ b/dom/base/Webapps.jsm
@@ -400,17 +400,17 @@ DOMApplicationManifest = function(aManif
   this._localeRoot = this._manifest;
   
   if (this._manifest.locales && this._manifest.locales[locale]) {
     this._localeRoot = this._manifest.locales[locale];
   }
   else if (this._manifest.locales) {
     // try with the language part of the locale ("en" for en-GB) only
     let lang = locale.split('-')[0];
-    if (land != locale && this._manifest.locales[lang])
+    if (lang != locale && this._manifest.locales[lang])
       this._localeRoot = this._manifest.locales[lang];
   }
 }
 
 DOMApplicationManifest.prototype = {
   _localeProp: function(aProp) {
     if (this._localeRoot[aProp] != undefined)
       return this._localeRoot[aProp];
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -5245,20 +5245,18 @@ nsWindowSH::GlobalScopePolluterNewResolv
     // resolving a class name, doing a qualified resolve, or
     // resolving a number.
 
     return JS_TRUE;
   }
 
   nsHTMLDocument *document = GetDocument(obj);
 
-  if (!document ||
-      document->GetCompatibilityMode() != eCompatibility_NavQuirks) {
-    // If we don't have a document, or if the document is not in
-    // quirks mode, return early.
+  if (!document) {
+    // If we don't have a document, return early.
 
     return JS_TRUE;
   }
 
   JSObject *proto = ::JS_GetPrototype(obj);
   JSBool hasProp;
 
   if (!proto || !::JS_HasPropertyById(cx, proto, id, &hasProp) ||
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -55,17 +55,17 @@
 #include "nsIScrollableFrame.h"
 
 #include "nsContentUtils.h"
 #include "nsLayoutUtils.h"
 
 #include "nsIFrame.h"
 #include "nsIWidget.h"
 #include "nsGUIEvent.h"
-#include "nsIParser.h"
+#include "nsCharsetSource.h"
 #include "nsJSEnvironment.h"
 #include "nsJSUtils.h"
 
 #include "nsIViewManager.h"
 
 #include "nsIDOMHTMLCanvasElement.h"
 #include "gfxContext.h"
 #include "gfxImageSurface.h"
--- a/dom/base/test/Makefile.in
+++ b/dom/base/test/Makefile.in
@@ -41,13 +41,15 @@ srcdir = @srcdir@
 VPATH = @srcdir@
 relativesrcdir = dom/base/test
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
 TEST_FILES = \
   test_domrequest.html \
+  test_gsp-standards.html \
+  test_gsp-quirks.html \
   $(NULL)
 
 libs:: $(TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
 
new file mode 100644
--- /dev/null
+++ b/dom/base/test/test_gsp-quirks.html
@@ -0,0 +1,27 @@
+<!-- Purposefully in quirks mode -->
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=622491
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 622491</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=622491">Mozilla Bug 622491</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 622491 **/
+is(test, document.getElementById("test"), "Global scope polluter should map ids")
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/base/test/test_gsp-standards.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=622491
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 622491</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=622491">Mozilla Bug 622491</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 622491 **/
+is(test, document.getElementById("test"), "Global scope polluter should map ids")
+
+</script>
+</pre>
+</body>
+</html>
--- a/dom/interfaces/canvas/nsIDOMCanvasRenderingContext2D.idl
+++ b/dom/interfaces/canvas/nsIDOMCanvasRenderingContext2D.idl
@@ -62,17 +62,17 @@ interface nsIDOMTextMetrics : nsISupport
   readonly attribute float width;
 };
 
 [scriptable, builtinclass, uuid(1ea11207-b3e3-4ffc-a256-bf5c7011e806)]
 interface nsIDOMImageData : nsISupports
 {
   readonly attribute unsigned long width;
   readonly attribute unsigned long height;
-  readonly attribute jsval data;
+  [implicit_jscontext] readonly attribute jsval data;
 };
 
 [scriptable, uuid(c835c768-2dcc-461c-82f5-3653710d2942)]
 interface nsIDOMCanvasRenderingContext2D : nsISupports
 {
   // back-reference to the canvas element for which
   // this context was created
   readonly attribute nsIDOMHTMLCanvasElement canvas;
--- a/dom/system/gonk/GonkGPSGeolocationProvider.cpp
+++ b/dom/system/gonk/GonkGPSGeolocationProvider.cpp
@@ -98,18 +98,18 @@ static GpsCallbacks gCallbacks = {
   NULL, /* SetCapabilitiesCallback */
   NULL, /* AcquireWakelockCallback */
   NULL, /* ReleaseWakelockCallback */
   CreateThreadCallback,
 };
 
 GonkGPSGeolocationProvider::GonkGPSGeolocationProvider()
   : mStarted(false)
+  , mGpsInterface(nsnull)
 {
-  mGpsInterface = GetGPSInterface();
 }
 
 GonkGPSGeolocationProvider::~GonkGPSGeolocationProvider()
 {
   Shutdown();
   sSingleton = NULL;
 }
 
@@ -138,54 +138,65 @@ GonkGPSGeolocationProvider::GetGPSInterf
   if (hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module))
     return NULL;
 
   hw_device_t* device;
   if (module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device))
     return NULL;
 
   gps_device_t* gps_device = (gps_device_t *)device;
-  return gps_device->get_gps_interface(gps_device);
+  const GpsInterface* result = gps_device->get_gps_interface(gps_device);
+
+  if (result->size != sizeof(GpsInterface)) {
+    return nsnull;
+  }
+  return result;
 }
 
 NS_IMETHODIMP
 GonkGPSGeolocationProvider::Startup()
 {
   if (mStarted)
     return NS_OK;
 
+  mGpsInterface = GetGPSInterface();
+
   NS_ENSURE_TRUE(mGpsInterface, NS_ERROR_FAILURE);
 
   PRInt32 update = Preferences::GetInt("geo.default.update", 1000);
 
-  mGpsInterface->init(&gCallbacks);
+  if (mGpsInterface->init(&gCallbacks) != 0)
+    return NS_ERROR_FAILURE;
+
   mGpsInterface->start();
   mGpsInterface->set_position_mode(GPS_POSITION_MODE_STANDALONE,
                                    GPS_POSITION_RECURRENCE_PERIODIC,
                                    update, 0, 0);
+
+  mStarted = true;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 GonkGPSGeolocationProvider::Watch(nsIGeolocationUpdate* aCallback)
 {
   mLocationCallback = aCallback;
-
   return NS_OK;
 }
 
 NS_IMETHODIMP
 GonkGPSGeolocationProvider::Shutdown()
 {
   if (!mStarted)
     return NS_OK;
 
+  NS_ENSURE_TRUE(mGpsInterface, NS_OK);
+
   mGpsInterface->stop();
   mGpsInterface->cleanup();
-
   return NS_OK;
 }
 
 NS_IMETHODIMP
 GonkGPSGeolocationProvider::SetHighAccuracy(bool)
 {
   return NS_OK;
 }
--- a/dom/system/nsDeviceMotion.cpp
+++ b/dom/system/nsDeviceMotion.cpp
@@ -121,17 +121,16 @@ NS_IMETHODIMP nsDeviceMotionData::GetZ(d
 
 NS_IMPL_ISUPPORTS1(nsDeviceMotion, nsIDeviceMotion)
 
 nsDeviceMotion::nsDeviceMotion()
 : mStarted(false),
   mEnabled(true)
 {
   mLastDOMMotionEventTime = TimeStamp::Now();
-  mLastAccuracy = SENSOR_ACCURACY_UNKNOWN;
 
   nsCOMPtr<nsIPrefBranch> prefSrv = do_GetService(NS_PREFSERVICE_CONTRACTID);
   if (prefSrv) {
     bool bvalue;
     nsresult rv = prefSrv->GetBoolPref("device.motion.enabled", &bvalue);
     if (NS_SUCCEEDED(rv) && bvalue == false)
       mEnabled = false;
   }
@@ -235,23 +234,16 @@ nsDeviceMotion::Notify(const mozilla::ha
     return;
 
   PRUint32 type = aSensorData.sensor();
 
   double x = aSensorData.values()[0];
   double y = aSensorData.values()[1];
   double z = aSensorData.values()[2];
 
-  SensorAccuracyType accuracy = aSensorData.accuracy();
-
-  if (accuracy <= SENSOR_ACCURACY_LOW && mLastAccuracy >= SENSOR_ACCURACY_MED) {
-    FireNeedsCalibration();
-  }
-  mLastAccuracy = accuracy;
-
   nsCOMArray<nsIDeviceMotionListener> listeners = mListeners;
   for (PRUint32 i = listeners.Count(); i > 0 ; ) {
     --i;
     nsRefPtr<nsDeviceMotionData> a = new nsDeviceMotionData(type, x, y, z);
     listeners[i]->OnMotionChange(a);
   }
 
   nsCOMArray<nsIDOMWindow> windowListeners;
@@ -281,72 +273,16 @@ nsDeviceMotion::Notify(const mozilla::ha
         FireDOMMotionEvent(domdoc, target, type, x, y, z);
       else if (type == nsIDeviceMotionData::TYPE_ORIENTATION)
         FireDOMOrientationEvent(domdoc, target, x, y, z);
     }
   }
 }
 
 void
-nsDeviceMotion::FireNeedsCalibration()
-{
-  if (!mEnabled)
-    return;
-
-  nsCOMArray<nsIDeviceMotionListener> listeners = mListeners;
-  for (PRUint32 i = listeners.Count(); i > 0 ; ) {
-    --i;
-    listeners[i]->NeedsCalibration();
-  }
-
-  nsCOMArray<nsIDOMWindow> windowListeners;
-  for (PRUint32 i = 0; i < mWindowListeners.Length(); i++) {
-    windowListeners.AppendObject(mWindowListeners[i]);
-  }
-
-  for (PRUint32 i = windowListeners.Count(); i > 0 ; ) {
-    --i;
-
-    // check to see if this window is in the background.  if
-    // it is, don't send any device motion to it.
-    nsCOMPtr<nsPIDOMWindow> pwindow = do_QueryInterface(windowListeners[i]);
-    if (!pwindow ||
-        !pwindow->GetOuterWindow() ||
-        pwindow->GetOuterWindow()->IsBackground())
-      continue;
-
-    nsCOMPtr<nsIDOMDocument> domdoc;
-    windowListeners[i]->GetDocument(getter_AddRefs(domdoc));
-
-    if (domdoc) {
-	nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(windowListeners[i]);
-        FireNeedsCalibration(domdoc, target);
-    }
-  }
-}
-
-void
-nsDeviceMotion::FireNeedsCalibration(nsIDOMDocument *domdoc,
-				    nsIDOMEventTarget *target)
-{
-  nsCOMPtr<nsIDOMEvent> event;
-  domdoc->CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event));
-  if (!event)
-    return;
-
-  event->InitEvent(NS_LITERAL_STRING("compassneedscalibration"), true, false);
-  nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(event);
-  if (privateEvent)
-    privateEvent->SetTrusted(true);
-  
-  bool defaultActionEnabled = true;
-  target->DispatchEvent(event, &defaultActionEnabled);
-}
-
-void
 nsDeviceMotion::FireDOMOrientationEvent(nsIDOMDocument *domdoc,
                                         nsIDOMEventTarget *target,
                                         double alpha,
                                         double beta,
                                         double gamma)
 {
   nsCOMPtr<nsIDOMEvent> event;
   bool defaultActionEnabled = true;
--- a/dom/system/nsDeviceMotion.h
+++ b/dom/system/nsDeviceMotion.h
@@ -77,21 +77,16 @@ private:
   void StartDisconnectTimer();
 
   bool mStarted;
 
   nsCOMPtr<nsITimer> mTimeoutTimer;
   static void TimeoutHandler(nsITimer *aTimer, void *aClosure);
 
  protected:
-  void FireNeedsCalibration();
-
-  void FireNeedsCalibration(nsIDOMDocument *domdoc,
-			    nsIDOMEventTarget *target);
-
   void FireDOMOrientationEvent(class nsIDOMDocument *domDoc, 
                                class nsIDOMEventTarget *target,
                                double alpha,
                                double beta,
                                double gamma);
 
   void FireDOMMotionEvent(class nsIDOMDocument *domDoc, 
                           class nsIDOMEventTarget *target,
@@ -100,15 +95,14 @@ private:
                           double y,
                           double z);
 
   void Startup();
   void Shutdown();
 
   bool mEnabled;
   mozilla::TimeStamp mLastDOMMotionEventTime;
-  mozilla::hal::SensorAccuracyType mLastAccuracy;
   nsRefPtr<nsDOMDeviceAcceleration> mLastAcceleration;
   nsRefPtr<nsDOMDeviceAcceleration> mLastAccelerationIncluduingGravity;
   nsRefPtr<nsDOMDeviceRotationRate> mLastRotationRate;
 };
 
 #endif
--- a/dom/system/unix/QTMLocationProvider.cpp
+++ b/dom/system/unix/QTMLocationProvider.cpp
@@ -111,8 +111,13 @@ QTMLocationProvider::Shutdown()
         return NS_ERROR_NOT_IMPLEMENTED;
 
     mLocation->stopUpdates();
     mCallback = nsnull;
 
     return NS_OK;
 }
 
+NS_IMETHODIMP
+QTMLocationProvider::SetHighAccuracy(bool)
+{
+  return NS_OK;
+}
--- a/dom/tests/mochitest/chrome/sizemode_attribute.xul
+++ b/dom/tests/mochitest/chrome/sizemode_attribute.xul
@@ -5,17 +5,16 @@
   Test for fullscreen sizemode in chrome
   -->
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         persist="sizemode"
         sizemode="normal"
         onload="nextStep()">
 
 <script type="text/javascript;version=1.8">
-let testNum = 0;
 let tests = [
   function test1() {
     checkAndContinue("normal");
   },
 
   function test2() {
     listen("fullscreen", function() checkAndContinue("fullscreen"));
     window.fullScreen = true;
@@ -47,17 +46,16 @@ let tests = [
   },
 
   function test8() {
     window.opener.wrappedJSObject.done();
   }
 ];
 
 function nextStep() {
-  testNum++;
   tests.shift()();
 }
 
 function listen(event, fn) {
   window.addEventListener(event, function listener() {
     window.removeEventListener(event, listener, false);
     fn();
   }, false);
@@ -67,26 +65,19 @@ function checkAndContinue(sizemode) {
 
   let windowStates = {
     "fullscreen": window.STATE_FULLSCREEN,
     "normal": window.STATE_NORMAL,
     "maximized": window.STATE_MAXIMIZED
   };
 
   setTimeout(function() {
-    // The sizemode attribute is wrong when the window is in fullscreen.
-    // cf. bug 714911
-    if (sizemode != "fullscreen") {
-      is(window.document.documentElement.getAttribute("sizemode"), sizemode,
-         "Test " + testNum + ": sizemode attribute should match actual window state");
-    }
-    is(window.fullScreen, sizemode == "fullscreen",
-       "Test " + testNum + ": window.fullScreen should match actual window state");
-    is(window.windowState, windowStates[sizemode],
-       "Test " + testNum + ": window.sizeMode should match actual window state");
+    is(window.document.documentElement.getAttribute("sizemode"), sizemode, "sizemode attribute should match actual window state");
+    is(window.fullScreen, sizemode == "fullscreen", "window.fullScreen should match actual window state");
+    is(window.windowState, windowStates[sizemode], "window.sizeMode should match actual window state");
     nextStep();
   }, 0);
 }
 
 let is = window.opener.wrappedJSObject.is;
 
 </script>
 
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -1279,23 +1279,26 @@ public:
 
   NS_IMETHOD
   Dispatch(nsIRunnable* aRunnable, PRUint32 aFlags)
   {
     NS_ASSERTION(aFlags == nsIEventTarget::DISPATCH_NORMAL, "Don't call me!");
 
     nsRefPtr<WorkerRunnableEventTarget> kungFuDeathGrip = this;
 
+    // Run the runnable we're given now (should just call DummyCallback()),
+    // otherwise the timer thread will leak it...  If we run this after
+    // dispatch running the event can race against resetting the timer.
+    aRunnable->Run();
+
     // This can fail if we're racing to terminate or cancel, should be handled
     // by the terminate or cancel code.
     mWorkerRunnable->Dispatch(nsnull);
 
-    // Run the runnable we're given now (should just call DummyCallback()),
-    // otherwise the timer thread will leak it...
-    return aRunnable->Run();
+    return NS_OK;
   }
 
   NS_IMETHOD
   IsOnCurrentThread(bool* aIsOnCurrentThread)
   {
     *aIsOnCurrentThread = false;
     return NS_OK;
   }
--- a/editor/libeditor/html/nsHTMLDataTransfer.cpp
+++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp
@@ -71,18 +71,16 @@
 #include "nsIFile.h"
 #include "nsIURL.h"
 #include "nsIComponentManager.h"
 #include "nsIServiceManager.h"
 #include "nsIDocumentEncoder.h"
 #include "nsIDOMDocumentFragment.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
-#include "nsIParser.h"
-#include "nsParserCIID.h"
 #include "nsXPCOM.h"
 #include "nsISupportsPrimitives.h"
 #include "nsLinebreakConverter.h"
 #include "nsHtml5Module.h"
 #include "nsTreeSanitizer.h"
 
 // netwerk
 #include "nsIURI.h"
@@ -128,18 +126,16 @@
 #include "nsContentUtils.h"
 #include "mozilla/Preferences.h"
 #include "nsIParserUtils.h"
 
 using namespace mozilla;
 
 const PRUnichar nbsp = 160;
 
-static NS_DEFINE_CID(kCParserCID,     NS_PARSER_CID);
-
 #define kInsertCookie  "_moz_Insert Here_moz_"
 
 #define NS_FOUND_TARGET NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_EDITOR, 3)
 
 // some little helpers
 static bool FindIntegerAfterString(const char *aLeadingString, 
                                      nsCString &aCStr, PRInt32 &foundNumber);
 static nsresult RemoveFragComments(nsCString &theStr);
--- a/gfx/gl/GLContextProviderEGL.cpp
+++ b/gfx/gl/GLContextProviderEGL.cpp
@@ -275,17 +275,17 @@ public:
         : GLContext(aFormat, aIsOffscreen, aShareContext)
         , mConfig(aConfig) 
         , mSurface(aSurface), mContext(aContext)
         , mPlatformContext(nsnull)
         , mThebesSurface(nsnull)
         , mBound(false)
         , mIsPBuffer(false)
         , mIsDoubleBuffered(false)
-        , mPBufferCanBindToTexture(false)
+        , mCanBindToTexture(false)
     {
         // any EGL contexts will always be GLESv2
         SetIsGLES2(true);
 
 #ifdef DEBUG
         printf_stderr("Initializing context %p surface %p on display %p\n", mContext, mSurface, EGL_DISPLAY());
 #endif
     }
@@ -439,16 +439,25 @@ public:
                 mContextLost = true;
                 NS_WARNING("EGL context has been lost.");
             }
             NS_ASSERTION(succeeded, "Failed to make GL context current!");
             return succeeded;
         }
 #endif
         if (aForce || sEGLLibrary.fGetCurrentContext() != mContext) {
+#ifdef MOZ_WIDGET_QT
+            // Shared Qt GL context need to be informed about context switch
+            if (mSharedContext) {
+                QGLContext* qglCtx = static_cast<QGLContext*>(static_cast<GLContextEGL*>(mSharedContext.get())->mPlatformContext);
+                if (qglCtx) {
+                    qglCtx->doneCurrent();
+                }
+            }
+#endif
             succeeded = sEGLLibrary.fMakeCurrent(EGL_DISPLAY(),
                                                  mSurface, mSurface,
                                                  mContext);
             if (!succeeded && sEGLLibrary.fGetError() == LOCAL_EGL_CONTEXT_LOST) {
                 mContextLost = true;
                 NS_WARNING("EGL context has been lost.");
             }
             NS_ASSERTION(succeeded, "Failed to make GL context current!");
@@ -595,17 +604,17 @@ protected:
     EGLSurface mSurface;
     EGLContext mContext;
     void *mPlatformContext;
     nsRefPtr<gfxASurface> mThebesSurface;
     bool mBound;
 
     bool mIsPBuffer;
     bool mIsDoubleBuffered;
-    bool mPBufferCanBindToTexture;
+    bool mCanBindToTexture;
 
     static EGLSurface CreatePBufferSurfaceTryingPowerOfTwo(EGLConfig config,
                                                            EGLenum bindToTextureFormat,
                                                            gfxIntSize& pbsize)
     {
         nsTArray<EGLint> pbattrs(16);
         EGLSurface surface = nsnull;
 
@@ -651,17 +660,17 @@ GLContextEGL::BindTex2DOffscreen(GLConte
 {
     if (aOffscreen->GetContextType() != ContextTypeEGL) {
         NS_WARNING("non-EGL context");
         return false;
     }
 
     GLContextEGL *offs = static_cast<GLContextEGL*>(aOffscreen);
 
-    if (offs->mIsPBuffer && offs->mPBufferCanBindToTexture) {
+    if (offs->mCanBindToTexture) {
         bool ok = sEGLLibrary.fBindTexImage(EGL_DISPLAY(),
                                               offs->mSurface,
                                               LOCAL_EGL_BACK_BUFFER);
         return ok;
     }
 
     if (offs->mOffscreenTexture) {
         if (offs->GetSharedContext() != GLContextProviderEGL::GetGlobalContext())
@@ -681,17 +690,17 @@ GLContextEGL::BindTex2DOffscreen(GLConte
 
 void
 GLContextEGL::UnbindTex2DOffscreen(GLContext *aOffscreen)
 {
     NS_ASSERTION(aOffscreen->GetContextType() == ContextTypeEGL, "wrong type");
 
     GLContextEGL *offs = static_cast<GLContextEGL*>(aOffscreen);
 
-    if (offs->mIsPBuffer && offs->mPBufferCanBindToTexture) {
+    if (offs->mCanBindToTexture) {
         sEGLLibrary.fReleaseTexImage(EGL_DISPLAY(),
                                      offs->mSurface,
                                      LOCAL_EGL_BACK_BUFFER);
     }
 }
 
 bool
 GLContextEGL::ResizeOffscreen(const gfxIntSize& aNewSize)
@@ -699,17 +708,17 @@ GLContextEGL::ResizeOffscreen(const gfxI
     if (!IsOffscreenSizeAllowed(aNewSize))
         return false;
 
     if (mIsPBuffer) {
         gfxIntSize pbsize(aNewSize);
 
         EGLSurface surface =
             CreatePBufferSurfaceTryingPowerOfTwo(mConfig,
-                                                 mPBufferCanBindToTexture
+                                                 mCanBindToTexture
                                                  ? (mCreationFormat.minAlpha
                                                     ? LOCAL_EGL_TEXTURE_RGBA
                                                     : LOCAL_EGL_TEXTURE_RGB)
                                                  : LOCAL_EGL_NONE,
                                                  pbsize);
         if (!surface) {
             NS_WARNING("Failed to resize pbuffer");
             return false;
@@ -788,21 +797,18 @@ GetGlobalContextEGL()
     return static_cast<GLContextEGL*>(GLContextProviderEGL::GetGlobalContext());
 }
 
 static GLenum
 GLFormatForImage(gfxASurface::gfxImageFormat aFormat)
 {
     switch (aFormat) {
     case gfxASurface::ImageFormatARGB32:
-        return LOCAL_GL_RGBA;
     case gfxASurface::ImageFormatRGB24:
-        // this often isn't correct, because we can't guarantee that
-        // the alpha byte will be 0xff coming from the image surface
-        NS_WARNING("Using GL_RGBA for ImageFormatRGB24, are you sure you know what you're doing?");
+        // Thebes only supports RGBX, not packed RGB.
         return LOCAL_GL_RGBA;
     case gfxASurface::ImageFormatRGB16_565:
         return LOCAL_GL_RGB;
     default:
         NS_WARNING("Unknown GL format for Image format");
     }
     return 0;
 }
@@ -853,28 +859,24 @@ public:
                 mUpdateFormat = gfxASurface::ImageFormatARGB32;
                 mShaderType = RGBALayerProgramType;
 #endif
             } else {
                 mShaderType = RGBALayerProgramType;
             }
             Resize(aSize);
         } else {
-            // Convert RGB24 to either ARGB32 on mobile.  We can't
-            // generate GL_RGB data, so we'll always have an alpha byte
-            // for RGB24.  No easy way to upload that to GL.
-            // 
-            // Note that if we start using RGB565 here, we'll need to
-            // watch for a) setting the correct format; and b) getting
-            // the stride right.
             if (mUpdateFormat == gfxASurface::ImageFormatRGB24) {
-                mUpdateFormat = gfxASurface::ImageFormatARGB32;
+                // RGB24 means really RGBX for Thebes, which means we have to
+                // use the right shader and ignore the uninitialized alpha
+                // value.
+                mShaderType = BGRXLayerProgramType;
+            } else {
+                mShaderType = BGRALayerProgramType;
             }
-            // We currently always use BGRA type textures
-            mShaderType = BGRALayerProgramType;
         }
     }
 
     virtual ~TextureImageEGL()
     {
         GLContext *ctx = mGLContext;
         if (ctx->IsDestroyed() || !NS_IsMainThread()) {
             ctx = ctx->GetSharedContext();
@@ -1374,16 +1376,17 @@ DepthToGLFormat(int aDepth)
         case 16:
             return ContextFormat::BasicRGB16_565;
         default:
             break;
     }
     return ContextFormat::BasicRGBA32;
 }
 
+static nsRefPtr<GLContext> gGlobalContext;
 
 #ifdef MOZ_WIDGET_QT
 already_AddRefed<GLContext>
 GLContextProviderEGL::CreateForWindow(nsIWidget *aWidget)
 {
     if (!sEGLLibrary.EnsureInitialized()) {
         return nsnull;
     }
@@ -1401,16 +1404,17 @@ GLContextProviderEGL::CreateForWindow(ns
                              false);
 
         if (!glContext->Init())
             return nsnull;
 
         glContext->SetIsDoubleBuffered(context->format().doubleBuffer());
 
         glContext->SetPlatformContext(context);
+        gGlobalContext = glContext;
 
         return glContext.forget();
     }
 
     // All Qt nsIWidget's have the same X-Window surface
     // And EGL not allowing to create multiple GL context for the same window
     // we should be able to create GL context for QGV viewport once, and reuse it for all child widgets
     NS_ERROR("Failed to get QGLContext");
@@ -1734,17 +1738,17 @@ TRY_ATTRIBS_AGAIN:
                                                         config, surface, context,
                                                         true);
 
     if (!glContext->Init()) {
         NS_WARNING("Failed to initialize GLContext!");
         return nsnull;
     }
 
-    glContext->mPBufferCanBindToTexture = configCanBindToTexture;
+    glContext->mCanBindToTexture = configCanBindToTexture;
 
     if (!bufferUnused) {  // We *are* using the buffer
       glContext->SetOffscreenSize(aSize, pbsize);
       glContext->mIsPBuffer = true;
     }
 
     return glContext.forget();
 }
@@ -1883,33 +1887,35 @@ GLContextEGL::CreateEGLPixmapOffscreenCo
         GLContextEGL::CreateGLContext(aFormat,
                                       surface,
                                       config,
                                       shareContext,
                                       true);
 
     glContext->HoldSurface(thebesSurface);
 
+    glContext->mCanBindToTexture = true;
+
     return glContext.forget();
 }
 
 // Under EGL, if we're under X11, then we have to create a Pixmap
 // because Maemo's EGL implementation doesn't support pbuffers at all
 // for some reason.  On Android, pbuffers are supported fine, though
 // often without the ability to texture from them directly.
 already_AddRefed<GLContext>
 GLContextProviderEGL::CreateOffscreen(const gfxIntSize& aSize,
                                       const ContextFormat& aFormat,
                                       const ContextFlags aFlags)
 {
     if (!sEGLLibrary.EnsureInitialized()) {
         return nsnull;
     }
 
-#if defined(ANDROID) || defined(XP_WIN)
+#if !defined(MOZ_X11)
     bool usePBuffers = false; // Generally, prefer FBOs to PBuffers
 
     if (sEGLLibrary.IsANGLE())
       usePBuffers = true; // For d3d share handle, we need an EGL surface
 
     gfxIntSize pbufferSize = usePBuffers ? aSize : gfxIntSize(16, 16);
     nsRefPtr<GLContextEGL> glContext =
         GLContextEGL::CreateEGLPBufferOffscreenContext(pbufferSize, aFormat, !usePBuffers);
@@ -1983,18 +1989,16 @@ GLContextProviderEGL::CreateForNativePix
 
     return glContext.forget().get();
 #else
     // Not implemented
     return nsnull;
 #endif
 }
 
-static nsRefPtr<GLContext> gGlobalContext;
-
 GLContext *
 GLContextProviderEGL::GetGlobalContext()
 {
     static bool triedToCreateContext = false;
     if (!triedToCreateContext && !gGlobalContext) {
         triedToCreateContext = true;
         // Don't assign directly to gGlobalContext here, because
         // CreateOffscreen can call us re-entrantly.
--- a/gfx/layers/opengl/CanvasLayerOGL.cpp
+++ b/gfx/layers/opengl/CanvasLayerOGL.cpp
@@ -299,19 +299,18 @@ CanvasLayerOGL::RenderLayer(int aPreviou
     gl()->UnbindTex2DOffscreen(mCanvasGLContext);
   }
 }
 
 void
 CanvasLayerOGL::CleanupResources()
 {
   if (mTexture) {
-    GLContext* cx = mOGLManager->glForResources();
-    cx->MakeCurrent();
-    cx->fDeleteTextures(1, &mTexture);
+    gl()->MakeCurrent();
+    gl()->fDeleteTextures(1, &mTexture);
   }
 }
 
 
 ShadowCanvasLayerOGL::ShadowCanvasLayerOGL(LayerManagerOGL* aManager)
   : ShadowCanvasLayer(aManager, nsnull)
   , LayerOGL(aManager)
   , mNeedsYFlip(false)
--- a/gfx/layers/opengl/ImageLayerOGL.cpp
+++ b/gfx/layers/opengl/ImageLayerOGL.cpp
@@ -238,24 +238,32 @@ ImageLayerOGL::RenderLayer(int,
   if (image->GetFormat() == Image::PLANAR_YCBCR) {
     PlanarYCbCrImage *yuvImage =
       static_cast<PlanarYCbCrImage*>(image);
 
     if (!yuvImage->mBufferSize) {
       return;
     }
 
-    if (!yuvImage->GetBackendData(LayerManager::LAYERS_OPENGL)) {
-      AllocateTexturesYCbCr(yuvImage);
-    }
-
     PlanarYCbCrOGLBackendData *data =
       static_cast<PlanarYCbCrOGLBackendData*>(yuvImage->GetBackendData(LayerManager::LAYERS_OPENGL));
 
-    if (!data || data->mTextures->GetGLContext() != mOGLManager->glForResources()) {
+    if (data && data->mTextures->GetGLContext() != gl()) {
+      // If these textures were allocated by another layer manager,
+      // clear them out and re-allocate below.
+      data = nsnull;
+      yuvImage->SetBackendData(LayerManager::LAYERS_OPENGL, nsnull);
+    }
+
+    if (!data) {
+      AllocateTexturesYCbCr(yuvImage);
+      data = static_cast<PlanarYCbCrOGLBackendData*>(yuvImage->GetBackendData(LayerManager::LAYERS_OPENGL));
+    }
+
+    if (!data || data->mTextures->GetGLContext() != gl()) {
       // XXX - Can this ever happen? If so I need to fix this!
       return;
     }
 
     gl()->MakeCurrent();
     gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
     gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, data->mTextures[0].GetTextureID());
     gl()->ApplyFilterToBoundTexture(mFilter);
@@ -288,24 +296,32 @@ ImageLayerOGL::RenderLayer(int,
   } else if (image->GetFormat() == Image::CAIRO_SURFACE) {
     CairoImage *cairoImage =
       static_cast<CairoImage*>(image);
 
     if (!cairoImage->mSurface) {
       return;
     }
 
-    if (!cairoImage->GetBackendData(LayerManager::LAYERS_OPENGL)) {
-      AllocateTexturesCairo(cairoImage);
-    }
-
     CairoOGLBackendData *data =
       static_cast<CairoOGLBackendData*>(cairoImage->GetBackendData(LayerManager::LAYERS_OPENGL));
 
-    if (!data || data->mTexture.GetGLContext() != mOGLManager->glForResources()) {
+    if (data && data->mTexture.GetGLContext() != gl()) {
+      // If this texture was allocated by another layer manager, clear
+      // it out and re-allocate below.
+      data = nsnull;
+      cairoImage->SetBackendData(LayerManager::LAYERS_OPENGL, nsnull);
+    }
+
+    if (!data) {
+      AllocateTexturesCairo(cairoImage);
+      data = static_cast<CairoOGLBackendData*>(cairoImage->GetBackendData(LayerManager::LAYERS_OPENGL));
+    }
+
+    if (!data || data->mTexture.GetGLContext() != gl()) {
       // XXX - Can this ever happen? If so I need to fix this!
       return;
     }
 
     gl()->MakeCurrent();
     unsigned int iwidth  = cairoImage->mSize.width;
     unsigned int iheight = cairoImage->mSize.height;
 
@@ -437,33 +453,21 @@ ImageLayerOGL::RenderLayer(int,
      mOGLManager->BindAndDrawQuad(program);
      gl()->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, 0);
 #endif
   }
   GetContainer()->NotifyPaintedImage(image);
 }
 
 static void
-InitTexture(GLContext* aGL, GLuint aTexture, GLenum aFormat, const gfxIntSize& aSize)
+SetClamping(GLContext* aGL, GLuint aTexture)
 {
   aGL->fBindTexture(LOCAL_GL_TEXTURE_2D, aTexture);
-  aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
-  aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
   aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
   aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
-
-  aGL->fTexImage2D(LOCAL_GL_TEXTURE_2D,
-                   0,
-                   aFormat,
-                   aSize.width,
-                   aSize.height,
-                   0,
-                   aFormat,
-                   LOCAL_GL_UNSIGNED_BYTE,
-                   NULL);
 }
 
 static void
 UploadYUVToTexture(GLContext* gl, const PlanarYCbCrImage::Data& aData, 
                    GLTexture* aYTexture,
                    GLTexture* aUTexture,
                    GLTexture* aVTexture)
 {
@@ -505,30 +509,28 @@ ImageLayerOGL::AllocateTexturesYCbCr(Pla
   if (!aImage->mBufferSize)
     return;
 
   nsAutoPtr<PlanarYCbCrOGLBackendData> backendData(
     new PlanarYCbCrOGLBackendData);
 
   PlanarYCbCrImage::Data &data = aImage->mData;
 
-  GLContext *gl = mOGLManager->glForResources();
-
-  gl->MakeCurrent();
+  gl()->MakeCurrent();
  
-  mTextureRecycleBin->GetTexture(TextureRecycleBin::TEXTURE_Y, data.mYSize, gl, &backendData->mTextures[0]);
-  InitTexture(gl, backendData->mTextures[0].GetTextureID(), LOCAL_GL_LUMINANCE, data.mYSize);
+  mTextureRecycleBin->GetTexture(TextureRecycleBin::TEXTURE_Y, data.mYSize, gl(), &backendData->mTextures[0]);
+  SetClamping(gl(), backendData->mTextures[0].GetTextureID());
 
-  mTextureRecycleBin->GetTexture(TextureRecycleBin::TEXTURE_C, data.mCbCrSize, gl, &backendData->mTextures[1]);
-  InitTexture(gl, backendData->mTextures[1].GetTextureID(), LOCAL_GL_LUMINANCE, data.mCbCrSize);
+  mTextureRecycleBin->GetTexture(TextureRecycleBin::TEXTURE_C, data.mCbCrSize, gl(), &backendData->mTextures[1]);
+  SetClamping(gl(), backendData->mTextures[1].GetTextureID());
 
-  mTextureRecycleBin->GetTexture(TextureRecycleBin::TEXTURE_C, data.mCbCrSize, gl, &backendData->mTextures[2]);
-  InitTexture(gl, backendData->mTextures[2].GetTextureID(), LOCAL_GL_LUMINANCE, data.mCbCrSize);
+  mTextureRecycleBin->GetTexture(TextureRecycleBin::TEXTURE_C, data.mCbCrSize, gl(), &backendData->mTextures[2]);
+  SetClamping(gl(), backendData->mTextures[2].GetTextureID());
 
-  UploadYUVToTexture(gl, aImage->mData,
+  UploadYUVToTexture(gl(), aImage->mData,
                      &backendData->mTextures[0],
                      &backendData->mTextures[1],
                      &backendData->mTextures[2]);
 
   backendData->mYSize = aImage->mData.mYSize;
   backendData->mCbCrSize = aImage->mData.mCbCrSize;
   backendData->mTextureRecycleBin = mTextureRecycleBin;
 
@@ -538,28 +540,30 @@ ImageLayerOGL::AllocateTexturesYCbCr(Pla
 void
 ImageLayerOGL::AllocateTexturesCairo(CairoImage *aImage)
 {
   nsAutoPtr<CairoOGLBackendData> backendData(
     new CairoOGLBackendData);
 
   GLTexture &texture = backendData->mTexture;
 
-  texture.Allocate(mOGLManager->glForResources());
+  texture.Allocate(gl());
 
   if (!texture.IsAllocated()) {
     return;
   }
 
   mozilla::gl::GLContext *gl = texture.GetGLContext();
   gl->MakeCurrent();
 
   GLuint tex = texture.GetTextureID();
   gl->fActiveTexture(LOCAL_GL_TEXTURE0);
 
+  SetClamping(gl, tex);
+
 #if defined(MOZ_WIDGET_GTK2) && !defined(MOZ_PLATFORM_MAEMO)
   if (sGLXLibrary.SupportsTextureFromPixmap(aImage->mSurface)) {
     if (aImage->mSurface->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA) {
       backendData->mLayerProgram = gl::RGBALayerProgramType;
     } else {
       backendData->mLayerProgram = gl::RGBXLayerProgramType;
     }
 
@@ -606,30 +610,30 @@ ShadowImageLayerOGL::Init(const SharedIm
       gfxSharedImageSurface::Open(yuv.Udata());
     nsRefPtr<gfxSharedImageSurface> surfV =
       gfxSharedImageSurface::Open(yuv.Vdata());
 
     mSize = surfY->GetSize();
     mCbCrSize = surfU->GetSize();
 
     if (!mYUVTexture[0].IsAllocated()) {
-      mYUVTexture[0].Allocate(mOGLManager->glForResources());
-      mYUVTexture[1].Allocate(mOGLManager->glForResources());
-      mYUVTexture[2].Allocate(mOGLManager->glForResources());
+      mYUVTexture[0].Allocate(gl());
+      mYUVTexture[1].Allocate(gl());
+      mYUVTexture[2].Allocate(gl());
     }
 
     NS_ASSERTION(mYUVTexture[0].IsAllocated() &&
                  mYUVTexture[1].IsAllocated() &&
                  mYUVTexture[2].IsAllocated(),
                  "Texture allocation failed!");
 
     gl()->MakeCurrent();
-    InitTexture(gl(), mYUVTexture[0].GetTextureID(), LOCAL_GL_LUMINANCE, mSize);
-    InitTexture(gl(), mYUVTexture[1].GetTextureID(), LOCAL_GL_LUMINANCE, mCbCrSize);
-    InitTexture(gl(), mYUVTexture[2].GetTextureID(), LOCAL_GL_LUMINANCE, mCbCrSize);
+    SetClamping(gl(), mYUVTexture[0].GetTextureID());
+    SetClamping(gl(), mYUVTexture[1].GetTextureID());
+    SetClamping(gl(), mYUVTexture[2].GetTextureID());
     return true;
   }
   return false;
 }
 
 void
 ShadowImageLayerOGL::Swap(const SharedImage& aNewFront,
                           SharedImage* aNewBack)
--- a/gfx/layers/opengl/LayerManagerOGL.h
+++ b/gfx/layers/opengl/LayerManagerOGL.h
@@ -248,26 +248,16 @@ public:
   GLContext *gl() const { return mGLContext; }
 
   DrawThebesLayerCallback GetThebesLayerCallback() const
   { return mThebesLayerCallback; }
 
   void* GetThebesLayerCallbackData() const
   { return mThebesLayerCallbackData; }
 
-  // This is a GLContext that can be used for resource
-  // management (creation, destruction).  It is guaranteed
-  // to be either the same as the gl() context, or a context
-  // that is in the same share pool.
-  GLContext *glForResources() const {
-    if (mGLContext->GetSharedContext())
-      return mGLContext->GetSharedContext();
-    return mGLContext;
-  }
-
   /*
    * Helper functions for our layers
    */
   void CallThebesLayerDrawCallback(ThebesLayer* aLayer,
                                    gfxContext* aContext,
                                    const nsIntRegion& aRegionToDraw)
   {
     NS_ASSERTION(mThebesLayerCallback,
--- a/gfx/skia/Makefile.in
+++ b/gfx/skia/Makefile.in
@@ -328,16 +328,32 @@ CPPSRCS += \
 	SkTime_Unix.cpp \
 	SkMMapStream.cpp \
 	SkOSFile.cpp \
 	$(NULL)
 
 OS_CXXFLAGS += $(MOZ_PANGO_CFLAGS)
 endif
 
+ifeq (qt,$(MOZ_WIDGET_TOOLKIT))
+CPPSRCS += \
+	SkFontHost_FreeType.cpp \
+	SkFontHost_gamma_none.cpp \
+	SkMMapStream.cpp \
+	SkOSFile.cpp \
+	$(NULL)
+ifeq (Linux,$(OS_TARGET))
+CPPSRCS += \
+	SkFontHost_linux.cpp \
+	SkTime_Unix.cpp \
+	$(NULL)
+endif
+OS_CXXFLAGS += $(MOZ_PANGO_CFLAGS)
+endif
+
 ifeq (windows,$(MOZ_WIDGET_TOOLKIT))
 EXPORTS_skia += \
 	include/config/sk_stdint.h \
 	include/ports/SkTypeface_win.h \
 	$(NULL)
 CPPSRCS += \
 	SkFontHost_win.cpp \
 	SkFontHost_sandbox_none.cpp \
--- a/gfx/thebes/gfxFont.h
+++ b/gfx/thebes/gfxFont.h
@@ -2274,29 +2274,29 @@ public:
     }
     bool CanHyphenateBefore(PRUint32 aPos) {
         NS_ASSERTION(aPos < mCharacterCount, "aPos out of range");
         return mCharacterGlyphs[aPos].CanBreakBefore() ==
             CompressedGlyph::FLAG_BREAK_TYPE_HYPHEN;
     }
 
     bool CharIsSpace(PRUint32 aPos) {
-        NS_ASSERTION(aPos < mCharacterCount, "aPos out of range");
+        NS_ASSERTION(0 <= aPos && aPos < mCharacterCount, "aPos out of range");
         return mCharacterGlyphs[aPos].CharIsSpace();
     }
     bool CharIsTab(PRUint32 aPos) {
-        NS_ASSERTION(aPos < mCharacterCount, "aPos out of range");
+        NS_ASSERTION(0 <= aPos && aPos < mCharacterCount, "aPos out of range");
         return mCharacterGlyphs[aPos].CharIsTab();
     }
     bool CharIsNewline(PRUint32 aPos) {
-        NS_ASSERTION(aPos < mCharacterCount, "aPos out of range");
+        NS_ASSERTION(0 <= aPos && aPos < mCharacterCount, "aPos out of range");
         return mCharacterGlyphs[aPos].CharIsNewline();
     }
     bool CharIsLowSurrogate(PRUint32 aPos) {
-        NS_ASSERTION(aPos < mCharacterCount, "aPos out of range");
+        NS_ASSERTION(0 <= aPos && aPos < mCharacterCount, "aPos out of range");
         return mCharacterGlyphs[aPos].CharIsLowSurrogate();
     }
 
     PRUint32 GetLength() { return mCharacterCount; }
 
     // All PRUint32 aStart, PRUint32 aLength ranges below are restricted to
     // grapheme cluster boundaries! All offsets are in terms of the string
     // passed into MakeTextRun.
--- a/gfx/thebes/gfxQtPlatform.cpp
+++ b/gfx/thebes/gfxQtPlatform.cpp
@@ -41,16 +41,18 @@
 #include <QApplication>
 #include <QDesktopWidget>
 #include <QPaintEngine>
 
 #include "gfxQtPlatform.h"
 
 #include "gfxFontconfigUtils.h"
 
+#include "mozilla/gfx/2D.h"
+
 #include "cairo.h"
 
 #include "gfxImageSurface.h"
 #include "gfxQPainterSurface.h"
 #include "nsUnicodeProperties.h"
 
 #ifdef MOZ_PANGO
 #include "gfxPangoFonts.h"
@@ -76,16 +78,17 @@
 #include <ft2build.h>
 #include FT_FREETYPE_H
 #endif
 
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
 using namespace mozilla::unicode;
+using namespace mozilla::gfx;
 
 #define DEFAULT_RENDER_MODE RENDER_DIRECT
 
 static QPaintEngine::Type sDefaultQtPaintEngineType = QPaintEngine::Raster;
 gfxFontconfigUtils *gfxQtPlatform::sFontconfigUtils = nsnull;
 static cairo_user_data_key_t cairo_qt_pixmap_key;
 static void do_qt_pixmap_unref (void *data)
 {
@@ -591,8 +594,16 @@ gfxQtPlatform::GetDPI()
     return dpi <= 0 ? 96 : dpi;
 }
 
 gfxImageFormat
 gfxQtPlatform::GetOffscreenFormat()
 {
     return sOffscreenFormat;
 }
+
+bool
+gfxQtPlatform::SupportsAzure(BackendType& aBackend)
+{
+  aBackend = BACKEND_SKIA;
+  return true;
+}
+
--- a/gfx/thebes/gfxQtPlatform.h
+++ b/gfx/thebes/gfxQtPlatform.h
@@ -71,16 +71,18 @@ public:
 
     static gfxQtPlatform *GetPlatform() {
         return (gfxQtPlatform*) gfxPlatform::GetPlatform();
     }
 
     already_AddRefed<gfxASurface> CreateOffscreenSurface(const gfxIntSize& size,
                                                          gfxASurface::gfxContentType contentType);
 
+    virtual bool SupportsAzure(mozilla::gfx::BackendType& aBackend);
+
     nsresult GetFontList(nsIAtom *aLangGroup,
                          const nsACString& aGenericFamily,
                          nsTArray<nsString>& aListOfFonts);
 
     nsresult UpdateFontList();
 
     nsresult ResolveFontName(const nsAString& aFontName,
                              FontResolverCallback aCallback,
deleted file mode 100644
--- a/gfx/ycbcr/QuellGccWarnings.patch
+++ /dev/null
@@ -1,40 +0,0 @@
-diff --git a/gfx/ycbcr/yuv_convert.cpp b/gfx/ycbcr/yuv_convert.cpp
---- a/gfx/ycbcr/yuv_convert.cpp
-+++ b/gfx/ycbcr/yuv_convert.cpp
-@@ -337,16 +337,17 @@ NS_GFX_(void) ScaleYCbCrToRGB32(const ui
-                                          source_dx_uv >> kFractionBits);
-         }
-       }
-       else {
-         ScaleYUVToRGB32Row_C(y_ptr, u_ptr, v_ptr,
-                              dest_pixel, width, source_dx);
-       }
- #else
-+      (void)source_dx_uv;
-       ScaleYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
-                          dest_pixel, width, source_dx);
- #endif
-     }
-   }
-   // MMX used for FastConvertYUVToRGB32Row and FilterRows requires emms.
-   if (has_mmx)
-     EMMS();
-diff --git a/gfx/ycbcr/yuv_row.h b/gfx/ycbcr/yuv_row.h
---- a/gfx/ycbcr/yuv_row.h
-+++ b/gfx/ycbcr/yuv_row.h
-@@ -129,14 +129,14 @@ extern SIMD_ALIGNED(int16 kCoefficientsR
- #if defined(ARCH_CPU_X86) && !defined(ARCH_CPU_X86_64)
- #if defined(_MSC_VER)
- #define EMMS() __asm emms
- #pragma warning(disable: 4799)
- #else
- #define EMMS() asm("emms")
- #endif
- #else
--#define EMMS()
-+#define EMMS() ((void)0)
- #endif
- 
- }  // extern "C"
- 
- #endif  // MEDIA_BASE_YUV_ROW_H_
--- a/gfx/ycbcr/README
+++ b/gfx/ycbcr/README
@@ -20,10 +20,8 @@ convert.patch contains the following cha
   * Add YCbCr 4:4:4 support
   * Bug 619178 - Update CPU detection in yuv_convert to new SSE.h interface.
   * Bug 616778 - Split yuv_convert FilterRows vectorized code into separate files so it can
     be properly guarded with cpuid() calls.
 
 win64.patch: SSE2 optimization for Microsoft Visual C++ x64 version
 
 TypeFromSize.patch: Bug 656185 - Add a method to detect YUVType from plane sizes.
-
-QuellGccWarnings.patch: Bug 711895 - Avoid some GCC compilation warnings.
--- a/gfx/ycbcr/update.sh
+++ b/gfx/ycbcr/update.sh
@@ -4,9 +4,8 @@ cp $1/media/base/yuv_convert.cc yuv_conv
 cp $1/media/base/yuv_row.h .
 cp $1/media/base/yuv_row_table.cc yuv_row_table.cpp
 cp $1/media/base/yuv_row_posix.cc yuv_row_posix.cpp
 cp $1/media/base/yuv_row_win.cc yuv_row_win.cpp
 cp $1/media/base/yuv_row_posix.cc yuv_row_c.cpp
 patch -p3 <convert.patch
 patch -p3 <win64.patch
 patch -p3 <TypeFromSize.patch
-patch -p3 <QuellGccWarnings.patch
--- a/gfx/ycbcr/yuv_convert.cpp
+++ b/gfx/ycbcr/yuv_convert.cpp
@@ -337,17 +337,16 @@ NS_GFX_(void) ScaleYCbCrToRGB32(const ui
                                          source_dx_uv >> kFractionBits);
         }
       }
       else {
         ScaleYUVToRGB32Row_C(y_ptr, u_ptr, v_ptr,
                              dest_pixel, width, source_dx);
       }
 #else
-      (void)source_dx_uv;
       ScaleYUVToRGB32Row(y_ptr, u_ptr, v_ptr,
                          dest_pixel, width, source_dx);
 #endif
     }
   }
   // MMX used for FastConvertYUVToRGB32Row and FilterRows requires emms.
   if (has_mmx)
     EMMS();
--- a/gfx/ycbcr/yuv_row.h
+++ b/gfx/ycbcr/yuv_row.h
@@ -129,14 +129,14 @@ extern SIMD_ALIGNED(int16 kCoefficientsR
 #if defined(ARCH_CPU_X86) && !defined(ARCH_CPU_X86_64)
 #if defined(_MSC_VER)
 #define EMMS() __asm emms
 #pragma warning(disable: 4799)
 #else
 #define EMMS() asm("emms")
 #endif
 #else
-#define EMMS() ((void)0)
+#define EMMS()
 #endif
 
 }  // extern "C"
 
 #endif  // MEDIA_BASE_YUV_ROW_H_
--- a/hal/cocoa/CocoaSensor.mm
+++ b/hal/cocoa/CocoaSensor.mm
@@ -28,33 +28,41 @@ void UpdateHandler(nsITimer *aTimer, voi
   hal::SensorData sdata(hal::SENSOR_ACCELERATION,
 			PR_Now(),
 			values,
 			hal::SENSOR_ACCURACY_UNKNOWN);
   hal::NotifySensorChange(sdata);
 }
 
 void
-EnableSensorNotifications(SensorType aSensor) {
+EnableSensorNotifications(SensorType aSensor)
+{
+  if (aSensor != SENSOR_ACCELERATION)
+    return;
+
   if (sUpdateTimer)
     return;
 
   smsStartup(nil, nil);
   smsLoadCalibration();
 
   CallCreateInstance("@mozilla.org/timer;1", &sUpdateTimer);
   if (sUpdateTimer)
     sUpdateTimer->InitWithFuncCallback(UpdateHandler,
                                        NULL,
                                        DEFAULT_SENSOR_POLL,
                                        nsITimer::TYPE_REPEATING_SLACK);
 }
 
 void
-DisableSensorNotifications(SensorType aSensor) {
+DisableSensorNotifications(SensorType aSensor)
+{
+  if (aSensor != SENSOR_ACCELERATION)
+    return;
+
   if (sUpdateTimer) {
     sUpdateTimer->Cancel();
     NS_RELEASE(sUpdateTimer);
   }
   smsShutdown();
 }
 
 } // hal_impl
--- a/image/src/imgRequest.cpp
+++ b/image/src/imgRequest.cpp
@@ -680,16 +680,25 @@ NS_IMETHODIMP imgRequest::OnStopDecode(i
   mImage->GetStatusTracker().RecordStopDecode(aStatus, aStatusArg);
 
   nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
   while (iter.HasMore()) {
     mImage->GetStatusTracker().SendStopDecode(iter.GetNext(), aStatus,
                                               aStatusArg);
   }
 
+  if (NS_FAILED(aStatus)) {
+    // Some kind of problem has happened with image decoding.
+    // Report the URI to net:failed-to-decode-uri observers.
+
+    nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
+    if (os)
+      os->NotifyObservers(mURI, "net:failed-to-process-uri", nsnull);
+  }
+
   // RasterImage and everything below it is completely correct and
   // bulletproof about its handling of decoder notifications.
   // Unfortunately, here and above we have to make some gross and
   // inappropriate use of things to get things to work without
   // completely overhauling the decoder observer interface (this will,
   // thankfully, happen in bug 505385). From imgRequest and above (for
   // the time being), OnStopDecode is just a companion to OnStopRequest
   // that signals success or failure of the _load_ (not the _decode_).
--- a/image/test/mochitest/Makefile.in
+++ b/image/test/mochitest/Makefile.in
@@ -113,15 +113,18 @@ include $(topsrcdir)/config/rules.mk
                 filter-final.svg \
                 test_svg_filter_animation.html \
                 test_xultree_animation.xhtml \
                 test_changeOfSource.html \
                 test_changeOfSource2.html \
                 test_undisplayed_iframe.html \
                 iframe.html \
                 ref-iframe.html \
+                test_net_failedtoprocess.html \
+                invalid.jpg \
+                damon.jpg \
                 $(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
 
 libs:: $(_CHROME_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/image/test/mochitest/invalid.jpg
@@ -0,0 +1,1 @@
+notajpg
new file mode 100644
--- /dev/null
+++ b/image/test/mochitest/test_net_failedtoprocess.html
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+Test that a image decoding error producs a net:failed-to-process-uri
+observer event with the nsIURI of the failed image as the subject
+-->
+<head>
+  <title>Test for image net:failed-to-process-uri</title>
+  <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>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<p id="display"></p>
+<pre id="test">
+<script type="application/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+const Ci = Components.interfaces;
+const Cc = Components.classes;
+
+var observer = {
+  QueryInterface: function (aIID) {
+    if (aIID.equals(Ci.nsISupports) ||
+        aIID.equals(Ci.nsIObserver))
+      return this;
+    throw Cr.NS_ERROR_NO_INTERFACE;
+  },
+
+  observe: function(subject, topic, data) {
+    ok(topic == "net:failed-to-process-uri", "wrong topic");
+    subject = subject.QueryInterface(Ci.nsIURI);
+    ok(subject.asciiSpec == "chrome://mochitests/content/chrome/image/test/mochitest/invalid.jpg", "wrong subject");
+    SimpleTest.finish();
+  }
+};
+
+var obs = Cc["@mozilla.org/observer-service;1"].getService();
+obs = obs.QueryInterface(Ci.nsIObserverService);
+obs.addObserver(observer, "net:failed-to-process-uri", false);
+
+</script>
+</pre>
+<img src="damon.jpg">
+<img src="invalid.jpg">
+</body>
+</html>
--- a/ipc/ipdl/test/cxx/IPDLUnitTests.template.cpp
+++ b/ipc/ipdl/test/cxx/IPDLUnitTests.template.cpp
@@ -45,17 +45,17 @@ char* gIPDLUnitTestName = NULL;
 
 const char* const
 IPDLUnitTestName()
 {
     if (!gIPDLUnitTestName) {
 #if defined(OS_WIN)
         vector<wstring> args =
             CommandLine::ForCurrentProcess()->GetLooseValues();
-        gIPDLUnitTestName = strdup(WideToUTF8(args[0]).c_str());
+        gIPDLUnitTestName = ::strdup(WideToUTF8(args[0]).c_str());
 #elif defined(OS_POSIX)
         vector<string> argv = CommandLine::ForCurrentProcess()->argv();
         gIPDLUnitTestName = ::moz_xstrdup(argv[1].c_str());
 #else
 #  error Sorry
 #endif
     }
     return gIPDLUnitTestName;
--- a/js/jsd/jsd.h
+++ b/js/jsd/jsd.h
@@ -374,16 +374,20 @@ jsd_SetErrorReporter(JSDContext*       j
                      JSD_ErrorReporter reporter,
                      void*             callerdata);
 
 extern JSBool
 jsd_GetErrorReporter(JSDContext*        jsdc,
                      JSD_ErrorReporter* reporter,
                      void**             callerdata);
 
+static JSBool
+jsd_DebugErrorHook(JSContext *cx, const char *message,
+                   JSErrorReport *report, void *closure);
+
 /***************************************************************************/
 /* Script functions */
 
 extern JSBool
 jsd_InitScriptManager(JSDContext *jsdc);
 
 extern void
 jsd_DestroyScriptManager(JSDContext* jsdc);
--- a/js/jsd/jsd_high.c
+++ b/js/jsd/jsd_high.c
@@ -271,20 +271,16 @@ jsd_DebuggerPause(JSDContext* jsdc, JSBo
     if (forceAllHooksOff || !(jsdc->flags & JSD_COLLECT_PROFILE_DATA)) {
         JS_SetExecuteHook(jsdc->jsrt, NULL, NULL);
         JS_SetCallHook(jsdc->jsrt, NULL, NULL);
     }
     JS_SetThrowHook(jsdc->jsrt, NULL, NULL);
     JS_SetDebugErrorHook(jsdc->jsrt, NULL, NULL);
 }
 
-static JSBool
-jsd_DebugErrorHook(JSContext *cx, const char *message,
-                   JSErrorReport *report, void *closure);
-
 void
 jsd_DebuggerUnpause(JSDContext* jsdc)
 {
     JS_SetDebuggerHandler(jsdc->jsrt, jsd_DebuggerHandler, jsdc);
     JS_SetExecuteHook(jsdc->jsrt, jsd_TopLevelCallHook, jsdc);
     JS_SetCallHook(jsdc->jsrt, jsd_FunctionCallHook, jsdc);
     JS_SetThrowHook(jsdc->jsrt, jsd_ThrowHandler, jsdc);
     JS_SetDebugErrorHook(jsdc->jsrt, jsd_DebugErrorHook, jsdc);
--- a/js/src/build/autoconf/compiler-opts.m4
+++ b/js/src/build/autoconf/compiler-opts.m4
@@ -77,54 +77,8 @@ if test "$GNU_CC" -a "$GCC_USE_GNU_LD" -
         fi
         rm -rf conftest*])
     if test "$GC_SECTIONS_BREAKS_DEBUG_RANGES" = no; then
         DSO_LDOPTS="$DSO_LDOPTS -Wl,--gc-sections"
     fi
 fi
 
 ])
-
-dnl GCC and clang will fail if given an unknown warning option like -Wfoobar. 
-dnl But later versions won't fail if given an unknown negated warning option
-dnl like -Wno-foobar.  So when we are check for support of negated warning 
-dnl options, we actually test the positive form, but add the negated form to 
-dnl the flags variable.
-
-AC_DEFUN([MOZ_C_SUPPORTS_WARNING],
-[
-    AC_CACHE_CHECK(whether the C compiler supports $1$2, $3,
-        [
-            AC_LANG_SAVE
-            AC_LANG_C
-            _SAVE_CFLAGS="$CFLAGS"
-            CFLAGS="$CFLAGS -W$2"
-            AC_TRY_COMPILE([],
-                           [return(0);],
-                           $3="yes",
-                           $3="no")
-            CFLAGS="$_SAVE_CFLAGS"
-            AC_LANG_RESTORE
-        ])
-    if test "${$3}" = "yes"; then
-        _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} $1$2"
-    fi
-])
-
-AC_DEFUN([MOZ_CXX_SUPPORTS_WARNING],
-[
-    AC_CACHE_CHECK(whether the C++ compiler supports $1$2, $3,
-        [
-            AC_LANG_SAVE
-            AC_LANG_CPLUSPLUS
-            _SAVE_CXXFLAGS="$CXXFLAGS"
-            CXXFLAGS="$CXXFLAGS -W$2"
-            AC_TRY_COMPILE([],
-                           [return(0);],
-                           $3="yes",
-                           $3="no")
-            CXXFLAGS="$_SAVE_CXXFLAGS"
-            AC_LANG_RESTORE
-        ])
-    if test "${$3}" = "yes"; then
-        _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} $1$2"
-    fi
-])
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -1616,54 +1616,45 @@ if test "$GNU_CC"; then
     fi
     WARNINGS_AS_ERRORS='-Werror -Wno-error=uninitialized'
     DSO_CFLAGS=''
     DSO_PIC_CFLAGS='-fPIC'
     ASFLAGS="$ASFLAGS -fPIC"
     _MOZ_RTTI_FLAGS_ON=-frtti
     _MOZ_RTTI_FLAGS_OFF=-fno-rtti
 
-    # Turn on GNU-specific warnings:
-    # -Wall - turn on a lot of warnings
-    # -pedantic - this is turned on below
-    # -Wpointer-arith - enabled with -pedantic, but good to have even if not
-    # -Werror=declaration-after-statement - MSVC doesn't like these
-    # -Werror=return-type - catches missing returns, zero false positives
-    # -Wtype-limits - catches overflow bugs, few false positives
-    # -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
-    #
-    _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wall -Wpointer-arith -Werror=declaration-after-statement"
-    MOZ_C_SUPPORTS_WARNING(-W, error=return-type, ac_c_has_werror_return_type)
-    MOZ_C_SUPPORTS_WARNING(-W, type-limits, ac_c_has_wtype_limits)
-    MOZ_C_SUPPORTS_WARNING(-W, empty-body, ac_c_has_wempty_body)
-    
-    # Turn off the following warnings that -Wall/-pedantic turn on:
-    # -Wno-overlength-strings - we exceed the minimum maximum length frequently
-    # -Wno-unused - lots of violations in third-party code
-    #
-    _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wno-overlength-strings -Wno-unused"
-
+    # Turn on GNU specific features
+    # -Wall - turn on all warnings
+    # -pedantic - make compiler warn about non-ANSI stuff, and
+    #             be a little bit stricter
+    # Warnings slamm took out for now (these were giving more noise than help):
+    # -Wbad-function-cast - warns when casting a function to a new return type
+    # -Wshadow - removed because it generates more noise than help --pete
+    _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wall -W -Wno-unused -Wpointer-arith"
     if test -z "$INTEL_CC" -a -z "$CLANG_CC"; then
        # Don't use -Wcast-align with ICC or clang
        case "$CPU_ARCH" in
            # And don't use it on hppa, ia64, sparc, arm, since it's noisy there
            hppa | ia64 | sparc | arm)
            ;;
            *)
         _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wcast-align"
            ;;
        esac
     fi
 
     dnl Turn pedantic on but disable the warnings for long long
     _PEDANTIC=1
 
+    if test -z "$INTEL_CC"; then
+      _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -W"
+    fi
+
     _DEFINES_CFLAGS='-include $(DEPTH)/js-confdefs.h -DMOZILLA_CLIENT'
     _USE_CPP_INCLUDE_FLAG=1
-
 elif test "$SOLARIS_SUNPRO_CC"; then
     DSO_CFLAGS=''
     if test "$CPU_ARCH" = "sparc"; then
         # for Sun Studio on Solaris/SPARC
         DSO_PIC_CFLAGS='-xcode=pic32'
     else
         DSO_PIC_CFLAGS='-KPIC'
     fi
@@ -1679,40 +1670,18 @@ else
     fi
 
     DSO_CFLAGS=''
     DSO_PIC_CFLAGS='-KPIC'
     _DEFINES_CFLAGS='$(ACDEFINES) -D_JS_CONFDEFS_H_ -DMOZILLA_CLIENT'
 fi
 
 if test "$GNU_CXX"; then
-    # Turn on GNU-specific warnings:
-    # -Wall - turn on a lot of warnings
-    # -pedantic - this is turned on below
-    # -Wpointer-arith - enabled with -pedantic, but good to have even if not
-    # -Woverloaded-virtual - ???
-    # -Werror=return-type - catches missing returns, zero false positives
-    # -Wtype-limits - catches overflow bugs, few false positives
-    # -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
-    #
-    _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wall -Wpointer-arith -Woverloaded-virtual"
-    MOZ_CXX_SUPPORTS_WARNING(-W, error=return-type, ac_cxx_has_werror_return_type)
-    MOZ_CXX_SUPPORTS_WARNING(-W, type-limits, ac_cxx_has_wtype_limits)
-    MOZ_CXX_SUPPORTS_WARNING(-W, empty-body, ac_cxx_has_wempty_body)
-
-    # Turn off the following warnings that -Wall/-pedantic turn on:
-    # -Wno-overlength-strings - we exceed the minimum maximum length frequently
-    # -Wno-ctor-dtor-privacy - ???
-    # -Wno-invalid-offsetof - we use offsetof on non-POD types frequently
-    # -Wno-variadic-macros - ???
-    #
-    _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-overlength-strings -Wno-ctor-dtor-privacy"
-    MOZ_CXX_SUPPORTS_WARNING(-Wno-, invalid-offsetof, ac_cxx_has_wno_invalid_offsetof)
-    MOZ_CXX_SUPPORTS_WARNING(-Wno-, variadic-macros, ac_cxx_has_wno_variadic_macros)
-
+    # Turn on GNU specific features
+    _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wall -Wpointer-arith -Woverloaded-virtual -Wsynth -Wno-ctor-dtor-privacy -Wno-non-virtual-dtor"
     if test -z "$INTEL_CXX" -a -z "$CLANG_CXX"; then
        # Don't use -Wcast-align with ICC or clang
        case "$CPU_ARCH" in
            # And don't use it on hppa, ia64, sparc, arm, since it's noisy there
            hppa | ia64 | sparc | arm)
            ;;
            *)
         _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wcast-align"
@@ -1726,17 +1695,91 @@ if test "$GNU_CXX"; then
     # Recent clang and gcc support C++11 deleted functions without warnings if
     # compiling with -std=c++0x or -std=gnu++0x (or c++11 or gnu++11 in very new
     # versions).  We can't use -std=c++0x yet, so gcc's support must remain
     # unused.  But clang's warning can be disabled, so when compiling with clang
     # we use it to opt out of the warning, enabling (macro-encapsulated) use of
     # deleted function syntax.
     if test "$CLANG_CXX"; then
         _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-c++0x-extensions"
-        MOZ_CXX_SUPPORTS_WARNING(-Wno-, extended-offsetof, ac_cxx_has_wno_extended_offsetof)
+    fi
+
+    AC_CACHE_CHECK(whether the compiler supports -Wno-extended-offsetof,
+                   ac_has_wno_extended_offsetof,
+        [
+            AC_LANG_SAVE
+            AC_LANG_CPLUSPLUS
+            _SAVE_CXXFLAGS="$CXXFLAGS"
+            CXXFLAGS="$CXXFLAGS -Wno-extended-offsetof"
+            AC_TRY_COMPILE([$configure_static_assert_macros
+                            #ifndef __has_warning
+                            #define __has_warning(x) 0
+                            #endif],
+                           [CONFIGURE_STATIC_ASSERT(__has_warning("-Wextended-offsetof"))],
+                           ac_has_wno_extended_offsetof="yes",
+                           ac_has_wno_extended_offsetof="no")
+            CXXFLAGS="$_SAVE_CXXFLAGS"
+            AC_LANG_RESTORE
+        ])
+    if test "$ac_has_wno_extended_offsetof" = "yes"; then
+        _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-extended-offsetof"
+    fi
+
+    AC_CACHE_CHECK(whether the compiler supports -Wno-invalid-offsetof,
+                   ac_has_wno_invalid_offsetof,
+        [
+            AC_LANG_SAVE
+            AC_LANG_CPLUSPLUS
+            _SAVE_CXXFLAGS="$CXXFLAGS"
+            CXXFLAGS="$CXXFLAGS -Wno-invalid-offsetof"
+            AC_TRY_COMPILE([],
+                           [return(0);],
+                           ac_has_wno_invalid_offsetof="yes",
+                           ac_has_wno_invalid_offsetof="no")
+            CXXFLAGS="$_SAVE_CXXFLAGS"
+            AC_LANG_RESTORE
+        ])
+    if test "$ac_has_wno_invalid_offsetof" = "yes"; then
+        _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-invalid-offsetof"
+    fi
+
+    AC_CACHE_CHECK(whether the compiler supports -Wno-variadic-macros,
+                   ac_has_wno_variadic_macros,
+        [
+            AC_LANG_SAVE
+            AC_LANG_CPLUSPLUS
+            _SAVE_CXXFLAGS="$CXXFLAGS"
+            CXXFLAGS="$CXXFLAGS -Wno-variadic-macros"
+            AC_TRY_COMPILE([],
+                           [return(0);],
+                           ac_has_wno_variadic_macros="yes",
+                           ac_has_wno_variadic_macros="no")
+            CXXFLAGS="$_SAVE_CXXFLAGS"
+            AC_LANG_RESTORE
+        ])
+    if test "$ac_has_wno_variadic_macros" = "yes"; then
+        _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-variadic-macros"
+    fi
+
+    AC_CACHE_CHECK(whether the compiler supports -Werror=return-type,
+                   ac_has_werror_return_type,
+        [
+            AC_LANG_SAVE
+            AC_LANG_CPLUSPLUS
+            _SAVE_CXXFLAGS="$CXXFLAGS"
+            CXXFLAGS="$CXXFLAGS -Werror=return-type"
+            AC_TRY_COMPILE([],
+                           [return(0);],
+                           ac_has_werror_return_type="yes",
+                           ac_has_werror_return_type="no")
+            CXXFLAGS="$_SAVE_CXXFLAGS"
+            AC_LANG_RESTORE
+        ])
+    if test "$ac_has_werror_return_type" = "yes"; then
+        _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=return-type"
     fi
 
 else
     _DEFINES_CXXFLAGS='-DMOZILLA_CLIENT -D_JS_CONFDEFS_H_ $(ACDEFINES)'
 fi
 
 dnl gcc can come with its own linker so it is better to use the pass-thru calls
 dnl MKSHLIB_FORCE_ALL is used to force the linker to include all object
@@ -2177,17 +2220,16 @@ ia64*-hpux*)
         AR='lib'
         AR_FLAGS='-NOLOGO -OUT:"$@"'
         AR_EXTRACT=
         RANLIB='echo not_ranlib'
         STRIP='echo not_strip'
         PKG_SKIP_STRIP=1
         XARGS=xargs
         DOXYGEN=:
-        GARBAGE='$(OBJDIR)/vc20.pdb $(OBJDIR)/vc40.pdb'
         ASM_SUFFIX=asm
         OBJ_SUFFIX=obj
         LIB_SUFFIX=lib
         DLL_PREFIX=
         LIB_PREFIX=
         IMPORT_LIB_SUFFIX=lib
         MKSHLIB='$(LD) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
         MKCSHLIB='$(LD) -NOLOGO -DLL -OUT:$@ -PDB:$(LINK_PDBFILE) $(DSO_LDOPTS)'
@@ -4122,17 +4164,16 @@ MOZ_ARG_ENABLE_BOOL(wrap-malloc,
 [  --enable-wrap-malloc    Wrap malloc calls (gnu linker only)],
     _WRAP_MALLOC=1,
     _WRAP_MALLOC= )
 
 if test -n "$_WRAP_MALLOC"; then
     if test "$GNU_CC"; then
         WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=malloc,--wrap=calloc,--wrap=valloc,--wrap=free,--wrap=realloc,--wrap=memalign"
         WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=__builtin_new,--wrap=__builtin_vec_new,--wrap=__builtin_delete,--wrap=__builtin_vec_delete"
-        WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=PR_Free,--wrap=PR_Malloc,--wrap=PR_Calloc,--wrap=PR_Realloc"
         WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=strdup,--wrap=strndup"
         WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=posix_memalign,--wrap=malloc_usable_size"
     else
         AC_MSG_ERROR([--enable-wrap-malloc is not supported for non-GNU toolchains])
     fi
 fi
 
 dnl ========================================================
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -400,33 +400,20 @@ DoGetElement(JSContext *cx, JSObject *ob
     *hole = !present;
     if (*hole)
         vp->setUndefined();
 
     return true;
 }
 
 template<typename IndexType>
-static void
-AssertGreaterThanZero(IndexType index)
-{
-    JS_ASSERT(index >= 0);
-}
-
-template<>
-void
-AssertGreaterThanZero(uint32_t index)
-{
-}
-
-template<typename IndexType>
 static JSBool
 GetElement(JSContext *cx, JSObject *obj, IndexType index, JSBool *hole, Value *vp)
 {
-    AssertGreaterThanZero(index);
+    JS_ASSERT(index >= 0);
     if (obj->isDenseArray() && index < obj->getDenseArrayInitializedLength() &&
         !(*vp = obj->getDenseArrayElement(uint32_t(index))).isMagic(JS_ARRAY_HOLE)) {
         *hole = JS_FALSE;
         return JS_TRUE;
     }
     if (obj->isArguments()) {
         if (obj->asArguments().getElement(uint32_t(index), vp)) {
             *hole = JS_FALSE;
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -1451,17 +1451,17 @@ JSCompartment::setGCLastBytes(size_t las
     gcTriggerBytes = ComputeTriggerBytes(lastBytes, rt->gcMaxBytes, gckind);
     gcTriggerMallocAndFreeBytes = ComputeTriggerBytes(lastMallocBytes, SIZE_MAX, gckind);
 }
 
 void
 JSCompartment::reduceGCTriggerBytes(size_t amount)
 {
     JS_ASSERT(amount > 0);
-    JS_ASSERT(gcTriggerBytes >= amount);
+    JS_ASSERT(gcTriggerBytes - amount >= 0);
     if (gcTriggerBytes - amount < GC_ALLOCATION_THRESHOLD * GC_HEAP_GROWTH_FACTOR)
         return;
     gcTriggerBytes -= amount;
 }
 
 namespace js {
 namespace gc {
 
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -997,54 +997,35 @@ JSScript::NewScript(JSContext *cx, uint3
     JS_STATIC_ASSERT(sizeof(JSTryNoteArray) % sizeof(jsval) == 0);
     JS_STATIC_ASSERT(sizeof(GlobalSlotArray) % sizeof(jsval) == 0);
     JS_STATIC_ASSERT(sizeof(JSConstArray) % sizeof(jsval) == 0);
     if (nconsts != 0)
         size += sizeof(JSConstArray) + nconsts * sizeof(Value);
 
     size += length * sizeof(jsbytecode) + nsrcnotes * sizeof(jssrcnote);
 
-    uint8_t *data = NULL;
-#if JS_SCRIPT_INLINE_DATA_LIMIT
-    if (size <= JS_SCRIPT_INLINE_DATA_LIMIT) {
-        /*
-         * Check that if inlineData is big enough to store const values, we
-         * can do that without any special alignment requirements given that
-         * the script as a GC thing is always aligned on Cell::CellSize.
-         */
-        JS_STATIC_ASSERT(Cell::CellSize % sizeof(Value) == 0);
-        JS_STATIC_ASSERT(JS_SCRIPT_INLINE_DATA_LIMIT < sizeof(Value) ||
-                         offsetof(JSScript, inlineData) % sizeof(Value) == 0);
-    } else
-#endif
-    {
-        /*
-         * We assume that calloc aligns on sizeof(Value) if the size we ask to
-         * allocate divides sizeof(Value).
-         */
-        JS_STATIC_ASSERT(sizeof(Value) == sizeof(double));
-        data = static_cast<uint8_t *>(cx->calloc_(JS_ROUNDUP(size, sizeof(Value))));
-        if (!data)
-            return NULL;
-    }
+    /*
+     * We assume that calloc aligns on sizeof(Value) if the size we ask to
+     * allocate divides sizeof(Value).
+     */
+    JS_STATIC_ASSERT(sizeof(Value) == sizeof(double));
+    uint8_t *data = static_cast<uint8_t *>(cx->calloc_(JS_ROUNDUP(size, sizeof(Value))));
+    if (!data)
+        return NULL;
 
     JSScript *script = js_NewGCScript(cx);
     if (!script) {
         Foreground::free_(data);
         return NULL;
     }
 
     PodZero(script);
 #ifdef JS_CRASH_DIAGNOSTICS
     script->cookie1[0] = script->cookie2[0] = JS_SCRIPT_COOKIE;
 #endif
-#if JS_SCRIPT_INLINE_DATA_LIMIT
-    if (!data)
-        data = script->inlineData;
-#endif
     script->data  = data;
     script->length = length;
     script->version = version;
     new (&script->bindings) Bindings(cx);
 
     uint8_t *cursor = data;
     if (nobjects != 0) {
         script->objectsOffset = uint8_t(cursor - data);
@@ -1321,34 +1302,24 @@ JSScript::NewScriptFromEmitter(JSContext
         (void) script->initCounts(cx);
 
     return script;
 }
 
 size_t
 JSScript::computedSizeOfData()
 {
-#if JS_SCRIPT_INLINE_DATA_LIMIT
-    if (data == inlineData)
-        return 0;
-#endif
-
     uint8_t *dataEnd = code + length * sizeof(jsbytecode) + numNotes() * sizeof(jssrcnote);
     JS_ASSERT(dataEnd >= data);
     return dataEnd - data;
 }
 
 size_t
 JSScript::sizeOfData(JSMallocSizeOfFun mallocSizeOf)
 {
-#if JS_SCRIPT_INLINE_DATA_LIMIT
-    if (data == inlineData)
-        return 0;
-#endif
-
     return mallocSizeOf(data);
 }
 
 /*
  * Nb: srcnotes are variable-length.  This function computes the number of
  * srcnote *slots*, which may be greater than the number of srcnotes.
  */
 uint32_t
@@ -1436,23 +1407,18 @@ JSScript::finalize(JSContext *cx, bool b
                 JS_ASSERT(site->firstBreakpoint() == NULL);
                 site->clearTrap(cx, NULL, NULL);
                 JS_ASSERT(getBreakpointSite(pc) == NULL);
             }
         }
         cx->free_(debug);
     }
 
-#if JS_SCRIPT_INLINE_DATA_LIMIT
-    if (data != inlineData)
-#endif
-    {
-        JS_POISON(data, 0xdb, computedSizeOfData());
-        cx->free_(data);
-    }
+    JS_POISON(data, 0xdb, computedSizeOfData());
+    cx->free_(data);
 }
 
 namespace js {
 
 static const uint32_t GSN_CACHE_THRESHOLD = 100;
 static const uint32_t GSN_CACHE_MAP_INIT_SIZE = 20;
 
 void
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -457,26 +457,16 @@ struct JSScript : public js::gc::Cell
 
     uint32_t        natoms;     /* length of atoms array */
     uint16_t        nslots;     /* vars plus maximum stack depth */
     uint16_t        staticLevel;/* static level for display maintenance */
 
     uint16_t        nClosedArgs; /* number of args which are closed over. */
     uint16_t        nClosedVars; /* number of vars which are closed over. */
 
-    /*
-     * To ensure sizeof(JSScript) % gc::Cell::CellSize  == 0 on we must pad
-     * the script with 4 bytes. We use them to store tiny scripts like empty
-     * scripts.
-     */
-#if JS_BITS_PER_WORD == 64
-#define JS_SCRIPT_INLINE_DATA_LIMIT 4
-    uint8_t         inlineData[JS_SCRIPT_INLINE_DATA_LIMIT];
-#endif
-
     const char      *filename;  /* source filename or null */
     JSAtom          **atoms;    /* maps immediate index to literal struct */
   private:
     size_t          useCount;  /* Number of times the script has been called
                                  * or has had backedges taken. Reset if the
                                  * script's JIT code is forcibly discarded. */
   public:
     js::Bindings    bindings;   /* names of top-level variables in this script
--- a/js/src/jstypedarray.cpp
+++ b/js/src/jstypedarray.cpp
@@ -1770,17 +1770,19 @@ class TypedArrayTemplate
 
     static void copyIndexToValue(JSContext *cx, JSObject *tarray, uint32_t index, Value *vp);
 
     static JSObject *
     createSubarray(JSContext *cx, JSObject *tarray, uint32_t begin, uint32_t end)
     {
         JS_ASSERT(tarray);
 
+        JS_ASSERT(0 <= begin);
         JS_ASSERT(begin <= getLength(tarray));
+        JS_ASSERT(0 <= end);
         JS_ASSERT(end <= getLength(tarray));
 
         JSObject *bufobj = getBuffer(tarray);
         JS_ASSERT(bufobj);
 
         JS_ASSERT(begin <= end);
         uint32_t length = end - begin;
 
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -3765,34 +3765,36 @@ nsCSSFrameConstructor::ConstructFrameFro
       if (rootBox) {
         rootBox->AddTooltipSupport(content);
       }
     }
 #endif
 
     if (NS_SUCCEEDED(rv) && (bits & FCDATA_WRAP_KIDS_IN_BLOCKS)) {
       nsFrameItems newItems;
-      nsFrameItems currentBlock;
+      nsFrameItems currentBlockItems;
       nsIFrame* f;
       while ((f = childItems.FirstChild()) != nsnull) {
         bool wrapFrame = IsInlineFrame(f) || IsFrameSpecial(f);
         if (!wrapFrame) {
-          rv = FlushAccumulatedBlock(aState, content, newFrame, &currentBlock, &newItems);
+          rv = FlushAccumulatedBlock(aState, content, newFrame,
+                                     currentBlockItems, newItems);
           if (NS_FAILED(rv))
             break;
         }
 
         childItems.RemoveFrame(f);
         if (wrapFrame) {
-          currentBlock.AddChild(f);
+          currentBlockItems.AddChild(f);
         } else {
           newItems.AddChild(f);
         }
       }
-      rv = FlushAccumulatedBlock(aState, content, newFrame, &currentBlock, &newItems);
+      rv = FlushAccumulatedBlock(aState, content, newFrame,
+                                 currentBlockItems, newItems);
 
       if (childItems.NotEmpty()) {
         // an error must have occurred, delete unprocessed frames
         childItems.DestroyFrames();
       }
 
       childItems = newItems;
     }
@@ -4564,49 +4566,52 @@ nsCSSFrameConstructor::ResolveStyleConte
   return styleSet->ResolveStyleForNonElement(aParentStyleContext);
 }
 
 // MathML Mod - RBS
 nsresult
 nsCSSFrameConstructor::FlushAccumulatedBlock(nsFrameConstructorState& aState,
                                              nsIContent* aContent,
                                              nsIFrame* aParentFrame,
-                                             nsFrameItems* aBlockItems,
-                                             nsFrameItems* aNewItems)
-{
-  if (aBlockItems->IsEmpty()) {
+                                             nsFrameItems& aBlockItems,
+                                             nsFrameItems& aNewItems)
+{
+  if (aBlockItems.IsEmpty()) {
     // Nothing to do
     return NS_OK;
   }
 
+  nsIAtom* anonPseudo = nsCSSAnonBoxes::mozMathMLAnonymousBlock;
+
   nsStyleContext* parentContext =
     nsFrame::CorrectStyleParentFrame(aParentFrame,
-                                     nsCSSAnonBoxes::mozMathMLAnonymousBlock)->GetStyleContext(); 
-  nsStyleSet *styleSet = mPresShell->StyleSet();
+                                     anonPseudo)->GetStyleContext();
+  nsStyleSet* styleSet = mPresShell->StyleSet();
   nsRefPtr<nsStyleContext> blockContext;
   blockContext = styleSet->
-    ResolveAnonymousBoxStyle(nsCSSAnonBoxes::mozMathMLAnonymousBlock,
-                             parentContext);
+    ResolveAnonymousBoxStyle(anonPseudo, parentContext);
+
 
   // then, create a block frame that will wrap the child frames. Make it a
   // MathML frame so that Get(Absolute/Float)ContainingBlockFor know that this
   // is not a suitable block.
-  nsIFrame* blockFrame = NS_NewMathMLmathBlockFrame(mPresShell, blockContext,
-                          NS_BLOCK_FLOAT_MGR | NS_BLOCK_MARGIN_ROOT);
+  nsIFrame* blockFrame =
+      NS_NewMathMLmathBlockFrame(mPresShell, blockContext,
+                                 NS_BLOCK_FLOAT_MGR | NS_BLOCK_MARGIN_ROOT);
   if (NS_UNLIKELY(!blockFrame))
     return NS_ERROR_OUT_OF_MEMORY;
 
   InitAndRestoreFrame(aState, aContent, aParentFrame, nsnull, blockFrame);
-  ReparentFrames(this, blockFrame, *aBlockItems);
+  ReparentFrames(this, blockFrame, aBlockItems);
   // abs-pos and floats are disabled in MathML children so we don't have to
   // worry about messing up those.
-  blockFrame->SetInitialChildList(kPrincipalList, *aBlockItems);
-  NS_ASSERTION(aBlockItems->IsEmpty(), "What happened?");
-  aBlockItems->Clear();
-  aNewItems->AddChild(blockFrame);
+  blockFrame->SetInitialChildList(kPrincipalList, aBlockItems);
+  NS_ASSERTION(aBlockItems.IsEmpty(), "What happened?");
+  aBlockItems.Clear();
+  aNewItems.AddChild(blockFrame);
   return NS_OK;
 }
 
 // Only <math> elements can be floated or positioned.  All other MathML
 // should be in-flow.
 #define SIMPLE_MATHML_CREATE(_tag, _func)                               \
   { &nsGkAtoms::_tag,                                                   \
       FCDATA_DECL(FCDATA_DISALLOW_OUT_OF_FLOW |                         \
@@ -4834,17 +4839,17 @@ nsCSSFrameConstructor::FindSVGData(Eleme
     SIMPLE_SVG_CREATE(polygon, NS_NewSVGPathGeometryFrame),
     SIMPLE_SVG_CREATE(polyline, NS_NewSVGPathGeometryFrame),
     SIMPLE_SVG_CREATE(circle, NS_NewSVGPathGeometryFrame),
     SIMPLE_SVG_CREATE(ellipse, NS_NewSVGPathGeometryFrame),
     SIMPLE_SVG_CREATE(line, NS_NewSVGPathGeometryFrame),
     SIMPLE_SVG_CREATE(rect, NS_NewSVGPathGeometryFrame),
     SIMPLE_SVG_CREATE(path, NS_NewSVGPathGeometryFrame),
     SIMPLE_SVG_CREATE(defs, NS_NewSVGContainerFrame),
-    SIMPLE_SVG_CREATE(generic, NS_NewSVGGenericContainerFrame),
+    SIMPLE_SVG_CREATE(generic_, NS_NewSVGGenericContainerFrame),
     { &nsGkAtoms::foreignObject,
       FCDATA_WITH_WRAPPING_BLOCK(FCDATA_DISALLOW_OUT_OF_FLOW,
                                  NS_NewSVGForeignObjectFrame,
                                  nsCSSAnonBoxes::mozSVGForeignContent) },
     SIMPLE_SVG_CREATE(a, NS_NewSVGAFrame),
     SIMPLE_SVG_CREATE(altGlyph, NS_NewSVGTSpanFrame),
     SIMPLE_SVG_CREATE(text, NS_NewSVGTextFrame),
     SIMPLE_SVG_CREATE(tspan, NS_NewSVGTSpanFrame),
--- a/layout/base/nsCSSFrameConstructor.h
+++ b/layout/base/nsCSSFrameConstructor.h
@@ -1303,18 +1303,18 @@ private:
   /**
    * Takes the frames in aBlockItems and wraps them in a new anonymous block
    * frame whose content is aContent and whose parent will be aParentFrame.
    * The anonymous block is added to aNewItems and aBlockItems is cleared.
    */
   nsresult FlushAccumulatedBlock(nsFrameConstructorState& aState,
                                  nsIContent* aContent,
                                  nsIFrame* aParentFrame,
-                                 nsFrameItems* aBlockItems,
-                                 nsFrameItems* aNewItems);
+                                 nsFrameItems& aBlockItems,
+                                 nsFrameItems& aNewItems);
 
   // Function to find FrameConstructionData for aContent.  Will return
   // null if aContent is not MathML.
   static const FrameConstructionData* FindMathMLData(Element* aElement,
                                                      nsIAtom* aTag,
                                                      PRInt32 aNameSpaceID,
                                                      nsStyleContext* aStyleContext);
 
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -92,17 +92,17 @@
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDocShellTreeNode.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIDocShell.h"
 #include "nsIBaseWindow.h"
 #include "nsILayoutHistoryState.h"
-#include "nsIParser.h"
+#include "nsCharsetSource.h"
 #include "nsGUIEvent.h"
 #include "nsHTMLReflowState.h"
 #include "nsIDOMHTMLAnchorElement.h"
 #include "nsIDOMHTMLAreaElement.h"
 #include "nsIDOMHTMLLinkElement.h"
 #include "nsIImageLoadingContent.h"
 #include "nsCopySupport.h"
 #include "nsIDOMHTMLFrameSetElement.h"
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -103,18 +103,16 @@
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsReadableUtils.h"
 #include "nsUnicharUtils.h"
 #include "nsIPageSequenceFrame.h"
 #include "nsCaret.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsIDOMXMLDocument.h"
-#include "nsIParser.h"
-#include "nsParserCIID.h"
 #include "nsViewsCID.h"
 #include "nsFrameManager.h"
 #include "nsEventStateManager.h"
 #include "nsXPCOM.h"
 #include "nsISupportsPrimitives.h"
 #include "nsILayoutHistoryState.h"
 #include "nsILineIterator.h" // for ScrollContentIntoView
 #include "nsWeakPtr.h"
--- a/layout/build/nsContentDLF.cpp
+++ b/layout/build/nsContentDLF.cpp
@@ -55,17 +55,17 @@
 #include "nsNetUtil.h"
 #include "nsCRT.h"
 #include "nsIViewSourceChannel.h"
 #ifdef MOZ_MEDIA
 #include "nsHTMLMediaElement.h"
 #endif
 #include "nsContentUtils.h"
 #include "imgILoader.h"
-#include "nsIParser.h"
+#include "nsCharsetSource.h"
 #include "nsMimeTypes.h"
 
 #include "mozilla/FunctionTimer.h"
 
 // plugins
 #include "nsIPluginHost.h"
 #include "nsPluginHost.h"
 static NS_DEFINE_CID(kPluginDocumentCID, NS_PLUGINDOCUMENT_CID);
--- a/layout/generic/nsHTMLReflowMetrics.h
+++ b/layout/generic/nsHTMLReflowMetrics.h
@@ -66,21 +66,21 @@ enum nsOverflowType { eVisualOverflow, e
   for (nsOverflowType var_ = nsOverflowType(0); var_ < 2;                     \
        var_ = nsOverflowType(var_ + 1))
 
 struct nsOverflowAreas {
 private:
   nsRect mRects[2];
 public:
   nsRect& Overflow(size_t aIndex) {
-    NS_ASSERTION(aIndex < 2, "index out of range");
+    NS_ASSERTION(0 <= aIndex && aIndex < 2, "index out of range");
     return mRects[aIndex];
   }
   const nsRect& Overflow(size_t aIndex) const {
-    NS_ASSERTION(aIndex < 2, "index out of range");
+    NS_ASSERTION(0 <= aIndex && aIndex < 2, "index out of range");
     return mRects[aIndex];
   }
 
   nsRect& VisualOverflow() { return mRects[eVisualOverflow]; }
   const nsRect& VisualOverflow() const { return mRects[eVisualOverflow]; }
 
   nsRect& ScrollableOverflow() { return mRects[eScrollableOverflow]; }
   const nsRect& ScrollableOverflow() const { return mRects[eScrollableOverflow]; }
--- a/layout/printing/nsPrintEngine.cpp
+++ b/layout/printing/nsPrintEngine.cpp
@@ -137,17 +137,16 @@ static const char kPrintingPromptService
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDocShellTreeNode.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsIBaseWindow.h"
 #include "nsILayoutHistoryState.h"
 #include "nsFrameManager.h"
-#include "nsIParser.h"
 #include "nsGUIEvent.h"
 #include "nsHTMLReflowState.h"
 #include "nsIDOMHTMLAnchorElement.h"
 #include "nsIDOMHTMLAreaElement.h"
 #include "nsIDOMHTMLLinkElement.h"
 #include "nsIDOMHTMLImageElement.h"
 #include "nsIContentViewerContainer.h"
 #include "nsIContentViewer.h"
--- a/layout/style/nsAnimationManager.cpp
+++ b/layout/style/nsAnimationManager.cpp
@@ -582,37 +582,26 @@ public:
   enum { ALLOW_MEMMOVE = true };
 
 private:
   const float mValue;
 };
 
 struct KeyframeData {
   float mKey;
+  PRUint32 mIndex; // store original order since sort algorithm is not stable
   nsCSSKeyframeRule *mRule;
 };
 
-typedef InfallibleTArray<KeyframeData> KeyframeDataArray;
-
-static PLDHashOperator
-AppendKeyframeData(const float &aKey, nsCSSKeyframeRule *aRule, void *aData)
-{
-  KeyframeDataArray *array = static_cast<KeyframeDataArray*>(aData);
-  KeyframeData *data = array->AppendElement();
-  data->mKey = aKey;
-  data->mRule = aRule;
-  return PL_DHASH_NEXT;
-}
-
 struct KeyframeDataComparator {
   bool Equals(const KeyframeData& A, const KeyframeData& B) const {
-    return A.mKey == B.mKey;
+    return A.mKey == B.mKey && A.mIndex == B.mIndex;
   }
   bool LessThan(const KeyframeData& A, const KeyframeData& B) const {
-    return A.mKey < B.mKey;
+    return A.mKey < B.mKey || (A.mKey == B.mKey && A.mIndex < B.mIndex);
   }
 };
 
 class ResolvedStyleCache {
 public:
   ResolvedStyleCache() {
     mCache.Init(16); // FIXME: make infallible!
   }
@@ -680,21 +669,25 @@ nsAnimationManager::BuildAnimations(nsSt
     aDest.mIterationDuration = TimeDuration::FromMilliseconds(aSrc.GetDuration());
 
     nsCSSKeyframesRule *rule = KeyframesRuleFor(aDest.mName);
     if (!rule) {
       // no segments
       continue;
     }
 
-    // Build the set of unique keyframes in the @keyframes rule.  Per
-    // css3-animations, later keyframes with the same key replace
-    // earlier ones (no cascading).
-    nsDataHashtable<PercentageHashKey, nsCSSKeyframeRule*> keyframes;
-    keyframes.Init(16); // FIXME: make infallible!
+    // While current drafts of css3-animations say that later keyframes
+    // with the same key entirely replace earlier ones (no cascading),
+    // this is a bad idea and contradictory to the rest of CSS.  So
+    // we're going to keep all the keyframes for each key and then do
+    // the replacement on a per-property basis rather than a per-rule
+    // basis, just like everything else in CSS.
+
+    AutoInfallibleTArray<KeyframeData, 16> sortedKeyframes;
+
     for (PRUint32 ruleIdx = 0, ruleEnd = rule->StyleRuleCount();
          ruleIdx != ruleEnd; ++ruleIdx) {
       css::Rule* cssRule = rule->GetStyleRuleAt(ruleIdx);
       NS_ABORT_IF_FALSE(cssRule, "must have rule");
       NS_ABORT_IF_FALSE(cssRule->GetType() == css::Rule::KEYFRAME_RULE,
                         "must be keyframe rule");
       nsCSSKeyframeRule *kfRule = static_cast<nsCSSKeyframeRule*>(cssRule);
 
@@ -702,23 +695,24 @@ nsAnimationManager::BuildAnimations(nsSt
       for (PRUint32 keyIdx = 0, keyEnd = keys.Length();
            keyIdx != keyEnd; ++keyIdx) {
         float key = keys[keyIdx];
         // FIXME (spec):  The spec doesn't say what to do with
         // out-of-range keyframes.  We'll ignore them.
         // (And PercentageHashKey currently assumes we either ignore or
         // clamp them.)
         if (0.0f <= key && key <= 1.0f) {
-          keyframes.Put(key, kfRule);
+          KeyframeData *data = sortedKeyframes.AppendElement();
+          data->mKey = key;
+          data->mIndex = ruleIdx;
+          data->mRule = kfRule;
         }
       }
     }
 
-    KeyframeDataArray sortedKeyframes;
-    keyframes.EnumerateRead(AppendKeyframeData, &sortedKeyframes);
     sortedKeyframes.Sort(KeyframeDataComparator());
 
     if (sortedKeyframes.Length() == 0) {
       // no segments
       continue;
     }
 
     // Record the properties that are present in any keyframe rules we
@@ -737,28 +731,47 @@ nsAnimationManager::BuildAnimations(nsSt
     for (nsCSSProperty prop = nsCSSProperty(0);
          prop < eCSSProperty_COUNT_no_shorthands;
          prop = nsCSSProperty(prop + 1)) {
       if (!properties.HasProperty(prop) ||
           nsCSSProps::kAnimTypeTable[prop] == eStyleAnimType_None) {
         continue;
       }
 
+      // Build a list of the keyframes to use for this property.  This
+      // means we need every keyframe with the property in it, except
+      // for those keyframes where a later keyframe with the *same key*
+      // also has the property.
+      AutoInfallibleTArray<PRUint32, 16> keyframesWithProperty;
+      float lastKey = 100.0f; // an invalid key
+      for (PRUint32 kfIdx = 0, kfEnd = sortedKeyframes.Length();
+           kfIdx != kfEnd; ++kfIdx) {
+        KeyframeData &kf = sortedKeyframes[kfIdx];
+        if (!kf.mRule->Declaration()->HasProperty(prop)) {
+          continue;
+        }
+        if (kf.mKey == lastKey) {
+          // Replace previous occurrence of same key.
+          keyframesWithProperty[keyframesWithProperty.Length() - 1] = kfIdx;
+        } else {
+          keyframesWithProperty.AppendElement(kfIdx);
+        }
+        lastKey = kf.mKey;
+      }
+
       AnimationProperty &propData = *aDest.mProperties.AppendElement();
       propData.mProperty = prop;
 
       KeyframeData *fromKeyframe = nsnull;
       nsRefPtr<nsStyleContext> fromContext;
       bool interpolated = true;
-      for (PRUint32 kfIdx = 0, kfEnd = sortedKeyframes.Length();
-           kfIdx != kfEnd; ++kfIdx) {
+      for (PRUint32 wpIdx = 0, wpEnd = keyframesWithProperty.Length();
+           wpIdx != wpEnd; ++wpIdx) {
+        PRUint32 kfIdx = keyframesWithProperty[wpIdx];
         KeyframeData &toKeyframe = sortedKeyframes[kfIdx];
-        if (!toKeyframe.mRule->Declaration()->HasProperty(prop)) {
-          continue;
-        }
 
         nsRefPtr<nsStyleContext> toContext =
           resolvedStyles.Get(mPresContext, aStyleContext, toKeyframe.mRule);
 
         if (fromKeyframe) {
           interpolated = interpolated &&
             BuildSegment(propData.mSegments, prop, aSrc,
                          fromKeyframe->mKey, fromContext,
--- a/layout/style/test/test_animations.html
+++ b/layout/style/test/test_animations.html
@@ -82,16 +82,30 @@ https://bugzilla.mozilla.org/show_bug.cg
       -moz-animation-timing-function: ease-in;
     }
   }
 
   @-moz-keyframes uaoverride {
     0%, 100% { line-height: 3; margin-top: 20px }
     50% { margin-top: 120px }
   }
+
+  @-moz-keyframes cascade {
+    0%, 25%, 100% { top: 0 }
+    50%, 75% { top: 100px }
+    0%, 75%, 100% { left: 0 }
+    25%, 50% { left: 100px }
+  }
+  @-moz-keyframes cascade2 {
+    0% { text-indent: 0 }
+    25% { text-indent: 30px; -moz-animation-timing-function: ease-in } /* beaten by rule below */
+    50% { text-indent: 0 }
+    25% { text-indent: 50px }
+    100% { text-indent: 100px }
+  }
   </style>
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=435442">Mozilla Bug 435442</a>
 <div id="display"></div>
 <pre id="test">
 <script type="application/javascript">
 "use strict";
@@ -1247,14 +1261,62 @@ display.style.overflow = "scroll";
 is(cs.marginTop, "100px", "bug 686656 test 2 at 250ms");
 advance_clock(375);
 is(cs.marginTop, "50px", "bug 686656 test 2 at 625ms");
 advance_clock(375);
 is(cs.marginTop, "0px", "bug 686656 test 2 at 1000ms");
 done_div();
 display.style.overflow = "";
 
+// Test that cascading between keyframes rules is per-property rather
+// than per-rule (bug ), and that the timing function isn't taken from a
+// rule that's skipped.  (Bug 738003)
+new_div("-moz-animation: cascade 1s linear forwards; position: relative");
+is(cs.top, "0px", "cascade test (top) at 0ms");
+is(cs.left, "0px", "cascade test (top) at 0ms");
+advance_clock(125);
+is(cs.top, "0px", "cascade test (top) at 125ms");
+is(cs.left, "50px", "cascade test (top) at 125ms");
+advance_clock(125);
+is(cs.top, "0px", "cascade test (top) at 250ms");
+is(cs.left, "100px", "cascade test (top) at 250ms");
+advance_clock(125);
+is(cs.top, "50px", "cascade test (top) at 375ms");
+is(cs.left, "100px", "cascade test (top) at 375ms");
+advance_clock(125);
+is(cs.top, "100px", "cascade test (top) at 500ms");
+is(cs.left, "100px", "cascade test (top) at 500ms");
+advance_clock(125);
+is(cs.top, "100px", "cascade test (top) at 625ms");
+is(cs.left, "50px", "cascade test (top) at 625ms");
+advance_clock(125);
+is(cs.top, "100px", "cascade test (top) at 750ms");
+is(cs.left, "0px", "cascade test (top) at 750ms");
+advance_clock(125);
+is(cs.top, "50px", "cascade test (top) at 875ms");
+is(cs.left, "0px", "cascade test (top) at 875ms");
+advance_clock(125);
+is(cs.top, "0px", "cascade test (top) at 1000ms");
+is(cs.left, "0px", "cascade test (top) at 1000ms");
+done_div();
+
+new_div("-moz-animation: cascade2 8s linear forwards");
+is(cs.textIndent, "0px", "cascade2 test at 0s");
+advance_clock(1000);
+is(cs.textIndent, "25px", "cascade2 test at 1s");
+advance_clock(1000);
+is(cs.textIndent, "50px", "cascade2 test at 2s");
+advance_clock(1000);
+is(cs.textIndent, "25px", "cascade2 test at 3s");
+advance_clock(1000);
+is(cs.textIndent, "0px", "cascade2 test at 4s");
+advance_clock(3000);
+is(cs.textIndent, "75px", "cascade2 test at 7s");
+advance_clock(1000);
+is(cs.textIndent, "100px", "cascade2 test at 8s");
+done_div();
+
 SpecialPowers.DOMWindowUtils.restoreNormalRefresh();
 
 </script>
 </pre>
 </body>
 </html>
--- a/layout/tools/reftest/remotereftest.py
+++ b/layout/tools/reftest/remotereftest.py
@@ -385,23 +385,28 @@ def main():
     automation = RemoteAutomation(None)
     parser = RemoteOptions(automation)
     options, args = parser.parse_args()
 
     if (options.deviceIP == None):
         print "Error: you must provide a device IP to connect to via the --device option"
         sys.exit(1)
 
-    if (options.dm_trans == "adb"):
-        if (options.deviceIP):
-            dm = devicemanagerADB.DeviceManagerADB(options.deviceIP, options.devicePort)
+    try:
+        if (options.dm_trans == "adb"):
+            if (options.deviceIP):
+                dm = devicemanagerADB.DeviceManagerADB(options.deviceIP, options.devicePort)
+            else:
+                dm = devicemanagerADB.DeviceManagerADB(None, None)
         else:
-            dm = devicemanagerADB.DeviceManagerADB(None, None)
-    else:
-         dm = devicemanagerSUT.DeviceManagerSUT(options.deviceIP, options.devicePort)
+            dm = devicemanagerSUT.DeviceManagerSUT(options.deviceIP, options.devicePort)
+    except devicemanager.DMError:
+        print "Error: exception while initializing devicemanager.  Most likely the device is not in a testable state."
+        sys.exit(1)
+
     automation.setDeviceManager(dm)
 
     if (options.remoteProductName != None):
         automation.setProduct(options.remoteProductName)
 
     # Set up the defaults and ensure options are set
     options = parser.verifyRemoteOptions(options)
     if (options == None):
--- a/memory/jemalloc/jemalloc.c
+++ b/memory/jemalloc/jemalloc.c
@@ -1414,23 +1414,18 @@ static void	*huge_palloc(size_t alignmen
 static void	*huge_ralloc(void *ptr, size_t size, size_t oldsize);
 static void	huge_dalloc(void *ptr);
 static void	malloc_print_stats(void);
 #ifndef MOZ_MEMORY_WINDOWS
 static
 #endif
 bool		malloc_init_hard(void);
 
-#ifdef MOZ_MEMORY_ANDROID
-void	_malloc_prefork(void);
-void	_malloc_postfork(void);
-#else
 static void	_malloc_prefork(void);
 static void	_malloc_postfork(void);
-#endif
 
 #ifdef MOZ_MEMORY_DARWIN
 /*
  * MALLOC_ZONE_T_NOTE
  *
  * On Darwin, we hook into the memory allocator using a malloc_zone_t struct.
  * We must be very careful around this struct because of different behaviour on
  * different versions of OSX.
@@ -5918,20 +5913,18 @@ MALLOC_OUT:
 	/* Take care to call atexit() only once. */
 	if (opt_print_stats) {
 #ifndef MOZ_MEMORY_WINDOWS
 		/* Print statistics at exit. */
 		atexit(malloc_print_stats);
 #endif
 	}
 
-#if (!defined(MOZ_MEMORY_WINDOWS) && !defined(MOZ_MEMORY_DARWIN) && !defined(MOZ_MEMORY_ANDROID))
+#if !defined(MOZ_MEMORY_WINDOWS)
 	/* Prevent potential deadlock on malloc locks after fork. */
-	/* XXX on Android there is no pthread_atfork, so we specifically
-	   call _malloc_prefork and _malloc_postfork in process_util_linux.cc */
 	pthread_atfork(_malloc_prefork, _malloc_postfork, _malloc_postfork);
 #endif
 
 #ifndef MALLOC_STATIC_SIZES
 	/* Set variables according to the value of opt_small_max_2pow. */
 	if (opt_small_max_2pow < opt_quantum_2pow)
 		opt_small_max_2pow = opt_quantum_2pow;
 	small_max = (1U << opt_small_max_2pow);
@@ -6206,27 +6199,16 @@ malloc_shutdown()
 
 #ifdef MOZ_MEMORY_ANDROID
 /*
  * On Android, we use __wrap_* instead of je_* to accomodate with the
  * linker's --wrap option we use. That option prefixes the function
  * names it is given with __wrap_.
  */
 #define wrap(a) __wrap_ ## a
-
-/* Extra wrappers for NSPR alloc functions */
-void *
-__wrap_PR_Malloc(size_t size) __attribute__((alias("__wrap_malloc")));
-void *
-__wrap_PR_Calloc(size_t num, size_t size) __attribute__((alias("__wrap_calloc")));
-void *
-__wrap_PR_Realloc(void *ptr, size_t size) __attribute__((alias("__wrap_realloc")));
-void
-__wrap_PR_Free(void *ptr) __attribute__((alias("__wrap_free")));
-
 #else
 #define wrap(a) je_ ## a
 #endif
 
 #define malloc(a)               wrap(malloc)(a)
 #define memalign(a, b)          wrap(memalign)(a, b)
 #define posix_memalign(a, b, c) wrap(posix_memalign)(a, b, c)
 #define valloc(a)               wrap(valloc)(a)
@@ -6855,21 +6837,17 @@ size_t
 /******************************************************************************/
 /*
  * Begin library-private functions, used by threading libraries for protection
  * of malloc during fork().  These functions are only called if the program is
  * running in threaded mode, so there is no need to check whether the program
  * is threaded here.
  */
 
-#ifdef MOZ_MEMORY_ANDROID
-void
-#else
 static void
-#endif
 _malloc_prefork(void)
 {
 	unsigned i;
 
 	/* Acquire all mutexes in a safe order. */
 
 	malloc_spin_lock(&arenas_lock);
 	for (i = 0; i < narenas; i++) {
@@ -6877,21 +6855,17 @@ static void
 			malloc_spin_lock(&arenas[i]->lock);
 	}
 
 	malloc_mutex_lock(&base_mtx);
 
 	malloc_mutex_lock(&huge_mtx);
 }
 
-#ifdef MOZ_MEMORY_ANDROID
-void
-#else
 static void
-#endif
 _malloc_postfork(void)
 {
 	unsigned i;
 
 	/* Release all mutexes, now that fork() has completed. */
 
 	malloc_mutex_unlock(&huge_mtx);
 
--- a/memory/jemalloc/jemalloc.h
+++ b/memory/jemalloc/jemalloc.h
@@ -48,20 +48,16 @@ void	*calloc(size_t num, size_t size);
 void	*realloc(void *ptr, size_t size);
 void	free(void *ptr);
 int	posix_memalign(void **memptr, size_t alignment, size_t size);
 #endif /* MOZ_MEMORY_DARWIN, MOZ_MEMORY_LINUX */
 
 /* Android doesn't have posix_memalign */
 #ifdef MOZ_MEMORY_ANDROID
 int	posix_memalign(void **memptr, size_t alignment, size_t size);
-/* Android < 2.3 doesn't have pthread_atfork, so we need to call these
- * when forking the child process. See bug 680190 */
-void    _malloc_prefork(void);
-void    _malloc_postfork(void);
 #endif
 
 #if defined(MOZ_MEMORY_DARWIN) || defined(MOZ_MEMORY_WINDOWS)
 void	*je_malloc(size_t size);
 void	*je_valloc(size_t size);
 void	*je_calloc(size_t num, size_t size);
 void	*je_realloc(void *ptr, size_t size);
 void	je_free(void *ptr);
--- a/mobile/android/app/mobile.js
+++ b/mobile/android/app/mobile.js
@@ -140,17 +140,17 @@ pref("browser.display.history.maxresults
 pref("browser.display.remotetabs.timeout", 10);
 
 /* session history */
 pref("browser.sessionhistory.max_total_viewers", 1);
 pref("browser.sessionhistory.max_entries", 50);
 
 /* session store */
 pref("browser.sessionstore.resume_session_once", false);
-pref("browser.sessionstore.resume_from_crash", true);
+pref("browser.sessionstore.resume_from_crash", false);
 pref("browser.sessionstore.resume_from_crash_timeout", 60); // minutes
 pref("browser.sessionstore.interval", 10000); // milliseconds
 pref("browser.sessionstore.max_tabs_undo", 1);
 pref("browser.sessionstore.max_resumed_crashes", 1);
 pref("browser.sessionstore.recent_crashes", 0);
 
 /* these should help performance */
 pref("mozilla.widget.force-24bpp", true);
--- a/mobile/android/base/Favicons.java
+++ b/mobile/android/base/Favicons.java
@@ -46,16 +46,17 @@ import android.database.sqlite.SQLiteOpe
 import android.database.sqlite.SQLiteQueryBuilder;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
 import android.util.Log;
 
 import java.io.BufferedInputStream;
 import java.io.ByteArrayInputStream;
+import java.io.InputStream;
 import java.io.IOException;
 import java.net.URLConnection;
 import java.net.HttpURLConnection;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
@@ -289,17 +290,17 @@ public class Favicons {
                 int offset = 0;
                 while ((pos = contentStream.read(bytes, offset, length - offset)) > 0)
                     offset += pos;
                 if (length == offset) {
                     byteStream = new ByteArrayInputStream(bytes);
                     image = (BitmapDrawable) Drawable.createFromStream(byteStream, "src");
                 }
             } catch (Exception e) {
-                Log.d(LOGTAG, "Error downloading favicon: " + e);
+                Log.e(LOGTAG, "Error downloading favicon", e);
             } finally {
                 if (urlConnection != null && urlConnection instanceof HttpURLConnection) {
                     HttpURLConnection httpConnection = (HttpURLConnection) urlConnection;
                     httpConnection.disconnect();
                 }
 
                 try {
                     if (contentStream != null)
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -448,20 +448,20 @@ abstract public class GeckoApp
             bookmark.setIcon(R.drawable.ic_menu_bookmark_remove);
         } else {
             bookmark.setChecked(false);
             bookmark.setIcon(R.drawable.ic_menu_bookmark_add);
         }
 
         forward.setEnabled(tab.canDoForward());
 
-        // Disable share menuitem for about:, chrome: and file: URIs
+        // Disable share menuitem for about:, chrome:, file:, and resource: URIs
         String scheme = Uri.parse(tab.getURL()).getScheme();
         share.setEnabled(!(scheme.equals("about") || scheme.equals("chrome") ||
-                           scheme.equals("file")));
+                           scheme.equals("file") || scheme.equals("resource")));
 
         // Disable save as PDF for about:home and xul pages
         saveAsPDF.setEnabled(!(tab.getURL().equals("about:home") ||
                                tab.getContentType().equals("application/vnd.mozilla.xul+xml")));
 
         charEncoding.setVisible(GeckoPreferences.getCharEncodingState());
 
         return true;
@@ -1672,19 +1672,20 @@ abstract public class GeckoApp
 
         mBrowserToolbar.setTitle(mLastTitle);
 
         String passedUri = null;
         String uri = getURIFromIntent(intent);
         if (uri != null && uri.length() > 0)
             passedUri = mLastTitle = uri;
 
+        mRestoreSession |= getProfile().shouldRestoreSession();
         if (passedUri == null || passedUri.equals("about:home")) {
             // show about:home if we aren't restoring previous session
-            if (! getProfile().hasSession()) {
+            if (!mRestoreSession) {
                 mBrowserToolbar.updateTabCount(1);
                 showAboutHome();
             }
         } else {
             mBrowserToolbar.updateTabCount(1);
         }
 
         Uri data = intent.getData();
@@ -1737,19 +1738,25 @@ abstract public class GeckoApp
              * and zoom a cached screenshot of the previous page. This call will return null if
              * there is no cached screenshot; in that case, we have no choice but to display a
              * checkerboard.
              *
              * TODO: Fall back to a built-in screenshot of the Fennec Start page for a nice first-
              * run experience, perhaps?
              */
             mLayerController = new LayerController(this);
+            View v = mLayerController.getView();
+
             mPlaceholderLayerClient = new PlaceholderLayerClient(mLayerController, mLastViewport);
-
-            mGeckoLayout.addView(mLayerController.getView(), 0);
+            if (!mPlaceholderLayerClient.loadScreenshot()) {
+                // Instead of flickering the checkerboard, show a white screen until Gecko paints
+                v.setBackgroundColor(Color.WHITE);
+            }
+
+            mGeckoLayout.addView(v, 0);
         }
 
         mPluginContainer = (AbsoluteLayout) findViewById(R.id.plugin_container);
 
         mDoorHangerPopup = new DoorHangerPopup(this);
         mFormAssistPopup = (FormAssistPopup) findViewById(R.id.form_assist_popup);
 
         Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - UI almost up");
@@ -2779,16 +2786,17 @@ abstract public class GeckoApp
             args.put("parentId", Tabs.getInstance().getSelectedTab().getId());
         } catch (Exception e) {
             Log.e(LOGTAG, "error building JSON arguments");
         }
         Log.i(LOGTAG, "Sending message to Gecko: " + SystemClock.uptimeMillis() + " - Tab:Add");
         GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Tab:Add", args.toString()));
     }
 
+    /* This method is referenced by Robocop via reflection. */
     public GeckoLayerClient getLayerClient() { return mLayerClient; }
     public LayerController getLayerController() { return mLayerController; }
 
     // accelerometer
     public void onAccuracyChanged(Sensor sensor, int accuracy) {}
 
     public void onSensorChanged(SensorEvent event)
     {
--- a/mobile/android/base/GeckoAppShell.java
+++ b/mobile/android/base/GeckoAppShell.java
@@ -367,16 +367,17 @@ public class GeckoAppShell
 
         // setup the downloads path
         f = Environment.getDownloadCacheDirectory();
         GeckoAppShell.putenv("EXTERNAL_STORAGE=" + f.getPath());
 
         putLocaleEnv();
     }
 
+    /* This method is referenced by Robocop via reflection. */
     public static void loadSQLiteLibs(Context context, String apkName) {
         if (sSQLiteLibsLoaded)
             return;
         synchronized(sSQLiteLibsLoaded) {
             if (sSQLiteLibsLoaded)
                 return;
             loadMozGlue();
             // the extract libs parameter is being removed in bug 732069
@@ -477,16 +478,17 @@ public class GeckoAppShell
         try {
             while (!gPendingEvents.isEmpty()) {
                 GeckoEvent e = gPendingEvents.removeFirst();
                 notifyGeckoOfEvent(e);
             }
         } catch (NoSuchElementException e) {}
     }
 
+    /* This method is referenced by Robocop via reflection. */
     public static void sendEventToGecko(GeckoEvent e) {
         if (GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning)) {
             notifyGeckoOfEvent(e);
         } else {
             gPendingEvents.addLast(e);
         }
     }
 
@@ -1658,16 +1660,17 @@ public class GeckoAppShell
         if (sCamera != null) {
             sCamera.stopPreview();
             sCamera.release();
             sCamera = null;
             sCameraBuffer = null;
         }
     }
 
+    /* This method is referenced by Robocop via reflection. */
     public static void registerGeckoEventListener(String event, GeckoEventListener listener) {
         if (mEventListeners == null)
             mEventListeners = new HashMap<String, ArrayList<GeckoEventListener>>();
 
         if (!mEventListeners.containsKey(event))
             mEventListeners.put(event, new ArrayList<GeckoEventListener>());
 
         ArrayList<GeckoEventListener> listeners = mEventListeners.get(event);
@@ -1687,16 +1690,17 @@ public class GeckoAppShell
         });
         try {
             sTracerQueue.take();
         } catch(InterruptedException ie) {
             Log.w(LOGTAG, "exception firing tracer", ie);
         }
     }
 
+    /* This method is referenced by Robocop via reflection. */
     public static void unregisterGeckoEventListener(String event, GeckoEventListener listener) {
         if (mEventListeners == null)
             return;
 
         if (!mEventListeners.containsKey(event))
             return;
 
         ArrayList<GeckoEventListener> listeners = mEventListeners.get(event);
--- a/mobile/android/base/GeckoEvent.java
+++ b/mobile/android/base/GeckoEvent.java
@@ -58,16 +58,19 @@ import java.lang.System;
 
 import android.util.Log;
 
 /* We're not allowed to hold on to most events given to us
  * so we save the parts of the events we want to use in GeckoEvent.
  * Fields have different meanings depending on the event type.
  */
 
+/* This class is referenced by Robocop via reflection; use care when 
+ * modifying the signature.
+ */
 public class GeckoEvent {
     private static final String LOGTAG = "GeckoEvent";
 
     private static final int INVALID = -1;
     private static final int NATIVE_POKE = 0;
     private static final int KEY_EVENT = 1;
     private static final int MOTION_EVENT = 2;
     private static final int SENSOR_EVENT = 3;
--- a/mobile/android/base/GeckoEventListener.java
+++ b/mobile/android/base/GeckoEventListener.java
@@ -34,11 +34,14 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 package org.mozilla.gecko;
 
 import org.json.JSONObject;
 
+/* This class is referenced by Robocop via reflection; use care when 
+ * modifying the signature.
+ */ 
 public interface GeckoEventListener {
     public void handleMessage(String event, JSONObject message);
 }
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/GeckoJarReader.java
@@ -0,0 +1,124 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.gecko;
+
+import java.io.File;
+import java.net.URL;
+import java.util.EmptyStackException;
+import java.util.Stack;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipEntry;
+import java.io.InputStream;
+import java.io.IOException;
+
+import android.util.Log;
+
+/* Reads out of a multiple level deep jar file such as
+ *  jar:jar:file:///data/app/org.mozilla.fennec.apk!/omni.ja!/chrome/chrome/content/branding/favicon32.png
+ */
+public class GeckoJarReader {
+    static private String LOGTAG = "GeckoJarReader";
+
+    static public InputStream getStream(String url) {
+        Stack<String> jarUrls = parseUrl(url);
+        ZipInputStream inputStream = null;
+
+        ZipFile zip = null;
+        try {
+            // Load the initial jar file as a zip
+            URL fileUrl = new URL(jarUrls.pop());
+            File file = new File(fileUrl.getPath());
+            zip = new ZipFile(file);
+            ZipEntry entry = null;
+
+            // loop through children jar files until we reach the innermost one
+            while (jarUrls.peek() != null) {
+                String fileName = jarUrls.pop();
+
+                if (inputStream != null) {
+                    entry = getEntryFromStream(inputStream, fileName);
+                } else {
+                    entry = zip.getEntry(fileName);
+                }
+
+                // if there is nothing else on the stack, this will throw and break us out of the loop
+                jarUrls.peek();
+
+                if (inputStream != null) {
+                    inputStream = new ZipInputStream(inputStream);
+                } else {
+                    inputStream = new ZipInputStream(zip.getInputStream(entry));
+                }
+  
+                if (entry == null) {
+                    Log.d(LOGTAG, "No Entry for " + fileName);
+                    return null;
+                }
+            }
+        } catch (EmptyStackException ex) {
+            Log.d(LOGTAG, "Reached Jar reader reached end of stack");
+        } catch (IOException ex) {
+            Log.e(LOGTAG, "Exception ", ex);
+        } catch (Exception ex) {
+            Log.e(LOGTAG, "Exception ", ex);
+        } finally {
+            if (zip != null) {
+                try {
+                    zip.close();
+                } catch(IOException ex) {
+                    Log.e(LOGTAG, "Error closing zip", ex);
+                }
+            }
+        }
+
+        return inputStream;
+    }
+
+    /* Searches through a ZipInputStream for an entry with a given name */
+    static private ZipEntry getEntryFromStream(ZipInputStream zipStream, String entryName) {
+        ZipEntry entry = null;
+
+        try {
+            entry = zipStream.getNextEntry();
+            while(entry != null && !entry.getName().equals(entryName)) {
+                entry = zipStream.getNextEntry();
+            }
+        } catch (IOException ex) {
+            Log.e(LOGTAG, "Exception getting stream entry", ex);
+        }
+
+        return entry;
+    }
+
+    /* Returns a stack of strings breaking the url up into pieces. Each piece
+     * is assumed to point to a jar file except for the final one. Callers should
+     * pass in the url to parse, and null for the parent parameter (used for recursion)
+     * For example, jar:jar:file:///data/app/org.mozilla.fennec.apk!/omni.ja!/chrome/chrome/content/branding/favicon32.png
+     * will return:
+     *    file:///data/app/org.mozilla.fennec.apk
+     *    omni.ja
+     *    chrome/chrome/content/branding/favicon32.png
+     */
+    static private Stack<String> parseUrl(String url) {
+        return parseUrl(url, null);
+    }
+
+    static private Stack<String> parseUrl(String url, Stack<String> results) {
+        if (results == null) {
+            results = new Stack<String>();
+        }
+
+        if (url.startsWith("jar:")) {
+            int jarEnd = url.lastIndexOf("!");
+            String subStr = url.substring(4, jarEnd);
+            results.push(url.substring(jarEnd+2)); // remove the !/ characters
+            return parseUrl(subStr, results);
+        } else {
+            results.push(url);
+            return results;
+        }
+    }
+}
--- a/mobile/android/base/GeckoProfile.java
+++ b/mobile/android/base/GeckoProfile.java
@@ -28,16 +28,19 @@ public final class GeckoProfile {
 
     private static HashMap<String, GeckoProfile> sProfileCache = new HashMap<String, GeckoProfile>();
 
     private final Context mContext;
     private final String mName;
     private File mMozDir;
     private File mDir;
 
+    // this short timeout is a temporary fix until bug 735399 is implemented
+    private static final long SESSION_TIMEOUT = 30 * 1000; // 30 seconds
+
     public static GeckoProfile get(Context context) {
         return get(context, null);
     }
 
     public static GeckoProfile get(Context context, String profileName) {
         if (context == null) {
             throw new IllegalArgumentException("context must be non-null");
         }
@@ -75,22 +78,29 @@ public final class GeckoProfile {
                 Log.d(LOGTAG, "Found profile dir: " + mDir.getAbsolutePath());
             }
         } catch (IOException ioe) {
             Log.e(LOGTAG, "Error getting profile dir", ioe);
         }
         return mDir;
     }
 
-    public boolean hasSession() {
+    public boolean shouldRestoreSession() {
         Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - start check sessionstore.js exists");
         File dir = getDir();
-        boolean hasSession = (dir != null && new File(dir, "sessionstore.js").exists());
+        if (dir == null)
+            return false;
+
+        File sessionFile = new File(dir, "sessionstore.js");
+        if (!sessionFile.exists())
+            return false;
+
+        boolean shouldRestore = (System.currentTimeMillis() - sessionFile.lastModified() < SESSION_TIMEOUT);
         Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - finish check sessionstore.js exists");
-        return hasSession;
+        return shouldRestore;
     }
 
     public String readSessionFile(boolean geckoReady) {
         File dir = getDir();
         if (dir == null) {
             return null;
         }
 
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -85,16 +85,17 @@ FENNEC_JAVA_FILES = \
   GeckoBatteryManager.java \
   GeckoBackgroundThread.java \
   GeckoConnectivityReceiver.java \
   GeckoEvent.java \
   GeckoEventListener.java \
   GeckoEventResponder.java \
   GeckoHalDefines.java \
   GeckoInputConnection.java \
+  GeckoJarReader.java \
 	GeckoMessageReceiver.java \
   GeckoPreferences.java \
   GeckoProfile.java \
   GeckoStateListDrawable.java \
   GeckoThread.java \
   GlobalHistory.java \
   LinkPreference.java \
   LinkTextView.java \
--- a/mobile/android/base/db/LocalBrowserDB.java
+++ b/mobile/android/base/db/LocalBrowserDB.java
@@ -92,16 +92,17 @@ public class LocalBrowserDB implements B
 
     private static final String[] DEFAULT_BOOKMARK_COLUMNS =
             new String[] { Bookmarks._ID,
                            Bookmarks.GUID,
                            Bookmarks.URL,
                            Bookmarks.TITLE,
                            Bookmarks.TYPE,
                            Bookmarks.PARENT,
+                           Bookmarks.KEYWORD,
                            Bookmarks.FAVICON }; 
 
     public LocalBrowserDB(String profile) {
         mProfile = profile;
         mMobileFolderId = -1;
         mDesktopBookmarksExist = null;
 
         mBookmarksUriWithProfile = appendProfile(Bookmarks.CONTENT_URI);
--- a/mobile/android/base/gfx/GeckoLayerClient.java
+++ b/mobile/android/base/gfx/GeckoLayerClient.java
@@ -362,16 +362,17 @@ public class GeckoLayerClient implements
             // At this point, we have just switched to displaying a different document than we
             // we previously displaying. This means we need to abort any panning/zooming animations
             // that are in progress and send an updated display port request to browser.js as soon
             // as possible. We accomplish this by passing true to abortPanZoomAnimation, which
             // sends the request after aborting the animation. The display port request is actually
             // a full viewport update, which is fine because if browser.js has somehow moved to
             // be out of sync with this first-paint viewport, then we force them back in sync.
             mLayerController.abortPanZoomAnimation();
+            mLayerController.getView().setPaintState(LayerView.PAINT_BEFORE_FIRST);
         }
     }
 
     /** This function is invoked by Gecko via JNI; be careful when modifying signature.
       * The compositor invokes this function whenever it determines that the page size
       * has changed (based on the information it gets from layout). If setFirstPaintViewport
       * is invoked on a frame, then this function will not be. For any given frame, this
       * function will be invoked before syncViewportInfo.
--- a/mobile/android/base/gfx/LayerRenderer.java
+++ b/mobile/android/base/gfx/LayerRenderer.java
@@ -675,11 +675,21 @@ public class LayerRenderer implements GL
                 synchronized (pixelBuffer) {
                     pixelBuffer.position(0);
                     GLES20.glReadPixels(0, 0, (int)mScreenContext.viewport.width(),
                                         (int)mScreenContext.viewport.height(), GLES20.GL_RGBA,
                                         GLES20.GL_UNSIGNED_BYTE, pixelBuffer);
                     pixelBuffer.notify();
                 }
             }
+
+            // Remove white screen once we've painted
+            if (mView.getPaintState() == LayerView.PAINT_BEFORE_FIRST) {
+                GeckoAppShell.getMainHandler().postAtFrontOfQueue(new Runnable() {
+                    public void run() {
+                        mView.setBackgroundColor(android.graphics.Color.TRANSPARENT);
+                    }
+                });
+                mView.setPaintState(LayerView.PAINT_AFTER_FIRST);
+            }
         }
     }
 }
--- a/mobile/android/base/gfx/LayerView.java
+++ b/mobile/android/base/gfx/LayerView.java
@@ -33,16 +33,17 @@
  * 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 ***** */
 
 package org.mozilla.gecko.gfx;
 
+import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.GeckoInputConnection;
 import org.mozilla.gecko.gfx.FloatSize;
 import org.mozilla.gecko.gfx.InputConnectionHandler;
 import org.mozilla.gecko.gfx.LayerController;
 import org.mozilla.gecko.ui.SimpleScaleGestureDetector;
 import android.content.Context;
 import android.opengl.GLSurfaceView;
 import android.view.View;
@@ -57,29 +58,39 @@ import android.util.Log;
 import java.nio.IntBuffer;
 import java.util.LinkedList;
 
 /**
  * A view rendered by the layer compositor.
  *
  * This view delegates to LayerRenderer to actually do the drawing. Its role is largely that of a
  * mediator between the LayerRenderer and the LayerController.
+ *
+ * Note that LayerView is accessed by Robocop via reflection.
  */
 public class LayerView extends FlexibleGLSurfaceView {
     private Context mContext;
     private LayerController mController;
     private InputConnectionHandler mInputConnectionHandler;
     private LayerRenderer mRenderer;
     private GestureDetector mGestureDetector;
     private SimpleScaleGestureDetector mScaleGestureDetector;
     private long mRenderTime;
     private boolean mRenderTimeReset;
     private static String LOGTAG = "GeckoLayerView";
     /* List of events to be processed if the page does not prevent them. Should only be touched on the main thread */
     private LinkedList<MotionEvent> mEventQueue = new LinkedList<MotionEvent>();
+    /* Must be a PAINT_xxx constant */
+    private int mPaintState = PAINT_NONE;
+
+    /* Flags used to determine when to show the painted surface. The integer
+     * order must correspond to the order in which these states occur. */
+    public static final int PAINT_NONE = 0;
+    public static final int PAINT_BEFORE_FIRST = 1;
+    public static final int PAINT_AFTER_FIRST = 2;
 
 
     public LayerView(Context context, LayerController controller) {
         super(context);
 
         mContext = context;
         mController = controller;
         mRenderer = new LayerRenderer(this);
@@ -230,10 +241,23 @@ public class LayerView extends FlexibleG
     public void setLayerRenderer(LayerRenderer renderer) {
         mRenderer = renderer;
         setRenderer(mRenderer);
     }
 
     public LayerRenderer getLayerRenderer() {
         return mRenderer;
     }
+    
+    /* paintState must be a PAINT_xxx constant. The state will only be changed
+     * if paintState represents a state that occurs after the current state. */
+    public void setPaintState(int paintState) {
+        if (paintState > mPaintState) {
+            Log.d(LOGTAG, "LayerView paint state set to " + paintState);
+            mPaintState = paintState;
+        }
+    }
+
+    public int getPaintState() {
+        return mPaintState;
+    }
 }
 
--- a/mobile/android/base/gfx/PlaceholderLayerClient.java
+++ b/mobile/android/base/gfx/PlaceholderLayerClient.java
@@ -74,45 +74,26 @@ public class PlaceholderLayerClient {
                 mViewportUnknown = false;
             } catch (JSONException e) {
                 Log.e(LOGTAG, "Error parsing saved viewport!");
                 mViewport = new ViewportMetrics();
             }
         } else {
             mViewport = new ViewportMetrics();
         }
-        loadScreenshot();
-
-
-        if (mViewportUnknown)
-            mViewport.setViewport(mLayerController.getViewport());
-        mLayerController.setViewportMetrics(mViewport);
-
-        BufferedCairoImage image = new BufferedCairoImage(mBuffer, mWidth, mHeight, mFormat);
-        SingleTileLayer tileLayer = new SingleTileLayer(image);
-
-        tileLayer.beginTransaction();   // calling thread irrelevant; nobody else has a ref to tileLayer yet
-        try {
-            Point origin = PointUtils.round(mViewport.getOrigin());
-            tileLayer.setPosition(new Rect(origin.x, origin.y, origin.x + mWidth, origin.y + mHeight));
-        } finally {
-            tileLayer.endTransaction();
-        }
-
-        mLayerController.setRoot(tileLayer);
     }
 
     public void destroy() {
         if (mBuffer != null) {
             GeckoAppShell.freeDirectBuffer(mBuffer);
             mBuffer = null;
         }
     }
 
-    boolean loadScreenshot() {
+    public boolean loadScreenshot() {
         if (GeckoApp.mAppContext.mLastScreen == null)
             return false;
 
         Bitmap bitmap = BitmapFactory.decodeStream(new ByteArrayInputStream(GeckoApp.mAppContext.mLastScreen));
         if (bitmap == null)
             return false;
 
         Bitmap.Config config = bitmap.getConfig();
@@ -126,11 +107,23 @@ public class PlaceholderLayerClient {
 
         bitmap.copyPixelsToBuffer(mBuffer.asIntBuffer());
 
         if (mViewportUnknown) {
             mViewport.setPageSize(new FloatSize(mWidth, mHeight));
             mLayerController.setPageSize(mViewport.getPageSize());
         }
 
+        BufferedCairoImage image = new BufferedCairoImage(mBuffer, mWidth, mHeight, mFormat);
+        SingleTileLayer tileLayer = new SingleTileLayer(image);
+
+        tileLayer.beginTransaction();   // calling thread irrelevant; nobody else has a ref to tileLayer yet
+        try {
+            Point origin = PointUtils.round(mViewport.getOrigin());
+            tileLayer.setPosition(new Rect(origin.x, origin.y, origin.x + mWidth, origin.y + mHeight));
+        } finally {
+            tileLayer.endTransaction();
+        }
+
+        mLayerController.setRoot(tileLayer);
         return true;
     }
 }
--- a/mobile/android/base/sqlite/SQLiteBridge.java
+++ b/mobile/android/base/sqlite/SQLiteBridge.java
@@ -108,16 +108,17 @@ public class SQLiteBridge {
 
         if (limit != null) {
             sb.append(" " + limit);
         }
 
         return rawQuery(sb.toString(), selectionArgs);
     }
 
+    /* This method is referenced by Robocop via reflection. */
     public Cursor rawQuery(String sql, String[] selectionArgs)
         throws SQLiteBridgeException {
         return internalQuery(sql, selectionArgs);
     }
 
     public long insert(String table, String nullColumnHack, ContentValues values)
                throws SQLiteBridgeException {
         Set<Entry<String, Object>> valueSet = values.valueSet();
--- a/mobile/android/base/tests/PixelTest.java.in
+++ b/mobile/android/base/tests/PixelTest.java.in
@@ -5,41 +5,57 @@ import @ANDROID_PACKAGE_NAME@.*;
 
 class PixelTest extends BaseTest {
     private static final long PAINT_CLEAR_DELAY = 500; // milliseconds
 
     protected final PaintedSurface loadAndPaint(String url) {
         Actions.RepeatedEventExpecter paintExpecter = mActions.expectPaint();
         loadUrl(url);
         paintExpecter.blockUntilClear(PAINT_CLEAR_DELAY);
-        return mDriver.getPaintedSurface();
+        PaintedSurface p = mDriver.getPaintedSurface();
+        if (p == null) {
+            mAsserter.ok(p != null, "checking that painted surface loaded", 
+                 "painted surface loaded");
+        }
+        return p;
     }
 
     protected final PaintedSurface waitForPaint(Actions.RepeatedEventExpecter expecter) {
         expecter.blockUntilClear(PAINT_CLEAR_DELAY);
-        return mDriver.getPaintedSurface();
+        PaintedSurface p = mDriver.getPaintedSurface();
+        if (p == null) {
+            mAsserter.ok(p != null, "checking that painted surface loaded", 
+                 "painted surface loaded");
+        }
+        return p;
     }
 
     protected final PaintedSurface waitWithNoPaint(Actions.RepeatedEventExpecter expecter) {
         try {
             Thread.sleep(PAINT_CLEAR_DELAY);
         } catch (InterruptedException ie) {
             ie.printStackTrace();
         }
         mAsserter.is(expecter.eventReceived(), false, "Checking gecko didn't draw unnecessarily");
-        return mDriver.getPaintedSurface();
+        PaintedSurface p = mDriver.getPaintedSurface();
+        if (p == null) {
+            mAsserter.ok(p != null, "checking that painted surface loaded", 
+                 "painted surface loaded");
+        }
+        return p;
     }
 
     // this matches the algorithm in robocop_boxes.html
     protected final int[] getBoxColorAt(int x, int y) {
-        x -= (x % 100);
-        y -= (y % 100);
-        int r = (x + y) % 255;
-        int g = 255 - (y / 10);
-        int b = 255 - (x / 10);
+        int r = ((int)Math.floor(x / 3) % 256);
+        r = r & 0xF8;
+        int g = (x + y) % 256;
+        g = g & 0xFC;
+        int b = ((int)Math.floor(y / 3) % 256);
+        b = b & 0xF8;
         return new int[] { r, g, b };
     }
 
     /**
      * Checks the top-left corner of the visible area of the page is at (x,y) of robocop_boxes.html.
      */
     protected final void checkScrollWithBoxes(PaintedSurface painted, int x, int y) {
         int[] color = getBoxColorAt(x, y);
--- a/mobile/android/base/tests/robocop.ini
+++ b/mobile/android/base/tests/robocop.ini
@@ -9,13 +9,14 @@
 [testOverscroll]
 [testAxisLocking]
 [testAboutPage]
 [testWebContentContextMenu]
 [testPasswordProvider]
 [testPasswordEncrypt]
 [testFormHistory]
 [testBrowserProvider]
+[testJarReader]
 
 # Used for Talos, please don't use in mochitest
 #[testPan]
 #[testCheck]
 #[testBrowserProviderPerf]
--- a/mobile/android/base/tests/robocop_boxes.html
+++ b/mobile/android/base/tests/robocop_boxes.html
@@ -1,31 +1,41 @@
 <!--
 DO NOT MODIFY THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
 
 This file is specifically designed to create a page larger than
 any screen fennec could run on (to allow panning in both axes).
 It is filled with 100x100 pixel boxes that are of unique colour,
 so that we can identify exactly what part of the page we are
-rendering at any given time. A lot of the tests depend on this
-behaviour, so ensure that all the tests pass (on a variety of
-screen sizes) when making any changes to this file.
+rendering at any given time. The colours are specifically chosen
+so that adjacent boxes have a fairly large variation in colour,
+and so that errors due to 565/888 conversion are minimised. This
+is done by dropping the bottom few bits on each color channel,
+so that conversion from 888->565 is pretty much lossless, and any
+variation only comes in from however the drivers do 565->888.
+
+A lot of the tests depend on this behaviour, so ensure that all
+the tests pass (on a variety of screen sizes) when making any
+changes to this file.
  -->
 <html style="margin: 0; padding: 0">
 <head>
  <title>Browser Box test</title>
  <meta name="viewport" content="initial-scale=1.0"/>
 </head>
 <body style="margin: 0; padding: 0">
 <script type="text/javascript">
 for (var y = 0; y < 2000; y += 100) {
     document.write("<div style='width: 2000px; height: 100px; margin: 0; padding: 0; border: none'>\n");
     for (var x = 0; x < 2000; x += 100) {
-        var r = (y + x) % 255;
-        var g = 255 - (y / 10);
-        var b = 255 - (x / 10);
+        var r = (Math.floor(x / 3) % 256);
+        r = r & 0xF8;
+        var g = (x + y) % 256;
+        g = g & 0xFC;
+        var b = (Math.floor(y / 3) % 256);
+        b = b & 0xF8;
         document.write("<div style='float: left; width: 100px; height: 100px; margin: 0; padding: 0; border: none; background-color: rgb(" + r + "," + g + "," + b + ")'> </div>\n");
     }
     document.write("</div>\n");
 }
 </script>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/tests/testJarReader.java.in
@@ -0,0 +1,71 @@
+#filter substitution
+package @ANDROID_PACKAGE_NAME@.tests;
+
+import @ANDROID_PACKAGE_NAME@.*;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.Bitmap;
+import java.lang.ClassLoader;
+import java.util.ArrayList;
+import java.io.Writer;
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+import java.lang.reflect.Method;
+import java.io.StringWriter;
+
+/**
+ * A basic jar reader test. Tests reading a png from fennec's apk, as well
+ * as loading some invalid jar urls.
+ */
+public class testJarReader extends BaseTest {
+    public void testJarReader() {
+        setTestType("mochitest");
+        try {
+            ClassLoader classLoader = getActivity().getClassLoader();
+            Class gjrClass = classLoader.loadClass("org.mozilla.gecko.GeckoJarReader");
+            Method getStreamMethod = gjrClass.getMethod("getStream", String.class);
+            String appPath = getActivity().getApplication().getPackageResourcePath();
+
+            // Test reading a file from a jar url
+            String url = "jar:file://" + getActivity().getApplication().getPackageResourcePath() + "!/omni.ja";
+            InputStream stream = (InputStream)getStreamMethod.invoke(null, "jar:" + url + "!/chrome/chrome/content/branding/favicon32.png");
+            mAsserter.isnot(stream, null, "JarReader returned null for invalid jar file");
+
+            // Test looking for a jar that doesn't exist
+            url = "jar:file://" + getActivity().getApplication().getPackageResourcePath() + "2!/omni.ja";
+            stream = (InputStream)getStreamMethod.invoke(null, "jar:" + url + "!/chrome/chrome/content/branding/favicon32.png");
+            mAsserter.is(stream, null, "JarReader returned null for invalid jar file");
+
+            // Test looking for an non-existant file in a jar
+            url = "jar:file://" + getActivity().getApplication().getPackageResourcePath() + "2!/omni.ja";
+            stream = (InputStream)getStreamMethod.invoke(null, "jar:" + url + "!/chrome/chrome/content/branding/nonexistant_file.png");
+            mAsserter.is(stream, null, "JarReader returned null for non-existant file in jar");
+
+            // Test looking for an jar with an invalid url
+            url = "jar:file://" + getActivity().getApplication().getPackageResourcePath() + "2!!/omni.ja";
+            stream = (InputStream)getStreamMethod.invoke(null, "jar:" + url + "!/chrome/chrome/content/branding/nonexistant_file.png");
+            mAsserter.is(stream, null, "JarReader returned null for bar jar url");
+        } catch (java.lang.ClassNotFoundException ex) {
+            mAsserter.is(false, true, "Error getting class");
+            return;
+        } catch (java.lang.NoSuchMethodException ex) {
+            mAsserter.is(false, true, "Error getting method");
+            return;
+        } catch (java.lang.IllegalAccessException ex) {
+            mAsserter.is(false, true, "Error calling method");
+            return;
+        } catch (java.lang.reflect.InvocationTargetException ex) {
+            mAsserter.is(false, true, "Invocation target exception " + ex.getTargetException());
+            return;
+        }
+    }
+
+    private String getData(InputStream stream) {
+        return new java.util.Scanner(stream).useDelimiter("\\A").next();
+    }
+
+    public void tearDown() throws Exception {
+      super.tearDown();
+    }
+}
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -229,16 +229,17 @@ var BrowserApp = {
     OfflineApps.init();
     IndexedDB.init();
     XPInstallObserver.init();
     ConsoleAPI.init();
     ClipboardHelper.init();
     PermissionsHelper.init();
     CharacterEncoding.init();
     SearchEngines.init();
+    ActivityObserver.init();
 
     // Init LoginManager
     Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
     // Init FormHistory
     Cc["@mozilla.org/satchel/form-history;1"].getService(Ci.nsIFormHistory2);
 
     let url = "about:home";
     let forceRestore = false;
@@ -321,17 +322,17 @@ var BrowserApp = {
     sendMessageToJava({
       gecko: {
         "type": "Checkerboard:Toggle",
         "value": Services.prefs.getBoolPref("gfx.show_checkerboard_pattern")
       }
     });
 
     if (this.isAppUpdated())
-      this.onUpdate();
+      this.onAppUpdated();
   },
 
   isAppUpdated: function() {
     let savedmstone = null;
     try {
       savedmstone = Services.prefs.getCharPref("browser.startup.homepage_override.mstone");
     } catch (e) {
     }
@@ -1588,16 +1589,20 @@ Tab.prototype = {
       this.browser.focus();
       this.browser.docShellIsActive = true;
     } else {
       this.browser.setAttribute("type", "content-targetable");
       this.browser.docShellIsActive = false;
     }
   },
 
+  getActive: function getActive() {
+      return this.browser.docShellIsActive;
+  },
+
   setDisplayPort: function(aViewportX, aViewportY, aDisplayPortRect) {
     let zoom = this._zoom;
     if (zoom <= 0)
       return;
 
     let element = this.browser.contentDocument.documentElement;
     if (!element)
       return;
@@ -4415,8 +4420,31 @@ var SearchEngines = {
         for each (let param in formData) {
           if (param.name && param.value)
             engine.addParam(param.name, param.value, null);
         }
       }
     });
   }
 };
+
+var ActivityObserver = {
+  init: function ao_init() {
+    Services.obs.addObserver(this, "application-background", false);
+    Services.obs.addObserver(this, "application-foreground", false);
+  },
+
+  observe: function ao_observe(aSubject, aTopic, aData) {
+    let isForeground = false
+    switch (aTopic) {
+      case "application-background" :
+        isForeground = false;
+        break;
+      case "application-foreground" :
+        isForeground = true;
+        break;
+    }
+
+    if (BrowserApp.selectedTab.getActive() != isForeground) {
+      BrowserApp.selectedTab.setActive(isForeground);
+    }
+  }
+};
--- a/mobile/android/themes/core/aboutAddons.css
+++ b/mobile/android/themes/core/aboutAddons.css
@@ -200,46 +200,50 @@ setting {
 setting > vbox {
   -moz-box-flex: 1;
 }
 
 .preferences-title {
   font-weight: bold;
 }
 
+.preferences-description {
+  margin-top: 4px;
+}
+
 .preferences-description:empty {
   display: none;
 }
 
 /* Put setting textboxes on a separate row */
 setting[type="integer"],
 setting[type="string"] {
   -moz-box-align: stretch;
   -moz-box-orient: vertical;
 }
 
 .preferences-alignment > textbox {
-  margin-top: 12px;
+  margin: 12px 0 0 0;
   font-size: 22px !important;
 }
 
 checkbox {
   -moz-binding: url("chrome://global/content/bindings/checkbox.xml#checkbox-with-spacing") !important;
 }
 
+checkbox[label=""] > .checkbox-label-box,
+checkbox:not([label]) > .checkbox-label-box {
+  display: none;
+}
+
 .checkbox-check {
-  border: 2px transparent;
-  -moz-border-top-colors: -moz-initial;
-  -moz-border-right-colors: -moz-initial;
-  -moz-border-bottom-colors: -moz-initial;
-  -moz-border-left-colors: -moz-initial;
-  -moz-box-sizing: border-box;
+  background: url("chrome://browser/skin/images/checkbox_unchecked.png") no-repeat 50% 50%;
+  border: 0 transparent;
   width: 48px;
   height: 48px;
-  background: url("chrome://browser/skin/images/checkbox_unchecked.png") no-repeat 50% 50%;
 }
 
 setting:active checkbox > .checkbox-spacer-box > .checkbox-check {
   background-image: url("chrome://browser/skin/images/checkbox_unchecked_pressed.png");
 }
 
 checkbox[disabled="true"] > .checkbox-spacer-box > .checkbox-check {
   background-image: url("chrome://browser/skin/images/checkbox_unchecked_disabled.png");
@@ -252,16 +256,72 @@ checkbox[checked="true"] > .checkbox-spa
 setting:active checkbox[checked="true"] > .checkbox-spacer-box > .checkbox-check {
   background-image: url("chrome://browser/skin/images/checkbox_checked_pressed.png");
 }
 
 checkbox[checked="true"][disabled="true"] > .checkbox-spacer-box > .checkbox-check {
   background-image: url("chrome://browser/skin/images/checkbox_checked_disabled.png");
 }
 
+/* Textbox */
+
+textbox[type="number"] > spinbuttons {
+  visibility: collapse;
+}
+
+textbox {
+  background: white -moz-linear-gradient(top, rgba(27,113,177,0.5) 0, rgba(198,225,246,0.2) 3px, rgba(255,255,255,0.2) 16px);
+  border-radius: 3px;
+  border-color: rgb(94,128,153);
+  padding: 0 !important;
+}
+
+.textbox-input-box {
+  padding: 8px 12px;
+}
+
+/* Menulist */
+
+menulist {
+  -moz-appearance: none !important;
+  -moz-user-focus: ignore;
+  /* min-width: 200px !important; */
+  color: #000 !important;
+  border-radius: 5px;
+  border-color: rgb(94,128,153);
+  border-style: solid;
+  padding: 8px 12px;
+  background: white;
+  border: 1px solid #cacdd5;
+  border-style: solid;
+  border-color: rgb(94,128,153);
+  min-width: 200px;
+}
+
+.menulist-label {
+  background-color: transparent !important;
+}
+
+menulist > menupopup > menuitem > label{
+-moz-padding-start:3px !important;
+-moz-padding-end:7px !important;
+}
+
+menulist > dropmarker {
+  height: 32px;
+  width: 32px;
+  margin-left: @margin_snormal@;
+  background-color: transparent; /* for windows */
+  border: none;                  /* for windows */
+  -moz-box-align: center;
+  -moz-box-pack: center;
+  list-style-image: url("chrome://browser/skin/images/dropmarker.svg") !important;
+  -moz-image-region: auto;
+  display: block;
+}
 
 /* XBL bindings */
 
 settings {
   -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#settings");
 }
 
 setting {
--- a/modules/libpref/public/Preferences.h
+++ b/modules/libpref/public/Preferences.h
@@ -347,16 +347,22 @@ public:
   static void MirrorPreferences(nsTArray<PrefTuple,
                                 nsTArrayInfallibleAllocator> *aArray);
   static bool MirrorPreference(const char *aPref, PrefTuple *aTuple);
   static void ClearContentPref(const char *aPref);
   static void SetPreference(const PrefTuple *aTuple);
 
 protected:
   nsresult NotifyServiceObservers(const char *aSubject);
+  /**
+   * Reads the default pref file or, if that failed, try to save a new one.
+   *
+   * @return NS_OK if either action succeeded,
+   *         or the error code related to the read attempt.
+   */
   nsresult UseDefaultPrefFile();
   nsresult UseUserPrefFile();
   nsresult ReadAndOwnUserPrefFile(nsIFile *aFile);
   nsresult ReadAndOwnSharedUserPrefFile(nsIFile *aFile);
   nsresult SavePrefFileInternal(nsIFile* aFile);
   nsresult WritePrefFile(nsIFile* aFile);
   nsresult MakeBackupPrefFile(nsIFile *aFile);
 
--- a/modules/libpref/src/Preferences.cpp
+++ b/modules/libpref/src/Preferences.cpp
@@ -399,24 +399,26 @@ Preferences::ReadUserPrefs(nsIFile *aFil
   if (XRE_GetProcessType() == GeckoProcessType_Content) {
     NS_ERROR("cannot load prefs from content process");
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   nsresult rv;
 
   if (nsnull == aFile) {
-
     NotifyServiceObservers(NS_PREFSERVICE_READ_TOPIC_ID);
 
     rv = UseDefaultPrefFile();
-    UseUserPrefFile();
+    // A user pref file is optional.
+    // Ignore all errors related to it, so we retain 'rv' value :-|
+    (void) UseUserPrefFile();
   } else {
     rv = ReadAndOwnUserPrefFile(aFile);
   }
+
   return rv;
 }
 
 NS_IMETHODIMP
 Preferences::ResetPrefs()
 {
   if (XRE_GetProcessType() == GeckoProcessType_Content) {
     NS_ERROR("cannot set prefs from content process");
@@ -582,28 +584,30 @@ Preferences::NotifyServiceObservers(cons
   observerService->NotifyObservers(subject, aTopic, nsnull);
   
   return NS_OK;
 }
 
 nsresult
 Preferences::UseDefaultPrefFile()
 {
-  nsresult rv, rv2;
+  nsresult rv;
   nsCOMPtr<nsIFile> aFile;
 
   rv = NS_GetSpecialDirectory(NS_APP_PREFS_50_FILE, getter_AddRefs(aFile));
   if (NS_SUCCEEDED(rv)) {
     rv = ReadAndOwnUserPrefFile(aFile);
     // Most likely cause of failure here is that the file didn't
     // exist, so save a new one. mUserPrefReadFailed will be
     // used to catch an error in actually reading the file.
     if (NS_FAILED(rv)) {
-      rv2 = SavePrefFileInternal(aFile);
-      NS_ASSERTION(NS_SUCCEEDED(rv2), "Failed to save new shared pref file");
+      if (NS_FAILED(SavePrefFileInternal(aFile)))
+        NS_ERROR("Failed to save new shared pref file");
+      else
+        rv = NS_OK;
     }
   }
   
   return rv;
 }
 
 nsresult
 Preferences::UseUserPrefFile()
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -804,21 +804,33 @@ pref("network.http.redirection-limit", 2
 // NOTE: separate values with comma+space (", "): see bug 576033
 pref("network.http.accept-encoding", "gzip, deflate");
 
 pref("network.http.pipelining"      , false);
 pref("network.http.pipelining.ssl"  , false); // disable pipelining over SSL
 pref("network.http.proxy.pipelining", false);
 
 // Max number of requests in the pipeline
-pref("network.http.pipelining.maxrequests" , 4);
+pref("network.http.pipelining.maxrequests" , 32);
+
+// An optimistic request is one pipelined when policy might allow a new
+// connection instead
+pref("network.http.pipelining.max-optimistic-requests" , 4);
+
+pref("network.http.pipelining.aggressive", false);
+pref("network.http.pipelining.maxsize" , 300000);
+pref("network.http.pipelining.read-timeout", 10000);
 
 // Prompt for 307 redirects
 pref("network.http.prompt-temp-redirect", true);
 
+// If true generate CORRUPTED_CONTENT errors for entities that
+// contain an invalid Assoc-Req response header
+pref("network.http.assoc-req.enforce", false);
+
 // On networks deploying QoS, it is recommended that these be lockpref()'d,
 // since inappropriate marking can easily overwhelm bandwidth reservations
 // for certain services (i.e. EF for VoIP, AF4x for interactive video,
 // AF3x for broadcast/streaming video, etc)
 
 // default value for HTTP
 // in a DSCP environment this should be 40 (0x28, or AF11), per RFC-4594,
 // Section 4.8 "High-Throughput Data Service Class"
--- a/mozglue/android/APKOpen.cpp
+++ b/mozglue/android/APKOpen.cpp
@@ -1032,8 +1032,51 @@ ChildProcessInit(int argc, char* argv[])
   XRE_InitChildProcess_t fXRE_InitChildProcess =
     (XRE_InitChildProcess_t)__wrap_dlsym(xul_handle, "XRE_InitChildProcess");
 
   GeckoProcessType proctype = fXRE_StringToChildProcessType(argv[--argc]);
 
   return fXRE_InitChildProcess(argc, argv, proctype);
 }
 
+/* Android doesn't have pthread_atfork(), so we need to use our own. */
+struct AtForkFuncs {
+  void (*prepare)(void);
+  void (*parent)(void);
+  void (*child)(void);
+};
+static std::vector<AtForkFuncs> atfork;
+
+extern "C" NS_EXPORT int
+__wrap_pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void))
+{
+  AtForkFuncs funcs;
+  funcs.prepare = prepare;
+  funcs.parent = parent;
+  funcs.child = child;
+  atfork.push_back(funcs);
+  return 0;
+}
+
+extern "C" NS_EXPORT pid_t
+__wrap_fork(void)
+{
+  pid_t pid;
+  for (std::vector<AtForkFuncs>::reverse_iterator it = atfork.rbegin();
+       it < atfork.rend(); ++it)
+    if (it->prepare)
+      it->prepare();
+
+  switch ((pid = fork())) {
+  case 0:
+    for (std::vector<AtForkFuncs>::iterator it = atfork.begin();
+         it < atfork.end(); ++it)
+      if (it->child)
+        it->child();
+    break;
+  default:
+    for (std::vector<AtForkFuncs>::iterator it = atfork.begin();
+         it < atfork.end(); ++it)
+      if (it->parent)
+        it->parent();
+  }
+  return pid;
+}
--- a/mozglue/build/Makefile.in
+++ b/mozglue/build/Makefile.in
@@ -79,16 +79,20 @@ ifneq (,$(filter -DEFAULTLIB:mozcrt,$(MO
 # Don't install the import library if we use mozcrt
 NO_INSTALL_IMPORT_LIBRARY = 1
 endif
 endif
 
 ifeq (android, $(MOZ_WIDGET_TOOLKIT))
 # Add Android specific code
 EXTRA_DSO_LDOPTS += $(ZLIB_LIBS)
+ifdef MOZ_MEMORY
+# To properly wrap jemalloc's pthread_atfork call.
+EXTRA_DSO_LDOPTS += -Wl,--wrap=pthread_atfork
+endif
 SHARED_LIBRARY_LIBS += $(call EXPAND_LIBNAME_PATH,android,$(DEPTH)/other-licenses/android)
 SHARED_LIBRARY_LIBS += $(call EXPAND_LIBNAME_PATH,android,../android)
 endif
 
 ifdef MOZ_LINKER
 # Add custom dynamic linker
 SHARED_LIBRARY_LIBS += $(call EXPAND_LIBNAME_PATH,linker,../linker)
 
--- a/netwerk/base/public/nsIRequest.idl
+++ b/netwerk/base/public/nsIRequest.idl
@@ -155,16 +155,23 @@ interface nsIRequest : nsISupports
      */
     const unsigned long LOAD_BACKGROUND = 1 << 0; 
 
     /**************************************************************************
      * The following flags control the flow of data into the cache.
      */
 
     /**
+     *  This flag prevents loading of the request with an HTTP pipeline.
+     *  Generally this is because the resource is expected to take a
+     *  while to load and may cause head of line blocking problems.
+     */
+    const unsigned long INHIBIT_PIPELINE = 1 << 6;
+
+    /**
      * This flag prevents caching of any kind.  It does not, however, prevent
      * cached content from being used to satisfy this request.
      */
     const unsigned long INHIBIT_CACHING = 1 << 7;
 
     /**
      * This flag prevents caching on disk (or other persistent media), which
      * may be needed to preserve privacy.  For HTTPS, this flag is set auto-
--- a/netwerk/cache/nsCacheService.cpp
+++ b/netwerk/cache/nsCacheService.cpp
@@ -1015,30 +1015,116 @@ public:
                      "Sync OpenCacheEntry() posted to background thread!");
 
         nsCacheServiceAutoLock lock;
         rv = nsCacheService::gService->ProcessRequest(mRequest,
                                                       false,
                                                       nsnull);
 
         // Don't delete the request if it was queued
-        if (rv != NS_ERROR_CACHE_WAIT_FOR_VALIDATION)
+        if (!(mRequest->IsBlocking() &&
+            rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION))
             delete mRequest;
 
         return NS_OK;
     }
 
 protected:
     virtual ~nsProcessRequestEvent() {}
 
 private:
     nsCacheRequest *mRequest;
 };
 
 /******************************************************************************
+ * nsNotifyDoomListener
+ *****************************************************************************/
+
+class nsNotifyDoomListener : public nsRunnable {
+public:
+    nsNotifyDoomListener(nsICacheListener *listener,
+                         nsresult status)
+        : mListener(listener)      // transfers reference
+        , mStatus(status)
+    {}
+
+    NS_IMETHOD Run()
+    {
+        mListener->OnCacheEntryDoomed(mStatus);
+        NS_RELEASE(mListener);
+        return NS_OK;
+    }
+
+private:
+    nsICacheListener *mListener;
+    nsresult          mStatus;
+};
+
+/******************************************************************************
+ * nsDoomEvent
+ *****************************************************************************/
+
+class nsDoomEvent : public nsRunnable {
+public:
+    nsDoomEvent(nsCacheSession *session,
+                const nsACString &key,
+                nsICacheListener *listener)
+    {
+        mKey = *session->ClientID();
+        mKey.Append(':');
+        mKey.Append(key);
+        mStoragePolicy = session->StoragePolicy();
+        mListener = listener;
+        mThread = do_GetCurrentThread();
+        // We addref the listener here and release it in nsNotifyDoomListener
+        // on the callers thread. If posting of nsNotifyDoomListener event fails
+        // we leak the listener which is better than releasing it on a wrong
+        // thread.
+        NS_IF_ADDREF(mListener);
+    }
+
+    NS_IMETHOD Run()
+    {
+        nsCacheServiceAutoLock lock;
+
+        bool foundActive = true;
+        nsresult status = NS_ERROR_NOT_AVAILABLE;
+        nsCacheEntry *entry;
+        entry = nsCacheService::gService->mActiveEntries.GetEntry(&mKey);
+        if (!entry) {
+            bool collision = false;
+            foundActive = false;
+            entry = nsCacheService::gService->SearchCacheDevices(&mKey,
+                                                                 mStoragePolicy,
+                                                                 &collision);
+        }
+
+        if (entry) {
+            status = NS_OK;
+            nsCacheService::gService->DoomEntry_Internal(entry, foundActive);
+        }
+
+        if (mListener) {
+            mThread->Dispatch(new nsNotifyDoomListener(mListener, status),
+                              NS_DISPATCH_NORMAL);
+            // posted event will release the reference on the correct thread
+            mListener = nsnull;
+        }
+
+        return NS_OK;
+    }
+
+private:
+    nsCString             mKey;
+    nsCacheStoragePolicy  mStoragePolicy;
+    nsICacheListener     *mListener;
+    nsCOMPtr<nsIThread>   mThread;
+};
+
+/******************************************************************************
  * nsCacheService
  *****************************************************************************/
 nsCacheService *   nsCacheService::gService = nsnull;
 
 static nsCOMPtr<nsIMemoryReporter> MemoryCacheReporter = nsnull;
 
 NS_THREADSAFE_MEMORY_REPORTER_IMPLEMENT(NetworkMemoryCache,
     "explicit/network-memory-cache",
@@ -1344,16 +1430,32 @@ nsCacheService::IsStorageEnabledForPolic
     if (gService == nsnull) return NS_ERROR_NOT_AVAILABLE;
     nsCacheServiceAutoLock lock;
 
     *result = gService->IsStorageEnabledForPolicy_Locked(storagePolicy);
     return NS_OK;
 }
 
 
+nsresult
+nsCacheService::DoomEntry(nsCacheSession   *session,
+                          const nsACString &key,
+                          nsICacheListener *listener)
+{
+    CACHE_LOG_DEBUG(("Dooming entry for session %p, key %s\n",
+                     session, PromiseFlatCString(key).get()));
+    NS_ASSERTION(gService, "nsCacheService::gService is null.");
+
+    if (!gService->mInitialized)
+        return NS_ERROR_NOT_INITIALIZED;
+
+    return DispatchToCacheIOThread(new nsDoomEvent(session, key, listener));
+}
+
+
 bool          
 nsCacheService::IsStorageEnabledForPolicy_Locked(nsCacheStoragePolicy  storagePolicy)
 {
     if (gService->mEnableMemoryDevice &&
         (storagePolicy == nsICache::STORE_ANYWHERE ||
          storagePolicy == nsICache::STORE_IN_MEMORY)) {
         return true;
     }
@@ -1657,21 +1759,23 @@ nsCacheService::ProcessRequest(nsCacheRe
         rv = ActivateEntry(request, &entry, &doomedEntry);  // get the entry for this request
         if (NS_FAILED(rv))  break;
 
         while(1) { // Request Access loop
             NS_ASSERTION(entry, "no entry in Request Access loop!");
             // entry->RequestAccess queues request on entry
             rv = entry->RequestAccess(request, &accessGranted);
             if (rv != NS_ERROR_CACHE_WAIT_FOR_VALIDATION) break;
-            
-            if (request->mListener) // async exits - validate, doom, or close will resume
-                return rv;
-            
+
             if (request->IsBlocking()) {
+                if (request->mListener) {
+                    // async exits - validate, doom, or close will resume
+                    return rv;
+                }
+
                 // XXX this is probably wrong...
                 Unlock();
                 rv = request->WaitForValidation();
                 Lock();
             }
 
             PR_REMOVE_AND_INIT_LINK(request);
             if (NS_FAILED(rv)) break;   // non-blocking mode returns WAIT_FOR_VALIDATION error
@@ -1768,17 +1872,18 @@ nsCacheService::OpenCacheEntry(nsCacheSe
             delete request;
     }
     else {
 
         nsCacheServiceAutoLock lock;
         rv = gService->ProcessRequest(request, true, result);
 
         // delete requests that have completed
-        if (!(listener && (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION)))
+        if (!(listener && blockingMode &&
+            (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION)))
             delete request;
     }
 
     return rv;
 }
 
 
 nsresult
--- a/netwerk/cache/nsCacheService.h
+++ b/netwerk/cache/nsCacheService.h
@@ -94,16 +94,20 @@ public:
                                     nsICacheListener *         listener,
                                     nsICacheEntryDescriptor ** result);
 
     static nsresult  EvictEntriesForSession(nsCacheSession *   session);
 
     static nsresult  IsStorageEnabledForPolicy(nsCacheStoragePolicy  storagePolicy,
                                                bool *              result);
 
+    static nsresult  DoomEntry(nsCacheSession   *session,
+                               const nsACString &key,
+                               nsICacheListener *listener);
+
     /**
      * Methods called by nsCacheEntryDescriptor
      */
 
     static void      CloseDescriptor(nsCacheEntryDescriptor * descriptor);
 
     static nsresult  GetFileForEntry(nsCacheEntry *         entry,
                                      nsIFile **             result);
@@ -193,16 +197,17 @@ public:
 
 private:
     friend class nsCacheServiceAutoLock;
     friend class nsOfflineCacheDevice;
     friend class nsProcessRequestEvent;
     friend class nsSetSmartSizeEvent;
     friend class nsBlockOnCacheThreadEvent;
     friend class nsSetDiskSmartSizeCallback;
+    friend class nsDoomEvent;
 
     /**
      * Internal Methods
      */
 
     static void      Lock();
     static void      Unlock();
 
--- a/netwerk/cache/nsCacheSession.cpp
+++ b/netwerk/cache/nsCacheSession.cpp
@@ -97,23 +97,24 @@ nsCacheSession::OpenCacheEntry(const nsA
                                          nsnull, // no listener
                                          result);
     return rv;
 }
 
 
 NS_IMETHODIMP nsCacheSession::AsyncOpenCacheEntry(const nsACString & key,
                                                   nsCacheAccessMode accessRequested,
-                                                  nsICacheListener *listener)
+                                                  nsICacheListener *listener,
+                                                  bool              noWait)
 {
     nsresult rv;
     rv = nsCacheService::OpenCacheEntry(this,
                                         key,
                                         accessRequested,
-                                        nsICache::BLOCKING,
+                                        !noWait,
                                         listener,
                                         nsnull); // no result
 
     if (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) rv = NS_OK;
     return rv;
 }
 
 NS_IMETHODIMP nsCacheSession::EvictEntries()
@@ -122,8 +123,14 @@ NS_IMETHODIMP nsCacheSession::EvictEntri
 }
 
 
 NS_IMETHODIMP nsCacheSession::IsStorageEnabled(bool *result)
 {
 
     return nsCacheService::IsStorageEnabledForPolicy(StoragePolicy(), result);
 }
+
+NS_IMETHODIMP nsCacheSession::DoomEntry(const nsACString &key,
+                                        nsICacheListener *listener)
+{
+    return nsCacheService::DoomEntry(this, key, listener);
+}
--- a/netwerk/cache/nsICacheListener.idl
+++ b/netwerk/cache/nsICacheListener.idl
@@ -42,20 +42,27 @@
 
 
 #include "nsISupports.idl"
 #include "nsICache.idl"
 
 
 interface nsICacheEntryDescriptor;
 
-[scriptable, uuid(638c3848-778b-4851-8ff3-9400f65b8773)]
+[scriptable, uuid(8eadf2ed-8cac-4961-8025-6da6d5827e74)]
 interface nsICacheListener : nsISupports
 {
     /**
      * Called when the requested access (or appropriate subset) is
      * acquired.  The status parameter equals NS_OK on success.
      * See nsICacheService.idl for accessGranted values.
      */
     void onCacheEntryAvailable(in nsICacheEntryDescriptor descriptor,
                                in nsCacheAccessMode       accessGranted,
                                in nsresult                status);
+
+    /**
+     * Called when nsCacheSession::DoomEntry() is completed. The status
+     * parameter is NS_OK when the entry was doomed, or NS_ERROR_NOT_AVAILABLE
+     * when there is no such entry.
+     */
+    void onCacheEntryDoomed(in nsresult status);
 };
--- a/netwerk/cache/nsICacheSession.idl
+++ b/netwerk/cache/nsICacheSession.idl
@@ -41,17 +41,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsISupports.idl"
 #include "nsICache.idl"
 
 interface nsICacheEntryDescriptor;
 interface nsICacheListener;
 
-[scriptable, uuid(ae9e84b5-3e2d-457e-8fcd-5bbd2a8b832e)]
+[scriptable, uuid(1dd7708c-de48-4ffe-b5aa-cd218c762887)]
 interface nsICacheSession : nsISupports
 {
     /**
      * Expired entries will be doomed or evicted if this attribute is set to
      * true.  If false, expired entries will be returned (useful for offline-
      * mode and clients, such as HTTP, that can update the valid lifetime of
      * cached content).  This attribute defaults to true.
      */
@@ -71,27 +71,38 @@ interface nsICacheSession : nsISupports
      * return NS_ERROR_CACHE_WAIT_FOR_VALIDATION rather than block when another
      * descriptor has been given WRITE access but hasn't validated the entry yet.
      */
     nsICacheEntryDescriptor openCacheEntry(in ACString          key,
                                            in nsCacheAccessMode accessRequested,
                                            in boolean           blockingMode);
 
     /**
-     * Asynchronous cache access. Does not block the calling thread.
-     * Instead, the listener will be notified when the descriptor is
-     * available.
+     * Asynchronous cache access. Does not block the calling thread. Instead,
+     * the listener will be notified when the descriptor is available. If
+     * 'noWait' is set to true, the listener will be notified immediately with
+     * status NS_ERROR_CACHE_WAIT_FOR_VALIDATION rather than queuing the request
+     * when another descriptor has been given WRITE access but hasn't validated
+     * the entry yet.
      */
-    void asyncOpenCacheEntry(in ACString          key,
-                             in nsCacheAccessMode accessRequested,
-                             in nsICacheListener  listener);
+    void asyncOpenCacheEntry(in ACString           key,
+                             in nsCacheAccessMode  accessRequested,
+                             in nsICacheListener   listener,
+                             [optional] in boolean noWait);
 
     /**
      * Evict all entries for this session's clientID according to its storagePolicy.
      */
     void evictEntries();
     
     /**
      * Return whether any of the cache devices implied by the session storage policy
      * are currently enabled for instantiation if they don't already exist.
      */
     boolean isStorageEnabled();
+
+    /**
+     * Asynchronously doom an entry specified by the key. Listener will be
+     * notified about the status of the operation. Null may be passed if caller
+     * doesn't care about the result.
+     */
+    void doomEntry(in ACString key, in nsICacheListener listener);
 };
--- a/netwerk/protocol/ftp/nsFtpConnectionThread.cpp
+++ b/netwerk/protocol/ftp/nsFtpConnectionThread.cpp
@@ -2091,16 +2091,24 @@ nsFtpState::OnCacheEntryAvailable(nsICac
 
     Connect();
     return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
+nsFtpState::OnCacheEntryDoomed(nsresult status)
+{
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+//-----------------------------------------------------------------------------
+
+NS_IMETHODIMP
 nsFtpState::OnStartRequest(nsIRequest *request, nsISupports *context)
 {
     mStorReplyReceived = false;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFtpState::OnStopRequest(nsIRequest *request, nsISupports *context,
@@ -2283,17 +2291,17 @@ nsFtpState::CheckCache()
     nsresult rv = session->OpenCacheEntry(key, accessReq, false,
                                           getter_AddRefs(mCacheEntry));
     if (NS_SUCCEEDED(rv) && mCacheEntry) {
         mDoomCache = true;
         return false;  // great, we're ready to proceed!
     }
 
     if (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) {
-        rv = session->AsyncOpenCacheEntry(key, accessReq, this);
+        rv = session->AsyncOpenCacheEntry(key, accessReq, this, false);
         return NS_SUCCEEDED(rv);
     }
 
     return false;
 }
 
 nsresult
 nsFtpState::ConvertUTF8PathToCharset(const nsACString &aCharset)
--- a/netwerk/protocol/http/SpdySession.cpp
+++ b/netwerk/protocol/http/SpdySession.cpp
@@ -2029,16 +2029,40 @@ SpdySession::TakeHttpConnection()
 nsISocketTransport *
 SpdySession::Transport()
 {
   if (!mConnection)
     return nsnull;
   return mConnection->Transport();
 }
 
+PRUint32
+SpdySession::CancelPipeline(nsresult reason)
+{
+  // we don't pipeline inside spdy, so this isn't an issue
+  return 0;
+}
+
+nsAHttpTransaction::Classifier
+SpdySession::Classification()
+{
+  if (!mConnection)
+    return nsAHttpTransaction::CLASS_GENERAL;
+  return mConnection->Classification();
+}
+
+void
+SpdySession::Classify(nsAHttpTransaction::Classifier newclass)
+{
+  if (!mConnection)
+    return;
+  
+  mConnection->Classify(newclass);
+}
+
 //-----------------------------------------------------------------------------
 // unused methods of nsAHttpTransaction
 // We can be sure of this because SpdySession is only constructed in
 // nsHttpConnection and is never passed out of that object
 //-----------------------------------------------------------------------------
 
 void
 SpdySession::SetConnection(nsAHttpConnection *)
@@ -2059,27 +2083,33 @@ void
 SpdySession::SetSSLConnectFailed()
 {
   NS_ABORT_IF_FALSE(false, "SpdySession::SetSSLConnectFailed()");
 }
 
 bool
 SpdySession::IsDone()
 {
-  NS_ABORT_IF_FALSE(false, "SpdySession::IsDone()");
-  return false;
+  return !mStreamTransactionHash.Count();
 }
 
 nsresult
 SpdySession::Status()
 {
   NS_ABORT_IF_FALSE(false, "SpdySession::Status()");
   return NS_ERROR_UNEXPECTED;
 }
 
+PRUint8
+SpdySession::Caps()
+{
+  NS_ABORT_IF_FALSE(false, "SpdySession::Caps()");
+  return 0;
+}
+
 PRUint32
 SpdySession::Available()
 {
   NS_ABORT_IF_FALSE(false, "SpdySession::Available()");
   return 0;
 }
 
 nsHttpRequestHead *
@@ -2127,16 +2157,52 @@ SpdySession::TakeSubTransactions(
     return NS_ERROR_ALREADY_OPENED;
 
   LOG3(("   taking %d\n", mStreamTransactionHash.Count()));
 
   mStreamTransactionHash.Enumerate(TakeStream, &outTransactions);
   return NS_OK;
 }
 
+nsresult
+SpdySession::AddTransaction(nsAHttpTransaction *)
+{
+  // This API is meant for pipelining, SpdySession's should be
+  // extended with AddStream()
+
+  NS_ABORT_IF_FALSE(false,
+                    "SpdySession::AddTransaction() should not be called");
+
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+PRUint32
+SpdySession::PipelineDepth()
+{
+  return IsDone() ? 0 : 1;
+}
+
+nsresult
+SpdySession::SetPipelinePosition(PRInt32 position)
+{
+  // This API is meant for pipelining, SpdySession's should be
+  // extended with AddStream()
+
+  NS_ABORT_IF_FALSE(false,
+                    "SpdySession::SetPipelinePosition() should not be called");
+
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+PRInt32
+SpdySession::PipelinePosition()
+{
+    return 0;
+}
+
 //-----------------------------------------------------------------------------
 // Pass through methods of nsAHttpConnection
 //-----------------------------------------------------------------------------
 
 nsAHttpConnection *
 SpdySession::Connection()
 {
   NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");
@@ -2175,16 +2241,23 @@ SpdySession::IsReused()
 
 nsresult
 SpdySession::PushBack(const char *buf, PRUint32 len)
 {
   return mConnection->PushBack(buf, len);
 }
 
 bool
+SpdySession::IsProxyConnectInProgress()
+{
+    NS_ABORT_IF_FALSE(mConnection, "no connection");
+    return mConnection->IsProxyConnectInProgress();
+}
+
+bool
 SpdySession::LastTransactionExpectedNoContent()
 {
   return mConnection->LastTransactionExpectedNoContent();
 }
 
 void
 SpdySession::SetLastTransactionExpectedNoContent(bool val)
 {
--- a/netwerk/protocol/http/SpdySession.h
+++ b/netwerk/protocol/http/SpdySession.h
@@ -70,20 +70,19 @@ public:
   NS_DECL_NSAHTTPSEGMENTREADER
   NS_DECL_NSAHTTPSEGMENTWRITER
 
   SpdySession(nsAHttpTransaction *, nsISocketTransport *, PRInt32);
   ~SpdySession();
 
   bool AddStream(nsAHttpTransaction *, PRInt32);
   bool CanReuse() { return !mShouldGoAway && !mClosed; }
-  void DontReuse();
   bool RoomForMoreStreams();
 
-  // When the connection is active this is called every 15 seconds
+  // When the connection is active this is called every 1 second
   void ReadTimeoutTick(PRIntervalTime now);
   
   // Idle time represents time since "goodput".. e.g. a data or header frame
   PRIntervalTime IdleTime();
 
   PRUint32 RegisterStreamID(SpdyStream *);
 
   const static PRUint8 kFlag_Control   = 0x80;
--- a/netwerk/protocol/http/nsAHttpConnection.h
+++ b/netwerk/protocol/http/nsAHttpConnection.h
@@ -34,18 +34,18 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsAHttpConnection_h__
 #define nsAHttpConnection_h__
 
 #include "nsISupports.h"
+#include "nsAHttpTransaction.h"
 
-class nsAHttpTransaction;
 class nsHttpRequestHead;
 class nsHttpResponseHead;
 class nsHttpConnectionInfo;
 class nsHttpConnection;
 class nsISocketTransport;
 class nsIAsyncInputStream;
 class nsIAsyncOutputStream;
 
@@ -115,48 +115,67 @@ public:
 
     // called by a transaction to get the security info from the socket.
     virtual void GetSecurityInfo(nsISupports **) = 0;
 
     // called by a transaction to determine whether or not the connection is
     // persistent... important in determining the end of a response.
     virtual bool IsPersistent() = 0;
 
-    // called to determine if a connection has been reused.
+    // called to determine or set if a connection has been reused.
     virtual bool IsReused() = 0;
-    
+    virtual void   DontReuse() = 0;
+
     // called by a transaction when the transaction reads more from the socket
     // than it should have (eg. containing part of the next pipelined response).
     virtual nsresult PushBack(const char *data, PRUint32 length) = 0;
 
+    // Used to determine if the connection wants read events even though
+    // it has not written out a transaction. Used when a connection has issued
+    // a preamble such as a proxy ssl CONNECT sequence.
+    virtual bool IsProxyConnectInProgress() = 0;
+
     // Used by a transaction to manage the state of previous response bodies on
     // the same connection and work around buggy servers.
     virtual bool LastTransactionExpectedNoContent() = 0;
     virtual void   SetLastTransactionExpectedNoContent(bool) = 0;
 
     // Transfer the base http connection object along with a
     // reference to it to the caller.
     virtual nsHttpConnection *TakeHttpConnection() = 0;
 
     // Get the nsISocketTransport used by the connection without changing
     //  references or ownership.
     virtual nsISocketTransport *Transport() = 0;
+
+    // Cancel and reschedule transactions deeper than the current response.
+    // Returns the number of canceled transactions.
+    virtual PRUint32 CancelPipeline(nsresult originalReason) = 0;
+
+    // Read and write class of transaction that is carried on this connection
+    virtual nsAHttpTransaction::Classifier Classification() = 0;
+    virtual void Classify(nsAHttpTransaction::Classifier newclass) = 0;
 };
 
 #define NS_DECL_NSAHTTPCONNECTION \
     nsresult OnHeadersAvailable(nsAHttpTransaction *, nsHttpRequestHead *, nsHttpResponseHead *, bool *reset); \
     nsresult ResumeSend(); \
     nsresult ResumeRecv(); \
     void CloseTransaction(nsAHttpTransaction *, nsresult); \
     void GetConnectionInfo(nsHttpConnectionInfo **); \
     nsresult TakeTransport(nsISocketTransport **,    \
                            nsIAsyncInputStream **,   \
                            nsIAsyncOutputStream **); \
     void GetSecurityInfo(nsISupports **); \
     bool IsPersistent(); \
     bool IsReused(); \
+    void DontReuse();  \
     nsresult PushBack(const char *, PRUint32); \
+    bool IsProxyConnectInProgress(); \
     bool LastTransactionExpectedNoContent(); \
-    void   SetLastTransactionExpectedNoContent(bool); \
+    void SetLastTransactionExpectedNoContent(bool); \
     nsHttpConnection *TakeHttpConnection(); \
-    nsISocketTransport *Transport();
+    nsISocketTransport *Transport();        \
+    PRUint32 CancelPipeline(nsresult originalReason);   \
+    nsAHttpTransaction::Classifier Classification();    \
+    void Classify(nsAHttpTransaction::Classifier);
 
 #endif // nsAHttpConnection_h__
--- a/netwerk/protocol/http/nsAHttpTransaction.h
+++ b/netwerk/protocol/http/nsAHttpTransaction.h
@@ -43,45 +43,49 @@
 
 class nsAHttpConnection;
 class nsAHttpSegmentReader;
 class nsAHttpSegmentWriter;
 class nsIInterfaceRequestor;
 class nsIEventTarget;
 class nsITransport;
 class nsHttpRequestHead;
+class nsHttpPipeline;
 
 //----------------------------------------------------------------------------
 // Abstract base class for a HTTP transaction:
 //
 // A transaction is a "sink" for the response data.  The connection pushes
 // data to the transaction by writing to it.  The transaction supports
 // WriteSegments and may refuse to accept data if its buffers are full (its
 // write function returns NS_BASE_STREAM_WOULD_BLOCK in this case).
 //----------------------------------------------------------------------------
 
 class nsAHttpTransaction : public nsISupports
 {
 public:
     // called by the connection when it takes ownership of the transaction.
     virtual void SetConnection(nsAHttpConnection *) = 0;
+
+    // used to obtain the connection associated with this transaction
     virtual nsAHttpConnection *Connection() = 0;
 
     // called by the connection to get security callbacks to set on the
     // socket transport.
     virtual void GetSecurityCallbacks(nsIInterfaceRequestor **,
                                       nsIEventTarget **) = 0;
 
     // called to report socket status (see nsITransportEventSink)
     virtual void OnTransportStatus(nsITransport* transport,
                                    nsresult status, PRUint64 progress) = 0;
 
     // called to check the transaction status.
     virtual bool     IsDone() = 0;
     virtual nsresult Status() = 0;
+    virtual PRUint8  Caps() = 0;
 
     // called to find out how much request data is available for writing.
     virtual PRUint32 Available() = 0;
 
     // called to read request data from the transaction.
     virtual nsresult ReadSegments(nsAHttpSegmentReader *reader,
                                   PRUint32 count, PRUint32 *countRead) = 0;
 
@@ -109,35 +113,83 @@ public:
     // Returns NS_ERROR_NOT_IMPLEMENTED if the object does not implement
     // sub-transactions.
     //
     // Returns NS_ERROR_ALREADY_OPENED if the subtransactions have been
     // at least partially written and cannot be moved.
     //
     virtual nsresult TakeSubTransactions(
         nsTArray<nsRefPtr<nsAHttpTransaction> > &outTransactions) = 0;
+
+    // called to add a sub-transaction in the case of pipelined transactions
+    // classes that do not implement sub transactions
+    // return NS_ERROR_NOT_IMPLEMENTED
+    virtual nsresult AddTransaction(nsAHttpTransaction *transaction) = 0;
+    
+    // The total length of the outstanding pipeline comprised of transacations
+    // and sub-transactions.
+    virtual PRUint32 PipelineDepth() = 0;
+
+    // Used to inform the connection that it is being used in a pipelined
+    // context. That may influence the handling of some errors.
+    // The value is the pipeline position (> 1).
+    virtual nsresult SetPipelinePosition(PRInt32) = 0;
+    virtual PRInt32  PipelinePosition() = 0;
+
+    // If we used rtti this would be the result of doing
+    // dynamic_cast<nsHttpPipeline *>(this).. i.e. it can be nsnull for
+    // non pipeline implementations of nsAHttpTransaction
+    virtual nsHttpPipeline *QueryPipeline() { return nsnull; }
+    
+    // Every transaction is classified into one of the types below. When using
+    // HTTP pipelines, only transactions with the same type appear on the same
+    // pipeline.
+    enum Classifier  {
+        // Transactions that expect a short 304 (no-content) response
+        CLASS_REVALIDATION,
+
+        // Transactions for content expected to be CSS or JS
+        CLASS_SCRIPT,
+
+        // Transactions for content expected to be an image
+        CLASS_IMAGE,
+
+        // Transactions that cannot involve a pipeline 
+        CLASS_SOLO,
+
+        // Transactions that do not fit any of the other categories. HTML
+        // is normally GENERAL.
+        CLASS_GENERAL,
+
+        CLASS_MAX
+    };
 };
 
 #define NS_DECL_NSAHTTPTRANSACTION \
     void SetConnection(nsAHttpConnection *); \
     nsAHttpConnection *Connection(); \
     void GetSecurityCallbacks(nsIInterfaceRequestor **, \
                               nsIEventTarget **);       \
     void OnTransportStatus(nsITransport* transport, \
                            nsresult status, PRUint64 progress); \
     bool     IsDone(); \
     nsresult Status(); \
+    PRUint8  Caps();   \
     PRUint32 Available(); \
     nsresult ReadSegments(nsAHttpSegmentReader *, PRUint32, PRUint32 *); \
     nsresult WriteSegments(nsAHttpSegmentWriter *, PRUint32, PRUint32 *); \
     void     Close(nsresult reason);                                    \
     void     SetSSLConnectFailed();                                     \
     nsHttpRequestHead *RequestHead();                                   \
     PRUint32 Http1xTransactionCount();                                  \
-    nsresult TakeSubTransactions(nsTArray<nsRefPtr<nsAHttpTransaction> > &outTransactions);
+    nsresult TakeSubTransactions(nsTArray<nsRefPtr<nsAHttpTransaction> > &outTransactions); \
+    nsresult AddTransaction(nsAHttpTransaction *);                      \
+    PRUint32 PipelineDepth();                                           \
+    nsresult SetPipelinePosition(PRInt32);                              \
+    PRInt32  PipelinePosition();
 
 //-----------------------------------------------------------------------------
 // nsAHttpSegmentReader
 //-----------------------------------------------------------------------------
 
 class nsAHttpSegmentReader
 {
 public:
--- a/netwerk/protocol/http/nsHttp.cpp
+++ b/netwerk/protocol/http/nsHttp.cpp
@@ -182,16 +182,22 @@ nsHttp::DestroyAtomTable()
     }
 
     if (sLock) {
         delete sLock;
         sLock = nsnull;
     }
 }
 
+Mutex *
+nsHttp::GetLock()
+{
+    return sLock;
+}
+
 // this function may be called from multiple threads
 nsHttpAtom
 nsHttp::ResolveAtom(const char *str)
 {
     nsHttpAtom atom = { nsnull };
 
     if (!str || !sAtomTable.ops)
         return atom;
--- a/netwerk/protocol/http/nsHttp.h
+++ b/netwerk/protocol/http/nsHttp.h
@@ -135,19 +135,16 @@ typedef PRUint8 nsHttpVersion;
 // such as HTTP upgrade which are nonsensical for SPDY, it is not the
 // SPDY configuration variable.
 #define NS_HTTP_DISALLOW_SPDY        (1<<7)
 
 //-----------------------------------------------------------------------------
 // some default values
 //-----------------------------------------------------------------------------
 
-// hard upper limit on the number of requests that can be pipelined
-#define NS_HTTP_MAX_PIPELINED_REQUESTS 8 
-
 #define NS_HTTP_DEFAULT_PORT  80
 #define NS_HTTPS_DEFAULT_PORT 443
 
 #define NS_HTTP_HEADER_SEPS ", \t"
 
 //-----------------------------------------------------------------------------
 // http atoms...
 //-----------------------------------------------------------------------------
@@ -164,16 +161,21 @@ struct nsHttpAtom
     const char *_val;
 };
 
 struct nsHttp
 {
     static nsresult CreateAtomTable();
     static void DestroyAtomTable();
 
+    // The mutex is valid any time the Atom Table is valid
+    // This mutex is used in the unusual case that the network thread and
+    // main thread might access the same data
+    static mozilla::Mutex *GetLock();
+
     // will dynamically add atoms to the table if they don't already exist
     static nsHttpAtom ResolveAtom(const char *);
     static nsHttpAtom ResolveAtom(const nsACString &s)
     {
         return ResolveAtom(PromiseFlatCString(s).get());
     }
 
     // returns true if the specified token [start,end) is valid per RFC 2616
--- a/netwerk/protocol/http/nsHttpAtomList.h
+++ b/netwerk/protocol/http/nsHttpAtomList.h
@@ -52,16 +52,17 @@
 
 HTTP_ATOM(Accept,                    "Accept")
 HTTP_ATOM(Accept_Encoding,           "Accept-Encoding")
 HTTP_ATOM(Accept_Language,           "Accept-Language")
 HTTP_ATOM(Accept_Ranges,             "Accept-Ranges")
 HTTP_ATOM(Age,                       "Age")
 HTTP_ATOM(Allow,                     "Allow")
 HTTP_ATOM(Alternate_Protocol,        "Alternate-Protocol")
+HTTP_ATOM(Assoc_Req,                 "Assoc-Req")
 HTTP_ATOM(Authentication,            "Authentication")
 HTTP_ATOM(Authorization,             "Authorization")
 HTTP_ATOM(Cache_Control,             "Cache-Control")
 HTTP_ATOM(Connection,                "Connection")
 HTTP_ATOM(Content_Disposition,       "Content-Disposition")
 HTTP_ATOM(Content_Encoding,          "Content-Encoding")
 HTTP_ATOM(Content_Language,          "Content-Language")
 HTTP_ATOM(Content_Length,            "Content-Length")
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -42,16 +42,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsHttpChannel.h"
 #include "nsHttpHandler.h"
+#include "nsStandardURL.h"
 #include "nsIApplicationCacheService.h"
 #include "nsIApplicationCacheContainer.h"
 #include "nsIAuthInformation.h"
 #include "nsIStringBundle.h"
 #include "nsIIDNService.h"
 #include "nsIStreamListenerTee.h"
 #include "nsISeekableStream.h"
 #include "nsMimeTypes.h"
@@ -65,16 +66,17 @@
 #include "nsDNSPrefetch.h"
 #include "nsChannelClassifier.h"
 #include "nsIRedirectResultListener.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Telemetry.h"
 #include "nsDOMError.h"
 #include "nsAlgorithm.h"
 #include "sampler.h"
+#include "nsIConsoleService.h"
 
 using namespace mozilla;
 
 // Device IDs for various cache types
 const char kDiskDeviceID[] = "disk";
 const char kMemoryDeviceID[] = "memory";
 const char kOfflineDeviceID[] = "offline";
 
@@ -120,17 +122,16 @@ AutoRedirectVetoNotifier::ReportRedirect
 
 nsHttpChannel::nsHttpChannel()
     : HttpAsyncAborter<nsHttpChannel>(this)
     , mLogicalOffset(0)
     , mCacheAccess(0)
     , mPostID(0)
     , mRequestTime(0)
     , mOnCacheEntryAvailableCallback(nsnull)
-    , mAsyncCacheOpen(false)
     , mCachedContentIsValid(false)
     , mCachedContentIsPartial(false)
     , mTransactionReplaced(false)
     , mAuthRetryPending(false)
     , mResuming(false)
     , mInitedCacheEntry(false)
     , mCacheForOfflineUse(false)
     , mCachingOpportunistically(false)
@@ -241,16 +242,22 @@ nsHttpChannel::Connect(bool firstTime)
         if (mResuming && (mLoadFlags & LOAD_ONLY_FROM_CACHE)) {
             LOG(("Resuming from cache is not supported yet"));
             return NS_ERROR_DOCUMENT_NOT_CACHED;
         }
 
         // open a cache entry for this channel...
         rv = OpenCacheEntry();
 
+        // do not continue if asyncOpenCacheEntry is in progress
+        if (mOnCacheEntryAvailableCallback) {
+            NS_ASSERTION(NS_SUCCEEDED(rv), "Unexpected state");
+            return NS_OK;
+        }
+
         if (NS_FAILED(rv)) {
             LOG(("OpenCacheEntry failed [rv=%x]\n", rv));
             // if this channel is only allowed to pull from the cache, then
             // we must fail if we were unable to open a cache entry.
             if (mLoadFlags & LOAD_ONLY_FROM_CACHE) {
                 // If we have a fallback URI (and we're not already
                 // falling back), process the fallback asynchronously.
                 if (!mFallbackChannel && !mFallbackKey.IsEmpty()) {
@@ -261,20 +268,20 @@ nsHttpChannel::Connect(bool firstTime)
             // otherwise, let's just proceed without using the cache.
         }
 
         // if cacheForOfflineUse has been set, open up an offline cache
         // entry to update
         if (mCacheForOfflineUse) {
             rv = OpenOfflineCacheEntryForWriting();
             if (NS_FAILED(rv)) return rv;
+
+            if (mOnCacheEntryAvailableCallback)
+                return NS_OK;
         }
-
-        if (NS_SUCCEEDED(rv) && mAsyncCacheOpen)
-            return NS_OK;
     }
 
     // we may or may not have a cache entry at this point
     if (mCacheEntry) {
         // inspect the cache entry to determine whether or not we need to go
         // out to net to validate it.  this call sets mCachedContentIsValid
         // and may set request headers as required for cache validation.
         rv = CheckCache();
@@ -495,26 +502,27 @@ nsHttpChannel::SetupTransaction()
 
     NS_ENSURE_TRUE(!mTransaction, NS_ERROR_ALREADY_INITIALIZED);
 
     nsresult rv;
 
     if (mCaps & NS_HTTP_ALLOW_PIPELINING) {
         //
         // disable pipelining if:
-        //   (1) pipelining has been explicitly disabled
-        //   (2) request corresponds to a top-level document load (link click)
-        //   (3) request method is non-idempotent
+        //   (1) pipelining has been disabled by config
+        //   (2) pipelining has been disabled by connection mgr info
+        //   (3) request corresponds to a top-level document load (link click)
+        //   (4) request method is non-idempotent
+        //   (5) request is marked slow (e.g XHR)
         //
-        // XXX does the toplevel document check really belong here?  or, should
-        //     we push it out entirely to necko consumers?
-        //
-        if (!mAllowPipelining || (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI) ||
+        if (!mAllowPipelining ||
+           (mLoadFlags & (LOAD_INITIAL_DOCUMENT_URI | INHIBIT_PIPELINE)) ||
             !(mRequestHead.Method() == nsHttp::Get ||
               mRequestHead.Method() == nsHttp::Head ||
+              mRequestHead.Method() == nsHttp::Options ||
               mRequestHead.Method() == nsHttp::Propfind ||
               mRequestHead.Method() == nsHttp::Proppatch)) {
             LOG(("  pipelining disallowed\n"));
             mCaps &= ~NS_HTTP_ALLOW_PIPELINING;
         }
     }
 
     if (!mAllowSpdy)
@@ -763,16 +771,20 @@ nsHttpChannel::CallOnStartRequest()
     LOG(("  calling mListener->OnStartRequest\n"));
     nsresult rv = mListener->OnStartRequest(this, mListenerContext);
     if (NS_FAILED(rv)) return rv;
 
     // install stream converter if required
     rv = ApplyContentConversions();
     if (NS_FAILED(rv)) return rv;
 
+    rv = EnsureAssocReq();
+    if (NS_FAILED(rv))
+        return rv;
+
     // if this channel is for a download, close off access to the cache.
     if (mCacheEntry && mChannelIsForDownload) {
         mCacheEntry->Doom();
         CloseCacheEntry(false);
     }
 
     if (!mCanceled) {
         // create offline cache entry if offline caching was requested
@@ -1708,16 +1720,127 @@ nsHttpChannel::Hash(const char *buf, nsA
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = mHasher->Finish(true, hash);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
 }
 
+nsresult
+nsHttpChannel::EnsureAssocReq()
+{
+    // Confirm Assoc-Req response header on pipelined transactions
+    // per draft-nottingham-http-pipeline-01.txt
+    // of the form: GET http://blah.com/foo/bar?qv
+    // return NS_OK as long as we don't find a violation
+    // (i.e. no header is ok, as are malformed headers, as are
+    // transactions that have not been pipelined (unless those have been
+    // opted in via pragma))
+
+    if (!mResponseHead)
+        return NS_OK;
+
+    const char *assoc_val = mResponseHead->PeekHeader(nsHttp::Assoc_Req);
+    if (!assoc_val)
+        return NS_OK;
+
+    if (!mTransaction || !mURI)
+        return NS_OK;
+    
+    if (!mTransaction->PipelinePosition()) {
+        // "Pragma: X-Verify-Assoc-Req" can be used to verify even non pipelined
+        // transactions. It is used by test harness.
+
+        const char *pragma_val = mResponseHead->PeekHeader(nsHttp::Pragma);
+        if (!pragma_val ||
+            !nsHttp::FindToken(pragma_val, "X-Verify-Assoc-Req",
+                               HTTP_HEADER_VALUE_SEPS))
+            return NS_OK;
+    }
+
+    char *method = net_FindCharNotInSet(assoc_val, HTTP_LWS);
+    if (!method)
+        return NS_OK;
+    
+    bool equals;
+    char *endofmethod;
+    
+    assoc_val = nsnull;
+    endofmethod = net_FindCharInSet(method, HTTP_LWS);
+    if (endofmethod)
+        assoc_val = net_FindCharNotInSet(endofmethod, HTTP_LWS);
+    if (!assoc_val)
+        return NS_OK;
+    
+    // check the method
+    PRInt32 methodlen = PL_strlen(mRequestHead.Method().get());
+    if ((methodlen != (endofmethod - method)) ||
+        PL_strncmp(method,
+                   mRequestHead.Method().get(),
+                   endofmethod - method)) {
+        LOG(("  Assoc-Req failure Method %s", method));
+        if (mConnectionInfo)
+            gHttpHandler->ConnMgr()->
+                PipelineFeedbackInfo(mConnectionInfo,
+                                     nsHttpConnectionMgr::RedCorruptedContent,
+                                     nsnull, 0);
+
+        nsCOMPtr<nsIConsoleService> consoleService =
+            do_GetService(NS_CONSOLESERVICE_CONTRACTID);
+        if (consoleService) {
+            nsAutoString message
+                (NS_LITERAL_STRING("Failed Assoc-Req. Received "));
+            AppendASCIItoUTF16(
+                mResponseHead->PeekHeader(nsHttp::Assoc_Req),
+                message);
+            message += NS_LITERAL_STRING(" expected method ");
+            AppendASCIItoUTF16(mRequestHead.Method().get(), message);
+            consoleService->LogStringMessage(message.get());
+        }
+
+        if (gHttpHandler->EnforceAssocReq())
+            return NS_ERROR_CORRUPTED_CONTENT;
+        return NS_OK;
+    }
+    
+    // check the URL
+    nsCOMPtr<nsIURI> assoc_url;
+    if (NS_FAILED(NS_NewURI(getter_AddRefs(assoc_url), assoc_val)) ||
+        !assoc_url)
+        return NS_OK;
+
+    mURI->Equals(assoc_url, &equals);
+    if (!equals) {
+        LOG(("  Assoc-Req failure URL %s", assoc_val));
+        if (mConnectionInfo)
+            gHttpHandler->ConnMgr()->
+                PipelineFeedbackInfo(mConnectionInfo,
+                                     nsHttpConnectionMgr::RedCorruptedContent,
+                                     nsnull, 0);
+
+        nsCOMPtr<nsIConsoleService> consoleService =
+            do_GetService(NS_CONSOLESERVICE_CONTRACTID);
+        if (consoleService) {
+            nsAutoString message
+                (NS_LITERAL_STRING("Failed Assoc-Req. Received "));
+            AppendASCIItoUTF16(
+                mResponseHead->PeekHeader(nsHttp::Assoc_Req),
+                message);
+            message += NS_LITERAL_STRING(" expected URL ");
+            AppendASCIItoUTF16(mSpec.get(), message);
+            consoleService->LogStringMessage(message.get());
+        }
+
+        if (gHttpHandler->EnforceAssocReq())
+            return NS_ERROR_CORRUPTED_CONTENT;
+    }
+    return NS_OK;
+}
+
 //-----------------------------------------------------------------------------
 // nsHttpChannel <byte-range>
 //-----------------------------------------------------------------------------
 
 nsresult
 nsHttpChannel::SetupByteRangeRequest(PRUint32 partialLen)
 {
     // cached content has been found to be partial, add necessary request
@@ -1851,16 +1974,43 @@ nsHttpChannel::ProcessNotModified()
     if (mCustomConditionalRequest) {
         LOG(("Bypassing ProcessNotModified due to custom conditional headers")); 
         return NS_ERROR_FAILURE;
     }
 
     NS_ENSURE_TRUE(mCachedResponseHead, NS_ERROR_NOT_INITIALIZED);
     NS_ENSURE_TRUE(mCacheEntry, NS_ERROR_NOT_INITIALIZED);
 
+    // If the 304 response contains a Last-Modified different than the
+    // one in our cache that is pretty suspicious and is, in at least the
+    // case of bug 716840, a sign of the server having previously corrupted
+    // our cache with a bad response. Take the minor step here of just dooming
+    // that cache entry so there is a fighting chance of getting things on the
+    // right track as well as disabling pipelining for that host.
+
+    nsCAutoString lastModified;
+    nsCAutoString lastModified304;
+
+    rv = mCachedResponseHead->GetHeader(nsHttp::Last_Modified,
+                                        lastModified);
+    if (NS_SUCCEEDED(rv))
+        rv = mResponseHead->GetHeader(nsHttp::Last_Modified, 
+                                      lastModified304);
+    if (NS_SUCCEEDED(rv) && !lastModified304.Equals(lastModified)) {
+        LOG(("Cache Entry and 304 Last-Modified Headers Do Not Match "
+             "%s and %s\n", lastModified.get(), lastModified304.get()));
+
+        mCacheEntry->Doom();
+        if (mConnectionInfo)
+            gHttpHandler->ConnMgr()->
+                PipelineFeedbackInfo(mConnectionInfo,
+                                     nsHttpConnectionMgr::RedCorruptedContent,
+                                     nsnull, 0);
+    }
+
     // merge any new headers with the cached response headers
     rv = mCachedResponseHead->UpdateHeaders(mResponseHead->Headers());
     if (NS_FAILED(rv)) return rv;
 
     // update the cached response head
     nsCAutoString head;
     mCachedResponseHead->Flatten(head, true);
     rv = mCacheEntry->SetMetaDataElement("response-head", head.get());
@@ -2029,17 +2179,17 @@ IsSubRangeRequest(nsHttpRequestHead &aRe
     return !byteRange.EqualsLiteral("bytes=0-");
 }
 
 nsresult
 nsHttpChannel::OpenCacheEntry()
 {
     nsresult rv;
 
-    mAsyncCacheOpen = false;
+    NS_ASSERTION(!mOnCacheEntryAvailableCallback, "Unexpected state");
     mLoadedFromApplicationCache = false;
 
     LOG(("nsHttpChannel::OpenCacheEntry [this=%p]", this));
 
     // make sure we're not abusing this function
     NS_PRECONDITION(!mCacheEntry, "cache entry already open");
 
     nsCAutoString cacheKey;
@@ -2112,92 +2262,76 @@ nsHttpChannel::OpenCacheEntry()
         NS_ENSURE_SUCCESS(rv, rv);
 
         rv = serv->CreateSession(appCacheClientID.get(),
                                  nsICache::STORE_OFFLINE,
                                  nsICache::STREAM_BASED,
                                  getter_AddRefs(session));
         NS_ENSURE_SUCCESS(rv, rv);
 
-        if (mLoadFlags & LOAD_BYPASS_LOCAL_CACHE_IF_BUSY) {
-            // must use synchronous open for LOAD_BYPASS_LOCAL_CACHE_IF_BUSY
-            rv = session->OpenCacheEntry(cacheKey,
-                                         nsICache::ACCESS_READ, false,
-                                         getter_AddRefs(mCacheEntry));
-            if (NS_SUCCEEDED(rv)) {
-                mCacheEntry->GetAccessGranted(&mCacheAccess);
-                LOG(("nsHttpChannel::OpenCacheEntry [this=%p grantedAccess=%d]",
-                    this, mCacheAccess));
-                mLoadedFromApplicationCache = true;
-                return NS_OK;
-            } else if (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) {
-                LOG(("bypassing local cache since it is busy\n"));
-                // Don't try to load normal cache entry
-                return NS_ERROR_NOT_AVAILABLE;
-            }
-        } else {
-            mOnCacheEntryAvailableCallback =
-                &nsHttpChannel::OnOfflineCacheEntryAvailable;
-            // We open with ACCESS_READ only, because we don't want to
-            // overwrite the offline cache entry non-atomically.
-            // ACCESS_READ will prevent us from writing to the offline
-            // cache as a normal cache entry.
-            rv = session->AsyncOpenCacheEntry(cacheKey,
-                                              nsICache::ACCESS_READ,
-                                              this);
-
-            if (NS_SUCCEEDED(rv)) {
-                mAsyncCacheOpen = true;
-                return NS_OK;
-            }
-        }
-
-        // sync or async opening failed
-        return OnOfflineCacheEntryAvailable(nsnull, nsICache::ACCESS_NONE,
-                                            rv, true);
+        mOnCacheEntryAvailableCallback =
+            &nsHttpChannel::OnOfflineCacheEntryAvailable;
+        // We open with ACCESS_READ only, because we don't want to overwrite
+        // the offline cache entry non-atomically. ACCESS_READ will prevent us
+        // from writing to the offline cache as a normal cache entry.
+        rv = session->AsyncOpenCacheEntry(
+            cacheKey,
+            nsICache::ACCESS_READ,
+            this,
+            mLoadFlags & LOAD_BYPASS_LOCAL_CACHE_IF_BUSY);
+
+        if (NS_SUCCEEDED(rv))
+            return NS_OK;
+
+        mOnCacheEntryAvailableCallback = nsnull;
+
+        // opening cache entry failed
+        return OnOfflineCacheEntryAvailable(nsnull, nsICache::ACCESS_NONE, rv);
     }
 
-    return OpenNormalCacheEntry(true);
+    return OpenNormalCacheEntry();
 }
 
 nsresult
 nsHttpChannel::OnOfflineCacheEntryAvailable(nsICacheEntryDescriptor *aEntry,
                                             nsCacheAccessMode aAccess,
-                                            nsresult aEntryStatus,
-                                            bool aIsSync)
+                                            nsresult aEntryStatus)
 {
     nsresult rv;
 
     if (NS_SUCCEEDED(aEntryStatus)) {
         // We successfully opened an offline cache session and the entry,
         // so indicate we will load from the offline cache.
         mLoadedFromApplicationCache = true;
         mCacheEntry = aEntry;
         mCacheAccess = aAccess;
     }
 
+    if (aEntryStatus == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) {
+        LOG(("bypassing local cache since it is busy\n"));
+        // Don't try to load normal cache entry
+        return NS_ERROR_NOT_AVAILABLE;
+    }
+
     if (mCanceled && NS_FAILED(mStatus)) {
         LOG(("channel was canceled [this=%p status=%x]\n", this, mStatus));
         return mStatus;
     }
 
     if (NS_SUCCEEDED(aEntryStatus))
-        // Called from OnCacheEntryAvailable, advance to the next state
-        return Connect(false);
+        return NS_OK;
 
     if (!mCacheForOfflineUse && !mFallbackChannel) {
         nsCAutoString cacheKey;
         GenerateCacheKey(mPostID, cacheKey);
 
         // Check for namespace match.
         nsCOMPtr<nsIApplicationCacheNamespace> namespaceEntry;
         rv = mApplicationCache->GetMatchingNamespace
             (cacheKey, getter_AddRefs(namespaceEntry));
-        if (NS_FAILED(rv) && !aIsSync)
-            return Connect(false);
         NS_ENSURE_SUCCESS(rv, rv);
 
         PRUint32 namespaceType = 0;
         if (!namespaceEntry ||
             NS_FAILED(namespaceEntry->GetItemType(&namespaceType)) ||
             (namespaceType &
              (nsIApplicationCacheNamespace::NAMESPACE_FALLBACK |
               nsIApplicationCacheNamespace::NAMESPACE_OPPORTUNISTIC |
@@ -2205,24 +2339,22 @@ nsHttpChannel::OnOfflineCacheEntryAvaila
             // When loading from an application cache, only items
             // on the whitelist or matching a
             // fallback/opportunistic namespace should hit the
             // network...
             mLoadFlags |= LOAD_ONLY_FROM_CACHE;
 
             // ... and if there were an application cache entry,
             // we would have found it earlier.
-            return aIsSync ? NS_ERROR_CACHE_KEY_NOT_FOUND : Connect(false);
+            return NS_ERROR_CACHE_KEY_NOT_FOUND;
         }
 
         if (namespaceType &
             nsIApplicationCacheNamespace::NAMESPACE_FALLBACK) {
             rv = namespaceEntry->GetData(mFallbackKey);
-            if (NS_FAILED(rv) && !aIsSync)
-                return Connect(false);
             NS_ENSURE_SUCCESS(rv, rv);
         }
 
         if ((namespaceType &
              nsIApplicationCacheNamespace::NAMESPACE_OPPORTUNISTIC) &&
             mLoadFlags & LOAD_DOCUMENT_URI) {
             // Document loads for items in an opportunistic namespace
             // should be placed in the offline cache.
@@ -2230,22 +2362,22 @@ nsHttpChannel::OnOfflineCacheEntryAvaila
             mApplicationCache->GetClientID(clientID);
 
             mCacheForOfflineUse = !clientID.IsEmpty();
             SetOfflineCacheClientID(clientID);
             mCachingOpportunistically = true;
         }
     }
 
-    return OpenNormalCacheEntry(aIsSync);
+    return OpenNormalCacheEntry();
 }
 
 
 nsresult
-nsHttpChannel::OpenNormalCacheEntry(bool aIsSync)
+nsHttpChannel::OpenNormalCacheEntry()
 {
     NS_ASSERTION(!mCacheEntry, "We have already mCacheEntry");
 
     nsresult rv;
 
     nsCAutoString cacheKey;
     GenerateCacheKey(mPostID, cacheKey);
 
@@ -2255,82 +2387,58 @@ nsHttpChannel::OpenNormalCacheEntry(bool
     rv = gHttpHandler->GetCacheSession(storagePolicy,
                                        getter_AddRefs(session));
     if (NS_FAILED(rv)) return rv;
 
     nsCacheAccessMode accessRequested;
     rv = DetermineCacheAccess(&accessRequested);
     if (NS_FAILED(rv)) return rv;
 
-    if (mLoadFlags & LOAD_BYPASS_LOCAL_CACHE_IF_BUSY) {
-        if (!aIsSync) {
-            // Unexpected state: we were called from OnCacheEntryAvailable(),
-            // so LOAD_BYPASS_LOCAL_CACHE_IF_BUSY shouldn't be set. Unless
-            // somebody altered mLoadFlags between OpenCacheEntry() and
-            // OnCacheEntryAvailable()...
-            NS_WARNING(
-                "OpenNormalCacheEntry() called from OnCacheEntryAvailable() "
-                "when LOAD_BYPASS_LOCAL_CACHE_IF_BUSY was specified");
-        }
-
-        // must use synchronous open for LOAD_BYPASS_LOCAL_CACHE_IF_BUSY
-        rv = session->OpenCacheEntry(cacheKey, accessRequested, false,
-                                     getter_AddRefs(mCacheEntry));
-        if (NS_SUCCEEDED(rv)) {
-            mCacheEntry->GetAccessGranted(&mCacheAccess);
-            LOG(("nsHttpChannel::OpenCacheEntry [this=%p grantedAccess=%d]",
-                this, mCacheAccess));
-        }
-        else if (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) {
-            LOG(("bypassing local cache since it is busy\n"));
-            rv = NS_ERROR_NOT_AVAILABLE;
-        }
-    }
-    else {
-        mOnCacheEntryAvailableCallback =
-            &nsHttpChannel::OnNormalCacheEntryAvailable;
-        rv = session->AsyncOpenCacheEntry(cacheKey, accessRequested, this);
-        if (NS_SUCCEEDED(rv)) {
-            mAsyncCacheOpen = true;
-            return NS_OK;
-        }
-    }
-
-    if (!aIsSync)
-        // Called from OnCacheEntryAvailable, advance to the next state
-        rv = Connect(false);
+    mOnCacheEntryAvailableCallback =
+        &nsHttpChannel::OnNormalCacheEntryAvailable;
+    rv = session->AsyncOpenCacheEntry(
+        cacheKey,
+        accessRequested,
+        this,
+        mLoadFlags & LOAD_BYPASS_LOCAL_CACHE_IF_BUSY);
+
+    if (NS_SUCCEEDED(rv))
+        return NS_OK;
+
+    mOnCacheEntryAvailableCallback = nsnull;
 
     return rv;
 }
 
 nsresult
 nsHttpChannel::OnNormalCacheEntryAvailable(nsICacheEntryDescriptor *aEntry,
                                            nsCacheAccessMode aAccess,
-                                           nsresult aEntryStatus,
-                                           bool aIsSync)
+                                           nsresult aEntryStatus)
 {
-    NS_ASSERTION(!aIsSync, "aIsSync should be false");
-
     if (NS_SUCCEEDED(aEntryStatus)) {
         mCacheEntry = aEntry;
         mCacheAccess = aAccess;
     }
 
+    if (aEntryStatus == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) {
+        LOG(("bypassing local cache since it is busy\n"));
+    }
+
     if (mCanceled && NS_FAILED(mStatus)) {
         LOG(("channel was canceled [this=%p status=%x]\n", this, mStatus));
         return mStatus;
     }
 
     if ((mLoadFlags & LOAD_ONLY_FROM_CACHE) && NS_FAILED(aEntryStatus))
         // if this channel is only allowed to pull from the cache, then
         // we must fail if we were unable to open a cache entry.
         return NS_ERROR_DOCUMENT_NOT_CACHED;
 
     // advance to the next state...
-    return Connect(false);
+    return NS_OK;
 }
 
 
 nsresult
 nsHttpChannel::OpenOfflineCacheEntryForWriting()
 {
     nsresult rv;
 
@@ -2367,32 +2475,53 @@ nsHttpChannel::OpenOfflineCacheEntryForW
     if (NS_FAILED(rv)) return rv;
 
     rv = serv->CreateSession(mOfflineCacheClientID.get(),
                              nsICache::STORE_OFFLINE,
                              nsICache::STREAM_BASED,
                              getter_AddRefs(session));
     if (NS_FAILED(rv)) return rv;
 
-    rv = session->OpenCacheEntry(cacheKey, nsICache::ACCESS_READ_WRITE,
-                                 false, getter_AddRefs(mOfflineCacheEntry));
-
-    if (rv == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) {
+    mOnCacheEntryAvailableCallback =
+        &nsHttpChannel::OnOfflineCacheEntryForWritingAvailable;
+    rv = session->AsyncOpenCacheEntry(cacheKey, nsICache::ACCESS_READ_WRITE,
+                                      this, true);
+    if (NS_SUCCEEDED(rv))
+        return NS_OK;
+
+    mOnCacheEntryAvailableCallback = nsnull;
+
+    return rv;
+}
+
+nsresult
+nsHttpChannel::OnOfflineCacheEntryForWritingAvailable(
+    nsICacheEntryDescriptor *aEntry,
+    nsCacheAccessMode aAccess,
+    nsresult aEntryStatus)
+{
+    if (NS_SUCCEEDED(aEntryStatus)) {
+        mOfflineCacheEntry = aEntry;
+        mOfflineCacheAccess = aAccess;
+    }
+
+    if (aEntryStatus == NS_ERROR_CACHE_WAIT_FOR_VALIDATION) {
         // access to the cache entry has been denied (because the cache entry
         // is probably in use by another channel).  Either the cache is being
         // read from (we're offline) or it's being updated elsewhere.
-        return NS_OK;
+        aEntryStatus = NS_OK;
     }
 
-    if (NS_SUCCEEDED(rv)) {
-        mOfflineCacheEntry->GetAccessGranted(&mOfflineCacheAccess);
-        LOG(("got offline cache entry [access=%x]\n", mOfflineCacheAccess));
+    if (mCanceled && NS_FAILED(mStatus)) {
+        LOG(("channel was canceled [this=%p status=%x]\n", this, mStatus));
+        return mStatus;
     }
 
-    return rv;
+    // advance to the next state...
+    return aEntryStatus;
 }
 
 // Generates the proper cache-key for this instance of nsHttpChannel
 nsresult
 nsHttpChannel::GenerateCacheKey(PRUint32 postID, nsACString &cacheKey)
 {
     AssembleCacheKey(mFallbackChannel ? mFallbackKey.get() : mSpec.get(),
                      postID, cacheKey);
@@ -4838,39 +4967,84 @@ nsHttpChannel::OnCacheEntryAvailable(nsI
     LOG(("nsHttpChannel::OnCacheEntryAvailable [this=%p entry=%p "
          "access=%x status=%x]\n", this, entry, access, status));
 
     // if the channel's already fired onStopRequest, then we should ignore
     // this event.
     if (!mIsPending)
         return NS_OK;
 
+    rv = OnCacheEntryAvailableInternal(entry, access, status);
+    if (NS_FAILED(rv)) {
+        CloseCacheEntry(true);
+        AsyncAbort(rv);
+    }
+
+    return NS_OK;
+}
+
+nsresult
+nsHttpChannel::OnCacheEntryAvailableInternal(nsICacheEntryDescriptor *entry,
+                                             nsCacheAccessMode access,
+                                             nsresult status)
+{
+    nsresult rv;
+
     nsOnCacheEntryAvailableCallback callback = mOnCacheEntryAvailableCallback;
     mOnCacheEntryAvailableCallback = nsnull;
 
     NS_ASSERTION(callback,
         "nsHttpChannel::OnCacheEntryAvailable called without callback");
-    rv = ((*this).*callback)(entry, access, status, false);
-
-    if (NS_FAILED(rv)) {
-        LOG(("AsyncOpenCacheEntry failed [rv=%x]\n", rv));
-        if (mLoadFlags & LOAD_ONLY_FROM_CACHE) {
-            // If we have a fallback URI (an