Merge last PGO green changeset from mozilla-inbound to mozilla-central
authorGraeme McCutcheon <graememcc_firefox@graeme-online.co.uk>
Wed, 19 Sep 2012 15:15:34 +0100
changeset 107580 0c8ac138706ebf11ed4dcce231f45a5942efc567
parent 107465 80499f04e875f18710102fefbfb97dc7bbf4cad0 (current diff)
parent 107579 acec40170961cea7d91c3f58fab338e6f01e1939 (diff)
child 107581 230b0284d50dc903342896d90a4d4bd68a9142e4
child 107612 42a17ba82cc282df1875bab7196ce02ee6f32bcd
child 111087 c71133aa64a85f765ec1727e72c99a52aa06dc4d
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
milestone18.0a1
Merge last PGO green changeset from mozilla-inbound to mozilla-central
gfx/skia/include/core/SkAutoKern.h
gfx/skia/include/core/SkBlitter.h
gfx/skia/include/core/SkBuffer.h
gfx/skia/include/core/SkClampRange.h
gfx/skia/include/core/SkDescriptor.h
gfx/skia/include/core/SkDeviceProfile.h
gfx/skia/include/core/SkEdgeClipper.h
gfx/skia/include/core/SkFDot6.h
gfx/skia/include/core/SkGlobals.h
gfx/skia/include/core/SkOrderedReadBuffer.h
gfx/skia/include/core/SkOrderedWriteBuffer.h
gfx/skia/include/core/SkPerspIter.h
gfx/skia/include/core/SkPtrRecorder.h
gfx/skia/include/core/SkRefDict.h
gfx/skia/include/core/SkRelay.h
gfx/skia/include/core/SkScalerContext.h
gfx/skia/include/core/SkScan.h
gfx/skia/include/core/SkShape.h
gfx/skia/include/core/SkStroke.h
gfx/skia/include/effects/SkEffects.h
gfx/skia/include/effects/SkGroupShape.h
gfx/skia/include/effects/SkRectShape.h
gfx/skia/include/gpu/GrClip.h
gfx/skia/include/gpu/GrClipIterator.h
gfx/skia/include/gpu/GrGLConfig.h
gfx/skia/include/gpu/GrGLConfig_chrome.h
gfx/skia/include/gpu/GrGLDefines.h
gfx/skia/include/gpu/GrGLInterface.h
gfx/skia/include/gpu/GrPath.h
gfx/skia/include/gpu/GrTemplates.h
gfx/skia/include/gpu/SkGLContext.h
gfx/skia/include/gpu/SkMesaGLContext.h
gfx/skia/include/gpu/SkNativeGLContext.h
gfx/skia/include/gpu/SkNullGLContext.h
gfx/skia/include/pdf/SkBitSet.h
gfx/skia/include/pdf/SkPDFCatalog.h
gfx/skia/include/pdf/SkPDFFont.h
gfx/skia/include/pdf/SkPDFFormXObject.h
gfx/skia/include/pdf/SkPDFGraphicState.h
gfx/skia/include/pdf/SkPDFImage.h
gfx/skia/include/pdf/SkPDFPage.h
gfx/skia/include/pdf/SkPDFShader.h
gfx/skia/include/pdf/SkPDFStream.h
gfx/skia/include/pdf/SkPDFTypes.h
gfx/skia/include/pdf/SkPDFUtils.h
gfx/skia/include/utils/SkGLCanvas.h
gfx/skia/include/utils/SkSfntUtils.h
gfx/skia/include/utils/SkTextBox.h
gfx/skia/include/utils/android/AndroidKeyToSkKey.h
gfx/skia/include/utils/unix/XkeysToSkKeys.h
gfx/skia/include/utils/unix/keysym2ucs.h
gfx/skia/include/views/SkBorderView.h
gfx/skia/include/views/SkImageView.h
gfx/skia/include/views/SkProgressBarView.h
gfx/skia/include/views/SkScrollBarView.h
gfx/skia/include/views/SkWidgetViews.h
gfx/skia/patches/0001-Bug-687189-Implement-SkPaint-getPosTextPath.patch
gfx/skia/patches/0002-Bug-688366-Dont-invalidate-all-radial-gradients.patch
gfx/skia/patches/0003-SkUserConfig-for-Mozilla.patch
gfx/skia/patches/0004-Bug-722011-Fix-trailing-commas-in-enums.patch
gfx/skia/patches/0005-Bug-731384-Fix-clang-SK_OVERRIDE.patch
gfx/skia/patches/0006-Bug-751814-ARM-EDSP-ARMv6-Skia-fixes.patch
gfx/skia/patches/0007-Bug-719872-Old-Android-FontHost.patch
gfx/skia/patches/0008-Bug-687188-Skia-radial-gradients.patch
gfx/skia/patches/0009-Bug-755869-FreeBSD-Hurd.patch
gfx/skia/patches/0010-Bug-689069-ARM-Opts.patch
gfx/skia/patches/0011-Bug-719575-Fix-clang-build.patch
gfx/skia/patches/0012-Bug-759683-make-ssse3-conditional.patch
gfx/skia/patches/0013-Bug-761890-fonts.patch
gfx/skia/patches/0014-Bug-765038-Fix-clang-build.patch
gfx/skia/patches/0015-Bug-766017-warnings.patch
gfx/skia/patches/0016-Bug-718849-Radial-gradients.patch
gfx/skia/patches/0017-Bug-740194-SkMemory-mozalloc.patch
gfx/skia/src/animator/SkBase64.cpp
gfx/skia/src/animator/SkBase64.h
gfx/skia/src/core/SkBitmapProcState_matrix_clamp.h
gfx/skia/src/core/SkBitmapProcState_matrix_repeat.h
gfx/skia/src/core/SkClampRange.cpp
gfx/skia/src/core/SkDrawing.cpp
gfx/skia/src/core/SkGlobals.cpp
gfx/skia/src/core/SkShape.cpp
gfx/skia/src/effects/SkBitmapCache.cpp
gfx/skia/src/effects/SkBitmapCache.h
gfx/skia/src/effects/SkClampRange.cpp
gfx/skia/src/effects/SkClampRange.h
gfx/skia/src/effects/SkEffects.cpp
gfx/skia/src/effects/SkEffects_none.cpp
gfx/skia/src/effects/SkGradientShader.cpp
gfx/skia/src/effects/SkGroupShape.cpp
gfx/skia/src/effects/SkRadialGradient_Table.h
gfx/skia/src/gpu/GrAddPathRenderers_aahairline.cpp
gfx/skia/src/gpu/GrAddPathRenderers_tesselated.cpp
gfx/skia/src/gpu/GrBatchedTextContext.cpp
gfx/skia/src/gpu/GrBatchedTextContext.h
gfx/skia/src/gpu/GrClip.cpp
gfx/skia/src/gpu/GrDefaultTextContext.cpp
gfx/skia/src/gpu/GrDefaultTextContext.h
gfx/skia/src/gpu/GrGLCreateNativeInterface_none.cpp
gfx/skia/src/gpu/GrGLCreateNullInterface.cpp
gfx/skia/src/gpu/GrGLDefaultInterface_native.cpp
gfx/skia/src/gpu/GrGLDefaultInterface_none.cpp
gfx/skia/src/gpu/GrGLIRect.h
gfx/skia/src/gpu/GrGLIndexBuffer.cpp
gfx/skia/src/gpu/GrGLIndexBuffer.h
gfx/skia/src/gpu/GrGLInterface.cpp
gfx/skia/src/gpu/GrGLProgram.cpp
gfx/skia/src/gpu/GrGLProgram.h
gfx/skia/src/gpu/GrGLRenderTarget.cpp
gfx/skia/src/gpu/GrGLRenderTarget.h
gfx/skia/src/gpu/GrGLSL.cpp
gfx/skia/src/gpu/GrGLSL.h
gfx/skia/src/gpu/GrGLShaderVar.h
gfx/skia/src/gpu/GrGLStencilBuffer.cpp
gfx/skia/src/gpu/GrGLStencilBuffer.h
gfx/skia/src/gpu/GrGLTexture.cpp
gfx/skia/src/gpu/GrGLTexture.h
gfx/skia/src/gpu/GrGLUtil.cpp
gfx/skia/src/gpu/GrGLVertexBuffer.cpp
gfx/skia/src/gpu/GrGLVertexBuffer.h
gfx/skia/src/gpu/GrGpuGL.cpp
gfx/skia/src/gpu/GrGpuGL.h
gfx/skia/src/gpu/GrGpuGLFixed.cpp
gfx/skia/src/gpu/GrGpuGLFixed.h
gfx/skia/src/gpu/GrGpuGLShaders.cpp
gfx/skia/src/gpu/GrGpuGLShaders.h
gfx/skia/src/gpu/GrPrintf_printf.cpp
gfx/skia/src/gpu/GrPrintf_skia.cpp
gfx/skia/src/gpu/GrStringBuilder.h
gfx/skia/src/gpu/GrTesselatedPathRenderer.cpp
gfx/skia/src/gpu/GrTesselatedPathRenderer.h
gfx/skia/src/gpu/SkGLContext.cpp
gfx/skia/src/gpu/SkNullGLContext.cpp
gfx/skia/src/images/SkBitmap_RLEPixels.h
gfx/skia/src/images/SkCreateRLEPixelRef.cpp
gfx/skia/src/pdf/SkBitSet.cpp
gfx/skia/src/ports/SkFontHost_gamma.cpp
gfx/skia/src/ports/SkFontHost_gamma_none.cpp
gfx/skia/src/ports/SkGlobals_global.cpp
gfx/skia/src/ports/SkOSEvent_android.cpp
gfx/skia/src/ports/SkOSEvent_dummy.cpp
gfx/skia/src/ports/sk_predefined_gamma.h
gfx/skia/src/utils/SDL/SkOSWindow_SDL.cpp
gfx/skia/src/utils/SkColorMatrix.cpp
gfx/skia/src/utils/SkSfntUtils.cpp
gfx/skia/src/utils/mac/SampleApp-Info.plist
gfx/skia/src/utils/mac/SampleApp.xib
gfx/skia/src/utils/mac/SampleAppDelegate.h
gfx/skia/src/utils/mac/SampleAppDelegate.mm
gfx/skia/src/utils/mac/SkEventNotifier.h
gfx/skia/src/utils/mac/SkEventNotifier.mm
gfx/skia/src/utils/mac/SkNSView.h
gfx/skia/src/utils/mac/SkNSView.mm
gfx/skia/src/utils/mac/SkOSWindow_Mac.cpp
gfx/skia/src/utils/mac/SkOSWindow_Mac.mm
gfx/skia/src/utils/mac/SkOptionsTableView.h
gfx/skia/src/utils/mac/SkOptionsTableView.mm
gfx/skia/src/utils/mac/SkSampleNSView.h
gfx/skia/src/utils/mac/SkSampleNSView.mm
gfx/skia/src/utils/mac/SkTextFieldCell.h
gfx/skia/src/utils/mac/skia_mac.mm
gfx/skia/src/utils/unix/SkOSWindow_Unix.cpp
gfx/skia/src/utils/unix/keysym2ucs.c
gfx/skia/src/utils/win/SkOSWindow_Win.cpp
gfx/skia/src/utils/win/skia_win.cpp
gfx/skia/src/views/SkBorderView.cpp
gfx/skia/src/views/SkImageView.cpp
gfx/skia/src/views/SkListView.cpp
gfx/skia/src/views/SkListWidget.cpp
gfx/skia/src/views/SkProgressBarView.cpp
gfx/skia/src/views/SkScrollBarView.cpp
gfx/skia/src/views/SkStaticTextView.cpp
gfx/skia/src/views/SkWidgetViews.cpp
gfx/skia/third_party/glu/LICENSE.txt
gfx/skia/third_party/glu/README.skia
gfx/skia/third_party/glu/gluos.h
gfx/skia/third_party/glu/libtess/GNUmakefile
gfx/skia/third_party/glu/libtess/Imakefile
gfx/skia/third_party/glu/libtess/README
gfx/skia/third_party/glu/libtess/alg-outline
gfx/skia/third_party/glu/libtess/dict-list.h
gfx/skia/third_party/glu/libtess/dict.c
gfx/skia/third_party/glu/libtess/dict.h
gfx/skia/third_party/glu/libtess/geom.c
gfx/skia/third_party/glu/libtess/geom.h
gfx/skia/third_party/glu/libtess/memalloc.c
gfx/skia/third_party/glu/libtess/memalloc.h
gfx/skia/third_party/glu/libtess/mesh.c
gfx/skia/third_party/glu/libtess/mesh.h
gfx/skia/third_party/glu/libtess/normal.c
gfx/skia/third_party/glu/libtess/normal.h
gfx/skia/third_party/glu/libtess/priorityq-heap.c
gfx/skia/third_party/glu/libtess/priorityq-heap.h
gfx/skia/third_party/glu/libtess/priorityq-sort.h
gfx/skia/third_party/glu/libtess/priorityq.c
gfx/skia/third_party/glu/libtess/priorityq.h
gfx/skia/third_party/glu/libtess/render.c
gfx/skia/third_party/glu/libtess/render.h
gfx/skia/third_party/glu/libtess/sweep.c
gfx/skia/third_party/glu/libtess/sweep.h
gfx/skia/third_party/glu/libtess/tess.c
gfx/skia/third_party/glu/libtess/tess.h
gfx/skia/third_party/glu/libtess/tessmono.c
gfx/skia/third_party/glu/libtess/tessmono.h
gfx/skia/third_party/glu/sk_glu.h
gfx/skia/update.sh
netwerk/test/unit_ipc/test_cookie_wrap.js
testing/mochitest/tests/SimpleTest/TestRunner.js
toolkit/components/alerts/mac/growl/CFGrowlAdditions.c
toolkit/components/alerts/mac/growl/CFGrowlAdditions.h
toolkit/components/alerts/mac/growl/CFGrowlDefines.h
toolkit/components/alerts/mac/growl/CFMutableDictionaryAdditions.c
toolkit/components/alerts/mac/growl/CFMutableDictionaryAdditions.h
toolkit/components/alerts/mac/growl/CFURLAdditions.c
toolkit/components/alerts/mac/growl/CFURLAdditions.h
toolkit/components/alerts/mac/growl/GrowlAbstractSingletonObject.h
toolkit/components/alerts/mac/growl/GrowlApplicationBridge.h
toolkit/components/alerts/mac/growl/GrowlApplicationBridge.m
toolkit/components/alerts/mac/growl/GrowlDefines.h
toolkit/components/alerts/mac/growl/GrowlDefinesInternal.h
toolkit/components/alerts/mac/growl/GrowlPathUtilities.h
toolkit/components/alerts/mac/growl/GrowlPathUtilities.m
toolkit/components/alerts/mac/growl/GrowlPathway.h
toolkit/components/alerts/mac/growl/GrowlPreferencesController.h
toolkit/components/alerts/mac/growl/GrowlTicketController.h
toolkit/components/alerts/mac/growl/Makefile.in
toolkit/components/alerts/mac/growl/license.txt
toolkit/components/alerts/mac/mozGrowlDelegate.h
toolkit/components/alerts/mac/mozGrowlDelegate.mm
toolkit/components/alerts/mac/nsAlertsImageLoadListener.h
toolkit/components/alerts/mac/nsAlertsImageLoadListener.mm
toolkit/components/alerts/mac/nsNotificationsList.h
toolkit/components/alerts/mac/nsNotificationsList.mm
toolkit/components/alerts/nsINotificationsList.idl
--- a/accessible/src/atk/AccessibleWrap.cpp
+++ b/accessible/src/atk/AccessibleWrap.cpp
@@ -943,17 +943,17 @@ GetAccessibleWrap(AtkObject* aAtkObj)
   AccessibleWrap* accWrap = MAI_ATK_OBJECT(aAtkObj)->accWrap;
 
   // Check if the accessible was deconstructed.
   if (!accWrap)
     return nullptr;
 
   NS_ENSURE_TRUE(accWrap->GetAtkObject() == aAtkObj, nullptr);
 
-  AccessibleWrap* appAccWrap = nsAccessNode::GetApplicationAccessible();
+  AccessibleWrap* appAccWrap = ApplicationAcc();
   if (appAccWrap != accWrap && !accWrap->IsValidObject())
     return nullptr;
 
   return accWrap;
 }
 
 nsresult
 AccessibleWrap::HandleAccEvent(AccEvent* aEvent)
--- a/accessible/src/atk/ApplicationAccessibleWrap.cpp
+++ b/accessible/src/atk/ApplicationAccessibleWrap.cpp
@@ -439,17 +439,17 @@ mai_util_get_root(void)
     // We've shutdown, try to use gail instead
     // (to avoid assert in spi_atk_tidy_windows())
     if (gail_get_root)
       return gail_get_root();
 
     return nullptr;
   }
 
-  return nsAccessNode::GetApplicationAccessible()->GetAtkObject();
+  return ApplicationAcc()->GetAtkObject();
 }
 
 G_CONST_RETURN gchar *
 mai_util_get_toolkit_name(void)
 {
     return MAI_NAME;
 }
 
--- a/accessible/src/atk/nsAccessNodeWrap.cpp
+++ b/accessible/src/atk/nsAccessNodeWrap.cpp
@@ -33,11 +33,10 @@ nsAccessNodeWrap::~nsAccessNodeWrap()
 }
 
 void nsAccessNodeWrap::InitAccessibility()
 {
 }
 
 void nsAccessNodeWrap::ShutdownAccessibility()
 {
-  nsAccessNode::ShutdownXPAccessibility();
 }
 
--- a/accessible/src/base/AccEvent.cpp
+++ b/accessible/src/base/AccEvent.cpp
@@ -122,20 +122,18 @@ AccEvent::CaptureIsFromUserInput(EIsFrom
 {
   nsINode *targetNode = GetNode();
 
 #ifdef DEBUG
   if (!targetNode) {
     // XXX: remove this hack during reorganization of 506907. Meanwhile we
     // want to get rid an assertion for application accessible events which
     // don't have DOM node (see bug 506206).
-    ApplicationAccessible* applicationAcc =
-      nsAccessNode::GetApplicationAccessible();
 
-    if (mAccessible != static_cast<nsIAccessible*>(applicationAcc))
+    if (mAccessible != static_cast<nsIAccessible*>(ApplicationAcc()))
       NS_ASSERTION(targetNode, "There should always be a DOM node for an event");
   }
 #endif
 
   if (aIsFromUserInput != eAutoDetect) {
     mIsFromUserInput = aIsFromUserInput == eFromUserInput ? true : false;
     return;
   }
--- a/accessible/src/base/nsAccDocManager.cpp
+++ b/accessible/src/base/nsAccDocManager.cpp
@@ -40,17 +40,17 @@ using namespace mozilla::a11y;
 
 DocAccessible*
 nsAccDocManager::GetDocAccessible(nsIDocument *aDocument)
 {
   if (!aDocument)
     return nullptr;
 
   // Ensure CacheChildren is called before we query cache.
-  nsAccessNode::GetApplicationAccessible()->EnsureChildren();
+  ApplicationAcc()->EnsureChildren();
 
   DocAccessible* docAcc = mDocAccessibleCache.GetWeak(aDocument);
   if (docAcc)
     return docAcc;
 
   return CreateDocOrRootAccessible(aDocument);
 }
 
@@ -388,29 +388,28 @@ nsAccDocManager::CreateDocOrRootAccessib
   mDocAccessibleCache.Put(aDocument, docAcc);
 
   // Initialize the document accessible.
   docAcc->Init();
   docAcc->SetRoleMapEntry(aria::GetRoleMap(aDocument));
 
   // Bind the document to the tree.
   if (isRootDoc) {
-    Accessible* appAcc = nsAccessNode::GetApplicationAccessible();
-    if (!appAcc->AppendChild(docAcc)) {
+    if (!ApplicationAcc()->AppendChild(docAcc)) {
       docAcc->Shutdown();
       return nullptr;
     }
 
     // Fire reorder event to notify new accessible document has been attached to
     // the tree. The reorder event is delivered after the document tree is
     // constructed because event processing and tree construction are done by
     // the same document.
     nsRefPtr<AccEvent> reorderEvent =
-      new AccEvent(nsIAccessibleEvent::EVENT_REORDER, appAcc, eAutoDetect,
-                   AccEvent::eCoalesceFromSameSubtree);
+      new AccEvent(nsIAccessibleEvent::EVENT_REORDER, ApplicationAcc(),
+                   eAutoDetect, AccEvent::eCoalesceFromSameSubtree);
     docAcc->FireDelayedAccessibleEvent(reorderEvent);
 
   } else {
     parentDocAcc->BindChildDocument(docAcc);
   }
 
 #ifdef DEBUG
   if (logging::IsEnabled(logging::eDocCreate)) {
--- a/accessible/src/base/nsAccessNode.cpp
+++ b/accessible/src/base/nsAccessNode.cpp
@@ -1,16 +1,15 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 #include "nsAccessNode.h"
 
-#include "ApplicationAccessibleWrap.h"
 #include "nsAccessibilityService.h"
 #include "nsAccUtils.h"
 #include "nsCoreUtils.h"
 #include "RootAccessible.h"
 
 #include "nsIDocShell.h"
 #include "nsIDocShellTreeItem.h"
 #include "nsIDOMWindow.h"
@@ -19,26 +18,24 @@
 #include "nsIPresShell.h"
 #include "nsIServiceManager.h"
 #include "nsFocusManager.h"
 #include "nsPresContext.h"
 #include "mozilla/Services.h"
 
 using namespace mozilla::a11y;
 
-/* For documentation of the accessibility architecture, 
+/* For documentation of the accessibility architecture,
  * see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
  */
 
-ApplicationAccessible* nsAccessNode::gApplicationAccessible = nullptr;
-
 /*
  * Class nsAccessNode
  */
- 
+
 ////////////////////////////////////////////////////////////////////////////////
 // AccessNode. nsISupports
 
 NS_IMPL_CYCLE_COLLECTION_1(nsAccessNode, mContent)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsAccessNode)
   NS_INTERFACE_MAP_ENTRY(nsAccessNode)
 NS_INTERFACE_MAP_END
@@ -77,51 +74,16 @@ void nsAccessNode::LastRelease()
 
 void
 nsAccessNode::Shutdown()
 {
   mContent = nullptr;
   mDoc = nullptr;
 }
 
-ApplicationAccessible*
-nsAccessNode::GetApplicationAccessible()
-{
-  NS_ASSERTION(!nsAccessibilityService::IsShutdown(),
-               "Accessibility wasn't initialized!");
-
-  if (!gApplicationAccessible) {
-    ApplicationAccessibleWrap::PreCreate();
-
-    gApplicationAccessible = new ApplicationAccessibleWrap();
-
-    // Addref on create. Will Release in ShutdownXPAccessibility()
-    NS_ADDREF(gApplicationAccessible);
-
-    gApplicationAccessible->Init();
-  }
-
-  return gApplicationAccessible;
-}
-
-void nsAccessNode::ShutdownXPAccessibility()
-{
-  // Called by nsAccessibilityService::Shutdown()
-  // which happens when xpcom is shutting down
-  // at exit of program
-
-  // Release gApplicationAccessible after everything else is shutdown
-  // so we don't accidently create it again while tearing down root accessibles
-  ApplicationAccessibleWrap::Unload();
-  if (gApplicationAccessible) {
-    gApplicationAccessible->Shutdown();
-    NS_RELEASE(gApplicationAccessible);
-  }
-}
-
 RootAccessible*
 nsAccessNode::RootAccessible() const
 {
   nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
     nsCoreUtils::GetDocShellTreeItemFor(mContent);
   NS_ASSERTION(docShellTreeItem, "No docshell tree item for mContent");
   if (!docShellTreeItem) {
     return nullptr;
--- a/accessible/src/base/nsAccessNode.h
+++ b/accessible/src/base/nsAccessNode.h
@@ -16,17 +16,16 @@
 
 class nsAccessNode;
 class DocAccessible;
 class nsIAccessibleDocument;
 class nsIContent;
 
 namespace mozilla {
 namespace a11y {
-class ApplicationAccessible;
 class RootAccessible;
 }
 }
 
 class nsIPresShell;
 class nsPresContext;
 class nsIFrame;
 class nsIDocShellTreeItem;
@@ -36,23 +35,16 @@ class nsAccessNode: public nsISupports
 public:
 
   nsAccessNode(nsIContent* aContent, DocAccessible* aDoc);
   virtual ~nsAccessNode();
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(nsAccessNode)
 
-  static void ShutdownXPAccessibility();
-
-  /**
-   * Return an application accessible.
-   */
-  static mozilla::a11y::ApplicationAccessible* GetApplicationAccessible();
-
   /**
    * Return the document accessible for this access node.
    */
   DocAccessible* Document() const { return mDoc; }
 
   /**
    * Return the root document accessible for this accessnode.
    */
@@ -106,14 +98,12 @@ protected:
 
   nsCOMPtr<nsIContent> mContent;
   DocAccessible* mDoc;
 
 private:
   nsAccessNode() MOZ_DELETE;
   nsAccessNode(const nsAccessNode&) MOZ_DELETE;
   nsAccessNode& operator =(const nsAccessNode&) MOZ_DELETE;
-  
-  static mozilla::a11y::ApplicationAccessible* gApplicationAccessible;
 };
 
 #endif
 
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -77,16 +77,17 @@
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessibilityService
 ////////////////////////////////////////////////////////////////////////////////
 
 nsAccessibilityService *nsAccessibilityService::gAccessibilityService = nullptr;
+ApplicationAccessible* nsAccessibilityService::gApplicationAccessible = nullptr;
 bool nsAccessibilityService::gIsShutdown = true;
 
 nsAccessibilityService::nsAccessibilityService() :
   nsAccDocManager(), FocusManager()
 {
   NS_TIME_FUNCTION;
 }
 
@@ -597,17 +598,18 @@ nsAccessibilityService::RecreateAccessib
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessibleRetrieval
 
 NS_IMETHODIMP
 nsAccessibilityService::GetApplicationAccessible(nsIAccessible** aAccessibleApplication)
 {
   NS_ENSURE_ARG_POINTER(aAccessibleApplication);
 
-  NS_IF_ADDREF(*aAccessibleApplication = nsAccessNode::GetApplicationAccessible());
+  NS_IF_ADDREF(*aAccessibleApplication = ApplicationAcc());
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsAccessibilityService::GetAccessibleFor(nsIDOMNode *aNode,
                                          nsIAccessible **aAccessible)
 {
   NS_ENSURE_ARG_POINTER(aAccessible);
@@ -1198,16 +1200,22 @@ nsAccessibilityService::Init()
 
   static const PRUnichar kInitIndicator[] = { '1', 0 };
   observerService->NotifyObservers(nullptr, "a11y-init-or-shutdown", kInitIndicator);
 
 #ifdef DEBUG
   logging::CheckEnv();
 #endif
 
+  // Create and initialize the application accessible.
+  ApplicationAccessibleWrap::PreCreate();
+  gApplicationAccessible = new ApplicationAccessibleWrap();
+  NS_ADDREF(gApplicationAccessible); // will release in Shutdown()
+  gApplicationAccessible->Init();
+
   // Initialize accessibility.
   nsAccessNodeWrap::InitAccessibility();
 
 #ifdef MOZ_CRASHREPORTER
   CrashReporter::
     AnnotateCrashReport(NS_LITERAL_CSTRING("Accessibility"),
                         NS_LITERAL_CSTRING("Active"));
 #endif
@@ -1237,16 +1245,21 @@ nsAccessibilityService::Shutdown()
   // Don't null accessibility service static member at this point to be safe
   // if someone will try to operate with it.
 
   NS_ASSERTION(!gIsShutdown, "Accessibility was shutdown already");
 
   gIsShutdown = true;
 
   nsAccessNodeWrap::ShutdownAccessibility();
+
+  ApplicationAccessibleWrap::Unload();
+  gApplicationAccessible->Shutdown();
+  NS_RELEASE(gApplicationAccessible);
+  gApplicationAccessible = nullptr;
 }
 
 bool
 nsAccessibilityService::HasUniversalAriaProperty(nsIContent *aContent)
 {
   // ARIA attributes that take token values (NMTOKEN, bool) are special cased
   // because of special value "undefined" (see HasDefinedARIAToken).
   return nsAccUtils::HasDefinedARIAToken(aContent, nsGkAtoms::aria_atomic) ||
@@ -1667,18 +1680,17 @@ nsAccessibilityService::CreateHTMLAccess
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessibilityService (DON'T put methods here)
 
 Accessible*
 nsAccessibilityService::AddNativeRootAccessible(void* aAtkAccessible)
 {
 #ifdef MOZ_ACCESSIBILITY_ATK
-  ApplicationAccessible* applicationAcc =
-    nsAccessNode::GetApplicationAccessible();
+  ApplicationAccessible* applicationAcc = ApplicationAcc();
   if (!applicationAcc)
     return nullptr;
 
   nsRefPtr<NativeRootAccessibleWrap> nativeRootAcc =
     new NativeRootAccessibleWrap(static_cast<AtkObject*>(aAtkAccessible));
   if (!nativeRootAcc)
     return nullptr;
 
@@ -1688,18 +1700,17 @@ nsAccessibilityService::AddNativeRootAcc
 
   return nullptr;
 }
 
 void
 nsAccessibilityService::RemoveNativeRootAccessible(Accessible* aAccessible)
 {
 #ifdef MOZ_ACCESSIBILITY_ATK
-  ApplicationAccessible* applicationAcc =
-    nsAccessNode::GetApplicationAccessible();
+  ApplicationAccessible* applicationAcc = ApplicationAcc();
 
   if (applicationAcc)
     applicationAcc->RemoveChild(aAccessible);
 #endif
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // NS_GetAccessibilityService
@@ -1808,16 +1819,22 @@ namespace mozilla {
 namespace a11y {
 
 FocusManager*
 FocusMgr()
 {
   return nsAccessibilityService::gAccessibilityService;
 }
 
+ApplicationAccessible*
+ApplicationAcc()
+{
+  return nsAccessibilityService::gApplicationAccessible;
+}
+
 EPlatformDisabledState
 PlatformDisabledState()
 {
   static int disabledState = 0xff;
 
   if (disabledState == 0xff) {
     disabledState = Preferences::GetInt("accessibility.force_disabled", 0);
     if (disabledState < ePlatformIsForceEnabled)
--- a/accessible/src/base/nsAccessibilityService.h
+++ b/accessible/src/base/nsAccessibilityService.h
@@ -16,32 +16,39 @@
 #include "nsIObserver.h"
 
 class nsImageFrame;
 class nsITreeView;
 
 namespace mozilla {
 namespace a11y {
 
+class ApplicationAccessible;
+
 /**
  * Return focus manager.
  */
 FocusManager* FocusMgr();
 
 enum EPlatformDisabledState {
   ePlatformIsForceEnabled = -1,
   ePlatformIsEnabled = 0,
   ePlatformIsDisabled = 1
 };
 
 /**
  * Return the platform disabled state.
  */
 EPlatformDisabledState PlatformDisabledState();
 
+/**
+ * Returns the application accessible.
+ */
+ApplicationAccessible* ApplicationAcc();
+
 #ifdef MOZ_ACCESSIBILITY_ATK
 /**
  * Perform initialization that should be done as soon as possible, in order
  * to minimize startup time.
  * XXX: this function and the next defined in ApplicationAccessibleWrap.cpp
  */
 void PreInit();
 #endif
@@ -248,31 +255,37 @@ private:
 #endif
 
   /**
    * Reference for accessibility service instance.
    */
   static nsAccessibilityService* gAccessibilityService;
 
   /**
+   * Reference for application accessible instance.
+   */
+  static mozilla::a11y::ApplicationAccessible* gApplicationAccessible;
+
+  /**
    * Indicates whether accessibility service was shutdown.
    */
   static bool gIsShutdown;
 
   /**
    * Does this content node have a universal ARIA property set on it?
    * A universal ARIA property is one that can be defined on any element even if there is no role.
    *
    * @param aContent The content node to test
    * @return true if there is a universal ARIA property set on the node
    */
   bool HasUniversalAriaProperty(nsIContent *aContent);
 
   friend nsAccessibilityService* GetAccService();
   friend mozilla::a11y::FocusManager* mozilla::a11y::FocusMgr();
+  friend mozilla::a11y::ApplicationAccessible* mozilla::a11y::ApplicationAcc();
 
   friend nsresult NS_GetAccessibilityService(nsIAccessibilityService** aResult);
 };
 
 /**
  * Return the accessibility service instance. (Handy global function)
  */
 inline nsAccessibilityService*
--- a/accessible/src/mac/nsAccessNodeWrap.mm
+++ b/accessible/src/mac/nsAccessNodeWrap.mm
@@ -33,11 +33,10 @@ nsAccessNodeWrap::~nsAccessNodeWrap()
 
 
 void nsAccessNodeWrap::InitAccessibility()
 {
 }
 
 void nsAccessNodeWrap::ShutdownAccessibility()
 {
-  nsAccessNode::ShutdownXPAccessibility();
 }
 
--- a/accessible/src/msaa/nsAccessNodeWrap.cpp
+++ b/accessible/src/msaa/nsAccessNodeWrap.cpp
@@ -125,17 +125,17 @@ nsAccessNodeWrap::QueryService(REFGUID g
     *ppv = static_cast<IAccessible*>(docAcc);
 
     (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
     return NS_OK;
   }
 
   // Can get to IAccessibleApplication from any node via QS
   if (guidService == IID_IAccessibleApplication) {
-    ApplicationAccessible* applicationAcc = GetApplicationAccessible();
+    ApplicationAccessible* applicationAcc = ApplicationAcc();
     if (!applicationAcc)
       return E_NOINTERFACE;
 
     nsresult rv = applicationAcc->QueryNativeInterface(iid, ppv);
     return NS_SUCCEEDED(rv) ? S_OK : E_NOINTERFACE;
   }
 
   /**
@@ -553,18 +553,16 @@ void nsAccessNodeWrap::InitAccessibility
 }
 
 void nsAccessNodeWrap::ShutdownAccessibility()
 {
   NS_IF_RELEASE(gTextEvent);
   ::DestroyCaret();
 
   nsWinUtils::ShutdownWindowEmulation();
-
-  nsAccessNode::ShutdownXPAccessibility();
 }
 
 int nsAccessNodeWrap::FilterA11yExceptions(unsigned int aCode, EXCEPTION_POINTERS *aExceptionInfo)
 {
   if (aCode == EXCEPTION_ACCESS_VIOLATION) {
 #ifdef MOZ_CRASHREPORTER
     // MSAA swallows crashes (because it is COM-based)
     // but we still need to learn about those crashes so we can fix them
--- a/accessible/src/other/nsAccessNodeWrap.cpp
+++ b/accessible/src/other/nsAccessNodeWrap.cpp
@@ -32,11 +32,10 @@ nsAccessNodeWrap::~nsAccessNodeWrap()
 }
 
 void nsAccessNodeWrap::InitAccessibility()
 {
 }
 
 void nsAccessNodeWrap::ShutdownAccessibility()
 {
-  nsAccessNode::ShutdownXPAccessibility();
 }
 
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -589,16 +589,18 @@ var WebappsHelper = {
       case "webapps-install-denied":
         DOMApplicationRegistry.denyInstall(installer);
         break;
     }
   },
 
   observe: function webapps_observe(subject, topic, data) {
     let json = JSON.parse(data);
+    json.mm = subject;
+
     switch(topic) {
       case "webapps-launch":
         DOMApplicationRegistry.getManifestFor(json.origin, function(aManifest) {
           if (!aManifest)
             return;
 
           let manifest = new DOMApplicationManifest(aManifest, json.origin);
           shell.sendChromeEvent({
--- a/b2g/config/tooltool-manifests/macosx64/releng.manifest
+++ b/b2g/config/tooltool-manifests/macosx64/releng.manifest
@@ -4,14 +4,14 @@
 },
 {
 "size": 47,
 "digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
 "algorithm": "sha512",
 "filename": "setup.sh"
 },
 {
-"size": 57249339,
-"digest": "708bf18f40edd46517c6368b6b5ad5cd05904d3c60614cdb483248e035cdca0fc905f0e72e90d94de9dccaa18270aadfe07987ab95adcc0c6bb4ce51aa292623",
+"size": 57746646,
+"digest": "e1d76c4c9d12edfba0d7c8db4cd37669d90e6824ee3d1f949dddc0f168815b115f9809a335d3ee0025432df995f898d9dc7545ee89e499944ed84e2407fc54b8",
 "algorithm": "sha512",
 "filename": "clang.tar.bz2"
 }
 ]
--- a/browser/base/content/pageinfo/pageInfo.js
+++ b/browser/base/content/pageinfo/pageInfo.js
@@ -284,16 +284,18 @@ var onProcessElement = [ ];
 
 // These functions are called once when all the elements in all of the target
 // document (and all of its subframes, if any) have been processed
 var onFinished = [ ];
 
 // These functions are called once when the Page Info window is closed.
 var onUnloadRegistry = [ ];
 
+// These functions are called once when an image preview is shown.
+var onImagePreviewShown = [ ];
 
 /* Called when PageInfo window is loaded.  Arguments are:
  *  window.arguments[0] - (optional) an object consisting of
  *                         - doc: (optional) document to use for source. if not provided,
  *                                the calling window's document will be used
  *                         - initialTab: (optional) id of the inital tab to display
  */
 function onLoadPageInfo()
@@ -459,16 +461,33 @@ function toggleGroupbox(id)
     elt.setAttribute("closed", "true");
     if (elt.flex) {
       elt.flexWhenOpened = elt.flex;
       elt.flex = 0;
     }
   }
 }
 
+function openCacheEntry(key, cb)
+{
+  var tries = 0;
+  var checkCacheListener = {
+    onCacheEntryAvailable: function(entry, access, status) {
+      if (entry || tries == 1) {
+        cb(entry);
+      }
+      else {
+        tries++;
+        ftpCacheSession.asyncOpenCacheEntry(key, ACCESS_READ, this, true);
+      }
+    }
+  };
+  httpCacheSession.asyncOpenCacheEntry(key, ACCESS_READ, checkCacheListener, true);
+}
+
 function makeGeneralTab()
 {
   var title = (gDocument.title) ? gBundle.getFormattedString("pageTitle", [gDocument.title]) : gBundle.getString("noPageTitle");
   document.getElementById("titletext").value = title;
 
   var url = gDocument.location.toString();
   setItemValue("urltext", url);
 
@@ -509,33 +528,25 @@ function makeGeneralTab()
   }
 
   // get the date of last modification
   var modifiedText = formatDate(gDocument.lastModified, gStrings.notSet);
   document.getElementById("modifiedtext").value = modifiedText;
 
   // get cache info
   var cacheKey = url.replace(/#.*$/, "");
-  try {
-    var cacheEntryDescriptor = httpCacheSession.openCacheEntry(cacheKey, ACCESS_READ, false);
-  }
-  catch(ex) {
-    try {
-      cacheEntryDescriptor = ftpCacheSession.openCacheEntry(cacheKey, ACCESS_READ, false);
+  openCacheEntry(cacheKey, function(cacheEntry) {
+    var sizeText;
+    if (cacheEntry) {
+      var pageSize = cacheEntry.dataSize;
+      var kbSize = formatNumber(Math.round(pageSize / 1024 * 100) / 100);
+      sizeText = gBundle.getFormattedString("generalSize", [kbSize, formatNumber(pageSize)]);
     }
-    catch(ex2) { }
-  }
-
-  var sizeText;
-  if (cacheEntryDescriptor) {
-    var pageSize = cacheEntryDescriptor.dataSize;
-    var kbSize = formatNumber(Math.round(pageSize / 1024 * 100) / 100);
-    sizeText = gBundle.getFormattedString("generalSize", [kbSize, formatNumber(pageSize)]);
-  }
-  setItemValue("sizetext", sizeText);
+    setItemValue("sizetext", sizeText);
+  });
 
   securityOnLoad();
 }
 
 //******** Generic Build-a-tab
 // Assumes the views are empty. Only called once to build the tabs, and
 // does so by farming the task off to another thread via setTimeout().
 // The actual work is done with a TreeWalker that calls doGrab() once for
@@ -590,30 +601,28 @@ function addImage(url, type, alt, elem, 
     return;
 
   if (!gImageHash.hasOwnProperty(url))
     gImageHash[url] = { };
   if (!gImageHash[url].hasOwnProperty(type))
     gImageHash[url][type] = { };
   if (!gImageHash[url][type].hasOwnProperty(alt)) {
     gImageHash[url][type][alt] = gImageView.data.length;
-    try {
-      // open for READ, in non-blocking mode
-      var cacheEntryDescriptor = httpCacheSession.openCacheEntry(url, ACCESS_READ, false);
-    }
-    catch(ex) {
-      try {
-        // open for READ, in non-blocking mode
-        cacheEntryDescriptor = ftpCacheSession.openCacheEntry(url, ACCESS_READ, false);
+    var row = [url, type, -1, alt, 1, elem, isBg];
+    gImageView.addRow(row);
+
+    // Fill in cache data asynchronously
+    openCacheEntry(url, function(cacheEntry) {
+      // The data at row[2] corresponds to the data size.
+      if (cacheEntry) {
+        row[2] = cacheEntry.dataSize;
+        // Invalidate the row to trigger a repaint.
+        gImageView.tree.invalidateRow(gImageView.data.indexOf(row));
       }
-      catch(ex2) { }
-    }
-
-    var dataSize = (cacheEntryDescriptor) ? cacheEntryDescriptor.dataSize : -1;
-    gImageView.addRow([url, type, dataSize, alt, 1, elem, isBg]);
+    });
 
     // Add the observer, only once.
     if (gImageView.data.length == 1) {
       document.getElementById("mediaTab").hidden = false;
       Components.classes["@mozilla.org/observer-service;1"]
                 .getService(Components.interfaces.nsIObserverService)
                 .addObserver(imagePermissionObserver, "perm-changed", false);
     }
@@ -893,183 +902,176 @@ function makePreview(row)
       imageText = getValueText(item);
   }
   setItemValue("imagetext", imageText);
 
   setItemValue("imagelongdesctext", item.longDesc);
 
   // get cache info
   var cacheKey = url.replace(/#.*$/, "");
-  try {
-    // open for READ, in non-blocking mode
-    var cacheEntryDescriptor = httpCacheSession.openCacheEntry(cacheKey, ACCESS_READ, false);
-  }
-  catch(ex) {
-    try {
-      // open for READ, in non-blocking mode
-      cacheEntryDescriptor = ftpCacheSession.openCacheEntry(cacheKey, ACCESS_READ, false);
+  openCacheEntry(cacheKey, function(cacheEntry) {
+    // find out the file size
+    var sizeText;
+    if (cacheEntry) {
+      var imageSize = cacheEntry.dataSize;
+      var kbSize = Math.round(imageSize / 1024 * 100) / 100;
+      sizeText = gBundle.getFormattedString("generalSize",
+                                            [formatNumber(kbSize), formatNumber(imageSize)]);
     }
-    catch(ex2) { }
-  }
+    else
+      sizeText = gBundle.getString("mediaUnknownNotCached");
+    setItemValue("imagesizetext", sizeText);
 
-  // find out the file size
-  var sizeText;
-  if (cacheEntryDescriptor) {
-    var imageSize = cacheEntryDescriptor.dataSize;
-    var kbSize = Math.round(imageSize / 1024 * 100) / 100;
-    sizeText = gBundle.getFormattedString("generalSize",
-                                          [formatNumber(kbSize), formatNumber(imageSize)]);
-  }
-  else
-    sizeText = gBundle.getString("mediaUnknownNotCached");
-  setItemValue("imagesizetext", sizeText);
-
-  var mimeType;
-  var numFrames = 1;
-  if (item instanceof HTMLObjectElement ||
-      item instanceof HTMLEmbedElement ||
-      item instanceof HTMLLinkElement)
-    mimeType = item.type;
+    var mimeType;
+    var numFrames = 1;
+    if (item instanceof HTMLObjectElement ||
+        item instanceof HTMLEmbedElement ||
+        item instanceof HTMLLinkElement)
+      mimeType = item.type;
 
-  if (!mimeType && !isBG && item instanceof nsIImageLoadingContent) {
-    var imageRequest = item.getRequest(nsIImageLoadingContent.CURRENT_REQUEST);
-    if (imageRequest) {
-      mimeType = imageRequest.mimeType;
-      var image = imageRequest.image;
-      if (image)
-        numFrames = image.numFrames;
+    if (!mimeType && !isBG && item instanceof nsIImageLoadingContent) {
+      var imageRequest = item.getRequest(nsIImageLoadingContent.CURRENT_REQUEST);
+      if (imageRequest) {
+        mimeType = imageRequest.mimeType;
+        var image = imageRequest.image;
+        if (image)
+          numFrames = image.numFrames;
+      }
     }
-  }
-  if (!mimeType)
-    mimeType = getContentTypeFromHeaders(cacheEntryDescriptor);
+    
+    if (!mimeType)
+      mimeType = getContentTypeFromHeaders(cacheEntry);
 
-  // if we have a data url, get the MIME type from the url
-  if (!mimeType && /^data:/.test(url)) {
-    let dataMimeType = /^data:(image\/[^;,]+)/i.exec(url);
-    if (dataMimeType)
-      mimeType = dataMimeType[1].toLowerCase();
-  }
+    // if we have a data url, get the MIME type from the url
+    if (!mimeType && /^data:/.test(url)) {
+      let dataMimeType = /^data:(image\/[^;,]+)/i.exec(url);
+      if (dataMimeType)
+        mimeType = dataMimeType[1].toLowerCase();
+    }
 
-  var imageType;
-  if (mimeType) {
-    // We found the type, try to display it nicely
-    let imageMimeType = /^image\/(.*)/i.exec(mimeType);
-    if (imageMimeType) {
-      imageType = imageMimeType[1].toUpperCase();
-      if (numFrames > 1)
-        imageType = gBundle.getFormattedString("mediaAnimatedImageType",
-                                               [imageType, numFrames]);
-      else
-        imageType = gBundle.getFormattedString("mediaImageType", [imageType]);
+    var imageType;
+    if (mimeType) {
+      // We found the type, try to display it nicely
+      let imageMimeType = /^image\/(.*)/i.exec(mimeType);
+      if (imageMimeType) {
+        imageType = imageMimeType[1].toUpperCase();
+        if (numFrames > 1)
+          imageType = gBundle.getFormattedString("mediaAnimatedImageType",
+                                                 [imageType, numFrames]);
+        else
+          imageType = gBundle.getFormattedString("mediaImageType", [imageType]);
+      }
+      else {
+        // the MIME type doesn't begin with image/, display the raw type
+        imageType = mimeType;
+      }
     }
     else {
-      // the MIME type doesn't begin with image/, display the raw type
-      imageType = mimeType;
+      // We couldn't find the type, fall back to the value in the treeview
+      imageType = gImageView.data[row][COL_IMAGE_TYPE];
     }
-  }
-  else {
-    // We couldn't find the type, fall back to the value in the treeview
-    imageType = gImageView.data[row][COL_IMAGE_TYPE];
-  }
-  setItemValue("imagetypetext", imageType);
+    setItemValue("imagetypetext", imageType);
+
+    var imageContainer = document.getElementById("theimagecontainer");
+    var oldImage = document.getElementById("thepreviewimage");
+
+    var isProtocolAllowed = checkProtocol(gImageView.data[row]);
+
+    var newImage = new Image;
+    newImage.id = "thepreviewimage";
+    var physWidth = 0, physHeight = 0;
+    var width = 0, height = 0;
 
-  var imageContainer = document.getElementById("theimagecontainer");
-  var oldImage = document.getElementById("thepreviewimage");
-
-  var isProtocolAllowed = checkProtocol(gImageView.data[row]);
+    if ((item instanceof HTMLLinkElement || item instanceof HTMLInputElement ||
+         item instanceof HTMLImageElement ||
+         item instanceof SVGImageElement ||
+        (item instanceof HTMLObjectElement && /^image\//.test(mimeType)) || isBG) && isProtocolAllowed) {
+      newImage.setAttribute("src", url);
+      physWidth = newImage.width || 0;
+      physHeight = newImage.height || 0;
 
-  var newImage = new Image;
-  newImage.id = "thepreviewimage";
-  var physWidth = 0, physHeight = 0;
-  var width = 0, height = 0;
+      // "width" and "height" attributes must be set to newImage,
+      // even if there is no "width" or "height attribute in item;
+      // otherwise, the preview image cannot be displayed correctly.
+      if (!isBG) {
+        newImage.width = ("width" in item && item.width) || newImage.naturalWidth;
+        newImage.height = ("height" in item && item.height) || newImage.naturalHeight;
+      }
+      else {
+        // the Width and Height of an HTML tag should not be used for its background image
+        // (for example, "table" can have "width" or "height" attributes)
+        newImage.width = newImage.naturalWidth;
+        newImage.height = newImage.naturalHeight;
+      }
 
-  if ((item instanceof HTMLLinkElement || item instanceof HTMLInputElement ||
-       item instanceof HTMLImageElement ||
-       item instanceof SVGImageElement ||
-      (item instanceof HTMLObjectElement && /^image\//.test(mimeType)) || isBG) && isProtocolAllowed) {
-    newImage.setAttribute("src", url);
-    physWidth = newImage.width || 0;
-    physHeight = newImage.height || 0;
+      if (item instanceof SVGImageElement) {
+        newImage.width = item.width.baseVal.value;
+        newImage.height = item.height.baseVal.value;
+      }
+
+      width = newImage.width;
+      height = newImage.height;
+
+      document.getElementById("theimagecontainer").collapsed = false
+      document.getElementById("brokenimagecontainer").collapsed = true;
+    }
+#ifdef MOZ_MEDIA
+    else if (item instanceof HTMLVideoElement && isProtocolAllowed) {
+      newImage = document.createElementNS("http://www.w3.org/1999/xhtml", "video");
+      newImage.id = "thepreviewimage";
+      newImage.mozLoadFrom(item);
+      newImage.controls = true;
+      width = physWidth = item.videoWidth;
+      height = physHeight = item.videoHeight;
 
-    // "width" and "height" attributes must be set to newImage,
-    // even if there is no "width" or "height attribute in item;
-    // otherwise, the preview image cannot be displayed correctly.
-    if (!isBG) {
-      newImage.width = ("width" in item && item.width) || newImage.naturalWidth;
-      newImage.height = ("height" in item && item.height) || newImage.naturalHeight;
+      document.getElementById("theimagecontainer").collapsed = false;
+      document.getElementById("brokenimagecontainer").collapsed = true;
     }
+    else if (item instanceof HTMLAudioElement && isProtocolAllowed) {
+      newImage = new Audio;
+      newImage.id = "thepreviewimage";
+      newImage.src = url;
+      newImage.controls = true;
+      isAudio = true;
+
+      document.getElementById("theimagecontainer").collapsed = false;
+      document.getElementById("brokenimagecontainer").collapsed = true;
+    }
+#endif
     else {
-      // the Width and Height of an HTML tag should not be used for its background image
-      // (for example, "table" can have "width" or "height" attributes)
-      newImage.width = newImage.naturalWidth;
-      newImage.height = newImage.naturalHeight;
-    }
-
-    if (item instanceof SVGImageElement) {
-      newImage.width = item.width.baseVal.value;
-      newImage.height = item.height.baseVal.value;
+      // fallback image for protocols not allowed (e.g., javascript:)
+      // or elements not [yet] handled (e.g., object, embed).
+      document.getElementById("brokenimagecontainer").collapsed = false;
+      document.getElementById("theimagecontainer").collapsed = true;
     }
 
-    width = newImage.width;
-    height = newImage.height;
-
-    document.getElementById("theimagecontainer").collapsed = false
-    document.getElementById("brokenimagecontainer").collapsed = true;
-  }
-#ifdef MOZ_MEDIA
-  else if (item instanceof HTMLVideoElement && isProtocolAllowed) {
-    newImage = document.createElementNS("http://www.w3.org/1999/xhtml", "video");
-    newImage.id = "thepreviewimage";
-    newImage.mozLoadFrom(item);
-    newImage.controls = true;
-    width = physWidth = item.videoWidth;
-    height = physHeight = item.videoHeight;
-
-    document.getElementById("theimagecontainer").collapsed = false;
-    document.getElementById("brokenimagecontainer").collapsed = true;
-  }
-  else if (item instanceof HTMLAudioElement && isProtocolAllowed) {
-    newImage = new Audio;
-    newImage.id = "thepreviewimage";
-    newImage.src = url;
-    newImage.controls = true;
-    isAudio = true;
+    var imageSize = "";
+    if (url && !isAudio) {
+      if (width != physWidth || height != physHeight) {
+        imageSize = gBundle.getFormattedString("mediaDimensionsScaled",
+                                               [formatNumber(physWidth),
+                                                formatNumber(physHeight),
+                                                formatNumber(width),
+                                                formatNumber(height)]);
+      }
+      else {
+        imageSize = gBundle.getFormattedString("mediaDimensions",
+                                               [formatNumber(width),
+                                                formatNumber(height)]);
+      }
+    }
+    setItemValue("imagedimensiontext", imageSize);
 
-    document.getElementById("theimagecontainer").collapsed = false;
-    document.getElementById("brokenimagecontainer").collapsed = true;
-  }
-#endif
-  else {
-    // fallback image for protocols not allowed (e.g., javascript:)
-    // or elements not [yet] handled (e.g., object, embed).
-    document.getElementById("brokenimagecontainer").collapsed = false;
-    document.getElementById("theimagecontainer").collapsed = true;
-  }
+    makeBlockImage(url);
 
-  var imageSize = "";
-  if (url && !isAudio) {
-    if (width != physWidth || height != physHeight) {
-      imageSize = gBundle.getFormattedString("mediaDimensionsScaled",
-                                             [formatNumber(physWidth),
-                                              formatNumber(physHeight),
-                                              formatNumber(width),
-                                              formatNumber(height)]);
-    }
-    else {
-      imageSize = gBundle.getFormattedString("mediaDimensions",
-                                             [formatNumber(width),
-                                              formatNumber(height)]);
-    }
-  }
-  setItemValue("imagedimensiontext", imageSize);
+    imageContainer.removeChild(oldImage);
+    imageContainer.appendChild(newImage);
 
-  makeBlockImage(url);
-
-  imageContainer.removeChild(oldImage);
-  imageContainer.appendChild(newImage);
+    onImagePreviewShown.forEach(function(func) { func(); });
+  });
 }
 
 function makeBlockImage(url)
 {
   var permissionManager = Components.classes[PERMISSION_CONTRACTID]
                                     .getService(nsIPermissionManager);
   var prefs = Components.classes[PREFERENCES_CONTRACTID]
                         .getService(Components.interfaces.nsIPrefBranch);
--- a/browser/base/content/test/browser_bug435325.js
+++ b/browser/base/content/test/browser_bug435325.js
@@ -1,21 +1,29 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /* Ensure that clicking the button in the Offline mode neterror page makes the browser go online. See bug 435325. */
 
+let proxyPrefValue;
+
 function test() {
   waitForExplicitFinish();
 
   gBrowser.selectedTab = gBrowser.addTab();
   window.addEventListener("DOMContentLoaded", checkPage, false);
 
-  // Go offline and disable the cache, then try to load the test URL.
+  // Go offline and disable the proxy and cache, then try to load the test URL.
   Services.io.offline = true;
+
+  // Tests always connect to localhost, and per bug 87717, localhost is now
+  // reachable in offline mode.  To avoid this, disable any proxy.
+  proxyPrefValue = Services.prefs.getIntPref("network.proxy.type");
+  Services.prefs.setIntPref("network.proxy.type", 0);
+
   Services.prefs.setBoolPref("browser.cache.disk.enable", false);
   Services.prefs.setBoolPref("browser.cache.memory.enable", false);
   content.location = "http://example.com/";
 }
 
 function checkPage() {
   if(content.location == "about:blank") {
     info("got about:blank, which is expected once, so return");
@@ -35,13 +43,14 @@ function checkPage() {
 
   ok(!Services.io.offline, "After clicking the Try Again button, we're back " +
                            "online.");
 
   finish();
 }
 
 registerCleanupFunction(function() {
+  Services.prefs.setIntPref("network.proxy.type", proxyPrefValue);
   Services.prefs.setBoolPref("browser.cache.disk.enable", true);
   Services.prefs.setBoolPref("browser.cache.memory.enable", true);
   Services.io.offline = false;
   gBrowser.removeCurrentTab();
 });
--- a/browser/base/content/test/browser_bug517902.js
+++ b/browser/base/content/test/browser_bug517902.js
@@ -9,17 +9,17 @@ function test() {
     gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
 
     var doc = gBrowser.contentDocument;
     var testImg = doc.getElementById("test-image");
     var pageInfo = BrowserPageInfo(doc, "mediaTab", testImg);
 
     pageInfo.addEventListener("load", function () {
       pageInfo.removeEventListener("load", arguments.callee, true);
-      pageInfo.onFinished.push(function () {
+      pageInfo.onImagePreviewShown.push(function () {
         executeSoon(function () {
           var pageInfoImg = pageInfo.document.getElementById("thepreviewimage");
 
           is(pageInfoImg.src, testImg.src, "selected image has the correct source");
           is(pageInfoImg.width, testImg.width, "selected image has the correct width");
           is(pageInfoImg.height, testImg.height, "selected image has the correct height");
 
           pageInfo.close();
--- a/browser/base/content/test/subtst_contextmenu.html
+++ b/browser/base/content/test/subtst_contextmenu.html
@@ -57,11 +57,12 @@ Browser context menu subtest.
     <menu>
     </menu>
     <menuitem label="Hidden item" hidden></menuitem>
     <menuitem></menuitem>
   </menu>
 </div>
 <div id="test-select-text">Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</div>
 <div id="test-select-text-link">http://mozilla.com</div>
+<a id="test-image-link" href="#"><img src="ctxmenu-image.png"></a>
 
 </body>
 </html>
--- a/browser/base/content/test/test_contextmenu.html
+++ b/browser/base/content/test/test_contextmenu.html
@@ -753,16 +753,41 @@ function runTest(testNum) {
                             "context-copy",                        true,
                             "context-selectall",                   true,
                             "---",                                 null,
                             "context-searchselect",                true,
                             "context-viewpartialsource-selection", true
                            ].concat(inspectItems));
         }
         closeContextMenu();
+        // clear the selection because following tests don't expect any selection
+        subwindow.getSelection().removeAllRanges();
+
+        openContextMenuFor(imagelink)
+        break;
+
+    case 26:
+        // Context menu for image link
+        checkContextMenu(["context-openlinkintab", true,
+                          "context-openlink",      true,
+                          "---",                   null,
+                          "context-bookmarklink",  true,
+                          "context-savelink",      true,
+                          "context-copylink",      true,
+                          "---",                   null,
+                          "context-viewimage",            true,
+                          "context-copyimage-contents",   true,
+                          "context-copyimage",            true,
+                          "---",                          null,
+                          "context-saveimage",            true,
+                          "context-sendimage",            true,
+                          "context-setDesktopBackground", true,
+                          "context-viewimageinfo",        true
+                         ].concat(inspectItems));
+        closeContextMenu();
 
         subwindow.close();
         SimpleTest.finish();
         return;
 
     /*
      * Other things that would be nice to test:
      *  - spelling / misspelled word (in text input?)
@@ -779,17 +804,18 @@ function runTest(testNum) {
 
 }
 
 
 var testNum = 1;
 var subwindow, chromeWin, contextMenu, lastElement;
 var text, link, mailto, input, img, canvas, video_ok, video_bad, video_bad2,
     iframe, video_in_iframe, image_in_iframe, textarea, contenteditable,
-    inputspell, pagemenu, dom_full_screen, plainTextItems, audio_in_video;
+    inputspell, pagemenu, dom_full_screen, plainTextItems, audio_in_video,
+    imagelink;
 
 function startTest() {
     chromeWin = SpecialPowers.wrap(subwindow)
                     .QueryInterface(Ci.nsIInterfaceRequestor)
                     .getInterface(Ci.nsIWebNavigation)
                     .QueryInterface(Ci.nsIDocShellTreeItem)
                     .rootTreeItem
                     .QueryInterface(Ci.nsIInterfaceRequestor)
@@ -804,16 +830,17 @@ function startTest() {
       return;
     }
 
     subwindow.mozAllowFullScreen = true;
     lastElement = null;
 
     text   = subwindow.document.getElementById("test-text");
     link   = subwindow.document.getElementById("test-link");
+    imagelink = subwindow.document.getElementById("test-image-link");
     mailto = subwindow.document.getElementById("test-mailto");
     input  = subwindow.document.getElementById("test-input");
     img    = subwindow.document.getElementById("test-image");
     canvas = subwindow.document.getElementById("test-canvas");
     video_ok   = subwindow.document.getElementById("test-video-ok");
     audio_in_video = subwindow.document.getElementById("test-audio-in-video");
     video_bad  = subwindow.document.getElementById("test-video-bad");
     video_bad2 = subwindow.document.getElementById("test-video-bad2");
@@ -848,17 +875,17 @@ function waitForEvents(event)
     loaded = true;
   if (painted && loaded) {
     subwindow.removeEventListener("MozAfterPaint", waitForEvents, false);
     subwindow.onload = null;
     startTest();
   }
 }
 
-var subwindow = window.open("./subtst_contextmenu.html", "contextmenu-subtext", "width=600,height=700");
+var subwindow = window.open("./subtst_contextmenu.html", "contextmenu-subtext", "width=600,height=800");
 subwindow.addEventListener("MozAfterPaint", waitForEvents, false);
 subwindow.onload = waitForEvents;
 
 SimpleTest.waitForExplicitFinish();
 </script>
 </pre>
 </body>
 </html>
--- a/browser/config/tooltool-manifests/linux32/clang.manifest
+++ b/browser/config/tooltool-manifests/linux32/clang.manifest
@@ -4,14 +4,14 @@
 },
 {
 "size": 47,
 "digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
 "algorithm": "sha512",
 "filename": "setup.sh"
 },
 {
-"size": 69025199,
-"digest": "924354fcaa711a3aa5bdd17bcaa395e49025fa942cef5a4d710200d5c529c7a96778ad78d80db19c022695baafaeed36c4da047f21c2d02753adc2299d81c8eb",
+"size": 69252183,
+"digest": "565fef702482b2bf9de3cdb87273fb41ce2c746f586bbe7e7a9ba4f3c796e525f41acd4b10e9f91c986c20b0435bcad71d7203fa2139ab3a6617e62ac96818f0",
 "algorithm": "sha512",
 "filename": "clang.tar.bz2"
 }
 ]
--- a/browser/config/tooltool-manifests/linux64/clang.manifest
+++ b/browser/config/tooltool-manifests/linux64/clang.manifest
@@ -4,14 +4,14 @@
 },
 {
 "size": 47,
 "digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
 "algorithm": "sha512",
 "filename": "setup.sh"
 },
 {
-"size": 64382403,
-"digest": "c0f02f07d6a9bd1b8fb6e86db04866393a2b973c07ca6c5a99f8f5794dd3438be687547329cec800a046a4f4ff4cc34450bd0320b152715d6dd51c5713eb6af1",
+"size": 65214493,
+"digest": "9584ec012d55e2c755cd7cc83e574a7a565e93993e9f705462890f25914401dd3e92893b3a5f76a856d77037a7f1843a9fb7b65dc77c80f8e1a32210df0dd5fb",
 "algorithm": "sha512",
 "filename": "clang.tar.bz2"
 }
 ]
--- a/browser/config/tooltool-manifests/macosx32/releng.manifest
+++ b/browser/config/tooltool-manifests/macosx32/releng.manifest
@@ -4,14 +4,14 @@
 },
 {
 "size": 47,
 "digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
 "algorithm": "sha512",
 "filename": "setup.sh"
 },
 {
-"size": 57249339,
-"digest": "708bf18f40edd46517c6368b6b5ad5cd05904d3c60614cdb483248e035cdca0fc905f0e72e90d94de9dccaa18270aadfe07987ab95adcc0c6bb4ce51aa292623",
+"size": 57746646,
+"digest": "e1d76c4c9d12edfba0d7c8db4cd37669d90e6824ee3d1f949dddc0f168815b115f9809a335d3ee0025432df995f898d9dc7545ee89e499944ed84e2407fc54b8",
 "algorithm": "sha512",
 "filename": "clang.tar.bz2"
 }
 ]
--- a/browser/config/tooltool-manifests/macosx64/releng.manifest
+++ b/browser/config/tooltool-manifests/macosx64/releng.manifest
@@ -4,14 +4,14 @@
 },
 {
 "size": 47,
 "digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
 "algorithm": "sha512",
 "filename": "setup.sh"
 },
 {
-"size": 57249339,
-"digest": "708bf18f40edd46517c6368b6b5ad5cd05904d3c60614cdb483248e035cdca0fc905f0e72e90d94de9dccaa18270aadfe07987ab95adcc0c6bb4ce51aa292623",
+"size": 57746646,
+"digest": "e1d76c4c9d12edfba0d7c8db4cd37669d90e6824ee3d1f949dddc0f168815b115f9809a335d3ee0025432df995f898d9dc7545ee89e499944ed84e2407fc54b8",
 "algorithm": "sha512",
 "filename": "clang.tar.bz2"
 }
 ]
--- a/browser/locales/en-US/chrome/browser/browser.dtd
+++ b/browser/locales/en-US/chrome/browser/browser.dtd
@@ -445,17 +445,17 @@ These should match what Safari and other
 <!ENTITY saveLinkCmd.accesskey        "k">
 <!ENTITY saveImageCmd.label           "Save Image As…">
 <!ENTITY saveImageCmd.accesskey       "v">
 <!ENTITY saveVideoCmd.label           "Save Video As…">
 <!ENTITY saveVideoCmd.accesskey       "v">
 <!ENTITY saveAudioCmd.label           "Save Audio As…">
 <!ENTITY saveAudioCmd.accesskey       "v">
 <!ENTITY emailImageCmd.label          "Email Image…">
-<!ENTITY emailImageCmd.accesskey      "a">
+<!ENTITY emailImageCmd.accesskey      "g">
 <!ENTITY emailVideoCmd.label          "Email Video…">
 <!ENTITY emailVideoCmd.accesskey      "a">
 <!ENTITY emailAudioCmd.label          "Email Audio…">
 <!ENTITY emailAudioCmd.accesskey      "a">
 <!ENTITY copyLinkCmd.label            "Copy Link Location">
 <!ENTITY copyLinkCmd.accesskey        "a">
 <!ENTITY copyImageCmd.label           "Copy Image Location">
 <!ENTITY copyImageCmd.accesskey       "o">
--- a/browser/modules/webappsUI.jsm
+++ b/browser/modules/webappsUI.jsm
@@ -24,16 +24,17 @@ let webappsUI = {
   uninit: function webappsUI_uninit() {
     Services.obs.removeObserver(this, "webapps-ask-install");
     Services.obs.removeObserver(this, "webapps-launch");
     Services.obs.removeObserver(this, "webapps-uninstall");
   },
 
   observe: function webappsUI_observe(aSubject, aTopic, aData) {
     let data = JSON.parse(aData);
+    data.mm = aSubject;
 
     switch(aTopic) {
       case "webapps-ask-install":
         let [chromeWin, browser] = this._getBrowserForId(data.oid);
         if (chromeWin)
           this.doInstall(data, browser, chromeWin);
         break;
       case "webapps-launch":
--- a/build/unix/build-clang/build-clang.py
+++ b/build/unix/build-clang/build-clang.py
@@ -123,19 +123,19 @@ if not os.path.exists(source_dir):
     svn_co("http://llvm.org/svn/llvm-project/llvm/trunk",
            llvm_source_dir, llvm_revision)
     svn_co("http://llvm.org/svn/llvm-project/cfe/trunk",
            clang_source_dir, llvm_revision)
     svn_co("http://llvm.org/svn/llvm-project/compiler-rt/trunk",
            compiler_rt_source_dir, llvm_revision)
     os.symlink("../../clang", llvm_source_dir + "/tools/clang")
     os.symlink("../../compiler-rt", llvm_source_dir + "/projects/compiler-rt")
+    patch("llvm-debug-frame.patch", 1, llvm_source_dir)
     if not isDarwin:
         patch("old-ld-hack.patch", 1, llvm_source_dir)
-        patch("llvm-debug-frame.patch", 1, llvm_source_dir)
         patch("compiler-rt-gnu89-inline.patch", 0, compiler_rt_source_dir)
         patch("no-sse-on-linux.patch", 1, clang_source_dir)
 
 if os.path.exists(build_dir):
     shutil.rmtree(build_dir)
 os.makedirs(build_dir)
 
 stage1_dir = build_dir + '/stage1'
--- a/configure.in
+++ b/configure.in
@@ -2278,16 +2278,17 @@ ia64*-hpux*)
 
         if test $_MSC_VER -ge 1400; then
             LDFLAGS="$LDFLAGS -SAFESEH"
         fi
 
         if test -n "$GNU_CC"; then
             CFLAGS="$CFLAGS -mstackrealign -fno-keep-inline-dllexport"
             CXXFLAGS="$CXXFLAGS -mstackrealign -fno-keep-inline-dllexport"
+            LDFLAGS="$LDFLAGS -Wl,--enable-stdcall-fixup"
         else
             AC_DEFINE(HAVE_STDCALL)
             DSO_LDOPTS="$DSO_LDOPTS -MACHINE:X86"
         fi
 
         MOZ_CHECK_HEADERS(mmintrin.h)
     	AC_DEFINE(_X86_)
 	;;
@@ -5720,17 +5721,17 @@ MOZ_ARG_DISABLE_BOOL(webgl,
     MOZ_WEBGL_DISABLED=1,
     MOZ_WEBGL_DISABLED=)
 
 if test -n "$MOZ_WEBGL_DISABLED"; then
   MOZ_WEBGL=
   MOZ_ANGLE_RENDERER=
 fi
 
-if test -n "$MOZ_ANGLE_RENDERER"; then
+if test -n "$MOZ_ANGLE_RENDERER" -a -z "$CROSS_COMPILE"; then
   # Get the SDK path from the registry.
   # First try to get the June 2010 SDK
   MOZ_DIRECTX_SDK_REG_KEY=`reg query 'HKLM\Software\Microsoft\DirectX' //s | grep 'Microsoft DirectX SDK (June 2010)' | head -n 1`
   if test -z "$MOZ_DIRECTX_SDK_REG_KEY" ; then
     # Otherwise just take whatever comes first
     MOZ_DIRECTX_SDK_REG_KEY=`reg query 'HKLM\Software\Microsoft\DirectX' //s | grep 'Microsoft DirectX SDK' | head -n 1`
   fi
 
--- a/content/base/public/nsIScriptElement.h
+++ b/content/base/public/nsIScriptElement.h
@@ -12,18 +12,18 @@
 #include "nsIScriptLoaderObserver.h"
 #include "nsWeakPtr.h"
 #include "nsIParser.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsIDOMHTMLScriptElement.h"
 #include "mozilla/CORSMode.h"
 
 #define NS_ISCRIPTELEMENT_IID \
-{ 0x24ab3ff2, 0xd75e, 0x4be4, \
-  { 0x8d, 0x50, 0xd6, 0x75, 0x31, 0x29, 0xab, 0x65 } }
+{ 0x491628bc, 0xce7c, 0x4db4, \
+ { 0x93, 0x3f, 0xce, 0x1b, 0x75, 0xee, 0x75, 0xce } }
 
 /**
  * Internal interface implemented by script elements
  */
 class nsIScriptElement : public nsIScriptLoaderObserver {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISCRIPTELEMENT_IID)
 
@@ -230,16 +230,21 @@ public:
    * Get the CORS mode of the script element
    */
   virtual mozilla::CORSMode GetCORSMode() const
   {
     /* Default to no CORS */
     return mozilla::CORS_NONE;
   }
 
+  /**
+   * Fire an error event
+   */
+  virtual nsresult FireErrorEvent() = 0;
+
 protected:
   /**
    * Processes the script if it's in the document-tree and links to or
    * contains a script. Once it has been evaluated there is no way to make it
    * reevaluate the script, you'll have to create a new element. This also means
    * that when adding a src attribute to an element that already contains an
    * inline script, the script referenced by the src attribute will not be
    * loaded.
--- a/content/base/src/nsCrossSiteListenerProxy.cpp
+++ b/content/base/src/nsCrossSiteListenerProxy.cpp
@@ -341,91 +341,59 @@ void
 nsCORSListenerProxy::Shutdown()
 {
   delete sPreflightCache;
   sPreflightCache = nullptr;
 }
 
 nsCORSListenerProxy::nsCORSListenerProxy(nsIStreamListener* aOuter,
                                          nsIPrincipal* aRequestingPrincipal,
-                                         nsIChannel* aChannel,
-                                         bool aWithCredentials,
-                                         nsresult* aResult)
+                                         bool aWithCredentials)
   : mOuterListener(aOuter),
     mRequestingPrincipal(aRequestingPrincipal),
     mWithCredentials(aWithCredentials && !gDisableCORSPrivateData),
     mRequestApproved(false),
     mHasBeenCrossSite(false),
     mIsPreflight(false)
 {
-  aChannel->GetNotificationCallbacks(getter_AddRefs(mOuterNotificationCallbacks));
-  aChannel->SetNotificationCallbacks(this);
-
-  *aResult = UpdateChannel(aChannel);
-  if (NS_FAILED(*aResult)) {
-    mOuterListener = nullptr;
-    mRequestingPrincipal = nullptr;
-    mOuterNotificationCallbacks = nullptr;
-  }
 }
 
 nsCORSListenerProxy::nsCORSListenerProxy(nsIStreamListener* aOuter,
                                          nsIPrincipal* aRequestingPrincipal,
-                                         nsIChannel* aChannel,
-                                         bool aWithCredentials,
-                                         bool aAllowDataURI,
-                                         nsresult* aResult)
-  : mOuterListener(aOuter),
-    mRequestingPrincipal(aRequestingPrincipal),
-    mWithCredentials(aWithCredentials && !gDisableCORSPrivateData),
-    mRequestApproved(false),
-    mHasBeenCrossSite(false),
-    mIsPreflight(false)
-{
-  aChannel->GetNotificationCallbacks(getter_AddRefs(mOuterNotificationCallbacks));
-  aChannel->SetNotificationCallbacks(this);
-
-  *aResult = UpdateChannel(aChannel, aAllowDataURI);
-  if (NS_FAILED(*aResult)) {
-    mOuterListener = nullptr;
-    mRequestingPrincipal = nullptr;
-    mOuterNotificationCallbacks = nullptr;
-  }
-}
-
-nsCORSListenerProxy::nsCORSListenerProxy(nsIStreamListener* aOuter,
-                                         nsIPrincipal* aRequestingPrincipal,
-                                         nsIChannel* aChannel,
                                          bool aWithCredentials,
                                          const nsCString& aPreflightMethod,
-                                         const nsTArray<nsCString>& aPreflightHeaders,
-                                         nsresult* aResult)
+                                         const nsTArray<nsCString>& aPreflightHeaders)
   : mOuterListener(aOuter),
     mRequestingPrincipal(aRequestingPrincipal),
     mWithCredentials(aWithCredentials && !gDisableCORSPrivateData),
     mRequestApproved(false),
     mHasBeenCrossSite(false),
     mIsPreflight(true),
     mPreflightMethod(aPreflightMethod),
     mPreflightHeaders(aPreflightHeaders)
 {
   for (uint32_t i = 0; i < mPreflightHeaders.Length(); ++i) {
     ToLowerCase(mPreflightHeaders[i]);
   }
   mPreflightHeaders.Sort();
+}
 
+nsresult
+nsCORSListenerProxy::Init(nsIChannel* aChannel, bool aAllowDataURI)
+{
   aChannel->GetNotificationCallbacks(getter_AddRefs(mOuterNotificationCallbacks));
   aChannel->SetNotificationCallbacks(this);
 
-  *aResult = UpdateChannel(aChannel);
-  if (NS_FAILED(*aResult)) {
+  nsresult rv = UpdateChannel(aChannel, aAllowDataURI);
+  if (NS_FAILED(rv)) {
     mOuterListener = nullptr;
     mRequestingPrincipal = nullptr;
     mOuterNotificationCallbacks = nullptr;
   }
+  return rv;
 }
 
 NS_IMETHODIMP
 nsCORSListenerProxy::OnStartRequest(nsIRequest* aRequest,
                                     nsISupports* aContext)
 {
   mRequestApproved = NS_SUCCEEDED(CheckRequestApproved(aRequest));
   if (!mRequestApproved) {
@@ -1086,22 +1054,23 @@ NS_StartCORSPreflight(nsIChannel* aReque
   NS_ENSURE_SUCCESS(rv, rv);
   
   // Set up listener which will start the original channel
   nsCOMPtr<nsIStreamListener> preflightListener =
     new nsCORSPreflightListener(aRequestChannel, aListener, nullptr, aPrincipal,
                                 method, aWithCredentials);
   NS_ENSURE_TRUE(preflightListener, NS_ERROR_OUT_OF_MEMORY);
 
-  preflightListener =
+  nsRefPtr<nsCORSListenerProxy> corsListener =
     new nsCORSListenerProxy(preflightListener, aPrincipal,
-                            preflightChannel, aWithCredentials,
-                            method, aUnsafeHeaders, &rv);
-  NS_ENSURE_TRUE(preflightListener, NS_ERROR_OUT_OF_MEMORY);
+                            aWithCredentials, method,
+                            aUnsafeHeaders);
+  rv = corsListener->Init(preflightChannel);
   NS_ENSURE_SUCCESS(rv, rv);
+  preflightListener = corsListener;
 
   // Start preflight
   rv = preflightChannel->AsyncOpen(preflightListener, nullptr);
   NS_ENSURE_SUCCESS(rv, rv);
   
   // Return newly created preflight channel
   preflightChannel.forget(aPreflightChannel);
 
--- a/content/base/src/nsCrossSiteListenerProxy.h
+++ b/content/base/src/nsCrossSiteListenerProxy.h
@@ -35,45 +35,37 @@ NS_StartCORSPreflight(nsIChannel* aReque
 class nsCORSListenerProxy MOZ_FINAL : public nsIStreamListener,
                                       public nsIInterfaceRequestor,
                                       public nsIChannelEventSink,
                                       public nsIAsyncVerifyRedirectCallback
 {
 public:
   nsCORSListenerProxy(nsIStreamListener* aOuter,
                       nsIPrincipal* aRequestingPrincipal,
-                      nsIChannel* aChannel,
-                      bool aWithCredentials,
-                      nsresult* aResult);
+                      bool aWithCredentials);
   nsCORSListenerProxy(nsIStreamListener* aOuter,
                       nsIPrincipal* aRequestingPrincipal,
-                      nsIChannel* aChannel,
-                      bool aWithCredentials,
-                      bool aAllowDataURI,
-                      nsresult* aResult);
-  nsCORSListenerProxy(nsIStreamListener* aOuter,
-                      nsIPrincipal* aRequestingPrincipal,
-                      nsIChannel* aChannel,
                       bool aWithCredentials,
                       const nsCString& aPreflightMethod,
-                      const nsTArray<nsCString>& aPreflightHeaders,
-                      nsresult* aResult);
+                      const nsTArray<nsCString>& aPreflightHeaders);
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIINTERFACEREQUESTOR
   NS_DECL_NSICHANNELEVENTSINK
   NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
 
   // Must be called at startup.
   static void Startup();
 
   static void Shutdown();
 
+  nsresult Init(nsIChannel* aChannel, bool aAllowDataURI = false);
+
 private:
   nsresult UpdateChannel(nsIChannel* aChannel, bool aAllowDataURI = false);
   nsresult CheckRequestApproved(nsIRequest* aRequest);
 
   nsCOMPtr<nsIStreamListener> mOuterListener;
   nsCOMPtr<nsIPrincipal> mRequestingPrincipal;
   nsCOMPtr<nsIInterfaceRequestor> mOuterNotificationCallbacks;
   bool mWithCredentials;
--- a/content/base/src/nsDOMFileReader.cpp
+++ b/content/base/src/nsDOMFileReader.cpp
@@ -405,17 +405,27 @@ nsDOMFileReader::ReadFileContent(JSConte
     // After the channel is created it will own whatever is backing
     // the DOMFile.
     nsDOMFileInternalUrlHolder urlHolder(mFile, mPrincipal);
 
     nsCOMPtr<nsIURI> uri;
     rv = NS_NewURI(getter_AddRefs(uri), urlHolder.mUrl);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    rv = NS_NewChannel(getter_AddRefs(mChannel), uri);
+    nsCOMPtr<nsILoadGroup> loadGroup;
+    if (HasOrHasHadOwner()) {
+      NS_ENSURE_STATE(GetOwner());
+      nsIDocument* doc = GetOwner()->GetExtantDoc();
+      if (doc) {
+        loadGroup = doc->GetDocumentLoadGroup();
+      }
+    }
+
+    rv = NS_NewChannel(getter_AddRefs(mChannel), uri, nullptr, loadGroup,
+                       nullptr, nsIRequest::LOAD_BACKGROUND);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   //Obtain the total size of the file before reading
   mTotal = mozilla::dom::kUnknownSize;
   mFile->GetSize(&mTotal);
 
   rv = mChannel->AsyncOpen(this, nullptr);
--- a/content/base/src/nsEventSource.cpp
+++ b/content/base/src/nsEventSource.cpp
@@ -898,19 +898,19 @@ nsEventSource::InitChannelAndRequestEven
 
   nsCOMPtr<nsIInterfaceRequestor> notificationCallbacks;
   mHttpChannel->GetNotificationCallbacks(getter_AddRefs(notificationCallbacks));
   if (notificationCallbacks != this) {
     mNotificationCallbacks = notificationCallbacks;
     mHttpChannel->SetNotificationCallbacks(this);
   }
 
-  nsCOMPtr<nsIStreamListener> listener =
-    new nsCORSListenerProxy(this, mPrincipal, mHttpChannel,
-                            mWithCredentials, &rv);
+  nsRefPtr<nsCORSListenerProxy> listener =
+    new nsCORSListenerProxy(this, mPrincipal, mWithCredentials);
+  rv = listener->Init(mHttpChannel);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Start reading from the channel
   rv = mHttpChannel->AsyncOpen(listener, nullptr);
   if (NS_SUCCEEDED(rv)) {
     mWaitingForOnStopRequest = true;
   }
   return rv;
--- a/content/base/src/nsScriptElement.cpp
+++ b/content/base/src/nsScriptElement.cpp
@@ -20,27 +20,32 @@ using namespace mozilla::dom;
 NS_IMETHODIMP
 nsScriptElement::ScriptAvailable(nsresult aResult,
                                  nsIScriptElement *aElement,
                                  bool aIsInline,
                                  nsIURI *aURI,
                                  int32_t aLineNo)
 {
   if (!aIsInline && NS_FAILED(aResult)) {
-    nsCOMPtr<nsIContent> cont =
-      do_QueryInterface((nsIScriptElement*) this);
+    return FireErrorEvent();
+  }
+  return NS_OK;
+}
 
-    return nsContentUtils::DispatchTrustedEvent(cont->OwnerDoc(),
-                                                cont,
-                                                NS_LITERAL_STRING("error"),
-                                                false /* bubbles */,
-                                                false /* cancelable */);
-  }
+/* virtual */ nsresult
+nsScriptElement::FireErrorEvent()
+{
+  nsCOMPtr<nsIContent> cont =
+    do_QueryInterface((nsIScriptElement*) this);
 
-  return NS_OK;
+  return nsContentUtils::DispatchTrustedEvent(cont->OwnerDoc(),
+                                              cont,
+                                              NS_LITERAL_STRING("error"),
+                                              false /* bubbles */,
+                                              false /* cancelable */);
 }
 
 NS_IMETHODIMP
 nsScriptElement::ScriptEvaluated(nsresult aResult,
                                  nsIScriptElement *aElement,
                                  bool aIsInline)
 {
   nsresult rv = NS_OK;
--- a/content/base/src/nsScriptElement.h
+++ b/content/base/src/nsScriptElement.h
@@ -26,16 +26,18 @@ public:
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
 
   nsScriptElement(mozilla::dom::FromParser aFromParser)
     : nsIScriptElement(aFromParser)
   {
   }
 
+  virtual nsresult FireErrorEvent();
+
 protected:
   // Internal methods
 
   /**
    * Check if this element contains any script, linked or inline
    */
   virtual bool HasScriptContent() = 0;
 
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -315,20 +315,22 @@ nsScriptLoader::StartLoad(nsScriptLoadRe
   nsCOMPtr<nsIStreamLoader> loader;
   rv = NS_NewStreamLoader(getter_AddRefs(loader), this);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIStreamListener> listener = loader.get();
 
   if (aRequest->mCORSMode != CORS_NONE) {
     bool withCredentials = (aRequest->mCORSMode == CORS_USE_CREDENTIALS);
-    listener =
-      new nsCORSListenerProxy(listener, mDocument->NodePrincipal(), channel,
-                              withCredentials, &rv);
+    nsRefPtr<nsCORSListenerProxy> corsListener =
+      new nsCORSListenerProxy(listener, mDocument->NodePrincipal(),
+                              withCredentials);
+    rv = corsListener->Init(channel);
     NS_ENSURE_SUCCESS(rv, rv);
+    listener = corsListener;
   }
 
   rv = channel->AsyncOpen(listener, aRequest);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
@@ -475,16 +477,20 @@ nsScriptLoader::ProcessScriptElement(nsI
 
   // Step 14. in the HTML5 spec
   nsresult rv = NS_OK;
   nsRefPtr<nsScriptLoadRequest> request;
   if (aElement->GetScriptExternal()) {
     // external script
     nsCOMPtr<nsIURI> scriptURI = aElement->GetScriptURI();
     if (!scriptURI) {
+      // Asynchronously report the failure to create a URI object
+      NS_DispatchToCurrentThread(
+        NS_NewRunnableMethod(aElement,
+                             &nsIScriptElement::FireErrorEvent));
       return false;
     }
     CORSMode ourCORSMode = aElement->GetCORSMode();
     nsTArray<PreloadInfo>::index_type i =
       mPreloads.IndexOf(scriptURI.get(), 0, PreloadURIComparator());
     if (i != nsTArray<PreloadInfo>::NoIndex) {
       // preloaded
       // note that a script-inserted script can steal a preload!
@@ -509,17 +515,23 @@ nsScriptLoader::ProcessScriptElement(nsI
 
     if (!request) {
       // no usable preload
       request = new nsScriptLoadRequest(aElement, version, ourCORSMode);
       request->mURI = scriptURI;
       request->mIsInline = false;
       request->mLoading = true;
       rv = StartLoad(request, type);
-      NS_ENSURE_SUCCESS(rv, false);
+      if (NS_FAILED(rv)) {
+        // Asynchronously report the load failure
+        NS_DispatchToCurrentThread(
+          NS_NewRunnableMethod(aElement,
+                               &nsIScriptElement::FireErrorEvent));
+        return false;
+      }
     }
 
     request->mJSVersion = version;
 
     if (aElement->GetScriptAsync()) {
       mAsyncRequests.AppendElement(request);
       if (!request->mLoading) {
         // The script is available already. Run it ASAP when the event
--- a/content/base/src/nsSyncLoadService.cpp
+++ b/content/base/src/nsSyncLoadService.cpp
@@ -175,19 +175,21 @@ nsSyncLoader::LoadDocument(nsIChannel* a
 
     if (aForceToXML) {
         nsCOMPtr<nsIStreamListener> forceListener =
             new nsForceXMLListener(listener);
         listener.swap(forceListener);
     }
 
     if (aLoaderPrincipal) {
-        listener = new nsCORSListenerProxy(listener, aLoaderPrincipal,
-                                           mChannel, false, &rv);
+        nsRefPtr<nsCORSListenerProxy> corsListener =
+          new nsCORSListenerProxy(listener, aLoaderPrincipal, false);
+        rv = corsListener->Init(mChannel);
         NS_ENSURE_SUCCESS(rv, rv);
+        listener = corsListener;
     }
 
     if (aChannelIsSync) {
         rv = PushSyncStream(listener);
     }
     else {
         rv = PushAsyncStream(listener);
     }
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -2923,19 +2923,21 @@ nsXMLHttpRequest::Send(nsIVariant* aVari
 
   // 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);
+    nsRefPtr<nsCORSListenerProxy> corsListener =
+      new nsCORSListenerProxy(listener, mPrincipal, withCredentials);
+    rv = corsListener->Init(mChannel, true);
     NS_ENSURE_SUCCESS(rv, rv);
+    listener = corsListener;
   }
   else {
     // Because of bug 682305, we can't let listener be the XHR object itself
     // because JS wouldn't be able to use it. So if we haven't otherwise
     // created a listener around 'this', do so now.
 
     listener = new nsStreamListenerWrapper(listener);
   }
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -555,16 +555,17 @@ MOCHITEST_FILES_B = \
 		test_XHR_anon.html \
 		file_XHR_anon.sjs \
 		test_XHR_system.html \
 		test_XHR_parameters.html \
 		test_ipc_messagemanager_blob.html \
 		test_mixed_content_blocker.html \
 		file_mixed_content_main.html \
 		file_mixed_content_server.sjs \
+		test_bug789856.html \
 		$(NULL)
 
 MOCHITEST_CHROME_FILES =	\
 		test_bug357450.js \
 		$(NULL)
 
 MOCHITEST_FILES_PARTS = $(foreach s,A B,MOCHITEST_FILES_$(s))
 
--- a/content/base/test/test_bug606729.html
+++ b/content/base/test/test_bug606729.html
@@ -11,30 +11,42 @@ https://bugzilla.mozilla.org/show_bug.cg
 </head>
 <body>
 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=606729">Mozilla Bug 606729</a>
 <p id="display"></p>
 <div id="content" style="display: none">
   
 </div>
 <pre id="test">
+<script>
+  SimpleTest.waitForExplicitFinish();
+  var events = 0;
+  var expectedEvents = 2;
+  function eventFired() {
+    ++events;
+    if (events == expectedEvents) {
+      SimpleTest.finish();
+    }
+  }
+</script>
 <script
   src="data:"
-  onerror="ok(false, 'Script with src=data: should not fire onerror.');"
-  onload="ok(false, 'Script with src=data: should not fire onload.');"
+  onerror="ok(true, 'Script with src=data: should fire onerror.');
+           eventFired();"
+  onload="ok(false, 'Script with src=data: should not fire onload.');
+          eventFired();"
 >
 ok(false, "Script with src=data: should not run textContent.");
 </script>
 <script
   src="bogus:"
-  onerror="ok(false, 'Script with src=bogus: should not fire onerror.');"
-  onload="ok(false, 'Script with src=bogus: should not fire onload.');"
+  onerror="ok(true, 'Script with src=bogus: should fire onerror.');
+           eventFired();"
+  onload="ok(false, 'Script with src=bogus: should not fire onload.');
+          eventFired();"
 >
 ok(false, "Script with src=bogus: should not run textContent.");
 </script>
-<script class="testbody" type="text/javascript">
-ok(true, "Obligatory succeeding test assertion.");
-</script>
 </pre>
 </body>
 </html>
 
 
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug789856.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=789856
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 789856</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=789856">Mozilla Bug 789856</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 789856 **/
+SimpleTest.waitForExplicitFinish();
+
+var script = document.createElement("script");
+script.onload = function() {
+  ok(false, "This script should not load");
+  SimpleTest.finish();
+}
+script.onerror = function() {
+  ok(true, "This script should fail to load");
+  SimpleTest.finish();
+}
+// If neither one fires,  the test fails, as it should
+
+// Use a URL the test is not allowed to load
+script.src = "file:///tmp/"
+document.body.appendChild(script);
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/base/test/unit/test_error_codes.js
+++ b/content/base/test/unit/test_error_codes.js
@@ -35,17 +35,17 @@ function run_test_pt1() {
 
   try {
     ioService.manageOfflineStatus = false;
   }
   catch (e) {
   }
   ioService.offline = true;
 
-  gExpectedStatus = Components.results.NS_ERROR_DOCUMENT_NOT_CACHED;
+  gExpectedStatus = Components.results.NS_ERROR_OFFLINE;
   gNextTestFunc = run_test_pt2;
   dump("Testing error returned by async XHR when the network is offline\n");
   asyncXHR.load();
 }
 
 // connection refused
 function run_test_pt2() {
   var ioService = Components.classes["@mozilla.org/network/io-service;1"]
--- a/content/canvas/test/test_canvas.html
+++ b/content/canvas/test/test_canvas.html
@@ -5972,22 +5972,17 @@ ctx.fillStyle = '#0f0';
 ctx.fillRect(0, 0, 100, 50);
 
 var g = ctx.createLinearGradient(50, 25, 50, 25); // zero-length line (undefined direction)
 g.addColorStop(0, '#f00');
 g.addColorStop(1, '#f00');
 ctx.fillStyle = g;
 ctx.fillRect(0, 0, 100, 50);
 
-if (IsAzureEnabled() && IsAzureSkia()) {
-  isPixel(ctx, 40,20, 0,255,0,255, 2);
-} else {
-  todo_isPixel(ctx, 40,20, 0,255,0,255, 2);
-}
-
+todo_isPixel(ctx, 40,20, 0,255,0,255, 2);
 
 }
 </script>
 
 <!-- [[[ test_2d.gradient.linear.nonfinite.html ]]] -->
 
 <p>Canvas test: 2d.gradient.linear.nonfinite</p>
 <!-- Testing: createLinearGradient() throws NOT_SUPPORTED_ERR if arguments are not finite -->
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -1092,30 +1092,31 @@ nsresult nsHTMLMediaElement::LoadResourc
   // notification before OnStartRequest fires.  Necko guarantees that
   // OnStartRequest will eventually fire if we don't shut down first.
   nsRefPtr<MediaLoadListener> loadListener = new MediaLoadListener(this);
 
   channel->SetNotificationCallbacks(loadListener);
 
   nsCOMPtr<nsIStreamListener> listener;
   if (ShouldCheckAllowOrigin()) {
-    listener =
+    nsRefPtr<nsCORSListenerProxy> corsListener =
       new nsCORSListenerProxy(loadListener,
                               NodePrincipal(),
-                              channel,
-                              GetCORSMode() == CORS_USE_CREDENTIALS,
-                              &rv);
+                              GetCORSMode() == CORS_USE_CREDENTIALS);
+    rv = corsListener->Init(channel);
+    NS_ENSURE_SUCCESS(rv, rv);
+    listener = corsListener;
   } else {
     rv = nsContentUtils::GetSecurityManager()->
            CheckLoadURIWithPrincipal(NodePrincipal(),
                                      mLoadingSrc,
                                      nsIScriptSecurityManager::STANDARD);
     listener = loadListener;
+    NS_ENSURE_SUCCESS(rv, rv);
   }
-  NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIHttpChannel> hc = do_QueryInterface(channel);
   if (hc) {
     // Use a byte range request from the start of the resource.
     // This enables us to detect if the stream supports byte range
     // requests, and therefore seeking, early.
     hc->SetRequestHeader(NS_LITERAL_CSTRING("Range"),
                          NS_LITERAL_CSTRING("bytes=0-"),
--- a/content/html/content/test/test_bug371375.html
+++ b/content/html/content/test/test_bug371375.html
@@ -34,17 +34,17 @@ https://bugzilla.mozilla.org/show_bug.cg
   s2.onload = function() { load2Called = true; };
   s2.onerror = function(event) { error2Called = true; event.stopPropagation(); };
   s2.src = 'data:text/plain, var x = 1;'
   document.body.appendChild(s2);
 
   SimpleTest.waitForExplicitFinish();
   addLoadEvent(function() {
     is(load1Called, false, "Load handler should not be called");
-    is(error1Called, false, "Error handler should not be called");
+    is(error1Called, true, "Error handler should be called");
     is(load2Called, true, "Load handler for valid script should be called");
     is(error2Called, false,
        "Error handler for valid script should not be called");
     SimpleTest.finish();
   });
 </script>
 </body>
 </html>
--- a/content/media/MediaResource.cpp
+++ b/content/media/MediaResource.cpp
@@ -441,23 +441,21 @@ nsresult ChannelMediaResource::OpenChann
 
     nsCOMPtr<nsIStreamListener> listener = mListener.get();
 
     // Ensure that if we're loading cross domain, that the server is sending
     // an authorizing Access-Control header.
     nsHTMLMediaElement* element = mDecoder->GetMediaElement();
     NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
     if (element->ShouldCheckAllowOrigin()) {
-      nsresult rv;
       nsCORSListenerProxy* crossSiteListener =
         new nsCORSListenerProxy(mListener,
                                 element->NodePrincipal(),
-                                mChannel,
-                                false,
-                                &rv);
+                                false);
+      nsresult rv = crossSiteListener->Init(mChannel);
       listener = crossSiteListener;
       NS_ENSURE_TRUE(crossSiteListener, NS_ERROR_OUT_OF_MEMORY);
       NS_ENSURE_SUCCESS(rv, rv);
     } else {
       nsresult rv = nsContentUtils::GetSecurityManager()->
         CheckLoadURIWithPrincipal(element->NodePrincipal(),
                                   mURI,
                                   nsIScriptSecurityManager::STANDARD);
--- a/content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp
+++ b/content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp
@@ -480,20 +480,19 @@ txCompileObserver::startLoad(nsIURI* aUr
 
     channel->SetNotificationCallbacks(sink);
 
     parser->SetCommand(kLoadAsData);
     parser->SetContentSink(sink);
     parser->Parse(aUri);
 
     // Always install in case of redirects
-    nsCOMPtr<nsIStreamListener> listener =
-        new nsCORSListenerProxy(sink, aReferrerPrincipal, channel,
-                                false, &rv);
-    NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
+    nsRefPtr<nsCORSListenerProxy> listener =
+        new nsCORSListenerProxy(sink, aReferrerPrincipal, false);
+    rv = listener->Init(channel);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return channel->AsyncOpen(listener, parser);
 }
 
 nsresult
 TX_LoadSheet(nsIURI* aUri, txMozillaXSLTProcessor* aProcessor,
              nsILoadGroup* aLoadGroup, nsIPrincipal* aCallerPrincipal)
--- a/docshell/base/SerializedLoadContext.cpp
+++ b/docshell/base/SerializedLoadContext.cpp
@@ -13,16 +13,21 @@ namespace IPC {
 
 SerializedLoadContext::SerializedLoadContext(nsILoadContext* aLoadContext)
 {
   Init(aLoadContext);
 }
 
 SerializedLoadContext::SerializedLoadContext(nsIChannel* aChannel)
 {
+  if (!aChannel) {
+    Init(nullptr);
+    return;
+  }
+
   nsCOMPtr<nsILoadContext> loadContext;
   NS_QueryNotificationCallbacks(aChannel, loadContext);
   Init(loadContext);
 
   if (!loadContext) {
     // Attempt to retrieve the private bit from the channel if it has been
     // overriden.
     bool isPrivate = false;
@@ -35,17 +40,19 @@ SerializedLoadContext::SerializedLoadCon
       mIsPrivateBitValid = true;
     }
   }
 }
 
 SerializedLoadContext::SerializedLoadContext(nsIWebSocketChannel* aChannel)
 {
   nsCOMPtr<nsILoadContext> loadContext;
-  NS_QueryNotificationCallbacks(aChannel, loadContext);
+  if (aChannel) {
+    NS_QueryNotificationCallbacks(aChannel, loadContext);
+  }
   Init(loadContext);
 }
 
 void
 SerializedLoadContext::Init(nsILoadContext* aLoadContext)
 {
   if (aLoadContext) {
     mIsNotNull = true;
--- a/docshell/test/chrome/Makefile.in
+++ b/docshell/test/chrome/Makefile.in
@@ -89,16 +89,17 @@ MOCHITEST_CHROME_FILES =	\
 		662200c.html \
 		test_bug690056.xul \
 		bug690056_window.xul \
 		test_bug311007.xul \
 		bug311007_window.xul \
 		test_principalInherit.xul \
 		test_mozFrameType.xul \
 		mozFrameType_window.xul \
+		test_bug789773.xul \
 		$(NULL)
 
 MOCHITEST_CHROME_FILES += \
     docshell_helpers.js \
     generic.html \
     $(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/docshell/test/chrome/test_bug789773.xul
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=789773
+-->
+<window title="Mozilla Bug 789773"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+
+  <!-- test results are displayed in the html:body -->
+  <body xmlns="http://www.w3.org/1999/xhtml">
+  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=789773"
+     target="_blank">Mozilla Bug 789773</a>
+  </body>
+
+  <!-- test code goes here -->
+  <script type="application/javascript">
+  <![CDATA[
+  const Cc = Components.classes;
+  const Ci = Components.interfaces;
+  const Cr = Components.results;
+  const Cu = Components.utils;
+
+  /* Test for Bug 789773.
+   *
+   * See comment 50 for the situation we're testing against here.
+   *
+   * Note that the failure mode of this test is to hang, and hang the browser on quit.
+   * This is an unfortunate occurance, but that's why we're testing it.
+   */
+  SimpleTest.waitForExplicitFinish();
+
+  var calledListenerForBrowserXUL = false;
+  var testProgressListener = {
+    START_DOC: Ci.nsIWebProgressListener.STATE_START | Ci.nsIWebProgressListener.STATE_IS_DOCUMENT,
+    onStateChange: function(wp, req, stateFlags, status) {
+      if (/browser.xul/.test(req.name)) {
+        wp.DOMWindow; // Force the lazy creation of a DOM window.
+        calledListenerForBrowserXUL = true;
+      }
+      if (/aboutHome.xhtml/.test(req.name) && (stateFlags & Ci.nsIWebProgressListener.STATE_STOP))
+        finishTest();
+    },
+    QueryInterface: function(iid) {
+      if (iid.equals(Ci.nsISupportsWeakReference) ||
+          iid.equals(Ci.nsIWebProgressListener))
+        return this;
+      throw Cr.NS_ERROR_NO_INTERFACE;
+    }
+  }
+
+   // Add our progress listener
+   var webProgress = Cc['@mozilla.org/docloaderservice;1'].getService(Ci.nsIWebProgress);
+   webProgress.addProgressListener(testProgressListener, Ci.nsIWebProgress.NOTIFY_STATE_REQUEST);
+
+   // Open the window.
+   var popup = window.open("about:home", "_blank", "width=640,height=400");
+
+   // Wait for the window to load.
+   function finishTest() {
+     webProgress.removeProgressListener(testProgressListener);
+     ok(true, "Loaded the popup window without spinning forever in the event loop!");
+     ok(calledListenerForBrowserXUL, "Should have called the progress listener for browser.xul");
+     popup.close();
+     SimpleTest.finish();
+   }
+
+  ]]>
+  </script>
+</window>
--- a/dom/apps/src/Webapps.js
+++ b/dom/apps/src/Webapps.js
@@ -63,16 +63,17 @@ WebappsRegistry.prototype = {
     if (!req)
       return;
     let app = msg.app;
     switch (aMessage.name) {
       case "Webapps:Install:Return:OK":
         Services.DOMRequest.fireSuccess(req, createApplicationObject(this._window, app));
         break;
       case "Webapps:Install:Return:KO":
+      dump("XxXxX Webapps:Install:Return:KO\n");
         Services.DOMRequest.fireError(req, msg.error || "DENIED");
         break;
       case "Webapps:GetSelf:Return:OK":
         if (msg.apps.length) {
           app = msg.apps[0];
           Services.DOMRequest.fireSuccess(req, createApplicationObject(this._window, app));
         } else {
           Services.DOMRequest.fireSuccess(req, null);
@@ -163,16 +164,18 @@ WebappsRegistry.prototype = {
   get mgmt() {
     if (!this._mgmt)
       this._mgmt = new WebappsApplicationMgmt(this._window);
     return this._mgmt;
   },
 
   uninit: function() {
     this._mgmt = null;
+    cpmm.sendAsyncMessage("Webapps:UnregisterForMessages",
+                          ["Webapps:Install:Return:OK"]);
   },
 
   // mozIDOMApplicationRegistry2 implementation
 
   installPackage: function(aPackageURL, aParams) {
     let request = this.createRequest();
     let requestID = this.getRequestId(request);
 
@@ -193,16 +196,18 @@ WebappsRegistry.prototype = {
   // nsIDOMGlobalPropertyInitializer implementation
   init: function(aWindow) {
     this.initHelper(aWindow, ["Webapps:Install:Return:OK", "Webapps:Install:Return:KO",
                               "Webapps:GetInstalled:Return:OK",
                               "Webapps:GetSelf:Return:OK", "Webapps:GetSelf:Return:KO"]);
 
     let util = this._window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
     this._id = util.outerWindowID;
+    cpmm.sendAsyncMessage("Webapps:RegisterForMessages",
+                          ["Webapps:Install:Return:OK"]);
   },
 
   classID: Components.ID("{fff440b3-fae2-45c1-bf03-3b5a2e432270}"),
 
   QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMApplicationRegistry,
 #ifdef MOZ_PHOENIX
 # Firefox Desktop: installPackage not implemented
 #elifdef ANDROID
@@ -265,16 +270,18 @@ WebappsApplication.prototype = {
     this.installTime = aApp.installTime;
     this.status = "installed";
     this.removable = aApp.removable;
     this.progress = NaN;
     this._onprogress = null;
     this.initHelper(aWindow, ["Webapps:Uninstall:Return:OK",
                               "Webapps:Uninstall:Return:KO",
                               "Webapps:OfflineCache"]);
+    cpmm.sendAsyncMessage("Webapps:RegisterForMessages",
+                          ["Webapps:Uninstall:Return:OK", "Webapps:OfflineCache"]);
   },
 
   set onprogress(aCallback) {
     this._onprogress = aCallback;
   },
 
   get onprogress() {
     return this._onprogress;
@@ -295,16 +302,18 @@ WebappsApplication.prototype = {
     cpmm.sendAsyncMessage("Webapps:Uninstall", { origin: this.origin,
                                                  oid: this._id,
                                                  requestID: this.getRequestId(request) });
     return request;
   },
 
   uninit: function() {
     this._onprogress = null;
+    cpmm.sendAsyncMessage("Webapps:UnregisterForMessages",
+                          ["Webapps:Uninstall:Return:OK", "Webapps:OfflineCache"]);
   },
 
   receiveMessage: function(aMessage) {
     var msg = aMessage.json;
     let req = this.takeRequest(msg.requestID);
     if ((msg.oid != this._id || !req) && aMessage.name !== "Webapps:OfflineCache")
       return;
     switch (aMessage.name) {
@@ -351,32 +360,37 @@ function WebappsApplicationMgmt(aWindow)
 
   //only pages with perm set can use some functions
   this.hasPrivileges = perm == Ci.nsIPermissionManager.ALLOW_ACTION;
 
   this.initHelper(aWindow, ["Webapps:GetAll:Return:OK", "Webapps:GetAll:Return:KO",
                             "Webapps:Install:Return:OK", "Webapps:Uninstall:Return:OK",
                             "Webapps:GetNotInstalled:Return:OK"]);
 
+  cpmm.sendAsyncMessage("Webapps:RegisterForMessages",
+                        ["Webapps:Install:Return:OK", "Webapps:Uninstall:Return:OK"]);
+
   this._oninstall = null;
   this._onuninstall = null;
 }
 
 WebappsApplicationMgmt.prototype = {
   __proto__: DOMRequestIpcHelper.prototype,
   __exposedProps__: {
                       getAll: 'r',
                       getNotInstalled: 'r',
                       oninstall: 'rw',
                       onuninstall: 'rw'
                      },
 
   uninit: function() {
     this._oninstall = null;
     this._onuninstall = null;
+    cpmm.sendAsyncMessage("Webapps:UnregisterForMessages",
+                          ["Webapps:Install:Return:OK", "Webapps:Uninstall:Return:OK"]);
   },
 
   getAll: function() {
     let request = this.createRequest();
     cpmm.sendAsyncMessage("Webapps:GetAll", { oid: this._id,
                                               requestID: this.getRequestId(request),
                                               hasPrivileges: this.hasPrivileges });
     return request;
--- a/dom/apps/src/Webapps.jsm
+++ b/dom/apps/src/Webapps.jsm
@@ -55,17 +55,18 @@ let DOMApplicationRegistry = {
   allAppsLaunchable: false,
 
   init: function() {
     this.messages = ["Webapps:Install", "Webapps:Uninstall",
                      "Webapps:GetSelf",
                      "Webapps:GetInstalled", "Webapps:GetNotInstalled",
                      "Webapps:Launch", "Webapps:GetAll",
                      "Webapps:InstallPackage", "Webapps:GetBasePath",
-                     "Webapps:GetList"];
+                     "Webapps:GetList", "Webapps:RegisterForMessages",
+                     "Webapps:UnregisterForMessages"];
 
     this.messages.forEach((function(msgName) {
       ppmm.addMessageListener(msgName, this);
     }).bind(this));
 
     Services.obs.addObserver(this, "xpcom-shutdown", false);
 
     this.appsFile = FileUtils.getFile(DIRECTORY_NAME,
@@ -314,62 +315,108 @@ let DOMApplicationRegistry = {
     } catch (ex) {
       Cu.reportError("DOMApplicationRegistry: Could not read from " +
                      aFile.path + " : " + ex);
       if (aCallback)
         aCallback(null);
     }
   },
 
+  addMessageListener: function(aMsgNames, aMm) {
+    aMsgNames.forEach(function (aMsgName) {
+      if (!(aMsgName in this.children)) {
+        this.children[aMsgName] = [];
+      }
+      this.children[aMsgName].push(aMm);
+    }, this);
+  },
+
+  removeMessageListener: function(aMsgNames, aMm) {
+    aMsgNames.forEach(function (aMsgName) {
+      if (!(aMsgName in this.children)) {
+        return;
+      }
+
+      let index;
+      if ((index = this.children[aMsgName].indexOf(aMm)) != -1) {
+        this.children[aMsgName].splice(index, 1);
+      }
+    }, this);
+  },
+
   receiveMessage: function(aMessage) {
     // nsIPrefBranch throws if pref does not exist, faster to simply write
     // the pref instead of first checking if it is false.
     Services.prefs.setBoolPref("dom.mozApps.used", true);
 
     let msg = aMessage.json;
+    let mm = aMessage.target;
+    msg.mm = mm;
 
     switch (aMessage.name) {
       case "Webapps:Install":
         // always ask for UI to install
-        Services.obs.notifyObservers(this, "webapps-ask-install", JSON.stringify(msg));
+        Services.obs.notifyObservers(mm, "webapps-ask-install", JSON.stringify(msg));
         break;
       case "Webapps:GetSelf":
-        this.getSelf(msg);
+        this.getSelf(msg, mm);
         break;
       case "Webapps:Uninstall":
-        Services.obs.notifyObservers(this, "webapps-uninstall", JSON.stringify(msg));
+        Services.obs.notifyObservers(mm, "webapps-uninstall", JSON.stringify(msg));
         this.uninstall(msg);
         break;
       case "Webapps:Launch":
-        Services.obs.notifyObservers(this, "webapps-launch", JSON.stringify(msg));
+        Services.obs.notifyObservers(mm, "webapps-launch", JSON.stringify(msg));
         break;
       case "Webapps:GetInstalled":
-        this.getInstalled(msg);
+        this.getInstalled(msg, mm);
         break;
       case "Webapps:GetNotInstalled":
-        this.getNotInstalled(msg);
+        this.getNotInstalled(msg, mm);
         break;
       case "Webapps:GetAll":
         if (msg.hasPrivileges)
-          this.getAll(msg);
+          this.getAll(msg, mm);
         else
-          ppmm.broadcastAsyncMessage("Webapps:GetAll:Return:KO", msg);
+          mm.sendAsyncMessage("Webapps:GetAll:Return:KO", msg);
         break;
       case "Webapps:InstallPackage":
-        this.installPackage(msg);
+        this.installPackage(msg, mm);
         break;
       case "Webapps:GetBasePath":
         return this.webapps[msg.id].basePath;
         break;
+      case "Webapps:RegisterForMessages":
+        this.addMessageListener(msg, mm);
+        break;
+      case "Webapps:UnregisterForMessages":
+        this.removeMessageListener(msg, mm);
+        break;
       case "Webapps:GetList":
-        this.children.push(aMessage.target);
+        this.addMessageListener(["Webapps:AddApp", "Webapps:RemoveApp"], mm);
         return this.webapps;
     }
   },
 
+  // Some messages can be listened by several content processes:
+  // Webapps:AddApp
+  // Webapps:RemoveApp
+  // Webapps:Install:Return:OK
+  // Webapps:Uninstall:Return:OK
+  // Webapps:OfflineCache
+  broadcastMessage: function broadcastMessage(aMsgName, aContent) {
+    if (!(aMsgName in this.children)) {
+      return;
+    }
+
+    this.children[aMsgName].forEach(function _doBroadcast(aMsgMgr) {
+      aMsgMgr.sendAsyncMessage(aMsgName, aContent);
+    });
+  },
+
   _getAppDir: function(aId) {
     return FileUtils.getDir(DIRECTORY_NAME, ["webapps", aId], true, true);
   },
 
   _writeFile: function ss_writeFile(aFile, aData, aCallbak) {
     // Initialize the file output stream.
     let ostream = FileUtils.openSafeFileOutputStream(aFile);
 
@@ -391,17 +438,17 @@ let DOMApplicationRegistry = {
     if (packageId) {
       let dir = FileUtils.getDir("TmpD", ["webapps", packageId],
                                  true, true);
       try {
         dir.remove(true);
       } catch(e) {
       }
     }
-    ppmm.broadcastAsyncMessage("Webapps:Install:Return:KO", aData);
+    aData.mm.sendAsyncMessage("Webapps:Install:Return:KO", aData);
   },
 
   confirmInstall: function(aData, aFromSync, aProfileDir, aOfflineCacheObserver) {
     let app = aData.app;
     app.removable = true;
     let id = app.syncId || this._appId(app.origin);
     let localId = this.getAppLocalIdByManifestURL(app.manifestURL);
 
@@ -453,21 +500,19 @@ let DOMApplicationRegistry = {
 
     appObject.status = "installed";
     appObject.name = app.manifest.name;
 
     let manifest = new DOMApplicationManifest(app.manifest, app.origin);
 
     if (!aFromSync)
       this._saveApps((function() {
-        ppmm.broadcastAsyncMessage("Webapps:Install:Return:OK", aData);
+        this.broadcastMessage("Webapps:Install:Return:OK", aData);
         Services.obs.notifyObservers(this, "webapps-sync-install", appNote);
-        this.children.forEach(function(aMsgMgr) {
-          aMsgMgr.sendAsyncMessage("Webapps:AddApp", { id: id, app: appObject });
-        });
+        this.broadcastMessage("Webapps:AddApp", { id: id, app: appObject });
       }).bind(this));
 
 #ifdef MOZ_SYS_MSG
     this._registerSystemMessages(app.manifest, app);
     this._registerActivities(app.manifest, app);
 #endif
 
     // if the manifest has an appcache_path property, use it to populate the appcache
@@ -534,17 +579,17 @@ let DOMApplicationRegistry = {
       aData[index].manifest = aJSON;
       if (index == aData.length - 1)
         aFinalCallback(aData);
       else
         this._readManifests(aData, aFinalCallback, index + 1);
     }).bind(this));
   },
 
-  installPackage: function(aData) {
+  installPackage: function(aData, aMm) {
     // Here are the steps when installing a package:
     // - create a temp directory where to store the app.
     // - download the zip in this directory.
     // - extract the manifest from the zip and check it.
     // - ask confirmation to the user.
     // - add the new app to the registry.
     // If we fail at any step, we backout the previous ones and return an error.
 
@@ -579,20 +624,20 @@ let DOMApplicationRegistry = {
       return true;
     }
 
     // Removes the directory we created, and sends an error to the DOM side.
     function cleanup(aError) {
       try {
         dir.remove(true);
       } catch (e) { }
-      ppmm.broadcastAsyncMessage("Webapps:Install:Return:KO",
-                            { oid: aData.oid,
-                              requestID: aData.requestID,
-                              error: aError });
+      aMm.sendAsyncMessage("Webapps:Install:Return:KO",
+                           { oid: aData.oid,
+                             requestID: aData.requestID,
+                             error: aError });
     }
 
     function getInferedStatus() {
       // XXX Update once we have digital signatures (bug 772365)
       return Ci.nsIPrincipal.APP_STATUS_INSTALLED;
     }
 
     function getAppManifestStatus(aManifest) {
@@ -720,101 +765,99 @@ let DOMApplicationRegistry = {
       let dir = this._getAppDir(id);
       try {
         dir.remove(true);
       } catch (e) {}
 
       delete this.webapps[id];
 
       this._saveApps((function() {
-        ppmm.broadcastAsyncMessage("Webapps:Uninstall:Return:OK", aData);
+        this.broadcastMessage("Webapps:Uninstall:Return:OK", aData);
         Services.obs.notifyObservers(this, "webapps-sync-uninstall", appNote);
-        this.children.forEach(function(aMsgMgr) {
-          aMsgMgr.broadcastAsyncMessage("Webapps:RemoveApp", { id: id });
-        });
+        this.broadcastMessage("Webapps:RemoveApp", { id: id });
       }).bind(this));
     }
 
     if (!found) {
-      ppmm.broadcastAsyncMessage("Webapps:Uninstall:Return:KO", aData);
+      aData.mm.broadcastMessage("Webapps:Uninstall:Return:KO", aData);
     }
   },
 
-  getSelf: function(aData) {
+  getSelf: function(aData, aMm) {
     aData.apps = [];
     let tmp = [];
     let id = this._appId(aData.origin);
 
     if (id && this._isLaunchable(this.webapps[id].origin)) {
       let app = AppsUtils.cloneAppObject(this.webapps[id]);
       aData.apps.push(app);
       tmp.push({ id: id });
     }
 
     this._readManifests(tmp, (function(aResult) {
       for (let i = 0; i < aResult.length; i++)
         aData.apps[i].manifest = aResult[i].manifest;
-      ppmm.broadcastAsyncMessage("Webapps:GetSelf:Return:OK", aData);
+      aMm.sendAsyncMessage("Webapps:GetSelf:Return:OK", aData);
     }).bind(this));
   },
 
-  getInstalled: function(aData) {
+  getInstalled: function(aData, aMm) {
     aData.apps = [];
     let tmp = [];
 
     for (let id in this.webapps) {
       if (this.webapps[id].installOrigin == aData.origin &&
           this._isLaunchable(this.webapps[id].origin)) {
         aData.apps.push(AppsUtils.cloneAppObject(this.webapps[id]));
         tmp.push({ id: id });
       }
     }
 
     this._readManifests(tmp, (function(aResult) {
       for (let i = 0; i < aResult.length; i++)
         aData.apps[i].manifest = aResult[i].manifest;
-      ppmm.broadcastAsyncMessage("Webapps:GetInstalled:Return:OK", aData);
+      aMm.sendAsyncMessage("Webapps:GetInstalled:Return:OK", aData);
     }).bind(this));
   },
 
-  getNotInstalled: function(aData) {
+  getNotInstalled: function(aData, aMm) {
     aData.apps = [];
     let tmp = [];
 
     for (let id in this.webapps) {
       if (!this._isLaunchable(this.webapps[id].origin)) {
         aData.apps.push(AppsUtils.cloneAppObject(this.webapps[id]));
         tmp.push({ id: id });
       }
     }
 
     this._readManifests(tmp, (function(aResult) {
       for (let i = 0; i < aResult.length; i++)
         aData.apps[i].manifest = aResult[i].manifest;
-      ppmm.broadcastAsyncMessage("Webapps:GetNotInstalled:Return:OK", aData);
+      aMm.sendAsyncMessage("Webapps:GetNotInstalled:Return:OK", aData);
     }).bind(this));
   },
 
-  getAll: function(aData) {
+  getAll: function(aData, aMm) {
     aData.apps = [];
     let tmp = [];
 
     for (let id in this.webapps) {
       let app = AppsUtils.cloneAppObject(this.webapps[id]);
       if (!this._isLaunchable(app.origin))
         continue;
 
       aData.apps.push(app);
       tmp.push({ id: id });
     }
 
     this._readManifests(tmp, (function(aResult) {
       for (let i = 0; i < aResult.length; i++)
         aData.apps[i].manifest = aResult[i].manifest;
-      ppmm.broadcastAsyncMessage("Webapps:GetAll:Return:OK", aData);
+      aMm.sendAsyncMessage("Webapps:GetAll:Return:OK", aData);
     }).bind(this));
   },
 
   getManifestFor: function(aOrigin, aCallback) {
     if (!aCallback)
       return;
 
     let id = this._appId(aOrigin);
@@ -878,25 +921,25 @@ let DOMApplicationRegistry = {
           continue;
         let origin = this.webapps[record.id].origin;
         delete this.webapps[record.id];
         let dir = this._getAppDir(record.id);
         try {
           dir.remove(true);
         } catch (e) {
         }
-        ppmm.broadcastAsyncMessage("Webapps:Uninstall:Return:OK", { origin: origin });
+        this.broadcastMessage("Webapps:Uninstall:Return:OK", { origin: origin });
       } else {
         if (this.webapps[record.id]) {
           this.webapps[record.id] = record.value;
           delete this.webapps[record.id].manifest;
         } else {
           let data = { app: record.value };
           this.confirmInstall(data, true);
-          ppmm.broadcastAsyncMessage("Webapps:Install:Return:OK", data);
+          this.broadcastMessage("Webapps:Install:Return:OK", data);
         }
       }
     }
     this._saveApps(aCallback);
   },
 
   getAllIDs: function() {
     let apps = {};
@@ -992,17 +1035,19 @@ AppcacheObserver.prototype = {
   // nsIOfflineCacheUpdateObserver implementation
   updateStateChanged: function appObs_Update(aUpdate, aState) {
     let mustSave = false;
     let app = this.app;
 
     let setStatus = function appObs_setStatus(aStatus) {
       mustSave = (app.status != aStatus);
       app.status = aStatus;
-      ppmm.broadcastAsyncMessage("Webapps:OfflineCache", { manifest: app.manifestURL, status: aStatus });
+      DOMApplicationRegistry.broadcastMessage("Webapps:OfflineCache",
+                                              { manifest: app.manifestURL,
+                                                status: aStatus });
     }
 
     switch (aState) {
       case Ci.nsIOfflineCacheUpdateObserver.STATE_ERROR:
         aUpdate.removeObserver(this);
         setStatus("cache-error");
         break;
       case Ci.nsIOfflineCacheUpdateObserver.STATE_NOUPDATE:
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -7446,18 +7446,16 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
     }
 
     if (sDialogArguments_id == id && win->IsModalContentWindow()) {
       nsCOMPtr<nsIArray> args;
       ((nsGlobalModalWindow *)win)->GetDialogArguments(getter_AddRefs(args));
 
       nsIScriptContext *script_cx = win->GetContext();
       if (script_cx) {
-        JSAutoSuspendRequest asr(cx);
-
         // Make nsJSContext::SetProperty()'s magic argument array
         // handling happen.
         rv = script_cx->SetProperty(obj, "dialogArguments", args);
         NS_ENSURE_SUCCESS(rv, rv);
 
         *objp = obj;
       }
 
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2257,41 +2257,16 @@ nsDOMWindowUtils::GetCursorType(int16_t 
 
   // fetch cursor value from window's widget
   *aCursor = widget->GetCursor();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDOMWindowUtils::GoOnline()
-{
-  // This is only allowed from about:neterror, which is unprivileged, so it
-  // can't access the io-service itself.
-  nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
-  NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
-  nsCOMPtr<nsIDocument> doc(do_QueryInterface(window->GetExtantDocument()));
-  NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
-  nsCOMPtr<nsIURI> documentURI;
-  documentURI = doc->GetDocumentURI();
-
-  nsAutoCString spec;
-  documentURI->GetSpec(spec);
-  if (!StringBeginsWith(spec,  NS_LITERAL_CSTRING("about:neterror?")))
-    return NS_ERROR_DOM_SECURITY_ERR;
-
-  nsCOMPtr<nsIIOService> ios = do_GetService("@mozilla.org/network/io-service;1");
-  if (ios) {
-    ios->SetOffline(false); // !offline
-    return NS_OK;
-  }
-  return NS_ERROR_NOT_AVAILABLE;
-}
-
-NS_IMETHODIMP
 nsDOMWindowUtils::GetDisplayDPI(float *aDPI)
 {
   if (!IsUniversalXPConnectCapable()) {
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget)
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1181,17 +1181,17 @@ nsJSContext::DestroyJSContext()
   mContext = nullptr;
 }
 
 // QueryInterface implementation for nsJSContext
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsJSContext)
 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsJSContext)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsJSContext)
-  NS_ASSERTION(!tmp->mContext || js::GetContextOutstandingRequests(tmp->mContext) == 0,
+  NS_ASSERTION(!tmp->mContext || !js::ContextHasOutstandingRequests(tmp->mContext),
                "Trying to unlink a context with outstanding requests.");
   tmp->mIsInitialized = false;
   tmp->mGCOnDestruction = false;
   tmp->DestroyJSContext();
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mGlobalObjectRef)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsJSContext)
   NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsJSContext, tmp->GetCCRefcnt())
@@ -1210,18 +1210,24 @@ NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsJSContext)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsJSContext)
 
 nsrefcnt
 nsJSContext::GetCCRefcnt()
 {
   nsrefcnt refcnt = mRefCnt.get();
-  if (NS_LIKELY(mContext))
-    refcnt += js::GetContextOutstandingRequests(mContext);
+
+  // In the (abnormal) case of synchronous cycle-collection, the context may be
+  // actively running JS code in which case we must keep it alive by adding an
+  // extra refcount.
+  if (mContext && js::ContextHasOutstandingRequests(mContext)) {
+    refcnt++;
+  }
+
   return refcnt;
 }
 
 nsresult
 nsJSContext::EvaluateStringWithValue(const nsAString& aScript,
                                      JSObject* aScopeObject,
                                      nsIPrincipal *aPrincipal,
                                      const char *aURL,
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -1570,16 +1570,37 @@ if (NS_FAILED(rv) || !wrappedJS) {
 // Use a temp nsCOMPtr for the null-check, because ${target} might be
 // OwningNonNull, not an nsCOMPtr.
 nsCOMPtr<${nativeType}> tmp = do_QueryObject(wrappedJS.get());
 if (!tmp) {
 ${codeOnFailure}
 }
 ${target} = tmp.forget();""").substitute(self.substitution)
 
+def dictionaryHasSequenceMember(dictionary):
+    return (any(typeIsSequenceOrHasSequenceMember(m.type) for m in
+                dictionary.members) or
+            (dictionary.parent and
+             dictionaryHasSequenceMember(dictionary.parent)))
+
+def typeIsSequenceOrHasSequenceMember(type):
+    if type.nullable():
+        type = type.inner
+    if type.isSequence():
+        return True
+    if  type.isArray():
+        elementType = type.inner
+        return typeIsSequenceOrHasSequenceMember(elementType)
+    if type.isDictionary():
+        return dictionaryHasSequenceMember(type.inner)
+    if type.isUnion():
+        return any(typeIsSequenceOrHasSequenceMember(m.type) for m in
+                   type.flatMemberTypes)
+    return False
+
 def getJSToNativeConversionTemplate(type, descriptorProvider, failureCode=None,
                                     isDefinitelyObject=False,
                                     isMember=False,
                                     isOptional=False,
                                     invalidEnumValueFatal=True,
                                     defaultValue=None,
                                     treatNullAs="Default",
                                     treatUndefinedAs="Default",
@@ -1595,17 +1616,19 @@ def getJSToNativeConversionTemplate(type
     out of memory conditions need to throw exceptions no matter what
     failureCode is.
 
     If isDefinitelyObject is True, that means we know the value
     isObject() and we have no need to recheck that.
 
     if isMember is True, we're being converted from a property of some
     JS object, not from an actual method argument, so we can't rely on
-    our jsval being rooted or outliving us in any way.
+    our jsval being rooted or outliving us in any way.  Any caller
+    passing true needs to ensure that it is handled correctly in
+    typeIsSequenceOrHasSequenceMember.
 
     If isOptional is true, then we are doing conversion of an optional
     argument with no default value.
 
     invalidEnumValueFatal controls whether an invalid enum value conversion
     attempt will throw (if true) or simply return without doing anything (if
     false).
 
@@ -1716,34 +1739,41 @@ def getJSToNativeConversionTemplate(type
     assert not (isEnforceRange and isClamp) # These are mutually exclusive
 
     if type.isArray():
         raise TypeError("Can't handle array arguments yet")
 
     if type.isSequence():
         assert not isEnforceRange and not isClamp
 
-        if isMember:
-            # XXXbz we probably _could_ handle this; we just have to be careful
-            # with reallocation behavior for arrays.  In particular, if we have
-            # a return value that's a sequence of dictionaries of sequences,
-            # that will cause us to have an nsTArray containing objects with
-            # nsAutoTArray members, which is a recipe for badness as the
-            # outermost array is resized.
-            raise TypeError("Can't handle unrooted sequences")
         if failureCode is not None:
             raise TypeError("Can't handle sequences when failureCode is not None")
         nullable = type.nullable();
         # Be very careful not to change "type": we need it later
         if nullable:
             elementType = type.inner.inner
         else:
             elementType = type.inner
-        # We don't know anything about the object-ness of the things
-        # we wrap, so don't pass through isDefinitelyObject
+
+        # We have to be careful with reallocation behavior for arrays.  In
+        # particular, if we have a sequence of elements which are themselves
+        # sequences (so nsAutoTArrays) or have sequences as members, we have a
+        # problem.  In that case, resizing the outermost nsAutoTarray to the
+        # right size will memmove its elements, but nsAutoTArrays are not
+        # memmovable and hence will end up with pointers to bogus memory, which
+        # is bad.  To deal with this, we disallow sequences, arrays,
+        # dictionaries, and unions which contain sequences as sequence item
+        # types.  If WebIDL ever adds another container type, we'd have to
+        # disallow it as well.
+        if typeIsSequenceOrHasSequenceMember(elementType):
+            raise TypeError("Can't handle a sequence containing another "
+                            "sequence as an element or member of an element.  "
+                            "See the big comment explaining why.\n%s" %
+                            str(type.location))
+
         (elementTemplate, elementDeclType,
          elementHolderType, dealWithOptional) = getJSToNativeConversionTemplate(
             elementType, descriptorProvider, isMember=True)
         if dealWithOptional:
             raise TypeError("Shouldn't have optional things in sequences")
         if elementHolderType is not None:
             raise TypeError("Shouldn't need holders for sequences")
 
old mode 100755
new mode 100644
--- a/dom/bindings/test/TestBindingHeader.h
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -392,16 +392,17 @@ public:
 
   // Dictionary tests
   void PassDictionary(const Dict&);
   void PassOtherDictionary(const GrandparentDict&);
   void PassSequenceOfDictionaries(const Sequence<Dict>&);
   void PassDictionaryOrLong(const Dict&);
   void PassDictionaryOrLong(int32_t);
   void PassDictContainingDict(const DictContainingDict&);
+  void PassDictContainingSequence(const DictContainingSequence&);
 
   // Typedefs
   void ExerciseTypedefInterfaces1(TestInterface&);
   already_AddRefed<TestInterface> ExerciseTypedefInterfaces2(TestInterface*);
   void ExerciseTypedefInterfaces3(TestInterface&);
 
   // Miscellania
   int32_t AttrWithLenientThis();
--- a/dom/bindings/test/TestCodeGen.webidl
+++ b/dom/bindings/test/TestCodeGen.webidl
@@ -305,16 +305,17 @@ interface TestInterface {
 
   void passDictionary(optional Dict x);
   void passOtherDictionary(optional GrandparentDict x);
   void passSequenceOfDictionaries(sequence<Dict> x);
   void passDictionaryOrLong(optional Dict x);
   void passDictionaryOrLong(long x);
 
   void passDictContainingDict(optional DictContainingDict arg);
+  void passDictContainingSequence(optional DictContainingSequence arg);
 
   // EnforceRange/Clamp tests
   void dontEnforceRangeOrClamp(byte arg);
   void doEnforceRange([EnforceRange] byte arg);
   void doClamp([Clamp] byte arg);
 
   // Typedefs
   const myLong myLongConstant = 5;
@@ -389,16 +390,20 @@ dictionary ParentDict : GrandparentDict 
   TestInterface someInterface;
   TestExternalInterface someExternalInterface;
 };
 
 dictionary DictContainingDict {
   Dict memberDict;
 };
 
+dictionary DictContainingSequence {
+  sequence<long> ourSequence;
+};
+
 interface TestIndexedGetterInterface {
   getter long item(unsigned long index);
   [Infallible]
   readonly attribute unsigned long length;
 };
 
 interface TestNamedGetterInterface {
   getter DOMString (DOMString name);
--- a/dom/bluetooth/BluetoothAdapter.cpp
+++ b/dom/bluetooth/BluetoothAdapter.cpp
@@ -302,24 +302,23 @@ BluetoothAdapter::Notify(const Bluetooth
 
     nsCOMPtr<nsIDOMBluetoothDeviceEvent> e = do_QueryInterface(event);
     e->InitBluetoothDeviceEvent(NS_LITERAL_STRING("devicecreated"),
                                 false, false, device);
     e->SetTrusted(true);
     bool dummy;
     DispatchEvent(event, &dummy);
   } else if (aData.name().EqualsLiteral("PropertyChanged")) {
-    // Get BluetoothNamedValue, make sure array length is 1
+    NS_ASSERTION(aData.value().type() == BluetoothValue::TArrayOfBluetoothNamedValue,
+                 "PropertyChanged: Invalid value type");
     arr = aData.value().get_ArrayOfBluetoothNamedValue();
 
     NS_ASSERTION(arr.Length() == 1, "Got more than one property in a change message!");
-    NS_ASSERTION(arr[0].value().type() == BluetoothValue::TArrayOfBluetoothNamedValue,
-                 "PropertyChanged: Invalid value type");
+    BluetoothNamedValue v = arr[0];
 
-    BluetoothNamedValue v = arr[0];
     SetPropertyByValue(v);
     nsRefPtr<BluetoothPropertyEvent> e = BluetoothPropertyEvent::Create(v.name());
     e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("propertychanged"));
   } else {
 #ifdef DEBUG
     nsCString warningMsg;
     warningMsg.AssignLiteral("Not handling adapter signal: ");
     warningMsg.Append(NS_ConvertUTF16toUTF8(aData.name()));
--- a/dom/bluetooth/BluetoothDevice.cpp
+++ b/dom/bluetooth/BluetoothDevice.cpp
@@ -110,17 +110,25 @@ BluetoothDevice::SetPropertyByValue(cons
     }
   } else if (name.EqualsLiteral("Address")) {
     mAddress = value.get_nsString();
   } else if (name.EqualsLiteral("Class")) {
     mClass = value.get_uint32_t();
   } else if (name.EqualsLiteral("Icon")) {
     mIcon = value.get_nsString();
   } else if (name.EqualsLiteral("Connected")) {
+#ifdef MOZ_WIDGET_GONK
+    // Connected is an 2-byte array
+    // arr[0]: boolean value, true means connected, false means disconnected
+    // arr[1]: disconnection reason
+    InfallibleTArray<uint8_t> arr = value.get_ArrayOfuint8_t();
+    mConnected = (arr[0] == 1);
+#else
     mConnected = value.get_bool();
+#endif
   } else if (name.EqualsLiteral("Paired")) {
     mPaired = value.get_bool();
   } else if (name.EqualsLiteral("UUIDs")) {
     mUuids = value.get_ArrayOfnsString();
     nsresult rv;
     nsIScriptContext* sc = GetContextForEventHandlers(&rv);
     if (sc) {
       rv =
@@ -180,39 +188,42 @@ BluetoothDevice::Create(nsPIDOMWindow* a
 
   return device.forget();
 }
 
 void
 BluetoothDevice::Notify(const BluetoothSignal& aData)
 {
   if (aData.name().EqualsLiteral("PropertyChanged")) {
-    // Get BluetoothNamedValue, make sure array length is 1
-    BluetoothNamedValue v = aData.value().get_ArrayOfBluetoothNamedValue()[0];
+    NS_ASSERTION(aData.value().type() == BluetoothValue::TArrayOfBluetoothNamedValue,
+                 "PropertyChanged: Invalid value type");
+    InfallibleTArray<BluetoothNamedValue> arr = aData.value().get_ArrayOfBluetoothNamedValue();
+
+    NS_ASSERTION(arr.Length() == 1, "Got more than one property in a change message!");
+    BluetoothNamedValue v = arr[0];
     nsString name = v.name();
 
+    SetPropertyByValue(v);
     if (name.EqualsLiteral("Connected")) {
-      bool isConnected = v.value();
       nsRefPtr<nsDOMEvent> event = new nsDOMEvent(nullptr, nullptr);
       nsresult rv;
-      if (isConnected) {
+      if (mConnected) {
         rv = event->InitEvent(NS_LITERAL_STRING("connected"), false, false);
       } else {
         rv = event->InitEvent(NS_LITERAL_STRING("disconnected"), false, false);
       }
       if (NS_FAILED(rv)) {
         NS_WARNING("Failed to init the connected/disconnected event!!!");
         return;
       }
 
       event->SetTrusted(true);
       bool dummy;
       DispatchEvent(event, &dummy);
     } else {
-      SetPropertyByValue(v);
       nsRefPtr<BluetoothPropertyEvent> e = BluetoothPropertyEvent::Create(name);
       e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("propertychanged"));
     }
   } else {
 #ifdef DEBUG
     nsCString warningMsg;
     warningMsg.AssignLiteral("Not handling device signal: ");
     warningMsg.Append(NS_ConvertUTF16toUTF8(aData.name()));
--- a/dom/bluetooth/ipc/BluetoothTypes.ipdlh
+++ b/dom/bluetooth/ipc/BluetoothTypes.ipdlh
@@ -15,16 +15,17 @@ namespace bluetooth {
  * 
  */
 union BluetoothValue
 {
   uint32_t;
   nsString;
   bool;
   nsString[];
+  uint8_t[];
   BluetoothNamedValue[];
 };
 
 /**
  * Key-value pair for dicts returned by the bluetooth backend. Used for things
  * like property updates, where the property will have a name and a type.
  * 
  */
--- a/dom/bluetooth/linux/BluetoothDBusService.cpp
+++ b/dom/bluetooth/linux/BluetoothDBusService.cpp
@@ -75,17 +75,21 @@ typedef struct {
 
 static Properties sDeviceProperties[] = {
   {"Address", DBUS_TYPE_STRING},
   {"Name", DBUS_TYPE_STRING},
   {"Icon", DBUS_TYPE_STRING},
   {"Class", DBUS_TYPE_UINT32},
   {"UUIDs", DBUS_TYPE_ARRAY},
   {"Paired", DBUS_TYPE_BOOLEAN},
+#ifdef MOZ_WIDGET_GONK
+  {"Connected", DBUS_TYPE_ARRAY},
+#else
   {"Connected", DBUS_TYPE_BOOLEAN},
+#endif
   {"Trusted", DBUS_TYPE_BOOLEAN},
   {"Blocked", DBUS_TYPE_BOOLEAN},
   {"Alias", DBUS_TYPE_STRING},
   {"Nodes", DBUS_TYPE_ARRAY},
   {"Adapter", DBUS_TYPE_OBJECT_PATH},
   {"LegacyPairing", DBUS_TYPE_BOOLEAN},
   {"RSSI", DBUS_TYPE_INT16},
   {"TX", DBUS_TYPE_UINT32},
@@ -701,26 +705,34 @@ GetProperty(DBusMessageIter aIter, Prope
       bool b;
       dbus_message_iter_get_basic(&prop_val, &b);
       propertyValue = b;
       break;
     case DBUS_TYPE_ARRAY:
       dbus_message_iter_recurse(&prop_val, &array_val_iter);
       array_type = dbus_message_iter_get_arg_type(&array_val_iter);
       if (array_type == DBUS_TYPE_OBJECT_PATH ||
-          array_type == DBUS_TYPE_STRING){
+          array_type == DBUS_TYPE_STRING) {
         InfallibleTArray<nsString> arr;
         do {
           const char* tmp;
           dbus_message_iter_get_basic(&array_val_iter, &tmp);
           nsString s;
           s = NS_ConvertUTF8toUTF16(tmp);
           arr.AppendElement(s);
         } while (dbus_message_iter_next(&array_val_iter));
         propertyValue = arr;
+      } else if (array_type == DBUS_TYPE_BYTE) {
+        InfallibleTArray<uint8_t> arr;
+        do {
+          uint8_t tmp;
+          dbus_message_iter_get_basic(&array_val_iter, &tmp);
+          arr.AppendElement(tmp);
+        } while (dbus_message_iter_next(&array_val_iter));
+        propertyValue = arr;
       } else {
         // This happens when the array is 0-length. Apparently we get a
         // DBUS_TYPE_INVALID type.
         propertyValue = InfallibleTArray<nsString>();
 #ifdef DEBUG
         NS_WARNING("Received array type that's not a string array!");
 #endif
       }
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -35,31 +35,32 @@
 #include "nsIDOMDeviceStorageChangeEvent.h"
 #include "nsCRT.h"
 #include "mozilla/Services.h"
 #include "nsIObserverService.h"
 #include "GeneratedEvents.h"
 #include "mozilla/dom/PermissionMessageUtils.h"
 #include "nsIMIMEService.h"
 #include "nsCExternalHandlerService.h"
-
+#include "nsIPermissionManager.h"
 #include "nsIStringBundle.h"
 
 // Microsoft's API Name hackery sucks
 #undef CreateEvent
 
 #ifdef MOZ_WIDGET_GONK
 #include "nsIVolume.h"
 #include "nsIVolumeService.h"
 #endif
 
 #define DEVICESTORAGE_PROPERTIES "chrome://global/content/devicestorage.properties"
 #define DEVICESTORAGE_PICTURES   "pictures"
 #define DEVICESTORAGE_VIDEOS     "videos"
 #define DEVICESTORAGE_MUSIC      "music"
+#define DEVICESTORAGE_APPS       "apps"
 
 using namespace mozilla::dom;
 using namespace mozilla::dom::devicestorage;
 
 #include "nsDirectoryServiceDefs.h"
 
 nsAutoPtr<DeviceStorageTypeChecker> DeviceStorageTypeChecker::sDeviceStorageTypeChecker;
 
@@ -124,24 +125,34 @@ DeviceStorageTypeChecker::Check(const ns
   if (aType.EqualsLiteral(DEVICESTORAGE_VIDEOS)) {
     return StringBeginsWith(mimeType, NS_LITERAL_STRING("video/"));
   }
 
   if (aType.EqualsLiteral(DEVICESTORAGE_MUSIC)) {
     return StringBeginsWith(mimeType, NS_LITERAL_STRING("audio/"));
   }
 
+  if (aType.EqualsLiteral(DEVICESTORAGE_APPS)) {
+    // Apps have no restriction on mime types
+    return true;
+  }
+
   return false;
 }
 
 bool
 DeviceStorageTypeChecker::Check(const nsAString& aType, nsIFile* aFile)
 {
   NS_ASSERTION(aFile, "Calling Check without a file");
 
+  if (aType.EqualsLiteral(DEVICESTORAGE_APPS)) {
+    // apps have no restrictions on what file extensions used.
+    return true;
+  }
+
   nsString path;
   aFile->GetPath(path);
 
   int32_t dotIdx = path.RFindChar(PRUnichar('.'));
   if (dotIdx == kNotFound) {
     return false;
   }
 
@@ -165,17 +176,18 @@ DeviceStorageTypeChecker::Check(const ns
   return false;
 }
 
 nsresult
 DeviceStorageTypeChecker::GetPermissionForType(const nsAString& aType, nsACString& aPermissionResult)
 {
   if (!aType.EqualsLiteral(DEVICESTORAGE_PICTURES) &&
       !aType.EqualsLiteral(DEVICESTORAGE_VIDEOS) &&
-      !aType.EqualsLiteral(DEVICESTORAGE_MUSIC)) {
+      !aType.EqualsLiteral(DEVICESTORAGE_MUSIC) &&
+      !aType.EqualsLiteral(DEVICESTORAGE_APPS)) {
     // unknown type
     return NS_ERROR_FAILURE;
   }
 
   aPermissionResult.AssignLiteral("device-storage:");
   aPermissionResult.Append(NS_ConvertUTF16toUTF8(aType));
   return NS_OK;
 }
@@ -607,53 +619,65 @@ UnregisterForSDCardChanges(nsIObserver* 
 void
 nsDOMDeviceStorage::SetRootDirectoryForType(const nsAString& aType)
 {
   nsCOMPtr<nsIFile> f;
   nsCOMPtr<nsIProperties> dirService = do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
   NS_ASSERTION(dirService, "Must have directory service");
 
   // Picture directory
-  if (aType.Equals(NS_LITERAL_STRING("pictures"))) {
+  if (aType.EqualsLiteral(DEVICESTORAGE_PICTURES)) {
 #ifdef MOZ_WIDGET_GONK
     NS_NewLocalFile(NS_LITERAL_STRING("/sdcard"), false, getter_AddRefs(f));
 #elif defined (MOZ_WIDGET_COCOA)
     dirService->Get(NS_OSX_PICTURE_DOCUMENTS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
 #elif defined (XP_UNIX)
     dirService->Get(NS_UNIX_XDG_PICTURES_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
 #elif defined (XP_WIN)
     dirService->Get(NS_WIN_PICTURES_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
 #endif
   }
 
   // Video directory
-  else if (aType.Equals(NS_LITERAL_STRING("videos"))) {
+  else if (aType.EqualsLiteral(DEVICESTORAGE_VIDEOS)) {
 #ifdef MOZ_WIDGET_GONK
     NS_NewLocalFile(NS_LITERAL_STRING("/sdcard"), false, getter_AddRefs(f));
 #elif defined (MOZ_WIDGET_COCOA)
     dirService->Get(NS_OSX_MOVIE_DOCUMENTS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
 #elif defined (XP_UNIX)
     dirService->Get(NS_UNIX_XDG_VIDEOS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
 #elif defined (XP_WIN)
     dirService->Get(NS_WIN_VIDEOS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
 #endif
   }
 
   // Music directory
-  else if (aType.Equals(NS_LITERAL_STRING("music"))) {
+  else if (aType.EqualsLiteral(DEVICESTORAGE_MUSIC)) {
 #ifdef MOZ_WIDGET_GONK
     NS_NewLocalFile(NS_LITERAL_STRING("/sdcard"), false, getter_AddRefs(f));
 #elif defined (MOZ_WIDGET_COCOA)
     dirService->Get(NS_OSX_MUSIC_DOCUMENTS_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
 #elif defined (XP_UNIX)
     dirService->Get(NS_UNIX_XDG_MUSIC_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
 #elif defined (XP_WIN)
     dirService->Get(NS_WIN_MUSIC_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
 #endif
   }
+  
+  // Apps directory
+  else if (aType.EqualsLiteral(DEVICESTORAGE_APPS)) {
+#ifdef MOZ_WIDGET_GONK
+    NS_NewLocalFile(NS_LITERAL_STRING("/data"), false, getter_AddRefs(f));
+#else
+    dirService->Get(NS_APP_USER_PROFILE_50_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
+    if (f) {
+      f->AppendRelativeNativePath(NS_LITERAL_CSTRING("webapps"));
+    }
+#endif
+  }
 
   // in testing, we default all device storage types to a temp directory
   if (f && mozilla::Preferences::GetBool("device.storage.testing", false)) {
     dirService->Get(NS_OS_TEMP_DIR, NS_GET_IID(nsIFile), getter_AddRefs(f));
     if (f) {
       f->AppendRelativeNativePath(NS_LITERAL_CSTRING("device-storage-testing"));
       f->Create(nsIFile::DIRECTORY_TYPE, 0777);
       f->Normalize();
@@ -1626,16 +1650,33 @@ nsDOMDeviceStorage::Init(nsPIDOMWindow* 
   // Grab the principal of the document
   nsCOMPtr<nsIDOMDocument> domdoc;
   aWindow->GetDocument(getter_AddRefs(domdoc));
   nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
   if (!doc) {
     return NS_ERROR_FAILURE;
   }
   mPrincipal = doc->NodePrincipal();
+
+  // the 'apps' type is special.  We only want this exposed
+  // if the caller has the "webapps-manage" permission.
+  if (aType.EqualsLiteral("apps")) {
+    nsCOMPtr<nsIPermissionManager> permissionManager = do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
+    NS_ENSURE_TRUE(permissionManager, NS_ERROR_FAILURE);
+
+    uint32_t permission;
+    nsresult rv = permissionManager->TestPermissionFromPrincipal(mPrincipal,
+                                                                 "webapps-manage",
+                                                                 &permission);
+
+    if (NS_FAILED(rv) || permission != nsIPermissionManager::ALLOW_ACTION) {
+      return NS_ERROR_NOT_AVAILABLE;
+    }
+  }
+
   return NS_OK;
 }
 
 nsDOMDeviceStorage::~nsDOMDeviceStorage()
 {
 }
 
 void
@@ -2046,17 +2087,17 @@ nsDOMDeviceStorage::Observe(nsISupports 
 #ifdef MOZ_WIDGET_GONK
   else if (!strcmp(aTopic, NS_VOLUME_STATE_CHANGED)) {
     nsCOMPtr<nsIVolume> vol = do_QueryInterface(aSubject);
     if (!vol) {
       return NS_OK;
     }
     nsString volName;
     vol->GetName(volName);
-    if (!volName.Equals(NS_LITERAL_STRING("sdcard"))) {
+    if (!volName.EqualsLiteral("sdcard")) {
       return NS_OK;
     }
 
     int32_t state;
     nsresult rv = vol->GetState(&state);
     if (NS_FAILED(rv)) {
       return NS_OK;
     }
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -35,17 +35,17 @@ interface nsIQueryContentEventResult;
 interface nsIDOMWindow;
 interface nsIDOMBlob;
 interface nsIDOMFile;
 interface nsIFile;
 interface nsIDOMTouch;
 interface nsIDOMClientRect;
 interface nsIURI;
 
-[scriptable, uuid(37cf79ee-fe7a-4d5a-9e41-e2186553969f)]
+[scriptable, uuid(6cf3e8f0-fb82-11e1-a21f-0800200c9a66)]
 interface nsIDOMWindowUtils : nsISupports {
 
   /**
    * Image animation mode of the window. When this attribute's value
    * is changed, the implementation should set all images in the window
    * to the given value. That is, when set to kDontAnimMode, all images
    * will stop animating. The attribute's value must be one of the
    * animationMode values from imgIContainer.
@@ -1018,23 +1018,16 @@ interface nsIDOMWindowUtils : nsISupport
 
   /**
    * Suspend/resume timeouts on this window and its descendant windows.
    */
   void suspendTimeouts();
   void resumeTimeouts();
 
   /**
-   * Set the network status to online from the Offline mode error page.
-   *
-   * The caller of this method must be about:neterror.
-   */
-  void goOnline();
-
-  /**
    * What type of layer manager the widget associated with this window is
    * using. "Basic" is unaccelerated; other types are accelerated. Throws an
    * error if there is no widget associated with this window.
    */
   readonly attribute AString layerManagerType;
 
   void startFrameTimeRecording();
   void stopFrameTimeRecording([optional] out unsigned long frameCount,
--- a/dom/messages/SystemMessageInternal.js
+++ b/dom/messages/SystemMessageInternal.js
@@ -20,56 +20,73 @@ XPCOMUtils.defineLazyServiceGetter(this,
 let kMaxPendingMessages;
 try {
   kMaxPendingMessages = Services.prefs.getIntPref("dom.messages.maxPendingMessages");
 } catch(e) {
   // getIntPref throws when the pref is not set.
   kMaxPendingMessages = 5;
 }
 
-function debug(aMsg) { 
+const kMessages =["SystemMessageManager:GetPending",
+                  "SystemMessageManager:Register",
+                  "SystemMessageManager:Unregister"]
+
+function debug(aMsg) {
   //dump("-- SystemMessageInternal " + Date.now() + " : " + aMsg + "\n");
 }
 
 // Implementation of the component used by internal users.
 
 function SystemMessageInternal() {
   // The set of pages registered by installed apps. We keep the
   // list of pending messages for each page here also.
   this._pages = [];
+  this._listeners = {};
   Services.obs.addObserver(this, "xpcom-shutdown", false);
-  ppmm.addMessageListener("SystemMessageManager:GetPending", this);
+  kMessages.forEach((function(aMsg) {
+    ppmm.addMessageListener(aMsg, this);
+  }).bind(this));
 }
 
 SystemMessageInternal.prototype = {
   sendMessage: function sendMessage(aType, aMessage, aPageURI, aManifestURI) {
     debug("Broadcasting " + aType + " " + JSON.stringify(aMessage));
-    ppmm.broadcastAsyncMessage("SystemMessageManager:Message" , { type: aType,
-                                                                  msg: aMessage,
-                                                                  manifest: aManifestURI.spec });
+    if (this._listeners[aManifestURI.spec]) {
+      this._listeners[aManifestURI.spec].forEach(function sendMsg(aListener) {
+        aListener.sendAsyncMessage("SystemMessageManager:Message",
+                                   { type: aType,
+                                     msg: aMessage,
+                                     manifest: aManifestURI.spec })
+      });
+    }
+
     this._pages.forEach(function sendMess_openPage(aPage) {
       if (aPage.type != aType ||
           aPage.manifest != aManifestURI.spec ||
           aPage.uri != aPageURI.spec) {
         return;
       }
 
       this._processPage(aPage, aMessage);
     }.bind(this))
   },
 
   broadcastMessage: function broadcastMessage(aType, aMessage) {
     debug("Broadcasting " + aType + " " + JSON.stringify(aMessage));
     // Find pages that registered an handler for this type.
     this._pages.forEach(function(aPage) {
       if (aPage.type == aType) {
-        ppmm.broadcastAsyncMessage("SystemMessageManager:Message" , { type: aType,
-                                                                      msg: aMessage,
-                                                                      manifest: aPage.manifest });
-
+        if (this._listeners[aPage.manifest]) {
+          this._listeners[aPage.manifest].forEach(function sendMsg(aListener) {
+            aListener.sendAsyncMessage("SystemMessageManager:Message",
+                                       { type: aType,
+                                         msg: aMessage,
+                                         manifest: aPage.manifest})
+          });
+        }
         this._processPage(aPage, aMessage);
       }
     }.bind(this))
   },
 
   registerPage: function registerPage(aType, aPageURI, aManifestURI) {
     if (!aPageURI || !aManifestURI) {
       throw Cr.NS_ERROR_INVALID_ARG;
@@ -77,47 +94,73 @@ SystemMessageInternal.prototype = {
 
     this._pages.push({ type: aType,
                        uri: aPageURI.spec,
                        manifest: aManifestURI.spec,
                        pending: [] });
   },
 
   receiveMessage: function receiveMessage(aMessage) {
-    debug("received SystemMessageManager:GetPending " + aMessage.json.type + " for " + aMessage.json.uri + " @ " + aMessage.json.manifest);
-    // This is a sync call, use to return the pending message for a page.
     let msg = aMessage.json;
-    debug(JSON.stringify(msg));
+    switch(aMessage.name) {
+      case "SystemMessageManager:Register":
+        let manifest = msg.manifest;
+        debug("Got Register from " + manifest);
+        if (!this._listeners[manifest]) {
+          this._listeners[manifest] = [];
+        }
+        this._listeners[manifest].push(aMessage.target);
+        debug("listeners for " + manifest + " : " + this._listeners[manifest].length);
+        break;
+      case "SystemMessageManager:Unregister":
+        debug("Got Unregister from " + aMessage.target);
+        let mm = aMessage.target;
+        for (let manifest in this._listeners) {
+          let index = this._listeners[manifest].indexOf(mm);
+          while (index != -1) {
+            debug("Removing " + mm + " at index " + index);
+            this._listeners[manifest].splice(index, 1);
+            index = this._listeners[manifest].indexOf(mm);
+          }
+        }
+        break;
+      case "SystemMessageManager:GetPending":
+        debug("received SystemMessageManager:GetPending " + aMessage.json.type +
+          " for " + aMessage.json.uri + " @ " + aMessage.json.manifest);
+        // This is a sync call, use to return the pending message for a page.
+        debug(JSON.stringify(msg));
+        // Find the right page.
+        let page = null;
+        this._pages.some(function(aPage) {
+          if (aPage.uri == msg.uri &&
+              aPage.type == msg.type &&
+              aPage.manifest == msg.manifest) {
+            page = aPage;
+          }
+          return page !== null;
+        });
+        if (!page) {
+          return null;
+        }
 
-    // Find the right page.
-    let page = null;
-    this._pages.some(function(aPage) {
-      if (aPage.uri == msg.uri &&
-          aPage.type == msg.type &&
-          aPage.manifest == msg.manifest) {
-        page = aPage;
-      }
-      return page !== null;
-    });
+        let pending = page.pending;
+        // Clear the pending queue for this page.
+        // This is ok since we'll store pending events in SystemMessageManager.js
+        page.pending = [];
 
-    if (!page) {
-      return null;
+        return pending;
+        break;
     }
-
-    let pending = page.pending;
-    // Clear the pending queue for this page.
-    // This is ok since we'll store pending events in SystemMessageManager.js
-    page.pending = [];
-
-    return pending;
   },
 
   observe: function observe(aSubject, aTopic, aData) {
     if (aTopic == "xpcom-shutdown") {
-      ppmm.removeMessageListener("SystemMessageManager:GetPending", this);
+      kMessages.forEach((function(aMsg) {
+        ppmm.removeMessageListener(aMsg, this);
+      }).bind(this));
       Services.obs.removeObserver(this, "xpcom-shutdown");
       ppmm = null;
       this._pages = null;
     }
   },
 
   _processPage: function _processPage(aPage, aMessage) {
     // Queue the message for the page.
--- a/dom/messages/SystemMessageManager.js
+++ b/dom/messages/SystemMessageManager.js
@@ -138,16 +138,17 @@ SystemMessageManager.prototype = {
     return pendings[aType].length != 0;
   },
 
   mozHasPendingMessage: function sysMessMgr_hasPendingMessage(aType) {
     return this._getPendingMessages(aType, false);
   },
 
   uninit: function sysMessMgr_uninit()  {
+    cpmm.sendAsyncMessage("SystemMessageManager:Unregister", { });
     this._handlers = null;
     this._pendings =  null;
   },
 
   receiveMessage: function sysMessMgr_receiveMessage(aMessage) {
     debug("receiveMessage " + aMessage.name + " - " +
           aMessage.json.type + " for " + aMessage.json.manifest +
           " (" + this._manifest + ")");
@@ -172,16 +173,19 @@ SystemMessageManager.prototype = {
 
     let principal = aWindow.document.nodePrincipal;
     this._uri = principal.URI.spec;
 
     let appsService = Cc["@mozilla.org/AppsService;1"]
                         .getService(Ci.nsIAppsService);
     this._manifest = appsService.getManifestURLByLocalId(principal.appId);
     this._window = aWindow;
+    cpmm.sendAsyncMessage("SystemMessageManager:Register",
+                          { manifest: this._manifest });
+    debug("done");
   },
 
   classID: Components.ID("{bc076ea0-609b-4d8f-83d7-5af7cbdc3bb2}"),
 
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMNavigatorSystemMessages,
                                          Ci.nsIDOMGlobalPropertyInitializer]),
 
   classInfo: XPCOMUtils.generateCI({classID: Components.ID("{bc076ea0-609b-4d8f-83d7-5af7cbdc3bb2}"),
--- a/dom/plugins/base/android/ANPWindow.cpp
+++ b/dom/plugins/base/android/ANPWindow.cpp
@@ -94,26 +94,20 @@ anp_window_requestCenterFitZoom(NPP inst
 
 ANPRectI
 anp_window_visibleRect(NPP instance)
 {
   ANPRectI rect = { 0, 0, 0, 0 };
 
   nsNPAPIPluginInstance* pinst = static_cast<nsNPAPIPluginInstance*>(instance->ndata);
 
-  nsRefPtr<nsPluginInstanceOwner> owner;
-  if (NS_FAILED(GetOwner(instance, getter_AddRefs(owner)))) {
-    return rect;
-  }
-
-  nsIntRect visibleRect = owner->GetVisibleRect();
-  rect.left = visibleRect.x;
-  rect.top = visibleRect.y;
-  rect.right = visibleRect.x + visibleRect.width;
-  rect.bottom = visibleRect.y + visibleRect.height;
+  nsIntSize currentSize = pinst->CurrentSize();
+  rect.left = rect.top = 0;
+  rect.right = currentSize.width;
+  rect.bottom = currentSize.height;
 
   return rect;
 }
 
 void anp_window_requestFullScreenOrientation(NPP instance, ANPScreenOrientation orientation)
 {
   short newOrientation;
 
--- a/dom/plugins/base/nsNPAPIPluginInstance.h
+++ b/dom/plugins/base/nsNPAPIPluginInstance.h
@@ -126,16 +126,18 @@ public:
 
 #ifdef MOZ_WIDGET_ANDROID
   void NotifyForeground(bool aForeground);
   void NotifyOnScreen(bool aOnScreen);
   void MemoryPressure();
   void NotifyFullScreen(bool aFullScreen);
   void NotifySize(nsIntSize size);
 
+  nsIntSize CurrentSize() { return mCurrentSize; }
+
   bool IsOnScreen() {
     return mOnScreen;
   }
 
   uint32_t GetANPDrawingModel() { return mANPDrawingModel; }
   void SetANPDrawingModel(uint32_t aModel);
 
   void* GetJavaSurface();
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -645,17 +645,16 @@ NS_IMETHODIMP nsPluginInstanceOwner::Inv
   if (!mObjectFrame || !invalidRect || !mWidgetVisible)
     return NS_ERROR_FAILURE;
 
   // Each time an asynchronously-drawing plugin sends a new surface to display,
   // InvalidateRect is called. We notify reftests that painting is up to
   // date and update our ImageContainer with the new surface.
   nsRefPtr<ImageContainer> container;
   mInstance->GetImageContainer(getter_AddRefs(container));
-  gfxIntSize oldSize(0, 0);
 
 #ifndef XP_MACOSX
   // Windowed plugins should not be calling NPN_InvalidateRect, but
   // Silverlight does and expects it to "work"
   if (mWidget) {
     mWidget->Invalidate(nsIntRect(invalidRect->left, invalidRect->top,
                                   invalidRect->right - invalidRect->left,
                                   invalidRect->bottom - invalidRect->top));
@@ -663,26 +662,17 @@ NS_IMETHODIMP nsPluginInstanceOwner::Inv
   }
 #endif
 
   nsPresContext* presContext = mObjectFrame->PresContext();
   nsRect rect(presContext->DevPixelsToAppUnits(invalidRect->left),
               presContext->DevPixelsToAppUnits(invalidRect->top),
               presContext->DevPixelsToAppUnits(invalidRect->right - invalidRect->left),
               presContext->DevPixelsToAppUnits(invalidRect->bottom - invalidRect->top));
-  if (container) {
-    gfxIntSize newSize = container->GetCurrentSize();
-    if (newSize != oldSize) {
-      // The image size has changed - invalidate the old area too, bug 635405.
-      nsRect oldRect = nsRect(0, 0,
-                              presContext->DevPixelsToAppUnits(oldSize.width),
-                              presContext->DevPixelsToAppUnits(oldSize.height));
-      rect.UnionRect(rect, oldRect);
-    }
-  }
+
   rect.MoveBy(mObjectFrame->GetContentRectRelativeToSelf().TopLeft());
   mObjectFrame->InvalidateLayer(rect, nsDisplayItem::TYPE_PLUGIN);
   return NS_OK;
 }
 
 NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRegion(NPRegion invalidRegion)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
@@ -1816,30 +1806,16 @@ already_AddRefed<ImageContainer> nsPlugi
 
   SharedTextureImage* pluginImage = static_cast<SharedTextureImage*>(img.get());
   pluginImage->SetData(data);
   container->SetCurrentImageInTransaction(img);
 
   return container.forget();
 }
 
-nsIntRect nsPluginInstanceOwner::GetVisibleRect()
-{
-  if (!mObjectFrame || !mPluginWindow)
-    return nsIntRect(0, 0, 0, 0);
-  
-  gfxRect r = nsIntRect(0, 0, mPluginWindow->width, mPluginWindow->height);
-
-  float xResolution = mObjectFrame->PresContext()->GetRootPresContext()->PresShell()->GetXResolution();
-  float yResolution = mObjectFrame->PresContext()->GetRootPresContext()->PresShell()->GetYResolution();
-  r.Scale(xResolution, yResolution);
-
-  return nsIntRect(r.x, r.y, r.width, r.height);
-}
-
 void nsPluginInstanceOwner::Invalidate() {
   NPRect rect;
   rect.left = rect.top = 0;
   rect.right = mPluginWindow->width;
   rect.bottom = mPluginWindow->height;
   InvalidateRect(&rect);
 }
 
--- a/dom/plugins/base/nsPluginInstanceOwner.h
+++ b/dom/plugins/base/nsPluginInstanceOwner.h
@@ -253,18 +253,16 @@ public:
   
   bool UseAsyncRendering();
 
 #ifdef MOZ_WIDGET_ANDROID
   // Returns the image container for the specified VideoInfo
   void GetVideos(nsTArray<nsNPAPIPluginInstance::VideoInfo*>& aVideos);
   already_AddRefed<ImageContainer> GetImageContainerForVideo(nsNPAPIPluginInstance::VideoInfo* aVideoInfo);
 
-  nsIntRect GetVisibleRect();
-
   void Invalidate();
 
   void RequestFullScreen();
   void ExitFullScreen();
 
   // Called from AndroidJNI when we removed the fullscreen view.
   static void ExitFullScreen(jobject view);
 #endif
--- a/dom/plugins/test/reftest/reftest.list
+++ b/dom/plugins/test/reftest/reftest.list
@@ -20,9 +20,10 @@ fails-if(!haveTestPlugin) == plugin-tran
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == plugin-busy-alpha-zindex.html div-alpha-zindex.html
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == plugin-background.html plugin-background-ref.html
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == plugin-background-1-step.html plugin-background-ref.html
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == plugin-background-2-step.html plugin-background-ref.html
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == plugin-background-5-step.html plugin-background-ref.html
 random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(!haveTestPlugin) == plugin-background-10-step.html plugin-background-ref.html
 random-if(!haveTestPlugin) == plugin-transform-1.html plugin-transform-1-ref.html
 fails-if(!haveTestPlugin) == plugin-transform-2.html plugin-transform-2-ref.html
+skip-if(!haveTestPlugin) == shrink-1.html shrink-1-ref.html
 fails-if(!haveTestPlugin) == windowless-layers.html windowless-layers-ref.html
new file mode 100644
--- /dev/null
+++ b/dom/plugins/test/reftest/shrink-1-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+  <embed id="plugin" type="application/x-test"
+         width="50px" height="40px">
+  </embed>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/plugins/test/reftest/shrink-1.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<head>
+  <script>
+function doShrink()
+{
+  var plugin = document.getElementById("plugin");
+  plugin.setSlowPaint(true);
+  plugin.width = "50";
+  plugin.height = "40";
+
+  document.documentElement.removeAttribute("class");
+}
+
+document.addEventListener("MozReftestInvalidate", doShrink, false);
+  </script>
+</head>
+<body>
+  <embed id="plugin" type="application/x-test"
+         width="300" height="500">
+  </embed>
+</body>
+</html>
--- a/dom/plugins/test/testplugin/README
+++ b/dom/plugins/test/testplugin/README
@@ -192,16 +192,19 @@ window.
 
 * getWidthAtLastPaint()
 Returns the window width that was current when the plugin last painted.
 
 * setInvalidateDuringPaint(value)
 When value is true, every time the plugin paints, it will invalidate
 itself *during the paint* using NPN_Invalidate.
 
+* setSlowPaint(value)
+When value is true, the instance will sleep briefly during paint.
+
 == Plugin geometry ==
 
 The test plugin supports the following scriptable methods:
 
 * getEdge(edge)
 Returns the integer screen pixel coordinate of an edge of the plugin's
 area:
 -- edge=0: returns left edge coordinate
--- a/dom/plugins/test/testplugin/nptest.cpp
+++ b/dom/plugins/test/testplugin/nptest.cpp
@@ -120,16 +120,17 @@ static bool getClipRegionRectEdge(NPObje
 static bool startWatchingInstanceCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool getInstanceCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool stopWatchingInstanceCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool getLastMouseX(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool getLastMouseY(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool getPaintCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool getWidthAtLastPaint(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool setInvalidateDuringPaint(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
+static bool setSlowPaint(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool getError(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool doInternalConsistencyCheck(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool setColor(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool throwExceptionNextInvoke(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool convertPointX(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool convertPointY(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool streamTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
 static bool setPluginWantsAllStreams(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
@@ -181,16 +182,17 @@ static const NPUTF8* sPluginMethodIdenti
   "startWatchingInstanceCount",
   "getInstanceCount",
   "stopWatchingInstanceCount",
   "getLastMouseX",
   "getLastMouseY",
   "getPaintCount",
   "getWidthAtLastPaint",
   "setInvalidateDuringPaint",
+  "setSlowPaint",
   "getError",
   "doInternalConsistencyCheck",
   "setColor",
   "throwExceptionNextInvoke",
   "convertPointX",
   "convertPointY",
   "streamTest",
   "setPluginWantsAllStreams",
@@ -243,16 +245,17 @@ static const ScriptableFunction sPluginM
   startWatchingInstanceCount,
   getInstanceCount,
   stopWatchingInstanceCount,
   getLastMouseX,
   getLastMouseY,
   getPaintCount,
   getWidthAtLastPaint,
   setInvalidateDuringPaint,
+  setSlowPaint,
   getError,
   doInternalConsistencyCheck,
   setColor,
   throwExceptionNextInvoke,
   convertPointX,
   convertPointY,
   streamTest,
   setPluginWantsAllStreams,
@@ -494,16 +497,25 @@ static void sendBufferToFrame(NPP instan
     NPError err = NPN_GetURL(instance, outbuf.c_str(), 
                              instanceData->frame.c_str());
     if (err != NPERR_NO_ERROR) {
       instanceData->err << "NPN_GetURL returned " << err;
     }
   }
 }
 
+static void XPSleep(unsigned int seconds)
+{
+#ifdef XP_WIN
+  Sleep(1000 * seconds);
+#else
+  sleep(seconds);
+#endif
+}
+
 TestFunction
 getFuncFromString(const char* funcname)
 {
   FunctionTable funcTable[] = 
     {
       { FUNCTION_NPP_NEWSTREAM, "npp_newstream" },
       { FUNCTION_NPP_WRITEREADY, "npp_writeready" },
       { FUNCTION_NPP_WRITE, "npp_write" },
@@ -760,16 +772,17 @@ NPP_New(NPMIMEType pluginType, NPP insta
   instanceData->fileBuf = NULL;
   instanceData->fileBufSize = 0;
   instanceData->throwOnNextInvoke = false;
   instanceData->runScriptOnPaint = false;
   instanceData->testrange = NULL;
   instanceData->hasWidget = false;
   instanceData->npnNewStream = false;
   instanceData->invalidateDuringPaint = false;
+  instanceData->slowPaint = false;
   instanceData->writeCount = 0;
   instanceData->writeReadyCount = 0;
   memset(&instanceData->window, 0, sizeof(instanceData->window));
   instanceData->crashOnDestroy = false;
   instanceData->cleanupWidget = true; // only used by nptest_gtk
   instanceData->topLevelWindowActivationState = ACTIVATION_STATE_UNKNOWN;
   instanceData->topLevelWindowActivationEventCount = 0;
   instanceData->focusState = ACTIVATION_STATE_UNKNOWN;
@@ -2485,16 +2498,32 @@ setInvalidateDuringPaint(NPObject* npobj
 
   NPP npp = static_cast<TestNPObject*>(npobj)->npp;
   InstanceData* id = static_cast<InstanceData*>(npp->pdata);
   id->invalidateDuringPaint = doInvalidate;
   return true;
 }
 
 static bool
+setSlowPaint(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
+{
+  if (argCount != 1)
+    return false;
+
+  if (!NPVARIANT_IS_BOOLEAN(args[0]))
+    return false;
+  bool slow = NPVARIANT_TO_BOOLEAN(args[0]);
+
+  NPP npp = static_cast<TestNPObject*>(npobj)->npp;
+  InstanceData* id = static_cast<InstanceData*>(npp->pdata);
+  id->slowPaint = slow;
+  return true;
+}
+
+static bool
 getError(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
 {
   if (argCount != 0)
     return false;
 
   NPP npp = static_cast<TestNPObject*>(npobj)->npp;
   InstanceData* id = static_cast<InstanceData*>(npp->pdata);
   if (id->err.str().length() == 0)
@@ -2773,16 +2802,20 @@ void notifyDidPaint(InstanceData* instan
     NPRect r;
     r.left = 0;
     r.top = 0;
     r.right = instanceData->window.width;
     r.bottom = instanceData->window.height;
     NPN_InvalidateRect(instanceData->npp, &r);
   }
 
+  if (instanceData->slowPaint) {
+    XPSleep(1);
+  }
+
   if (instanceData->runScriptOnPaint) {
     NPObject* o = NULL;
     NPN_GetValue(instanceData->npp, NPNVPluginElementNPObject, &o);
     if (o) {
       NPVariant param;
       STRINGZ_TO_NPVARIANT("paintscript", param);
       NPVariant result;
       NPN_Invoke(instanceData->npp, o, NPN_GetStringIdentifier("getAttribute"),
@@ -3161,21 +3194,17 @@ struct GCRaceData
   NPObject* localFunc_;
 };
 
 static void
 FinishGCRace(void* closure)
 {
   GCRaceData* rd = static_cast<GCRaceData*>(closure);
 
-#ifdef XP_WIN
-  Sleep(5000);
-#else
-  sleep(5);
-#endif
+  XPSleep(5);
 
   NPVariant arg;
   OBJECT_TO_NPVARIANT(rd->localFunc_, arg);
 
   NPVariant result;
   bool ok = NPN_InvokeDefault(rd->npp_, rd->callback_, &arg, 1, &result);
   if (!ok)
     return;
--- a/dom/plugins/test/testplugin/nptest.h
+++ b/dom/plugins/test/testplugin/nptest.h
@@ -106,16 +106,17 @@ typedef struct InstanceData {
   bool hasWidget;
   bool npnNewStream;
   bool throwOnNextInvoke;
   bool runScriptOnPaint;
   uint32_t timerID[2];
   bool timerTestResult;
   bool asyncCallbackResult;
   bool invalidateDuringPaint;
+  bool slowPaint;
   int32_t winX;
   int32_t winY;
   int32_t lastMouseX;
   int32_t lastMouseY;
   int32_t widthAtLastPaint;
   int32_t paintCount;
   int32_t writeCount;
   int32_t writeReadyCount;
--- a/dom/settings/SettingsChangeNotifier.jsm
+++ b/dom/settings/SettingsChangeNotifier.jsm
@@ -3,54 +3,81 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict"
 
 function debug(s) {
 //  dump("-*- SettingsChangeNotifier: " + s + "\n");
 }
 
-const Cu = Components.utils; 
+const Cu = Components.utils;
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 
 let EXPORTED_SYMBOLS = ["SettingsChangeNotifier"];
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 
+const kXpcomShutdownObserverTopic      = "xpcom-shutdown";
+const kMozSettingsChangedObserverTopic = "mozsettings-changed";
+const kFromSettingsChangeNotifier      = "fromSettingsChangeNotifier";
+
 XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
                                    "@mozilla.org/parentprocessmessagemanager;1",
                                    "nsIMessageBroadcaster");
 
-
 let SettingsChangeNotifier = {
   init: function() {
     debug("init");
     ppmm.addMessageListener("Settings:Changed", this);
-    Services.obs.addObserver(this, "xpcom-shutdown", false);
+    Services.obs.addObserver(this, kXpcomShutdownObserverTopic, false);
+    Services.obs.addObserver(this, kMozSettingsChangedObserverTopic, false);
   },
 
   observe: function(aSubject, aTopic, aData) {
     debug("observe");
-    ppmm.removeMessageListener("Settings:Changed", this);
-    Services.obs.removeObserver(this, "xpcom-shutdown");
-    ppmm = null;
+    switch (aTopic) {
+      case kXpcomShutdownObserverTopic:
+        ppmm.removeMessageListener("Settings:Changed", this);
+        Services.obs.removeObserver(this, kXpcomShutdownObserverTopic);
+        Services.obs.removeObserver(this, kMozSettingsChangedObserverTopic);
+        ppmm = null;
+        break;
+      case kMozSettingsChangedObserverTopic:
+      {
+        let setting = JSON.parse(aData);
+        // To avoid redundantly broadcasting settings-changed events that are
+        // just requested from content processes themselves, skip the observer
+        // messages that are notified from the internal SettingsChangeNotifier.
+        if (setting.message && setting.message === kFromSettingsChangeNotifier)
+          return;
+        ppmm.broadcastAsyncMessage("Settings:Change:Return:OK",
+          { key: setting.key, value: setting.value });
+        break;
+      }
+      default:
+        debug("Wrong observer topic: " + aTopic);
+        break;
+    }
   },
 
   receiveMessage: function(aMessage) {
     debug("receiveMessage");
     let msg = aMessage.json;
     switch (aMessage.name) {
       case "Settings:Changed":
-        ppmm.broadcastAsyncMessage("Settings:Change:Return:OK", { key: msg.key, value: msg.value });
-        Services.obs.notifyObservers(this, "mozsettings-changed", JSON.stringify({
-          key: msg.key,
-          value: msg.value
-        }));
+        ppmm.broadcastAsyncMessage("Settings:Change:Return:OK",
+          { key: msg.key, value: msg.value });
+        Services.obs.notifyObservers(this, kMozSettingsChangedObserverTopic,
+          JSON.stringify({
+            key: msg.key,
+            value: msg.value,
+            message: kFromSettingsChangeNotifier
+          }));
         break;
-      default: 
+      default:
         debug("Wrong message: " + aMessage.name);
     }
   }
 }
 
 SettingsChangeNotifier.init();
--- a/dom/time/TimeManager.h
+++ b/dom/time/TimeManager.h
@@ -3,26 +3,27 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_time_TimeManager_h
 #define mozilla_dom_time_TimeManager_h
 
 #include "mozilla/HalTypes.h"
 #include "nsIDOMTimeManager.h"
 #include "mozilla/Observer.h"
+#include "mozilla/Attributes.h"
 
 class nsPIDOMWindow;
 
 namespace mozilla {
 
 typedef Observer<hal::SystemTimeChange> SystemTimeObserver;
 
 namespace dom {
 namespace time {
-class TimeManager : public nsIDOMMozTimeManager
+class TimeManager MOZ_FINAL : public nsIDOMMozTimeManager
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMMOZTIMEMANAGER
 };
 
 } // namespace time
 } // namespace dom
--- a/dom/time/nsIDOMTimeManager.idl
+++ b/dom/time/nsIDOMTimeManager.idl
@@ -6,15 +6,15 @@
 
 [scriptable, builtinclass, uuid(d29beaaa-bd54-4fd5-9f18-e0eedb1dc96d)]
 interface nsIDOMMozTimeManager : nsISupports
 {
   /* Set the system time.
    *
    * The |time| argument can be either a Date object or a number.
    *
-   * - If |time| is a number, it's interpreted as seconds since the epoch 
-   *   (midnight UTC on January 1, 1970)
-   * - If |time| is a Date object, |set(time)| is equivalent to 
+   * - If |time| is a number, it's interpreted as milliseconds
+   *   since the epoch (midnight UTC on January 1, 1970).
+   * - If |time| is a Date object, |set(time)| is equivalent to
    *   |set(time.getTime())|.
    */
   [implicit_jscontext] void set(in jsval time);
 };
--- a/editor/composer/src/nsComposerCommands.cpp
+++ b/editor/composer/src/nsComposerCommands.cpp
@@ -21,17 +21,16 @@
 #include "nsIDOMElement.h"              // for nsIDOMElement
 #include "nsIEditor.h"                  // for nsIEditor
 #include "nsIHTMLAbsPosEditor.h"        // for nsIHTMLAbsPosEditor
 #include "nsIHTMLEditor.h"              // for nsIHTMLEditor, etc
 #include "nsLiteralString.h"            // for NS_LITERAL_STRING
 #include "nsReadableUtils.h"            // for EmptyString
 #include "nsString.h"                   // for nsAutoString, nsString, etc
 #include "nsStringFwd.h"                // for nsAFlatString
-#include "prtypes.h"                    // for int32_t
 
 class nsISupports;
 
 //prototype
 nsresult GetListState(nsIHTMLEditor* aEditor, bool* aMixed,
                       nsAString& aLocalName);
 nsresult RemoveOneProperty(nsIHTMLEditor* aEditor, const nsAString& aProp);
 nsresult RemoveTextProperty(nsIHTMLEditor* aEditor, const nsAString& aProp);
--- a/editor/composer/src/nsComposerCommandsUpdater.h
+++ b/editor/composer/src/nsComposerCommandsUpdater.h
@@ -13,17 +13,16 @@
 #include "nsCOMPtr.h"                   // for already_AddRefed, nsCOMPtr
 #include "nsIDocumentStateListener.h"
 #include "nsISelectionListener.h"
 #include "nsISupportsImpl.h"            // for NS_DECL_ISUPPORTS
 #include "nsITimer.h"                   // for NS_DECL_NSITIMERCALLBACK, etc
 #include "nsITransactionListener.h"     // for nsITransactionListener
 #include "nsIWeakReferenceUtils.h"      // for nsWeakPtr
 #include "nscore.h"                     // for NS_IMETHOD, nsresult, etc
-#include "prtypes.h"                    // for int8_t
 
 class nsIDOMWindow;
 class nsITransaction;
 class nsITransactionManager;
 class nsPICommandUpdater;
 
 class nsComposerCommandsUpdater : public nsISelectionListener,
                                   public nsIDocumentStateListener,
--- a/editor/composer/src/nsComposerDocumentCommands.cpp
+++ b/editor/composer/src/nsComposerDocumentCommands.cpp
@@ -22,17 +22,16 @@
 #include "nsIPlaintextEditor.h"         // for nsIPlaintextEditor, etc
 #include "nsIPresShell.h"               // for nsIPresShell
 #include "nsISelectionController.h"     // for nsISelectionController
 #include "nsISupportsImpl.h"            // for nsPresContext::Release
 #include "nsISupportsUtils.h"           // for NS_IF_ADDREF
 #include "nsIURI.h"                     // for nsIURI
 #include "nsPresContext.h"              // for nsPresContext
 #include "nscore.h"                     // for NS_IMETHODIMP, nsresult, etc
-#include "prtypes.h"                    // for uint32_t, int32_t
 
 class nsISupports;
 
 //defines
 #define STATE_ENABLED  "state_enabled"
 #define STATE_ALL "state_all"
 #define STATE_ATTRIBUTE "state_attribute"
 #define STATE_DATA "state_data"
--- a/editor/composer/src/nsEditingSession.h
+++ b/editor/composer/src/nsEditingSession.h
@@ -12,17 +12,16 @@
 #endif
 
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsCOMPtr.h"                   // for nsCOMPtr
 #include "nsISupportsImpl.h"            // for NS_DECL_ISUPPORTS
 #include "nsIWeakReferenceUtils.h"      // for nsWeakPtr
 #include "nsWeakReference.h"            // for nsSupportsWeakReference, etc
 #include "nscore.h"                     // for nsresult
-#include "prtypes.h"                    // for uint32_t, uint16_t
 
 #ifndef __gen_nsIWebProgressListener_h__
 #include "nsIWebProgressListener.h"
 #endif
 
 #ifndef __gen_nsIEditingSession_h__
 #include "nsIEditingSession.h"          // for NS_DECL_NSIEDITINGSESSION, etc
 #endif
--- a/editor/composer/src/nsEditorSpellCheck.h
+++ b/editor/composer/src/nsEditorSpellCheck.h
@@ -9,17 +9,16 @@
 
 #include "nsCOMPtr.h"                   // for nsCOMPtr
 #include "nsCycleCollectionParticipant.h"
 #include "nsIEditorSpellCheck.h"        // for NS_DECL_NSIEDITORSPELLCHECK, etc
 #include "nsISupportsImpl.h"
 #include "nsString.h"                   // for nsString
 #include "nsTArray.h"                   // for nsTArray
 #include "nscore.h"                     // for nsresult
-#include "prtypes.h"                    // for int32_t
 
 class nsIEditor;
 class nsISpellChecker;
 class nsITextServicesFilter;
 
 #define NS_EDITORSPELLCHECK_CID                     \
 { /* {75656ad9-bd13-4c5d-939a-ec6351eea0cc} */        \
     0x75656ad9, 0xbd13, 0x4c5d,                       \
--- a/editor/libeditor/base/ChangeCSSInlineStyleTxn.cpp
+++ b/editor/libeditor/base/ChangeCSSInlineStyleTxn.cpp
@@ -15,17 +15,16 @@
 #include "nsIDOMElementCSSInlineStyle.h"
 #include "nsISupportsImpl.h"            // for EditTxn::QueryInterface, etc
 #include "nsISupportsUtils.h"           // for NS_ADDREF
 #include "nsLiteralString.h"            // for NS_LITERAL_STRING, etc
 #include "nsReadableUtils.h"            // for ToNewUnicode
 #include "nsString.h"                   // for nsAutoString, nsString, etc
 #include "nsUnicharUtils.h"
 #include "nsXPCOM.h"                    // for NS_Free
-#include "prtypes.h"                    // for PRUnichar, uint32_t
 
 class nsIEditor;
 
 #define kNullCh (PRUnichar('\0'))
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(ChangeCSSInlineStyleTxn)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ChangeCSSInlineStyleTxn,
--- a/editor/libeditor/base/CreateElementTxn.h
+++ b/editor/libeditor/base/CreateElementTxn.h
@@ -8,17 +8,16 @@
 
 #include "EditTxn.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIDOMNode.h"
 #include "nsISupportsImpl.h"
 #include "nsString.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 class nsEditor;
 
 /**
  * A transaction that creates a new node in the content tree.
  */
 class CreateElementTxn : public EditTxn
 {
--- a/editor/libeditor/base/DeleteRangeTxn.h
+++ b/editor/libeditor/base/DeleteRangeTxn.h
@@ -10,17 +10,16 @@
 #include "EditTxn.h"
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsID.h"
 #include "nsIEditor.h"
 #include "nsISupportsImpl.h"
 #include "nsRange.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 class nsEditor;
 class nsINode;
 class nsRangeUpdater;
 
 /**
  * A transaction that deletes an entire range in the content tree
  */
--- a/editor/libeditor/base/DeleteTextTxn.h
+++ b/editor/libeditor/base/DeleteTextTxn.h
@@ -8,17 +8,16 @@
 
 #include "EditTxn.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsID.h"
 #include "nsIDOMCharacterData.h"
 #include "nsString.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 class nsEditor;
 class nsRangeUpdater;
 
 /**
  * A transaction that removes text from a content node.
  */
 class DeleteTextTxn : public EditTxn
--- a/editor/libeditor/base/EditAggregateTxn.cpp
+++ b/editor/libeditor/base/EditAggregateTxn.cpp
@@ -5,17 +5,16 @@
 
 #include "EditAggregateTxn.h"
 #include "nsAString.h"
 #include "nsCOMPtr.h"                   // for nsCOMPtr
 #include "nsError.h"                    // for NS_OK, etc
 #include "nsISupportsUtils.h"           // for NS_ADDREF
 #include "nsITransaction.h"             // for nsITransaction
 #include "nsString.h"                   // for nsAutoString
-#include "prtypes.h"                    // for uint32_t
 
 EditAggregateTxn::EditAggregateTxn()
   : EditTxn()
 {
 }
 NS_IMPL_CYCLE_COLLECTION_CLASS(EditAggregateTxn)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(EditAggregateTxn, EditTxn)
--- a/editor/libeditor/base/IMETextTxn.h
+++ b/editor/libeditor/base/IMETextTxn.h
@@ -9,17 +9,16 @@
 #include "EditTxn.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsID.h"
 #include "nsIDOMCharacterData.h"
 #include "nsIPrivateTextRange.h"
 #include "nsString.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 class nsITransaction;
 
 // {D4D25721-2813-11d3-9EA3-0060089FE59B}
 #define IME_TEXT_TXN_CID							\
 {0xd4d25721, 0x2813, 0x11d3,						\
 {0x9e, 0xa3, 0x0, 0x60, 0x8, 0x9f, 0xe5, 0x9b }}
 
--- a/editor/libeditor/base/InsertElementTxn.h
+++ b/editor/libeditor/base/InsertElementTxn.h
@@ -7,17 +7,16 @@
 #define InsertElementTxn_h__
 
 #include "EditTxn.h"                    // for EditTxn, NS_DECL_EDITTXN
 #include "nsCOMPtr.h"                   // for nsCOMPtr
 #include "nsCycleCollectionParticipant.h"
 #include "nsIDOMNode.h"                 // for nsIDOMNode
 #include "nsISupportsImpl.h"            // for NS_DECL_ISUPPORTS_INHERITED
 #include "nscore.h"                     // for NS_IMETHOD
-#include "prtypes.h"                    // for int32_t
 
 class nsIEditor;
 
 /**
  * A transaction that inserts a single element
  */
 class InsertElementTxn : public EditTxn
 {
--- a/editor/libeditor/base/InsertTextTxn.h
+++ b/editor/libeditor/base/InsertTextTxn.h
@@ -9,17 +9,16 @@
 #include "EditTxn.h"                    // for EditTxn, NS_DECL_EDITTXN
 #include "nsCOMPtr.h"                   // for nsCOMPtr
 #include "nsCycleCollectionParticipant.h"
 #include "nsID.h"                       // for nsIID
 #include "nsIDOMCharacterData.h"        // for nsIDOMCharacterData
 #include "nsISupportsImpl.h"            // for NS_DECL_ISUPPORTS_INHERITED
 #include "nsString.h"                   // for nsString
 #include "nscore.h"                     // for NS_IMETHOD, nsAString
-#include "prtypes.h"                    // for uint32_t
 
 class nsIEditor;
 class nsITransaction;
 
 
 #define INSERT_TEXT_TXN_CID \
 {/* 93276f00-ab2c-11d2-8f4b-006008159b0c*/ \
 0x93276f00, 0xab2c, 0x11d2, \
--- a/editor/libeditor/base/JoinElementTxn.h
+++ b/editor/libeditor/base/JoinElementTxn.h
@@ -7,17 +7,16 @@
 #define JoinElementTxn_h__
 
 #include "EditTxn.h"                    // for EditTxn, NS_DECL_EDITTXN
 #include "nsCOMPtr.h"                   // for nsCOMPtr
 #include "nsCycleCollectionParticipant.h"
 #include "nsID.h"                       // for REFNSIID
 #include "nsIDOMNode.h"                 // for nsIDOMNode
 #include "nscore.h"                     // for NS_IMETHOD
-#include "prtypes.h"                    // for uint32_t
 
 class nsEditor;
 
 /**
  * A transaction that joins two elements E1 (left node) and E2 (right node)
  * into a single node E.  
  * The children of E are the children of E1 followed by the children of E2.
  * After DoTransaction() and RedoTransaction(), E1 is removed from the content
--- a/editor/libeditor/base/SetDocTitleTxn.cpp
+++ b/editor/libeditor/base/SetDocTitleTxn.cpp
@@ -14,17 +14,16 @@
 #include "nsIDOMElement.h"              // for nsIDOMElement
 #include "nsIDOMNode.h"                 // for nsIDOMNode
 #include "nsIDOMNodeList.h"             // for nsIDOMNodeList
 #include "nsIDOMText.h"                 // for nsIDOMText
 #include "nsIDocument.h"                // for nsIDocument
 #include "nsIEditor.h"                  // for nsIEditor
 #include "nsIHTMLEditor.h"              // for nsIHTMLEditor
 #include "nsLiteralString.h"            // for NS_LITERAL_STRING
-#include "prtypes.h"                    // for uint32_t
 
 using namespace mozilla;
 
 // note that aEditor is not refcounted
 SetDocTitleTxn::SetDocTitleTxn()
   : EditTxn()
 , mIsTransient(false)
 {
--- a/editor/libeditor/base/SplitElementTxn.h
+++ b/editor/libeditor/base/SplitElementTxn.h
@@ -7,17 +7,16 @@
 #define SplitElementTxn_h__
 
 #include "EditTxn.h"                    // for EditTxn, NS_DECL_EDITTXN
 #include "nsCOMPtr.h"                   // for nsCOMPtr
 #include "nsCycleCollectionParticipant.h"
 #include "nsIDOMNode.h"                 // for nsIDOMNode
 #include "nsISupportsImpl.h"            // for NS_DECL_ISUPPORTS_INHERITED
 #include "nscore.h"                     // for NS_IMETHOD
-#include "prtypes.h"                    // for int32_t
 
 class nsEditor;
 
 /**
  * A transaction that splits an element E into two identical nodes, E1 and E2
  * with the children of E divided between E1 and E2.
  */
 class SplitElementTxn : public EditTxn
--- a/editor/libeditor/base/nsEditor.h
+++ b/editor/libeditor/base/nsEditor.h
@@ -19,17 +19,16 @@
 #include "nsIPlaintextEditor.h"         // for nsIPlaintextEditor, etc
 #include "nsISupportsImpl.h"            // for nsEditor::Release, etc
 #include "nsIWeakReferenceUtils.h"      // for nsWeakPtr
 #include "nsLiteralString.h"            // for NS_LITERAL_STRING
 #include "nsSelectionState.h"           // for nsRangeUpdater, etc
 #include "nsString.h"                   // for nsCString
 #include "nsWeakReference.h"            // for nsSupportsWeakReference
 #include "nscore.h"                     // for nsresult, nsAString, etc
-#include "prtypes.h"                    // for int32_t, uint32_t, int8_t, etc
 
 class AddStyleSheetTxn;
 class ChangeAttributeTxn;
 class CreateElementTxn;
 class DeleteNodeTxn;
 class DeleteTextTxn;
 class EditAggregateTxn;
 class IMETextTxn;
--- a/editor/libeditor/base/nsEditorCommands.cpp
+++ b/editor/libeditor/base/nsEditorCommands.cpp
@@ -19,17 +19,16 @@
 #include "nsIEditor.h"
 #include "nsIEditorMailSupport.h"
 #include "nsIPlaintextEditor.h"
 #include "nsISelection.h"
 #include "nsISelectionController.h"
 #include "nsITransferable.h"
 #include "nsString.h"
 #include "nsAString.h"
-#include "prtypes.h"
 
 class nsISupports;
 
 
 #define STATE_ENABLED  "state_enabled"
 #define STATE_DATA "state_data"
 
 
--- a/editor/libeditor/base/nsEditorEventListener.cpp
+++ b/editor/libeditor/base/nsEditorEventListener.cpp
@@ -43,17 +43,16 @@
 #include "nsIPrivateTextRange.h"        // for nsIPrivateTextRangeList
 #include "nsISelection.h"               // for nsISelection
 #include "nsISelectionController.h"     // for nsISelectionController, etc
 #include "nsISelectionPrivate.h"        // for nsISelectionPrivate
 #include "nsITransferable.h"            // for kFileMime, kHTMLMime, etc
 #include "nsLiteralString.h"            // for NS_LITERAL_STRING
 #include "nsServiceManagerUtils.h"      // for do_GetService
 #include "nsString.h"                   // for nsAutoString
-#include "prtypes.h"                    // for int32_t, uint16_t, uint32_t
 #ifdef HANDLE_NATIVE_TEXT_DIRECTION_SWITCH
 #include "nsContentUtils.h"             // for nsContentUtils, etc
 #include "nsIBidiKeyboard.h"            // for nsIBidiKeyboard
 #endif
 
 class nsPresContext;
 
 using namespace mozilla;
--- a/editor/libeditor/base/nsEditorUtils.h
+++ b/editor/libeditor/base/nsEditorUtils.h
@@ -9,17 +9,16 @@
 
 
 #include "nsCOMPtr.h"
 #include "nsDebug.h"
 #include "nsEditor.h"
 #include "nsIDOMNode.h"
 #include "nsIEditor.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 class nsIAtom;
 class nsIContentIterator;
 class nsIDOMDocument;
 class nsIDOMRange;
 class nsISelection;
 template <class E> class nsCOMArray;
 
--- a/editor/libeditor/base/nsSelectionState.h
+++ b/editor/libeditor/base/nsSelectionState.h
@@ -6,17 +6,16 @@
 #ifndef __selectionstate_h__
 #define __selectionstate_h__
 
 #include "nsCOMPtr.h"
 #include "nsIDOMNode.h"
 #include "nsINode.h"
 #include "nsTArray.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 class nsCycleCollectionTraversalCallback;
 class nsIDOMCharacterData;
 class nsIDOMRange;
 class nsISelection;
 class nsRange;
 namespace mozilla {
 class Selection;
--- a/editor/libeditor/html/TextEditorTest.h
+++ b/editor/libeditor/html/TextEditorTest.h
@@ -2,17 +2,16 @@
 /* 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/. */
 
 #ifndef __TextEditorTest_h__
 #define __TextEditorTest_h__
 
 #include "nscore.h"
-#include "prtypes.h"
 
 class nsIEditor;
 class nsIPlaintextEditor;
 #ifdef DEBUG
 
 #include "nsCOMPtr.h"
 
 class TextEditorTest
--- a/editor/libeditor/html/TypeInState.h
+++ b/editor/libeditor/html/TypeInState.h
@@ -8,17 +8,16 @@
 
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsISelectionListener.h"
 #include "nsISupportsImpl.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 class nsIAtom;
 class nsIDOMNode;
 class nsISelection;
 
 struct PropItem
 {
   nsIAtom *tag;
--- a/editor/libeditor/html/nsHTMLAbsPosition.cpp
+++ b/editor/libeditor/html/nsHTMLAbsPosition.cpp
@@ -45,17 +45,16 @@
 #include "nsISupportsUtils.h"
 #include "nsLiteralString.h"
 #include "nsReadableUtils.h"
 #include "nsString.h"
 #include "nsStringFwd.h"
 #include "nsTextEditRules.h"
 #include "nsTextEditUtils.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 using namespace mozilla;
 
 #define  BLACK_BG_RGB_TRIGGER 0xd0
 
 NS_IMETHODIMP
 nsHTMLEditor::AbsolutePositionSelection(bool aEnabled)
 {
--- a/editor/libeditor/html/nsHTMLAnonymousUtils.cpp
+++ b/editor/libeditor/html/nsHTMLAnonymousUtils.cpp
@@ -39,17 +39,16 @@
 #include "nsISupportsUtils.h"
 #include "nsLiteralString.h"
 #include "nsPresContext.h"
 #include "nsReadableUtils.h"
 #include "nsString.h"
 #include "nsStringFwd.h"
 #include "nsUnicharUtils.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 class nsIDOMEventListener;
 class nsISelection;
 
 using namespace mozilla;
 
 // retrieve an integer stored into a CSS computed float value
 static int32_t GetCSSFloatValue(nsIDOMCSSStyleDeclaration * aDecl,
--- a/editor/libeditor/html/nsHTMLCSSUtils.h
+++ b/editor/libeditor/html/nsHTMLCSSUtils.h
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsHTMLCSSUtils_h__
 #define nsHTMLCSSUtils_h__
 
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsTArray.h"                   // for nsTArray
 #include "nscore.h"                     // for nsAString, nsresult, nullptr
-#include "prtypes.h"                    // for uint8_t, int32_t, uint32_t
 
 class ChangeCSSInlineStyleTxn;
 class nsComputedDOMStyle;
 class nsIAtom;
 class nsIContent;
 class nsIDOMCSSStyleDeclaration;
 class nsIDOMElement;
 class nsIDOMNode;
--- a/editor/libeditor/html/nsHTMLDataTransfer.cpp
+++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp
@@ -86,17 +86,16 @@
 #include "nsTextEditRules.h"
 #include "nsTextEditUtils.h"
 #include "nsTreeSanitizer.h"
 #include "nsWSRunObject.h"
 #include "nsXPCOM.h"
 #include "nscore.h"
 #include "plbase64.h"
 #include "prmem.h"
-#include "prtypes.h"
 
 class nsIAtom;
 class nsILoadContext;
 class nsISupports;
 
 using namespace mozilla;
 
 const PRUnichar nbsp = 160;
--- a/editor/libeditor/html/nsHTMLEditRules.h
+++ b/editor/libeditor/html/nsHTMLEditRules.h
@@ -14,17 +14,16 @@
 #include "nsIEditor.h"
 #include "nsIHTMLEditor.h"
 #include "nsISupportsImpl.h"
 #include "nsSelectionState.h"
 #include "nsTArray.h"
 #include "nsTextEditRules.h"
 #include "nsTraceRefcnt.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 class nsHTMLEditor;
 class nsIAtom;
 class nsIDOMCharacterData;
 class nsIDOMDocument;
 class nsIDOMElement;
 class nsIDOMNode;
 class nsIDOMRange;
--- a/editor/libeditor/html/nsHTMLEditUtils.h
+++ b/editor/libeditor/html/nsHTMLEditUtils.h
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 #ifndef nsHTMLEditUtils_h__
 #define nsHTMLEditUtils_h__
 
-#include "prtypes.h"  // for int32_t
 
 class nsIDOMNode;
 class nsINode;
 
 class nsHTMLEditUtils
 {
 public:
   // from nsTextEditRules:
--- a/editor/libeditor/html/nsHTMLEditorEventListener.cpp
+++ b/editor/libeditor/html/nsHTMLEditorEventListener.cpp
@@ -18,17 +18,16 @@
 #include "nsIDOMRange.h"
 #include "nsIEditor.h"
 #include "nsIHTMLEditor.h"
 #include "nsIHTMLInlineTableEditor.h"
 #include "nsIHTMLObjectResizer.h"
 #include "nsISelection.h"
 #include "nsISupportsImpl.h"
 #include "nsLiteralString.h"
-#include "prtypes.h"
 
 /*
  * nsHTMLEditorEventListener implementation
  *
  */
 
 #ifdef DEBUG
 nsresult
--- a/editor/libeditor/html/nsHTMLEditorStyle.cpp
+++ b/editor/libeditor/html/nsHTMLEditorStyle.cpp
@@ -44,17 +44,16 @@
 #include "nsSelectionState.h"
 #include "nsString.h"
 #include "nsStringFwd.h"
 #include "nsTArray.h"
 #include "nsTextEditRules.h"
 #include "nsTextEditUtils.h"
 #include "nsUnicharUtils.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 class nsISupports;
 
 using namespace mozilla;
 
 NS_IMETHODIMP nsHTMLEditor::AddDefaultProperty(nsIAtom *aProperty, 
                                             const nsAString & aAttribute, 
                                             const nsAString & aValue)
--- a/editor/libeditor/html/nsHTMLInlineTableEditor.cpp
+++ b/editor/libeditor/html/nsHTMLInlineTableEditor.cpp
@@ -16,17 +16,16 @@
 #include "nsIDOMNode.h"
 #include "nsIHTMLEditor.h"
 #include "nsIHTMLObjectResizer.h"
 #include "nsIPresShell.h"
 #include "nsLiteralString.h"
 #include "nsReadableUtils.h"
 #include "nsString.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 // Uncomment the following line if you want to disable
 // table deletion when the only column/row is removed
 // #define DISABLE_TABLE_DELETION 1
 
 NS_IMETHODIMP
 nsHTMLEditor::SetInlineTableEditingEnabled(bool aIsEnabled)
 {
--- a/editor/libeditor/html/nsHTMLObjectResizer.cpp
+++ b/editor/libeditor/html/nsHTMLObjectResizer.cpp
@@ -37,17 +37,16 @@
 #include "nsIPresShell.h"
 #include "nsISupportsUtils.h"
 #include "nsPIDOMWindow.h"
 #include "nsReadableUtils.h"
 #include "nsString.h"
 #include "nsStringFwd.h"
 #include "nsSubstringTuple.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 class nsISelection;
 
 using namespace mozilla;
 
 class nsHTMLEditUtils;
 
 // ==================================================================
--- a/editor/libeditor/html/nsHTMLURIRefObject.h
+++ b/editor/libeditor/html/nsHTMLURIRefObject.h
@@ -3,17 +3,16 @@
  * 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/. */
 
 
 #include "nsCOMPtr.h"
 #include "nsISupportsImpl.h"
 #include "nsIURIRefObject.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 class nsIDOMNamedNodeMap;
 class nsIDOMNode;
 
 #ifndef nsHTMLURIRefObject_h__
 #define nsHTMLURIRefObject_h__
 
 #define NS_URI_REF_OBJECT_CID                          \
--- a/editor/libeditor/html/nsTableEditor.cpp
+++ b/editor/libeditor/html/nsTableEditor.cpp
@@ -33,17 +33,16 @@
 #include "nsITableCellLayout.h" // For efficient access to table cell
 #include "nsITableEditor.h"
 #include "nsITableLayout.h"     //  data owned by the table and cell frames
 #include "nsLiteralString.h"
 #include "nsQueryFrame.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 using namespace mozilla;
 
 /***************************************************************************
  * stack based helper class for restoring selection after table edit
  */
 class NS_STACK_CLASS nsSetSelectionAfterTableEdit
 {
--- a/editor/libeditor/html/nsWSRunObject.h
+++ b/editor/libeditor/html/nsWSRunObject.h
@@ -8,17 +8,16 @@
 
 #include "nsCOMArray.h"
 #include "nsCOMPtr.h"
 #include "nsIContent.h"
 #include "nsIDOMNode.h"
 #include "nsIEditor.h"
 #include "nsINode.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 class nsHTMLEditor;
 class nsIDOMDocument;
 class nsIDOMNode;
 struct DOMPoint;
 
 // class nsWSRunObject represents the entire whitespace situation
 // around a given point.  It collects up a list of nodes that contain
--- a/editor/libeditor/text/nsInternetCiter.h
+++ b/editor/libeditor/text/nsInternetCiter.h
@@ -2,17 +2,16 @@
 /* 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/. */
 
 #ifndef nsInternetCiter_h__
 #define nsInternetCiter_h__
 
 #include "nscore.h"
-#include "prtypes.h"
 
 /** Mail citations using standard Internet style.
   */
 class nsInternetCiter
 {
 public:
   static nsresult GetCiteString(const nsAString & aInString, nsAString & aOutString);
 
--- a/editor/libeditor/text/nsPlaintextDataTransfer.cpp
+++ b/editor/libeditor/text/nsPlaintextDataTransfer.cpp
@@ -39,17 +39,16 @@
 #include "nsIVariant.h"
 #include "nsLiteralString.h"
 #include "nsPlaintextEditor.h"
 #include "nsSelectionState.h"
 #include "nsServiceManagerUtils.h"
 #include "nsString.h"
 #include "nsXPCOM.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 class nsILoadContext;
 class nsISupports;
 
 using namespace mozilla;
 
 NS_IMETHODIMP nsPlaintextEditor::PrepareTransferable(nsITransferable **transferable)
 {
--- a/editor/libeditor/text/nsPlaintextEditor.h
+++ b/editor/libeditor/text/nsPlaintextEditor.h
@@ -9,17 +9,16 @@
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsEditor.h"
 #include "nsIEditor.h"
 #include "nsIEditorMailSupport.h"
 #include "nsIPlaintextEditor.h"
 #include "nsISupportsImpl.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 class nsIContent;
 class nsIDOMDataTransfer;
 class nsIDOMDocument;
 class nsIDOMElement;
 class nsIDOMEvent;
 class nsIDOMEventTarget;
 class nsIDOMKeyEvent;
--- a/editor/libeditor/text/nsTextEditRules.h
+++ b/editor/libeditor/text/nsTextEditRules.h
@@ -11,17 +11,16 @@
 #include "nsEditRules.h"
 #include "nsEditor.h"
 #include "nsIEditor.h"
 #include "nsISupportsImpl.h"
 #include "nsITimer.h"
 #include "nsPlaintextEditor.h"
 #include "nsString.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 class nsIDOMElement;
 class nsIDOMNode;
 class nsISelection;
 namespace mozilla {
 class Selection;
 }  // namespace mozilla
 
--- a/editor/libeditor/text/nsTextEditRulesBidi.cpp
+++ b/editor/libeditor/text/nsTextEditRulesBidi.cpp
@@ -14,17 +14,16 @@
 #include "nsIPresShell.h"
 #include "nsISelection.h"
 #include "nsISelectionPrivate.h"
 #include "nsISupportsImpl.h"
 #include "nsPlaintextEditor.h"
 #include "nsPresContext.h"
 #include "nsTextEditRules.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 // Test for distance between caret and text that will be deleted
 nsresult
 nsTextEditRules::CheckBidiLevelForDeletion(nsISelection         *aSelection,
                                            nsIDOMNode           *aSelNode, 
                                            int32_t               aSelOffset, 
                                            nsIEditor::EDirection aAction,
                                            bool                 *aCancel)
--- a/editor/txmgr/src/nsTransactionItem.h
+++ b/editor/txmgr/src/nsTransactionItem.h
@@ -5,17 +5,16 @@
 
 #ifndef nsTransactionItem_h__
 #define nsTransactionItem_h__
 
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsISupportsImpl.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 class nsITransaction;
 class nsTransactionManager;
 class nsTransactionStack;
 
 class nsTransactionItem
 {
   nsCOMPtr<nsITransaction> mTransaction;
--- a/editor/txmgr/src/nsTransactionList.cpp
+++ b/editor/txmgr/src/nsTransactionList.cpp
@@ -9,17 +9,16 @@
 #include "nsError.h"
 #include "nsID.h"
 #include "nsISupportsUtils.h"
 #include "nsITransactionManager.h"
 #include "nsTransactionItem.h"
 #include "nsTransactionList.h"
 #include "nsTransactionStack.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 NS_IMPL_ISUPPORTS1(nsTransactionList, nsITransactionList)
 
 nsTransactionList::nsTransactionList(nsITransactionManager *aTxnMgr, nsTransactionStack *aTxnStack)
   : mTxnStack(aTxnStack)
   , mTxnItem(0)
 {
   if (aTxnMgr)
--- a/editor/txmgr/src/nsTransactionManager.h
+++ b/editor/txmgr/src/nsTransactionManager.h
@@ -9,17 +9,16 @@
 #include "nsCOMArray.h"
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsISupportsImpl.h"
 #include "nsITransactionManager.h"
 #include "nsTransactionStack.h"
 #include "nsWeakReference.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 class nsITransaction;
 class nsITransactionListener;
 class nsTransactionItem;
 
 /** implementation of a transaction manager object.
  *
  */
--- a/editor/txmgr/src/nsTransactionStack.h
+++ b/editor/txmgr/src/nsTransactionStack.h
@@ -3,17 +3,16 @@
  * 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/. */
 
 #ifndef nsTransactionStack_h__
 #define nsTransactionStack_h__
 
 #include "nsCOMPtr.h"
 #include "nsDeque.h"
-#include "prtypes.h"
 
 class nsCycleCollectionTraversalCallback;
 class nsTransactionItem;
 
 class nsTransactionStack
 {
 public:
   enum Type { FOR_UNDO, FOR_REDO };
--- a/editor/txtsvc/src/nsFilteredContentIterator.cpp
+++ b/editor/txtsvc/src/nsFilteredContentIterator.cpp
@@ -14,17 +14,16 @@
 #include "nsIContentIterator.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMRange.h"
 #include "nsINode.h"
 #include "nsISupportsBase.h"
 #include "nsISupportsUtils.h"
 #include "nsITextServicesFilter.h"
 #include "nsRange.h"
-#include "prtypes.h"
 
 //------------------------------------------------------------
 nsFilteredContentIterator::nsFilteredContentIterator(nsITextServicesFilter* aFilter) :
   mFilter(aFilter),
   mDidSkip(false),
   mIsOutOfRange(false),
   mDirection(eDirNotSet)
 {
--- a/editor/txtsvc/src/nsTextServicesDocument.h
+++ b/editor/txtsvc/src/nsTextServicesDocument.h
@@ -9,17 +9,16 @@
 #include "nsCOMPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIEditActionListener.h"
 #include "nsISupportsImpl.h"
 #include "nsITextServicesDocument.h"
 #include "nsIWeakReferenceUtils.h"
 #include "nsTArray.h"
 #include "nscore.h"
-#include "prtypes.h"
 
 class OffsetEntry;
 class nsIAtom;
 class nsIContent;
 class nsIContentIterator;
 class nsIDOMCharacterData;
 class nsIDOMDocument;
 class nsIDOMNode;
--- a/embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp
+++ b/embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp
@@ -2208,17 +2208,23 @@ nsWebBrowserPersist::CalculateAndAppendF
                     mimeInfo->GetPrimaryExtension(fileExt);
                 } 
 
                 if (!fileExt.IsEmpty())
                 {
                     uint32_t newLength = newFileName.Length() + fileExt.Length() + 1;
                     if (newLength > kDefaultMaxFilenameLength)
                     {
-                        newFileName.Truncate(newFileName.Length() - (newLength - kDefaultMaxFilenameLength));
+                        if (fileExt.Length() > kDefaultMaxFilenameLength/2)
+                            fileExt.Truncate(kDefaultMaxFilenameLength/2);
+
+                        uint32_t diff = kDefaultMaxFilenameLength - 1 -
+                                        fileExt.Length();
+                        if (newFileName.Length() > diff)
+                            newFileName.Truncate(diff);
                     }
                     newFileName.Append(".");
                     newFileName.Append(fileExt);
                 }
 
                 if (localFile)
                 {
                     localFile->SetLeafName(NS_ConvertUTF8toUTF16(newFileName));
--- a/extensions/cookie/test/unit/test_cookies_sync_failure.js
+++ b/extensions/cookie/test/unit/test_cookies_sync_failure.js
@@ -13,16 +13,18 @@
 // 4) Migration fails. This will have different modes depending on the initial
 //    version:
 //    a) Schema 1: the 'lastAccessed' column already exists.
 //    b) Schema 2: the 'baseDomain' column already exists; or 'baseDomain'
 //       cannot be computed for a particular host.
 //    c) Schema 3: the 'creationTime' column already exists; or the
 //       'moz_uniqueid' index already exists.
 
+let COOKIE_DATABASE_SCHEMA_CURRENT = 5;
+
 let test_generator = do_run_test();
 
 function run_test() {
   do_test_pending();
   do_run_generator(test_generator);
 }
 
 function finish_test() {
@@ -57,16 +59,20 @@ function do_run_test() {
   this.sub_generator = run_test_2(test_generator);
   sub_generator.next();
   yield;
 
   this.sub_generator = run_test_3(test_generator, 99);
   sub_generator.next();
   yield;
 
+  this.sub_generator = run_test_3(test_generator, COOKIE_DATABASE_SCHEMA_CURRENT);
+  sub_generator.next();
+  yield;
+
   this.sub_generator = run_test_3(test_generator, 4);
   sub_generator.next();
   yield;
 
   this.sub_generator = run_test_3(test_generator, 3);
   sub_generator.next();
   yield;
 
@@ -201,17 +207,17 @@ function run_test_3(generator, schema)
   do_check_eq(do_count_cookies(), 0);
 
   // Close the profile.
   do_close_profile(sub_generator);
   yield;
 
   // Check that the schema version has been reset.
   let db = Services.storage.openDatabase(cookieFile);
-  do_check_eq(db.schemaVersion, 4);
+  do_check_eq(db.schemaVersion, COOKIE_DATABASE_SCHEMA_CURRENT);
   db.close();
 
   // Clean up.
   cookieFile.remove(false);
   do_check_false(cookieFile.exists());
   do_run_generator(generator);
 }
 
@@ -228,17 +234,17 @@ function run_test_4_exists(generator, sc
   do_check_eq(do_count_cookies(), 0);
 
   // Close the profile.
   do_close_profile(sub_generator);
   yield;
 
   // Check that the schema version has been reset and the backup file exists.
   db = Services.storage.openDatabase(cookieFile);
-  do_check_eq(db.schemaVersion, 4);
+  do_check_eq(db.schemaVersion, COOKIE_DATABASE_SCHEMA_CURRENT);
   db.close();
   do_check_true(backupFile.exists());
 
   // Clean up.
   cookieFile.remove(false);
   backupFile.remove(false);
   do_check_false(cookieFile.exists());
   do_check_false(backupFile.exists());
@@ -259,17 +265,17 @@ function run_test_4_baseDomain(generator
   do_check_eq(do_count_cookies(), 0);
 
   // Close the profile.
   do_close_profile(sub_generator);
   yield;
 
   // Check that the schema version has been reset and the backup file exists.
   db = Services.storage.openDatabase(cookieFile);
-  do_check_eq(db.schemaVersion, 4);
+  do_check_eq(db.schemaVersion, COOKIE_DATABASE_SCHEMA_CURRENT);
   db.close();
   do_check_true(backupFile.exists());
 
   // Clean up.
   cookieFile.remove(false);
   backupFile.remove(false);
   do_check_false(cookieFile.exists());
   do_check_false(backupFile.exists());
--- a/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
+++ b/extensions/pref/autoconfig/src/nsJSConfigTriggers.cpp
@@ -126,17 +126,20 @@ nsresult CentralizedAdminPrefManagerInit
 
     JS_SetErrorReporter(autoconfig_cx, autoConfigErrorReporter);
 
     // Create a new Security Manger and set it for the new JS context
     nsCOMPtr<nsIXPCSecurityManager> secman =
         static_cast<nsIXPCSecurityManager*>(new AutoConfigSecMan());
     xpc->SetSecurityManagerForJSContext(autoconfig_cx, secman, 0);
 
-    autoconfig_glob = JS_NewGlobalObject(autoconfig_cx, &global_class, NULL);
+
+    nsCOMPtr<nsIPrincipal> principal;
+    nsContentUtils::GetSecurityManager()->GetSystemPrincipal(getter_AddRefs(principal));
+    autoconfig_glob = JS_NewGlobalObject(autoconfig_cx, &global_class, nsJSPrincipals::get(principal));
     if (autoconfig_glob) {
         JSAutoCompartment ac(autoconfig_cx, autoconfig_glob);
         if (JS_InitStandardClasses(autoconfig_cx, autoconfig_glob)) {
             // XPCONNECT enable this JS context
             rv = xpc->InitClasses(autoconfig_cx, autoconfig_glob);
             if (NS_SUCCEEDED(rv)) 
                 return NS_OK;
         }
--- a/gfx/2d/DrawTargetD2D.cpp
+++ b/gfx/2d/DrawTargetD2D.cpp
@@ -95,17 +95,29 @@ public:
 
     hr = mDT->mRT->CreateSharedBitmap(IID_IDXGISurface, surf,
                                       &props, byRef(mOldSurfBitmap));
 
     if (FAILED(hr)) {
       gfxWarning() << "Failed to create shared bitmap for old surface.";
     }
 
-    mClippedArea = mDT->GetClippedGeometry();
+    IntRect clipBounds;
+    mClippedArea = mDT->GetClippedGeometry(&clipBounds);
+
+    if (!clipBounds.IsEqualEdges(IntRect(IntPoint(0, 0), mDT->mSize))) {
+      // We still need to take into account clipBounds if it contains additional
+      // clipping information.
+      RefPtr<ID2D1RectangleGeometry> rectGeom;
+      factory()->CreateRectangleGeometry(D2D1::Rect(clipBounds.x, clipBounds.y,
+                                                    clipBounds.XMost(), clipBounds.YMost()),
+                                         byRef(rectGeom));
+
+      mClippedArea = mDT->Intersect(mClippedArea, rectGeom);
+    }
   }
 
   ID2D1Factory *factory() { return mDT->factory(); }
 
   ~AutoSaveRestoreClippedOut()
   {
     if (!mOldSurfBitmap) {
       return;
@@ -320,16 +332,18 @@ DrawTargetD2D::DrawSurfaceWithShadow(Sou
                                      Float aSigma,
                                      CompositionOp aOperator)
 {
   RefPtr<ID3D10ShaderResourceView> srView = nullptr;
   if (aSurface->GetType() != SURFACE_D2D1_DRAWTARGET) {
     return;
   }
 
+  SetScissorToRect(nullptr);
+
   // XXX - This function is way too long, it should be split up soon to make
   // it more graspable!
 
   Flush();
 
   AutoSaveRestoreClippedOut restoreClippedOut(this);
 
   if (!IsOperatorBoundByMask(aOperator)) {
@@ -352,18 +366,19 @@ DrawTargetD2D::DrawSurfaceWithShadow(Sou
 
 
   RefPtr<ID3D10RenderTargetView> destRTView = mRTView;
   RefPtr<ID3D10Texture2D> destTexture;
   HRESULT hr;
 
   RefPtr<ID3D10Texture2D> maskTexture;
   RefPtr<ID3D10ShaderResourceView> maskSRView;
+  IntRect clipBounds;
   if (mPushedClips.size()) {
-    EnsureClipMaskTexture();
+    EnsureClipMaskTexture(&clipBounds);
 
     mDevice->CreateShaderResourceView(mCurrentClipMaskTexture, nullptr, byRef(maskSRView));
   }
 
   IntSize srcSurfSize;
   ID3D10RenderTargetView *rtViews;
   D3D10_VIEWPORT viewport;
 
@@ -609,16 +624,17 @@ DrawTargetD2D::DrawSurfaceWithShadow(Sou
   if (mPushedClips.size()) {
     mPrivateData->mEffect->GetVariableByName("mask")->AsShaderResource()->SetResource(maskSRView);
     mPrivateData->mEffect->GetVariableByName("MaskTexCoords")->AsVector()->
       SetFloatVector(ShaderConstantRectD3D10(shadowDest.x / mSize.width, shadowDest.y / mSize.height,
                                              Float(aSurface->GetSize().width) / mSize.width,
                                              Float(aSurface->GetSize().height) / mSize.height));
     mPrivateData->mEffect->GetTechniqueByName("SampleTextureWithShadow")->
       GetPassByIndex(2)->Apply(0);
+    SetScissorToRect(&clipBounds);
   } else {
     mPrivateData->mEffect->GetTechniqueByName("SampleTextureWithShadow")->
       GetPassByIndex(1)->Apply(0);
   }
 
   mDevice->OMSetBlendState(GetBlendStateForOperator(aOperator), nullptr, 0xffffffff);
 
   mDevice->Draw(4, 0);
@@ -634,16 +650,17 @@ DrawTargetD2D::DrawSurfaceWithShadow(Sou
 
   if (mPushedClips.size()) {
     mPrivateData->mEffect->GetVariableByName("MaskTexCoords")->AsVector()->
       SetFloatVector(ShaderConstantRectD3D10(aDest.x / mSize.width, aDest.y / mSize.height,
                                              Float(aSurface->GetSize().width) / mSize.width,
                                              Float(aSurface->GetSize().height) / mSize.height));
     mPrivateData->mEffect->GetTechniqueByName("SampleMaskedTexture")->
       GetPassByIndex(0)->Apply(0);
+    // We've set the scissor rect here for the previous draw call.
   } else {
     mPrivateData->mEffect->GetTechniqueByName("SampleTexture")->
       GetPassByIndex(0)->Apply(0);
   }
 
   mDevice->OMSetBlendState(GetBlendStateForOperator(aOperator), nullptr, 0xffffffff);
 
   mDevice->Draw(4, 0);
@@ -1001,25 +1018,30 @@ DrawTargetD2D::PushClipRect(const Rect &
     pathBuilder->LineTo(aRect.BottomRight());
     pathBuilder->LineTo(aRect.BottomLeft());
     pathBuilder->Close();
     RefPtr<Path> path = pathBuilder->Finish();
     return PushClip(path);
   }
 
   PushedClip clip;
+  Rect rect = mTransform.TransformBounds(aRect);
+  IntRect intRect;
+  clip.mIsPixelAligned = rect.ToIntRect(&intRect);
+
   // Do not store the transform, just store the device space rectangle directly.
-  clip.mBounds = D2DRect(mTransform.TransformBounds(aRect));
+  clip.mBounds = D2DRect(rect);
 
   mPushedClips.push_back(clip);
 
   mRT->SetTransform(D2D1::IdentityMatrix());
   mTransformDirty = true;
+
   if (mClipsArePushed) {
-    mRT->PushAxisAlignedClip(clip.mBounds, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
+    mRT->PushAxisAlignedClip(clip.mBounds, clip.mIsPixelAligned ? D2D1_ANTIALIAS_MODE_ALIASED : D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
   }
 }
 
 void
 DrawTargetD2D::PopClip()
 {
   mCurrentClipMaskTexture = nullptr;
   mCurrentClippedGeometry = nullptr;
@@ -1570,69 +1592,116 @@ DrawTargetD2D::FinalizeRTForOperation(Co
 
     mPrivateData->mEffect->GetVariableByName("mask")->AsShaderResource()->SetResource(mSRView);
 
     SetupEffectForRadialGradient(pat);
   }
 
   mDevice->OMSetBlendState(GetBlendStateForOperator(aOperator), nullptr, 0xffffffff);
   
+  SetScissorToRect(nullptr);
   mDevice->Draw(4, 0);
 }
 
 TemporaryRef<ID2D1Geometry>
 DrawTargetD2D::ConvertRectToGeometry(const D2D1_RECT_F& aRect)
 {
   RefPtr<ID2D1RectangleGeometry> rectGeom;
   factory()->CreateRectangleGeometry(&aRect, byRef(rectGeom));
   return rectGeom.forget();
 }
 
+TemporaryRef<ID2D1Geometry>
+DrawTargetD2D::GetTransformedGeometry(ID2D1Geometry *aGeometry, const D2D1_MATRIX_3X2_F &aTransform)
+{
+  RefPtr<ID2D1PathGeometry> tmpGeometry;
+  factory()->CreatePathGeometry(byRef(tmpGeometry));
+  RefPtr<ID2D1GeometrySink> currentSink;
+  tmpGeometry->Open(byRef(currentSink));
+  aGeometry->Simplify(D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
+                      aTransform, currentSink);
+  currentSink->Close();
+  return tmpGeometry;
+}
+
+TemporaryRef<ID2D1Geometry>
+DrawTargetD2D::Intersect(ID2D1Geometry *aGeometryA, ID2D1Geometry *aGeometryB)
+{
+  RefPtr<ID2D1PathGeometry> pathGeom;
+  factory()->CreatePathGeometry(byRef(pathGeom));
+  RefPtr<ID2D1GeometrySink> sink;
+  pathGeom->Open(byRef(sink));
+  aGeometryA->CombineWithGeometry(aGeometryB, D2D1_COMBINE_MODE_INTERSECT, nullptr, sink);
+  sink->Close();
+
+  return pathGeom;
+}
+
 static D2D1_RECT_F
 IntersectRect(const D2D1_RECT_F& aRect1, const D2D1_RECT_F& aRect2)
 {
   D2D1_RECT_F result;
   result.left = max(aRect1.left, aRect2.left);
   result.top = max(aRect1.top, aRect2.top);
   result.right = min(aRect1.right, aRect2.right);
   result.bottom = min(aRect1.bottom, aRect2.bottom);
   return result;
 }
 
 TemporaryRef<ID2D1Geometry>
-DrawTargetD2D::GetClippedGeometry()
+DrawTargetD2D::GetClippedGeometry(IntRect *aClipBounds)
 {
   if (mCurrentClippedGeometry) {
+    *aClipBounds = mCurrentClipBounds;
     return mCurrentClippedGeometry;
   }
 
+  mCurrentClipBounds = IntRect(IntPoint(0, 0), mSize);
+
   // if pathGeom is null then pathRect represents the path.
   RefPtr<ID2D1Geometry> pathGeom;
   D2D1_RECT_F pathRect;
+  bool pathRectIsAxisAligned = false;
   std::vector<DrawTargetD2D::PushedClip>::iterator iter = mPushedClips.begin();
+  
   if (iter->mPath) {
-    RefPtr<ID2D1PathGeometry> tmpGeometry;
-    factory()->CreatePathGeometry(byRef(tmpGeometry));
-    RefPtr<ID2D1GeometrySink> currentSink;
-    tmpGeometry->Open(byRef(currentSink));
-    iter->mPath->GetGeometry()->Simplify(D2D1_GEOMETRY_SIMPLIFICATION_OPTION_CUBICS_AND_LINES,
-                                         iter->mTransform, currentSink);
-    currentSink->Close();
-    pathGeom = tmpGeometry.forget();
+    pathGeom = GetTransformedGeometry(iter->mPath->GetGeometry(), iter->mTransform);
   } else {
     pathRect = iter->mBounds;
+    pathRectIsAxisAligned = iter->mIsPixelAligned;
   }
 
   iter++;
   for (;iter != mPushedClips.end(); iter++) {
+    // Do nothing but add it to the current clip bounds.
+    if (!iter->mPath && iter->mIsPixelAligned) {
+      mCurrentClipBounds.IntersectRect(mCurrentClipBounds,
+        IntRect(iter->mBounds.left, iter->mBounds.top,
+                int32_t(iter->mBounds.right - iter->mBounds.left),
+                int32_t(iter->mBounds.bottom - iter->mBounds.top)));
+      continue;
+    }
+
     if (!pathGeom) {
+      if (pathRectIsAxisAligned) {
+        mCurrentClipBounds.IntersectRect(mCurrentClipBounds,
+          IntRect(pathRect.left, pathRect.top,
+                  int32_t(pathRect.right - pathRect.left),
+                  int32_t(pathRect.bottom - pathRect.top)));
+      }
       if (iter->mPath) {
-        pathGeom = ConvertRectToGeometry(pathRect);
+        // See if pathRect needs to go into the path geometry.
+        if (!pathRectIsAxisAligned) {
+          pathGeom = ConvertRectToGeometry(pathRect);
+        } else {
+          pathGeom = GetTransformedGeometry(iter->mPath->GetGeometry(), iter->mTransform);
+        }
       } else {
         pathRect = IntersectRect(pathRect, iter->mBounds);
+        pathRectIsAxisAligned = false;
         continue;
       }
     }
 
     RefPtr<ID2D1PathGeometry> newGeom;
     factory()->CreatePathGeometry(byRef(newGeom));
 
     RefPtr<ID2D1GeometrySink> currentSink;
@@ -1647,20 +1716,25 @@ DrawTargetD2D::GetClippedGeometry()
                                     D2D1::IdentityMatrix(), currentSink);
     }
 
     currentSink->Close();
 
     pathGeom = newGeom.forget();
   }
 
+  // For now we need mCurrentClippedGeometry to always be non-NULL. This method
+  // might seem a little strange but it is just fine, if pathGeom is NULL
+  // pathRect will always still contain 1 clip unaccounted for regardless of
+  // mCurrentClipBounds.
   if (!pathGeom) {
     pathGeom = ConvertRectToGeometry(pathRect);
   }
   mCurrentClippedGeometry = pathGeom.forget();
+  *aClipBounds = mCurrentClipBounds;
   return mCurrentClippedGeometry;
 }
 
 TemporaryRef<ID2D1RenderTarget>
 DrawTargetD2D::CreateRTForTexture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat)
 {
   HRESULT hr;
 
@@ -1754,17 +1828,17 @@ DrawTargetD2D::PushClipsToRT(ID2D1Render
         options = D2D1_LAYER_OPTIONS_INITIALIZE_FOR_CLEARTYPE;
       }
 
       aRT->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), iter->mPath->mGeometry,
                                             D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
                                             iter->mTransform, 1.0f, nullptr,
                                             options), iter->mLayer);
     } else {
-      aRT->PushAxisAlignedClip(iter->mBounds, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
+      aRT->PushAxisAlignedClip(iter->mBounds, iter->mIsPixelAligned ? D2D1_ANTIALIAS_MODE_ALIASED : D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
     }
   }
 }
 
 void
 DrawTargetD2D::PopClipsFromRT(ID2D1RenderTarget *aRT)
 {
   for (int i = mPushedClips.size() - 1; i >= 0; i--) {
@@ -1772,22 +1846,25 @@ DrawTargetD2D::PopClipsFromRT(ID2D1Rende
       aRT->PopLayer();
     } else {
       aRT->PopAxisAlignedClip();
     }
   }
 }
 
 void
-DrawTargetD2D::EnsureClipMaskTexture()
+DrawTargetD2D::EnsureClipMaskTexture(IntRect *aBounds)
 {
   if (mCurrentClipMaskTexture || mPushedClips.empty()) {
+    *aBounds = mCurrentClipBounds;
     return;
   }
   
+  RefPtr<ID2D1Geometry> geometry = GetClippedGeometry(aBounds);
+
   CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_A8_UNORM,
                              mSize.width,
                              mSize.height,
                              1, 1);
   desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
 
   HRESULT hr = mDevice->CreateTexture2D(&desc, nullptr, byRef(mCurrentClipMaskTexture));
 
@@ -1801,18 +1878,16 @@ DrawTargetD2D::EnsureClipMaskTexture()
   if (!rt) {
     gfxWarning() << "Failed to create RT for ClipMask!";
     return;
   }
   
   RefPtr<ID2D1SolidColorBrush> brush;
   rt->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White), byRef(brush));
     
-  RefPtr<ID2D1Geometry> geometry = GetClippedGeometry();
-
   rt->BeginDraw();
   rt->Clear(D2D1::ColorF(0, 0));
   rt->FillGeometry(geometry, brush);
   rt->EndDraw();
 }
 
 bool
 DrawTargetD2D::FillGlyphsManual(ScaledFontDWrite *aFont,
@@ -1935,34 +2010,39 @@ DrawTargetD2D::FillGlyphsManual(ScaledFo
   FLOAT color[4] = { aColor.r, aColor.g, aColor.b, aColor.a };
   mPrivateData->mEffect->GetVariableByName("TextColor")->AsVector()->
     SetFloatVector(color);
   
   mPrivateData->mEffect->GetVariableByName("tex")->AsShaderResource()->SetResource(srView);
 
   bool isMasking = false;
 
+  IntRect clipBoundsStorage;
+  IntRect *clipBounds = nullptr;
+
   if (!mPushedClips.empty()) {
-    RefPtr<ID2D1Geometry> geom = GetClippedGeometry();
+    clipBounds = &clipBoundsStorage;
+    RefPtr<ID2D1Geometry> geom = GetClippedGeometry(clipBounds);
 
     RefPtr<ID2D1RectangleGeometry> rectGeom;
     factory()->CreateRectangleGeometry(D2D1::RectF(rectBounds.x, rectBounds.y,
                                                    rectBounds.width + rectBounds.x,
                                                    rectBounds.height + rectBounds.y),
                                        byRef(rectGeom));
 
     D2D1_GEOMETRY_RELATION relation;
     if (FAILED(geom->CompareWithGeometry(rectGeom, D2D1::IdentityMatrix(), &relation)) ||
-        relation != D2D1_GEOMETRY_RELATION_CONTAINS) {
+        relation != D2D1_GEOMETRY_RELATION_CONTAINS ) {
       isMasking = true;
     }        
   }
   
   if (isMasking) {
-    EnsureClipMaskTexture();
+    clipBounds = &clipBoundsStorage;
+    EnsureClipMaskTexture(clipBounds);
 
     RefPtr<ID3D10ShaderResourceView> srViewMask;
     hr = mDevice->CreateShaderResourceView(mCurrentClipMaskTexture, nullptr, byRef(srViewMask));
 
     if (FAILED(hr)) {
       return false;
     }
 
@@ -1978,17 +2058,17 @@ DrawTargetD2D::FillGlyphsManual(ScaledFo
   }  
 
   RefPtr<ID3D10RenderTargetView> rtView;
   ID3D10RenderTargetView *rtViews;
   mDevice->CreateRenderTargetView(mTexture, nullptr, byRef(rtView));
 
   rtViews = rtView;
   mDevice->OMSetRenderTargets(1, &rtViews, nullptr);
-
+  SetScissorToRect(clipBounds);
   mDevice->Draw(4, 0);
   return true;
 }
 
 TemporaryRef<ID2D1Brush>
 DrawTargetD2D::CreateBrushForPattern(const Pattern &aPattern, Float aAlpha)
 {
   if (IsPatternSupportedByD2D(aPattern)) {
@@ -2608,10 +2688,27 @@ DrawTargetD2D::GetDWriteFactory()
 
   if (FAILED(hr)) {
     gfxWarning() << "Failed to create DWrite Factory.";
   }
 
   return mDWriteFactory;
 }
 
+void
+DrawTargetD2D::SetScissorToRect(IntRect *aRect)
+{
+  D3D10_RECT rect;
+  if (aRect) {
+    rect.left = aRect->x;
+    rect.right = aRect->XMost();
+    rect.top = aRect->y;
+    rect.bottom = aRect->YMost();
+  } else {
+    rect.left = rect.left = INT32_MIN;
+    rect.right = rect.top = INT32_MAX;
+  }
+
+  mDevice->RSSetScissorRects(1, &rect);
+}
+
 }
 }
--- a/gfx/2d/DrawTargetD2D.h
+++ b/gfx/2d/DrawTargetD2D.h
@@ -167,51 +167,67 @@ private:
   ID3D10BlendState *GetBlendStateForOperator(CompositionOp aOperator);
   ID2D1RenderTarget *GetRTForOperation(CompositionOp aOperator, const Pattern &aPattern);
   void FinalizeRTForOperation(CompositionOp aOperator, const Pattern &aPattern, const Rect &aBounds);  void EnsureViews();
   void PopAllClips();
   void PushClipsToRT(ID2D1RenderTarget *aRT);
   void PopClipsFromRT(ID2D1RenderTarget *aRT);
 
   // This function ensures mCurrentClipMaskTexture contains a texture containing
-  // a mask corresponding with the current DrawTarget clip.
-  void EnsureClipMaskTexture();
+  // a mask corresponding with the current DrawTarget clip. See
+  // GetClippedGeometry for a description of aClipBounds.
+  void EnsureClipMaskTexture(IntRect *aClipBounds);
 
   bool FillGlyphsManual(ScaledFontDWrite *aFont,
                         const GlyphBuffer &aBuffer,
                         const Color &aColor,
                         IDWriteRenderingParams *aParams,
                         const DrawOptions &aOptions = DrawOptions());
 
   TemporaryRef<ID2D1RenderTarget> CreateRTForTexture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
   TemporaryRef<ID2D1Geometry> ConvertRectToGeometry(const D2D1_RECT_F& aRect);
-  TemporaryRef<ID2D1Geometry> GetClippedGeometry();
+  TemporaryRef<ID2D1Geometry> GetTransformedGeometry(ID2D1Geometry *aGeometry, const D2D1_MATRIX_3X2_F &aTransform);
+  TemporaryRef<ID2D1Geometry> Intersect(ID2D1Geometry *aGeometryA, ID2D1Geometry *aGeometryB);
+
+  // This returns the clipped geometry, in addition it returns aClipBounds which
+  // represents the intersection of all pixel-aligned rectangular clips that
+  // are currently set. The returned clipped geometry must be clipped by these
+  // bounds to correctly reflect the total clip. This is in device space.
+  TemporaryRef<ID2D1Geometry> GetClippedGeometry(IntRect *aClipBounds);
 
   TemporaryRef<ID2D1Brush> CreateBrushForPattern(const Pattern &aPattern, Float aAlpha = 1.0f);
 
   TemporaryRef<ID3D10Texture2D> CreateGradientTexture(const GradientStopsD2D *aStops);
   TemporaryRef<ID3D10Texture2D> CreateTextureForAnalysis(IDWriteGlyphRunAnalysis *aAnalysis, const IntRect &aBounds);
 
   // This creates a (partially) uploaded bitmap for a DataSourceSurface. It
   // uploads the minimum requirement and possibly downscales. It adjusts the
   // input Matrix to compensate.
   TemporaryRef<ID2D1Bitmap> CreatePartialBitmapForSurface(DataSourceSurface *aSurface, Matrix &aMatrix,
                                                           ExtendMode aExtendMode);
 
   void SetupEffectForRadialGradient(const RadialGradientPattern *aPattern);
   void SetupStateForRendering();
 
+  // Set the scissor rect to a certain IntRects, resets the scissor rect to
+  // surface bounds when NULL is specified.
+  void SetScissorToRect(IntRect *aRect);
+
   static const uint32_t test = 4;
 
   IntSize mSize;
 
   RefPtr<ID3D10Device1> mDevice;
   RefPtr<ID3D10Texture2D> mTexture;
   RefPtr<ID3D10Texture2D> mCurrentClipMaskTexture;
   RefPtr<ID2D1Geometry> mCurrentClippedGeometry;
+  // This is only valid if mCurrentClippedGeometry is non-null. And will
+  // only be the intersection of all pixel-aligned retangular clips. This is in
+  // device space.
+  IntRect mCurrentClipBounds;
   mutable RefPtr<ID2D1RenderTarget> mRT;
 
   // We store this to prevent excessive SetTextRenderingParams calls.
   RefPtr<IDWriteRenderingParams> mTextRenderingParams;
 
   // Temporary texture and render target used for supporting alternative operators.
   RefPtr<ID3D10Texture2D> mTempTexture;
   RefPtr<ID3D10RenderTargetView> mRTView;
@@ -219,17 +235,22 @@ private:
   RefPtr<ID2D1RenderTarget> mTempRT;
   RefPtr<ID3D10RenderTargetView> mTempRTView;
 
   // List of pushed clips.
   struct PushedClip
   {
     RefPtr<ID2D1Layer> mLayer;
     D2D1_RECT_F mBounds;
-    D2D1_MATRIX_3X2_F mTransform;
+    union {
+      // If mPath is non-NULL, the mTransform member will be used, otherwise
+      // the mIsPixelAligned member is valid.
+      D2D1_MATRIX_3X2_F mTransform;
+      bool mIsPixelAligned;
+    };
     RefPtr<PathD2D> mPath;
   };
   std::vector<PushedClip> mPushedClips;
 
   // We cache ID2D1Layer objects as it causes D2D to keep around textures that
   // serve as the temporary surfaces for these operations. As texture creation
   // is quite expensive this considerably improved performance.
   // Careful here, RAII will not ensure destruction of the RefPtrs.
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -224,24 +224,24 @@ void SetPaintPattern(SkPaint& aPaint, co
       GradientStopsSkia *stops = static_cast<GradientStopsSkia*>(pat.mStops.get());
       SkShader::TileMode mode = ExtendModeToTileMode(stops->mExtendMode);
 
       if (stops->mCount >= 2) {
         SkPoint points[2];
         points[0] = SkPoint::Make(SkFloatToScalar(pat.mCenter1.x), SkFloatToScalar(pat.mCenter1.y));
         points[1] = SkPoint::Make(SkFloatToScalar(pat.mCenter2.x), SkFloatToScalar(pat.mCenter2.y));
 
-        SkShader* shader = SkGradientShader::CreateTwoPointRadial(points[0], 
-                                                                  SkFloatToScalar(pat.mRadius1),
-                                                                  points[1], 
-                                                                  SkFloatToScalar(pat.mRadius2),
-                                                                  &stops->mColors.front(), 
-                                                                  &stops->mPositions.front(), 
-                                                                  stops->mCount, 
-                                                                  mode);
+        SkShader* shader = SkGradientShader::CreateTwoPointConical(points[0], 
+                                                                   SkFloatToScalar(pat.mRadius1),
+                                                                   points[1], 
+                                                                   SkFloatToScalar(pat.mRadius2),
+                                                                   &stops->mColors.front(), 
+                                                                   &stops->mPositions.front(), 
+                                                                   stops->mCount, 
+                                                                   mode);
         if (shader) {
             SkMatrix mat;
             GfxMatrixToSkiaMatrix(pat.mMatrix, mat);
             shader->setLocalMatrix(mat);
             SkSafeUnref(aPaint.setShader(shader));
         }
 
       } else {
@@ -671,16 +671,22 @@ DrawTargetSkia::Init(const IntSize &aSiz
   mCanvas = canvas.get();
   mFormat = aFormat;
   return true;
 }
 
 void
 DrawTargetSkia::Init(unsigned char* aData, const IntSize &aSize, int32_t aStride, SurfaceFormat aFormat)
 {
+  if (aFormat == FORMAT_B8G8R8X8) {
+    // We have to manually set the A channel to be 255 as Skia doesn't understand BGRX
+    ConvertBGRXToBGRA(aData, aSize, aStride);
+    mBitmap.setIsOpaque(true);
+  }
+
   mBitmap.setConfig(GfxFormatToSkiaConfig(aFormat), aSize.width, aSize.height, aStride);
   mBitmap.setPixels(aData);
   
   SkAutoTUnref<SkDevice> device(new SkDevice(mBitmap));
   SkAutoTUnref<SkCanvas> canvas(new SkCanvas(device.get()));
   mSize = aSize;
 
   mDevice = device.get();
--- a/gfx/2d/HelpersSkia.h
+++ b/gfx/2d/HelpersSkia.h
@@ -108,12 +108,25 @@ StrokeOptionsToPaint(SkPaint& aPaint, co
                                                   SkFloatToScalar(aOptions.mDashOffset));
     SkSafeUnref(aPaint.setPathEffect(dash));
   }
 
   aPaint.setStyle(SkPaint::kStroke_Style);
   return true;
 }
 
+static inline void
+ConvertBGRXToBGRA(unsigned char* aData, const IntSize &aSize, int32_t aStride)
+{
+    uint32_t* pixel = reinterpret_cast<uint32_t*>(aData);
+
+    for (int row = 0; row < aSize.height; ++row) {
+        for (int column = 0; column < aSize.width; ++column) {
+            pixel[column] |= 0xFF000000;
+        }
+        pixel += (aStride/4);
+    }
+}
+
 }
 }
 
 #endif /* MOZILLA_GFX_HELPERSSKIA_H_ */
--- a/gfx/2d/ShadersD2D.fx
+++ b/gfx/2d/ShadersD2D.fx
@@ -93,17 +93,17 @@ sampler sShadowSampler = sampler_state {
     Texture = tex;
     AddressU = Border;
     AddressV = Border;
     BorderColor = float4(0, 0, 0, 0);
 };
 
 RasterizerState TextureRast
 {
-  ScissorEnable = False;
+  ScissorEnable = True;
   CullMode = None;
 };
 
 BlendState ShadowBlendH
 {
   BlendEnable[0] = False;
   RenderTargetWriteMask[0] = 0xF;
 };
--- a/gfx/2d/ShadersD2D.h
+++ b/gfx/2d/ShadersD2D.h
@@ -70,17 +70,17 @@ SamplerState sShadowSampler
     Filter   = uint(MIN_MAG_MIP_LINEAR /* 21 */);
     Texture  = tex;
     AddressU = uint(BORDER /* 4 */);
     AddressV = uint(BORDER /* 4 */);
     BorderColor = float4(0, 0, 0, 0);
 };
 RasterizerState TextureRast
 {
-    ScissorEnable = bool(FALSE /* 0 */);
+    ScissorEnable = bool(TRUE /* 1 */);
     CullMode = uint(NONE /* 1 */);
 };
 BlendState ShadowBlendH
 {
     BlendEnable[0] = bool(FALSE /* 0 */);
     RenderTargetWriteMask[0] = byte(0x0f);
 };
 BlendState ShadowBlendV
@@ -3052,20 +3052,20 @@ technique10 SampleTextTexture
     }
 
 }
 
 #endif
 
 const BYTE d2deffect[] =
 {
-     68,  88,  66,  67, 180,  92, 
-     99,   8,  31, 243, 141,  10, 
-    239,  43,  71, 236,  45, 138, 
-     71, 112,   1,   0,   0,   0, 
+     68,  88,  66,  67, 162, 185, 
+     42, 249, 229,   2,  50,  89, 
+      3, 159,  21, 149,  11, 251, 
+     62, 135,   1,   0,   0,   0, 
     144, 191,   0,   0,   1,   0, 
       0,   0,  36,   0,   0,   0, 
      70,  88,  49,  48, 100, 191, 
       0,   0,   1,  16, 255, 254, 
       3,   0,   0,   0,  15,   0, 
       0,   0,  11,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -3207,17 +3207,17 @@ const BYTE d2deffect[] =
      97, 116, 101,   0, 238,   2, 
       0,   0,   2,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   4,   0, 
       0,   0,  84, 101, 120, 116, 
     117, 114, 101,  82,  97, 115, 
     116,   0,   1,   0,   0,   0, 
-      2,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   1,   0, 
       0,   0,   1,   0,   0,   0, 
       2,   0,   0,   0,   1,   0, 
       0,   0,  66, 108, 101, 110, 
     100,  83, 116,  97, 116, 101, 
       0,  62,   3,   0,   0,   2, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
--- a/gfx/2d/SourceSurfaceSkia.cpp
+++ b/gfx/2d/SourceSurfaceSkia.cpp
@@ -44,17 +44,26 @@ SourceSurfaceSkia::InitFromData(unsigned
 {
   SkBitmap temp;
   temp.setConfig(GfxFormatToSkiaConfig(aFormat), aSize.width, aSize.height, aStride);
   temp.setPixels(aData);
 
   if (!temp.copyTo(&mBitmap, GfxFormatToSkiaConfig(aFormat))) {
     return false;
   }
-  
+
+  if (aFormat == FORMAT_B8G8R8X8) {
+    mBitmap.lockPixels();
+    // We have to manually set the A channel to be 255 as Skia doesn't understand BGRX
+    ConvertBGRXToBGRA(reinterpret_cast<unsigned char*>(mBitmap.getPixels()), aSize, aStride);
+    mBitmap.unlockPixels();
+    mBitmap.notifyPixelsChanged();
+    mBitmap.setIsOpaque(true);
+  }
+
   mSize = aSize;
   mFormat = aFormat;
   mStride = aStride;
   return true;
 }
 
 bool
 SourceSurfaceSkia::InitWithBitmap(const SkBitmap& aBitmap,
--- a/gfx/angle/Makefile.in
+++ b/gfx/angle/Makefile.in
@@ -119,18 +119,22 @@ DEFINES += -DANGLE_COMPILE_OPTIMIZATION_
 DEFINES += -DANGLE_USE_NEW_PREPROCESSOR=1
 
 ifdef MOZ_ANGLE_RENDERER
 
 # libEGL depends on (links against!) libGLESv2!
 DIRS = src/libGLESv2 src/libEGL
 
 libs::
+ifdef MOZ_D3DX9_CAB
 	expand "$(MOZ_D3DX9_CAB)" -F:$(MOZ_D3DX9_DLL) "$(DIST)/bin"
+endif
+ifdef MOZ_D3DCOMPILER_CAB
 	expand "$(MOZ_D3DCOMPILER_CAB)" -F:$(MOZ_D3DCOMPILER_DLL) "$(DIST)/bin"
+endif
 
 endif
 
 include $(topsrcdir)/config/rules.mk
 
 # We have to filter out -pedantic, because of
 # comma-at-end-of-enumerator list failures.  We can try to get this fixed
 # upstream at some point.
new file mode 100644
--- /dev/null
+++ b/gfx/angle/angle-stdcall-alias.patch
@@ -0,0 +1,13 @@
+diff --git a/gfx/angle/src/libGLESv2/libGLESv2.def b/gfx/angle/src/libGLESv2/libGLESv2.def
+index 5f935c3..2324dcb 100644
+--- a/gfx/angle/src/libGLESv2/libGLESv2.def
++++ b/gfx/angle/src/libGLESv2/libGLESv2.def
+@@ -180,3 +180,8 @@ EXPORTS
+     glGetCurrentContext             @147 NONAME
+     glGetProcAddress                @148 NONAME
+     glBindTexImage                  @158 NONAME
++
++    ; GCC has problems with linking to undecored stdcall functions,
++    ; so we explicitly add aliases for APIs used by EGL
++    glGetProcAddress@4=glGetProcAddress
++    glBindTexImage@4=glBindTexImage
--- a/gfx/angle/src/libEGL/Makefile.in
+++ b/gfx/angle/src/libEGL/Makefile.in
@@ -63,14 +63,24 @@ CPPSRCS = \
   Surface.cpp \
   $(NULL)
 
 DEFFILE = $(srcdir)/libEGL.def
 RCFILE = $(srcdir)/libEGL.rc
 
 include $(topsrcdir)/config/rules.mk
 
+OS_LIBS += $(call EXPAND_LIBNAME,dwmapi)
+
+ifdef GNU_CC
+
+OS_CXXFLAGS := $(filter-out -fno-exceptions,$(OS_CXXFLAGS)) -fexceptions
+OS_LIBS += -ld3d9 -ldxguid -llibGLESv2
+
+else
+
 EXTRA_DSO_LDOPTS = "$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_DIRECTX_SDK_CPU_SUFFIX)/d3d9.lib" \
                    "$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_DIRECTX_SDK_CPU_SUFFIX)/dxguid.lib" \
 		   "$(DIST)/lib/libGLESv2.lib" \
-		   dwmapi.lib \
 		   delayimp.lib \
 		   /delayload:dwmapi.dll
+
+endif
--- a/gfx/angle/src/libGLESv2/Makefile.in
+++ b/gfx/angle/src/libGLESv2/Makefile.in
@@ -160,11 +160,27 @@ CPPSRCS += \
         VertexDataManager.cpp \
         $(NULL)
 
 DEFFILE = $(srcdir)/libGLESv2.def
 RCFILE = $(srcdir)/libGLESv2.rc
 
 include $(topsrcdir)/config/rules.mk
 
+ifdef GNU_CC
+
+TextureSSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2
+
+OS_CXXFLAGS := $(filter-out -fno-exceptions,$(OS_CXXFLAGS)) -fexceptions
+OS_LIBS += -ld3d9
+ifdef MOZ_D3DX9_VERSION
+OS_LIBS += -ld3dx9_$(MOZ_D3DX9_VERSION) -ld3dcompiler_$(MOZ_D3DX9_VERSION)
+else
+OS_LIBS += -ld3dx9 -ld3dcompiler
+endif
+
+else
+
 EXTRA_DSO_LDOPTS = "$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_DIRECTX_SDK_CPU_SUFFIX)/d3d9.lib" \
                    "$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_DIRECTX_SDK_CPU_SUFFIX)/d3dx9.lib" \
                    "$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_DIRECTX_SDK_CPU_SUFFIX)/D3DCompiler.lib"
+
+endif
--- a/gfx/angle/src/libGLESv2/libGLESv2.def
+++ b/gfx/angle/src/libGLESv2/libGLESv2.def
@@ -175,8 +175,13 @@ EXPORTS
 
     ; EGL dependencies
     glCreateContext                 @144 NONAME
     glDestroyContext                @145 NONAME
     glMakeCurrent                   @146 NONAME
     glGetCurrentContext             @147 NONAME
     glGetProcAddress                @148 NONAME
     glBindTexImage                  @158 NONAME
+
+    ; GCC has problems with linking to undecored stdcall functions,
+    ; so we explicitly add aliases for APIs used by EGL
+    glGetProcAddress@4=glGetProcAddress
+    glBindTexImage@4=glBindTexImage
--- a/gfx/layers/GrallocImages.cpp
+++ b/gfx/layers/GrallocImages.cpp
@@ -74,28 +74,28 @@ GrallocPlanarYCbCrImage::SetData(const D
   // Align to 16 bytes boundary
   int32_t uvStride = ((yStride / 2) + 15) & ~0x0F;
   uint8_t* uChannel = vChannel + (uvStride * uvSize.height);
 
   // Memory outside of the image width may not writable. If the stride
   // equals to the image width then we can use only one copy.
   if (yStride == mData.mYStride &&
       yStride == ySize.width) {
-    memcpy(yChannel, mData.mYChannel, yStride * ySize.width);
+    memcpy(yChannel, mData.mYChannel, yStride * ySize.height);
   } else {
     for (int i = 0; i < ySize.height; i++) {
       memcpy(yChannel + i * yStride,
              mData.mYChannel + i * mData.mYStride,
              ySize.width);
     }
   }
   if (uvStride == mData.mCbCrStride &&
       uvStride == uvSize.width) {
-    memcpy(uChannel, mData.mCbChannel, uvStride * uvSize.width);
-    memcpy(vChannel, mData.mCrChannel, uvStride * uvSize.width);
+    memcpy(uChannel, mData.mCbChannel, uvStride * uvSize.height);
+    memcpy(vChannel, mData.mCrChannel, uvStride * uvSize.height);
   } else {
     for (int i = 0; i < uvSize.height; i++) {
       memcpy(uChannel + i * uvStride,
              mData.mCbChannel + i * mData.mCbCrStride,
              uvSize.width);
       memcpy(vChannel + i * uvStride,
              mData.mCrChannel + i * mData.mCbCrStride,
              uvSize.width);
--- a/gfx/layers/ImageLayers.cpp
+++ b/gfx/layers/ImageLayers.cpp
@@ -19,26 +19,34 @@ ImageLayer::~ImageLayer()
 
 void ImageLayer::SetContainer(ImageContainer* aContainer) 
 {
   mContainer = aContainer;
 }
 
 void ImageLayer::ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface)
 {
+  gfx3DMatrix local = GetLocalTransform();
+
   // Snap image edges to pixel boundaries
-  gfxRect snap(0, 0, 0, 0);
+  gfxRect sourceRect(0, 0, 0, 0);
   if (mContainer) {
-    gfxIntSize size = mContainer->GetCurrentSize();
-    snap.SizeTo(gfxSize(size.width, size.height));
+    sourceRect.SizeTo(mContainer->GetCurrentSize());
+    if (mScaleMode != SCALE_NONE &&
+        sourceRect.width != 0.0 && sourceRect.height != 0.0) {
+      NS_ASSERTION(mScaleMode == SCALE_STRETCH,
+                   "No other scalemodes than stretch and none supported yet.");
+      local.Scale(mScaleToSize.width / sourceRect.width,
+                  mScaleToSize.height / sourceRect.height, 1.0);
+    }
   }
   // Snap our local transform first, and snap the inherited transform as well.
   // This makes our snapping equivalent to what would happen if our content
   // was drawn into a ThebesLayer (gfxContext would snap using the local
   // transform, then we'd snap again when compositing the ThebesLayer).
   mEffectiveTransform =
-      SnapTransform(GetLocalTransform(), snap, nullptr)*
+      SnapTransform(local, sourceRect, nullptr) *
       SnapTransform(aTransformToSurface, gfxRect(0, 0, 0, 0), nullptr);
   ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
 }
 
 }
 }
--- a/gfx/layers/ImageLayers.h
+++ b/gfx/layers/ImageLayers.h
@@ -19,17 +19,17 @@ class ImageContainer;
 
 /**
  * A Layer which renders an Image.
  */
 class THEBES_API ImageLayer : public Layer {
 public:
   enum ScaleMode {
     SCALE_NONE,
-    SCALE_STRETCH // Unimplemented on GL layers and e10s
+    SCALE_STRETCH
   // Unimplemented - SCALE_PRESERVE_ASPECT_RATIO_CONTAIN
   };
 
   /**
    * CONSTRUCTION PHASE ONLY
    * Set the ImageContainer. aContainer must have the same layer manager
    * as this layer.
    */
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -1084,17 +1084,17 @@ public:
     gfxMatrix residual;
     mEffectiveTransform = SnapTransform(idealTransform, gfxRect(0, 0, 0, 0),
         mAllowResidualTranslation ? &residual : nullptr);
     // The residual can only be a translation because ThebesLayer snapping
     // only aligns a single point with the pixel grid; scale factors are always
     // preserved exactly
     NS_ASSERTION(!residual.HasNonTranslation(),
                  "Residual transform can only be a translation");
-    if (residual.GetTranslation() != mResidualTranslation) {
+    if (!residual.GetTranslation().WithinEpsilonOf(mResidualTranslation, 1e-3f)) {
       mResidualTranslation = residual.GetTranslation();
       NS_ASSERTION(-0.5 <= mResidualTranslation.x && mResidualTranslation.x < 0.5 &&
                    -0.5 <= mResidualTranslation.y && mResidualTranslation.y < 0.5,
                    "Residual translation out of range");
       mValidRegion.SetEmpty();
     }
     ComputeEffectiveTransformForMaskLayer(aTransformToSurface);
   }
--- a/gfx/layers/basic/BasicImageLayer.cpp
+++ b/gfx/layers/basic/BasicImageLayer.cpp
@@ -93,25 +93,16 @@ BasicImageLayer::GetAndPaintCurrentImage
   }
 
   nsRefPtr<gfxPattern> pat = new gfxPattern(surface);
   if (!pat) {
     return nullptr;
   }
 
   pat->SetFilter(mFilter);
-  gfxIntSize sourceSize = surface->GetSize();
-  if (mScaleMode != SCALE_NONE) {
-    NS_ASSERTION(mScaleMode == SCALE_STRETCH,
-      "No other scalemodes than stretch and none supported yet.");
-    gfxMatrix mat = pat->GetMatrix();
-    mat.Scale(float(sourceSize.width) / mScaleToSize.width, float(sourceSize.height) / mScaleToSize.height);
-    pat->SetMatrix(mat);
-    size = mScaleToSize;
-  }
 
   // The visible region can extend outside the image, so just draw
   // within the image bounds.
   if (aContext) {
     AutoSetOperator setOperator(aContext, GetOperator());
     PaintContext(pat,
                  nsIntRegion(nsIntRect(0, 0, size.width, size.height)),
                  aOpacity, aContext, aMaskLayer);
--- a/gfx/layers/d3d10/ImageLayerD3D10.cpp
+++ b/gfx/layers/d3d10/ImageLayerD3D10.cpp
@@ -176,17 +176,17 @@ ImageLayerD3D10::RenderLayer()
 
   AutoLockImage autoLock(container);
 
   Image *image = autoLock.GetImage();
   if (!image) {
     return;
   }
 
-  gfxIntSize size = mScaleMode == SCALE_NONE ? image->GetSize() : mScaleToSize;
+  gfxIntSize size = image->GetSize();
 
   SetEffectTransformAndOpacity();
 
   ID3D10EffectTechnique *technique;
   nsRefPtr<IDXGIKeyedMutex> keyedMutex;
 
   if (image->GetFormat() == ImageFormat::CAIRO_SURFACE || image->GetFormat() == ImageFormat::REMOTE_IMAGE_BITMAP ||
       image->GetFormat() == ImageFormat::REMOTE_IMAGE_DXGI_TEXTURE)
--- a/gfx/layers/d3d10/ThebesLayerD3D10.cpp
+++ b/gfx/layers/d3d10/ThebesLayerD3D10.cpp
@@ -37,58 +37,48 @@ ThebesLayerD3D10::ThebesLayerD3D10(Layer
 {
   mImplData = static_cast<LayerD3D10*>(this);
 }
 
 ThebesLayerD3D10::~ThebesLayerD3D10()
 {
 }
 
-/**
- * Retention threshold - amount of pixels intersection required to enable
- * layer content retention. This is a guesstimate. Profiling could be done to
- * figure out the optimal threshold.
- */
-#define RETENTION_THRESHOLD 16384
-
 void
-
 ThebesLayerD3D10::InvalidateRegion(const nsIntRegion &aRegion)
 {
   mValidRegion.Sub(mValidRegion, aRegion);
 }
 
 void ThebesLayerD3D10::CopyRegion(ID3D10Texture2D* aSrc, const nsIntPoint &aSrcOffset,
                                   ID3D10Texture2D* aDest, const nsIntPoint &aDestOffset,
                                   const nsIntRegion &aCopyRegion, nsIntRegion* aValidRegion)
 {
   nsIntRegion retainedRegion;
   nsIntRegionRectIterator iter(aCopyRegion);
   const nsIntRect *r;
   while ((r = iter.Next())) {
-    if (r->width * r->height > RETENTION_THRESHOLD) {
-      // Calculate the retained rectangle's position on the old and the new
-      // surface.
-      D3D10_BOX box;
-      box.left = r->x - aSrcOffset.x;
-      box.top = r->y - aSrcOffset.y;
-      box.right = box.left + r->width;
-      box.bottom = box.top + r->height;
-      box.back = 1;
-      box.front = 0;
+    // Calculate the retained rectangle's position on the old and the new
+    // surface.
+    D3D10_BOX box;
+    box.left = r->x - aSrcOffset.x;
+    box.top = r->y - aSrcOffset.y;
+    box.right = box.left + r->width;
+    box.bottom = box.top + r->height;
+    box.back = 1;
+    box.front = 0;
 
-      device()->CopySubresourceRegion(aDest, 0,
-                                      r->x - aDestOffset.x,
-                                      r->y - aDestOffset.y,
-                                      0,
-                                      aSrc, 0,
-                                      &box);
+    device()->CopySubresourceRegion(aDest, 0,
+                                    r->x - aDestOffset.x,
+                                    r->y - aDestOffset.y,
+                                    0,
+                                    aSrc, 0,
+                                    &box);
 
-      retainedRegion.Or(retainedRegion, *r);
-    }
+    retainedRegion.Or(retainedRegion, *r);
   }
 
   // Areas which were valid and were retained are still valid
   aValidRegion->And(*aValidRegion, retainedRegion);  
 }
 
 void
 ThebesLayerD3D10::RenderLayer()
@@ -214,18 +204,17 @@ ThebesLayerD3D10::Validate(ReadbackProce
       nsIntRect largeRect = retainRegion.GetLargestRectangle();
 
       // If we had no hardware texture before, or have no retained area larger than
       // the retention threshold, we're not retaining and are done here.
       // If our texture creation failed this can mean a device reset is pending
       // and we should silently ignore the failure. In the future when device
       // failures are properly handled we should test for the type of failure
       // and gracefully handle different failures. See bug 569081.
-      if (!oldTexture || !mTexture ||
-          largeRect.width * largeRect.height < RETENTION_THRESHOLD) {
+      if (!oldTexture || !mTexture) {
         mValidRegion.SetEmpty();
       } else {
         CopyRegion(oldTexture, mTextureRect.TopLeft(),
                    mTexture, newTextureRect.TopLeft(),
                    retainRegion, &mValidRegion);
         if (oldTextureOnWhite) {
           CopyRegion(oldTextureOnWhite, mTextureRect.TopLeft(),
                      mTextureOnWhite, newTextureRect.TopLeft(),
@@ -432,17 +421,17 @@ ThebesLayerD3D10::DrawRegion(nsIntRegion
     context = new gfxContext(destinationSurface);
   }
 
   nsIntRegionRectIterator iter(aRegion);
   context->Translate(gfxPoint(-visibleRect.x, -visibleRect.y));
   context->NewPath();
   const nsIntRect *iterRect;
   while ((iterRect = iter.Next())) {
-    context->Rectangle(gfxRect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));      
+    context->Rectangle(gfxRect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));
     if (mDrawTarget && aMode == SURFACE_SINGLE_CHANNEL_ALPHA) {
       mDrawTarget->ClearRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));
     }
   }
   context->Clip();
 
   if (!mDrawTarget && aMode == SURFACE_SINGLE_CHANNEL_ALPHA) {
     context->SetOperator(gfxContext::OPERATOR_CLEAR);
--- a/gfx/layers/d3d9/ImageLayerD3D9.cpp
+++ b/gfx/layers/d3d9/ImageLayerD3D9.cpp
@@ -363,17 +363,17 @@ ImageLayerD3D9::RenderLayer()
 
   Image *image = autoLock.GetImage();
   if (!image) {
     return;
   }
 
   SetShaderTransformAndOpacity();
 
-  gfxIntSize size = mScaleMode == SCALE_NONE ? image->GetSize() : mScaleToSize;
+  gfxIntSize size = image->GetSize();
 
   if (image->GetFormat() == CAIRO_SURFACE ||
       image->GetFormat() == REMOTE_IMAGE_BITMAP)
   {
     NS_ASSERTION(image->GetFormat() != CAIRO_SURFACE ||
                  !static_cast<CairoImage*>(image)->mSurface ||
                  static_cast<CairoImage*>(image)->mSurface->GetContentType() != gfxASurface::CONTENT_ALPHA,
                  "Image layer has alpha image");
--- a/gfx/layers/opengl/ImageLayerOGL.cpp
+++ b/gfx/layers/opengl/ImageLayerOGL.cpp
@@ -9,19 +9,19 @@
 #include "ImageContainer.h" // for PlanarYCBCRImage
 #include "mozilla/layers/ShmemYCbCrImage.h"
 #include "ipc/AutoOpenSurface.h"
 #include "ImageLayerOGL.h"
 #include "gfxImageSurface.h"
 #include "gfxUtils.h"
 #include "yuv_convert.h"
 #include "GLContextProvider.h"
-#if defined(MOZ_WIDGET_GTK2) && !defined(MOZ_PLATFORM_MAEMO)
+#if defined(MOZ_X11) && !defined(MOZ_PLATFORM_MAEMO)
 # include "GLXLibrary.h"
-# include "mozilla/X11Util.h"
+# include "gfxXlibSurface.h"
 #endif
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "nsSurfaceTexture.h"
 #endif
 
 #ifdef MOZ_WIDGET_GONK
 # include "GonkIOSurfaceImage.h"
@@ -242,18 +242,16 @@ ImageLayerOGL::RenderLayer(int,
 
   Image *image = autoLock.GetImage();
   if (!image) {
     return;
   }
 
   NS_ASSERTION(image->GetFormat() != REMOTE_IMAGE_BITMAP,
     "Remote images aren't handled yet in OGL layers!");
-  NS_ASSERTION(mScaleMode == SCALE_NONE,
-    "Scale modes other than none not handled yet in OGL layers!");
 
   if (image->GetFormat() == PLANAR_YCBCR) {
     PlanarYCbCrImage *yuvImage =
       static_cast<PlanarYCbCrImage*>(image);
 
     if (!yuvImage->IsValid()) {
       return;
     }
@@ -341,51 +339,32 @@ ImageLayerOGL::RenderLayer(int,
       return;
     }
 
     gl()->MakeCurrent();
 
     gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
     gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, data->mTexture.GetTextureID());
 
-#if defined(MOZ_WIDGET_GTK2) && !defined(MOZ_PLATFORM_MAEMO)
-    GLXPixmap pixmap;
-
-    if (cairoImage->mSurface) {
-        pixmap = sDefGLXLib.CreatePixmap(cairoImage->mSurface);
-        NS_ASSERTION(pixmap, "Failed to create pixmap!");
-        if (pixmap) {
-            sDefGLXLib.BindTexImage(pixmap);
-        }
-    }
-#endif
-
     ShaderProgramOGL *program = 
       mOGLManager->GetProgram(data->mLayerProgram, GetMaskLayer());
 
     gl()->ApplyFilterToBoundTexture(mFilter);
 
     program->Activate();
     program->SetLayerQuadRect(nsIntRect(0, 0, 
                                         cairoImage->GetSize().width, 
                                         cairoImage->GetSize().height));
     program->SetLayerTransform(GetEffectiveTransform());
     program->SetLayerOpacity(GetEffectiveOpacity());
     program->SetRenderOffset(aOffset);
     program->SetTextureUnit(0);
     program->LoadMask(GetMaskLayer());
 
     mOGLManager->BindAndDrawQuad(program);
-
-#if defined(MOZ_WIDGET_GTK2) && !defined(MOZ_PLATFORM_MAEMO)
-    if (cairoImage->mSurface && pixmap) {
-        sDefGLXLib.ReleaseTexImage(pixmap);
-        sDefGLXLib.DestroyPixmap(pixmap);
-    }
-#endif
 #ifdef XP_MACOSX
   } else if (image->GetFormat() == MAC_IO_SURFACE) {
      MacIOSurfaceImage *ioImage =
        static_cast<MacIOSurfaceImage*>(image);
 
      if (!mOGLManager->GetThebesLayerCallback()) {
        // If its an empty transaction we still need to update
        // the plugin IO Surface and make sure we grab the
@@ -577,26 +556,35 @@ ImageLayerOGL::AllocateTexturesCairo(Cai
   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 (sDefGLXLib.SupportsTextureFromPixmap(aImage->mSurface)) {
-    if (aImage->mSurface->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA) {
-      backendData->mLayerProgram = gl::RGBALayerProgramType;
-    } else {
-      backendData->mLayerProgram = gl::RGBXLayerProgramType;
+#if defined(MOZ_X11) && !defined(MOZ_PLATFORM_MAEMO)
+  if (aImage->mSurface->GetType() == gfxASurface::SurfaceTypeXlib) {
+    gfxXlibSurface *xsurf =
+      static_cast<gfxXlibSurface*>(aImage->mSurface.get());
+    GLXPixmap pixmap = xsurf->GetGLXPixmap();
+    if (pixmap) {
+      if (aImage->mSurface->GetContentType()
+          == gfxASurface::CONTENT_COLOR_ALPHA) {
+        backendData->mLayerProgram = gl::RGBALayerProgramType;
+      } else {
+        backendData->mLayerProgram = gl::RGBXLayerProgramType;
+      }
+
+      aImage->SetBackendData(LAYERS_OPENGL, backendData.forget());
+
+      sDefGLXLib.BindTexImage(pixmap);
+
+      return;
     }
-
-    aImage->SetBackendData(LAYERS_OPENGL, backendData.forget());
-    return;
   }
 #endif
   backendData->mLayerProgram =
     gl->UploadSurfaceToTexture(aImage->mSurface,
                                nsIntRect(0,0, aImage->mSize.width, aImage->mSize.height),
                                tex, true);
 
   aImage->SetBackendData(LAYERS_OPENGL, backendData.forget());
--- a/gfx/skia/Makefile.in
+++ b/gfx/skia/Makefile.in
@@ -17,117 +17,109 @@ EXPORT_LIBRARY  = 1
 
 EXPORTS_NAMESPACES = skia
 
 DEFINES += -DSK_A32_SHIFT=24 -DSK_R32_SHIFT=16 -DSK_G32_SHIFT=8 -DSK_B32_SHIFT=0
 
 LOCAL_INCLUDES += \
 	-I$(srcdir)/include/core \
 	-I$(srcdir)/include/config \
+	-I$(srcdir)/include/gpu \
+	-I$(srcdir)/include/pipe \
 	-I$(srcdir)/include/ports \
-	-I$(srcdir)/src/core \
 	-I$(srcdir)/include/images \
 	-I$(srcdir)/include/utils \
 	-I$(srcdir)/include/utils/mac \
 	-I$(srcdir)/include/utils/win \
 	-I$(srcdir)/include/views \
 	-I$(srcdir)/include/effects \
+	-I$(srcdir)/src/core \
+	-I$(srcdir)/src/image \
+	-I$(srcdir)/src/gpu \
 	-I$(srcdir)/src/utils \
 	-I$(srcdir)/src/sfnt \
 	$(NULL)
 
 VPATH += \
 	$(srcdir)/src/core \
+	$(srcdir)/src/image \
+	$(srcdir)/src/images \
+	$(srcdir)/src/pipe \
 	$(srcdir)/src/ports \
 	$(srcdir)/src/opts \
 	$(srcdir)/src/effects \
+	$(srcdir)/src/effects/gradients \
 	$(srcdir)/src/utils \
 	$(srcdir)/src/utils/mac \
 	$(srcdir)/src/sfnt \
 	$(NULL)
 
 EXPORTS_skia = \
 	include/core/Sk64.h \
 	include/core/SkAdvancedTypefaceMetrics.h \
-	include/core/SkAutoKern.h \
 	include/core/SkBitmap.h \
 	include/core/SkBlitRow.h \
-	include/core/SkBlitter.h \
 	include/core/SkBounder.h \
-	include/core/SkBuffer.h \
 	include/core/SkCanvas.h \
 	include/core/SkChunkAlloc.h \
 	include/core/SkClipStack.h \
 	include/core/SkColor.h \
 	include/core/SkColorFilter.h \
 	include/core/SkColorPriv.h \
 	include/core/SkColorShader.h \
+	include/core/SkColorTable.h \
 	include/core/SkComposeShader.h \
 	include/core/SkData.h \
 	include/core/SkDeque.h \
-	include/core/SkDescriptor.h \
 	include/core/SkDevice.h \
-	include/core/SkDeviceProfile.h \
 	include/core/SkDither.h \
 	include/core/SkDraw.h \
 	include/core/SkDrawFilter.h \
 	include/core/SkDrawLooper.h \
-	include/core/SkEdgeClipper.h \
 	include/core/SkEmptyShader.h \
 	include/core/SkEndian.h \
-	include/core/SkFDot6.h \
 	include/core/SkFixed.h \
 	include/core/SkFlattenable.h \
 	include/core/SkFloatBits.h \
 	include/core/SkFloatingPoint.h \
 	include/core/SkFontHost.h \
 	include/core/SkGeometry.h \
-	include/core/SkGlobals.h \
 	include/core/SkGraphics.h \
+	include/core/SkInstCnt.h \
 	include/core/SkLineClipper.h \
 	include/core/SkMMapStream.h \
 	include/core/SkMallocPixelRef.h \
 	include/core/SkMask.h \
 	include/core/SkMaskFilter.h \
 	include/core/SkMath.h \
 	include/core/SkMatrix.h \
 	include/core/SkMetaData.h \
 	include/core/SkOSFile.h \
-	include/core/SkOrderedReadBuffer.h \
-	include/core/SkOrderedWriteBuffer.h \
 	include/core/SkPackBits.h \
 	include/core/SkPaint.h \
 	include/core/SkPath.h \
 	include/core/SkPathEffect.h \
 	include/core/SkPathMeasure.h \
-	include/core/SkPerspIter.h \
 	include/core/SkPicture.h \
 	include/core/SkPixelRef.h \
 	include/core/SkPoint.h \
 	include/core/SkPostConfig.h \
 	include/core/SkPreConfig.h \
-	include/core/SkPtrRecorder.h \
 	include/core/SkRandom.h \
 	include/core/SkRasterizer.h \
 	include/core/SkReader32.h \
 	include/core/SkRect.h \
 	include/core/SkRefCnt.h \
-	include/core/SkRefDict.h \
 	include/core/SkRegion.h \
-	include/core/SkRelay.h \
 	include/core/SkScalar.h \
 	include/core/SkScalarCompare.h \
-	include/core/SkScalerContext.h \
-	include/core/SkScan.h \
 	include/core/SkShader.h \
-	include/core/SkShape.h \
 	include/core/SkSize.h \
 	include/core/SkStream.h \
 	include/core/SkString.h \
-	include/core/SkStroke.h \
 	include/core/SkTDArray.h \
 	include/core/SkTDStack.h \
 	include/core/SkTDict.h \
 	include/core/SkTLazy.h \
 	include/core/SkTRegistry.h \
 	include/core/SkTScopedPtr.h \
 	include/core/SkTSearch.h \
 	include/core/SkTemplates.h \
@@ -157,20 +149,23 @@ EXPORTS_skia = \
 
 DEFINES += -DUSE_SKIA
 
 CPPSRCS = \
 	Sk64.cpp \
 	SkAAClip.cpp \
 	SkAdvancedTypefaceMetrics.cpp \
 	SkAlphaRuns.cpp \
+	SkBBoxRecord.cpp \
+	SkBBoxHierarchyRecord.cpp \
 	SkBase64.cpp \
 	SkBitSet.cpp \
 	SkBitmap.cpp \
 	SkBitmapCache.cpp \
+	SkBitmapHeap.cpp \
 	SkBitmapProcShader.cpp \
 	SkBitmapProcState.cpp \
 	SkBitmapProcState_matrixProcs.cpp \
 	SkBitmapSampler.cpp \
 	SkBitmap_scroll.cpp \
 	SkBlitMask_D32.cpp \
 	SkBlitRow_D16.cpp \
 	SkBlitRow_D32.cpp \
@@ -183,105 +178,125 @@ CPPSRCS = \
 	SkBlitter_RGB16.cpp \
 	SkBlitter_Sprite.cpp \
 	SkBlurDrawLooper.cpp \
 	SkBlurMaskFilter.cpp \
 	SkBlurMask.cpp \
 	SkBuffer.cpp \
 	SkCanvas.cpp \
 	SkChunkAlloc.cpp \
-	SkClampRange.cpp \
 	SkClipStack.cpp \
 	SkColor.cpp \
 	SkColorFilter.cpp \
 	SkColorFilters.cpp \
 	SkColorMatrix.cpp \
 	SkColorTable.cpp \
+	SkClampRange.cpp \
 	SkComposeShader.cpp \
 	SkConcaveToTriangles.cpp \
 	SkConfig8888.cpp \
 	SkCordic.cpp \
 	SkCubicClipper.cpp \
 	SkDashPathEffect.cpp \
 	SkData.cpp \
+	SkDataPixelRef.cpp \
 	SkDebug.cpp \
 	SkDeferredCanvas.cpp \
 	SkDeque.cpp \
 	SkDevice.cpp \
 	SkDeviceProfile.cpp \
 	SkDither.cpp \
 	SkDraw.cpp \
 	SkEdge.cpp \
 	SkEdgeBuilder.cpp \
 	SkEdgeClipper.cpp \
 	SkFilterProc.cpp \
 	SkFlattenable.cpp \
+	SkFlattenableBuffers.cpp \
 	SkFloat.cpp \
 	SkFloatBits.cpp \
+	SkFontDescriptor.cpp \
 	SkFontHost.cpp \
 	SkGeometry.cpp \
-	SkGlobals.cpp \
-	SkGlobals_global.cpp \
 	SkGlyphCache.cpp \
 	SkGradientShader.cpp \
 	SkGraphics.cpp \
+	SkGPipeRead.cpp \
+	SkGPipeWrite.cpp \
+	SkImage.cpp \
+	SkImage_Codec.cpp \
+	SkImage_Picture.cpp \
+	SkImage_Raster.cpp \
+	SkImageDecoder.cpp \
+	SkImageDecoder_Factory.cpp \
+	SkImageFilter.cpp \
+	SkImagePriv.cpp \
 	SkLayerDrawLooper.cpp \
 	SkLayerRasterizer.cpp \
+	SkLinearGradient.cpp \
 	SkLineClipper.cpp \
 	SkMallocPixelRef.cpp \
 	SkMask.cpp \
 	SkMaskFilter.cpp \
+	SkMaskGamma.cpp \
 	SkMath.cpp \
 	SkMatrix.cpp \
-	SkMemory_mozalloc.cpp \
+	SkMemory_malloc.cpp \
 	SkMetaData.cpp \
-	SkMorphologyImageFilter.cpp \
 	SkOrderedReadBuffer.cpp \
 	SkOrderedWriteBuffer.cpp \
 	SkOSFile_stdio.cpp \
 	SkOTUtils.cpp \
 	SkPackBits.cpp \
 	SkPaint.cpp \
 	SkPath.cpp \
 	SkPathEffect.cpp \
 	SkPathHeap.cpp \
 	SkPathMeasure.cpp \
 	SkPicture.cpp \
 	SkPictureFlat.cpp \
 	SkPicturePlayback.cpp \
 	SkPictureRecord.cpp \
+	SkPictureStateTree.cpp \
 	SkPixelRef.cpp \
 	SkPoint.cpp \
 	SkProcSpriteBlitter.cpp \
 	SkPtrRecorder.cpp \
 	SkQuadClipper.cpp \
+	SkRTree.cpp \
+	SkRadialGradient.cpp \
 	SkRasterClip.cpp \
 	SkRasterizer.cpp \
 	SkRect.cpp \
 	SkRefDict.cpp \
 	SkRegion.cpp \
 	SkRegion_path.cpp \
 	SkRegion_rects.cpp \
 	SkScalar.cpp \
 	SkScalerContext.cpp \
 	SkScan.cpp \
 	SkScan_AntiPath.cpp \
 	SkScan_Antihair.cpp \
 	SkScan_Hairline.cpp \
 	SkScan_Path.cpp \
 	SkShader.cpp \
-	SkShape.cpp \
 	SkSpriteBlitter_ARGB32.cpp \
 	SkSpriteBlitter_RGB16.cpp \
 	SkStream.cpp \
 	SkString.cpp \
 	SkStroke.cpp \
 	SkStrokerPriv.cpp \
+	SkSurface.cpp \
+	SkSurface_Raster.cpp \
+	SkSurface_Picture.cpp \
+	SkSweepGradient.cpp \
 	SkTLS.cpp \
 	SkTSearch.cpp \
+	SkTwoPointConicalGradient.cpp \
+	SkTwoPointRadialGradient.cpp \
 	SkTypeface.cpp \
 	SkTypefaceCache.cpp \
 	SkUnPreMultiply.cpp \
 	SkUtils.cpp \
 	SkWriter32.cpp \
 	SkXfermode.cpp \
 	$(NULL)
 
@@ -295,18 +310,18 @@ CPPSRCS += \
 	SkTime_Unix.cpp \
 	$(NULL)
 endif
 
 ifeq (android,$(MOZ_WIDGET_TOOLKIT))
 CPPSRCS += \
 	SkDebug_android.cpp \
 	SkFontHost_android_old.cpp \
-	SkFontHost_gamma.cpp \
 	SkFontHost_FreeType.cpp \
+	SkFontHost_FreeType_common.cpp \
 	SkFontHost_tables.cpp \
 	SkMMapStream.cpp \
 	SkTime_Unix.cpp \
 	SkThread_pthread.cpp \
 	$(NULL)
 
 DEFINES += -DSK_BUILD_FOR_ANDROID_NDK
 OS_CXXFLAGS += $(CAIRO_FT_CFLAGS)
@@ -315,31 +330,31 @@ CPPSRCS += \
 	SkDebug_stdio.cpp \
 	SkThread_none.cpp \
 	$(NULL)
 endif
 
 ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT))
 CPPSRCS += \
 	SkFontHost_FreeType.cpp \
-	SkFontHost_gamma_none.cpp \
+	SkFontHost_FreeType_common.cpp \
 	SkFontHost_linux.cpp \
 	SkFontHost_tables.cpp \
 	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 \
+	SkFontHost_FreeType_common.cpp \
 	SkFontHost_tables.cpp \
 	SkMMapStream.cpp \
 	SkOSFile.cpp \
 	$(NULL)
 ifeq (Linux,$(OS_TARGET))
 CPPSRCS += \
 	SkFontHost_linux.cpp \
 	SkFontHost_tables.cpp \
@@ -355,16 +370,19 @@ EXPORTS_skia += \
 	include/ports/SkTypeface_win.h \
 	$(NULL)
 CPPSRCS += \
 	SkFontHost_win.cpp \
 	SkFontHost_tables.cpp \
 	SkFontHost_sandbox_none.cpp \
 	SkTime_win.cpp \
 	$(NULL)
+ifdef _MSC_VER
+HAVE_COMPILER_FLAG_MSSSE3=1
+endif
 endif
 
 ifneq (,$(INTEL_ARCHITECTURE))
 CPPSRCS += \
 	SkBitmapProcState_opts_SSE2.cpp \
 	SkBlitRect_opts_SSE2.cpp \
 	SkBlitRow_opts_SSE2.cpp \
 	SkUtils_opts_SSE2.cpp \
@@ -402,8 +420,15 @@ SkBlitRect_opts_SSE2.$(OBJ_SUFFIX): CXXF
 SkUtils_opts_SSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2
 endif
 endif
 
 ifdef GNU_CC
 CXXFLAGS := $(filter-out -pedantic,$(CXXFLAGS))
 CFLAGS := $(filter-out -pedantic,$(CFLAGS))
 endif
+
+ifeq ($(CPU_ARCH)_$(GNU_CC),arm_1)
+# The assembly uses the frame pointer register (r7 in Thumb/r11 in
+# ARM), the compiler doesn't like that.
+CXXFLAGS := $(filter-out -fno-omit-frame-pointer,$(CXXFLAGS)) -fomit-frame-pointer
+CFLAGS := $(filter-out -fno-omit-frame-pointer,$(CFLAGS)) -fomit-frame-pointer
+endif
--- a/gfx/skia/README_MOZILLA
+++ b/gfx/skia/README_MOZILLA
@@ -1,5 +1,5 @@
 The source from this directory was copied from the skia subversion trunk
 using the update.sh script. The changes made were those applied by update.sh,
 the addition/update of Makefile.in files for the Mozilla build system.
 
-The subversion revision used was r4037.
+The subversion revision used was r5539.
--- a/gfx/skia/include/animator/SkAnimator.h
+++ b/gfx/skia/include/animator/SkAnimator.h
@@ -37,25 +37,25 @@ enum SkElementType {
     This enum is incomplete and will be fleshed out in a future release */
 enum SkFieldType {
     kFieldDummyType
 };
 
 /** \class SkAnimator
 
     The SkAnimator class decodes an XML stream into a display list. The
-    display list can be drawn statically as a picture, or can drawn 
+    display list can be drawn statically as a picture, or can drawn
     different elements at different times to form a moving animation.
 
     SkAnimator does not read the system time on its own; it relies on the
     caller to pass the current time. The caller can pause, speed up, or
     reverse the animation by varying the time passed in.
 
-    The XML describing the display list must conform to the schema 
-    described by SkAnimateSchema.xsd. 
+    The XML describing the display list must conform to the schema
+    described by SkAnimateSchema.xsd.
 
     The XML must contain an <event> element to draw. Usually, it contains
     an <event kind="onload" /> block to add some drawing elements to the
     display list when the document is first decoded.
 
     Here's an "Hello World" XML sample:
 
     <screenplay>
@@ -79,136 +79,136 @@ enum SkFieldType {
         SkCanvas canvas(getBitmap()); // create a canvas
         animator.draw(canvas, &paint, 0); // draw the scene
 */
 class SkAnimator : public SkEventSink {
 public:
     SkAnimator();
     virtual ~SkAnimator();
 
-    /** Add a drawable extension to the graphics engine. Experimental. 
+    /** Add a drawable extension to the graphics engine. Experimental.
         @param extras A derived class that implements methods that identify and instantiate the class
     */
     void addExtras(SkExtras* extras);
 
     /** Read in XML from a stream, and append it to the current
         animator. Returns false if an error was encountered.
         Error diagnostics are stored in fErrorCode and fLineNumber.
         @param stream  The stream to append.
         @return true if the XML was parsed successfully.
     */
     bool appendStream(SkStream* stream);
 
-    /** Read in XML from memory. Returns true if the file can be 
+    /** Read in XML from memory. Returns true if the file can be
         read without error. Returns false if an error was encountered.
         Error diagnostics are stored in fErrorCode and fLineNumber.
         @param buffer  The XML text as UTF-8 characters.
         @param size  The XML text length in bytes.
         @return true if the XML was parsed successfully.
     */
     bool decodeMemory(const void* buffer, size_t size);
 
-    /** Read in XML from a stream. Returns true if the file can be 
+    /** Read in XML from a stream. Returns true if the file can be
         read without error. Returns false if an error was encountered.
         Error diagnostics are stored in fErrorCode and fLineNumber.
         @param stream  The stream containg the XML text as UTF-8 characters.
         @return true if the XML was parsed successfully.
     */
     virtual bool decodeStream(SkStream* stream);
 
-    /** Parse the DOM tree starting at the specified node. Returns true if it can be 
+    /** Parse the DOM tree starting at the specified node. Returns true if it can be
         parsed without error. Returns false if an error was encountered.
         Error diagnostics are stored in fErrorCode and fLineNumber.
         @return true if the DOM was parsed successfully.
     */
     virtual bool decodeDOM(const SkDOM&, const SkDOMNode*);
 
-    /** Read in XML from a URI. Returns true if the file can be 
+    /** Read in XML from a URI. Returns true if the file can be
         read without error. Returns false if an error was encountered.
         Error diagnostics are stored in fErrorCode and fLineNumber.
         @param uri The complete url path to be read (either ftp, http or https).
         @return true if the XML was parsed successfully.
     */
     bool decodeURI(const char uri[]);
 
     /** Pass a char event, usually a keyboard symbol, to the animator.
         This triggers events of the form <event kind="keyChar" key="... />
-        @param ch  The character to match against <event> element "key" 
+        @param ch  The character to match against <event> element "key"
             attributes.
         @return true if the event was dispatched successfully.
     */
     bool doCharEvent(SkUnichar ch);
 
     /** Experimental:
-        Pass a mouse click event along with the mouse coordinates to 
+        Pass a mouse click event along with the mouse coordinates to
         the animator. This triggers events of the form <event kind="mouseDown" ... />
         and other mouse events.
         @param state The mouse state, described by SkView::Click::State : values are
         down == 0, moved == 1, up == 2
         @param x    The x-position of the mouse
         @param y The y-position of the mouse
         @return true if the event was dispatched successfully.
     */
     bool doClickEvent(int state, SkScalar x, SkScalar y);
 
     /** Pass a meta-key event, such as an arrow , to the animator.
         This triggers events of the form <event kind="keyPress" code="... />
-        @param code  The key to match against <event> element "code" 
+        @param code  The key to match against <event> element "code"
             attributes.
         @return true if the event was dispatched successfully.
     */
     bool doKeyEvent(SkKey code);
     bool doKeyUpEvent(SkKey code);
-    
-    /** Send an event to the animator. The animator's clock is set 
+
+    /** Send an event to the animator. The animator's clock is set
         relative to the current time.
         @return true if the event was dispatched successfully.
     */
     bool doUserEvent(const SkEvent& evt);
 
-    /** The possible results from the draw function. 
+    /** The possible results from the draw function.
     */
     enum DifferenceType {
         kNotDifferent,
         kDifferent,
         kPartiallyDifferent
     };
-    /** Draws one frame of the animation. The first call to draw always 
-        draws the initial frame of the animation. Subsequent calls draw 
-        the offset into the animation by 
+    /** Draws one frame of the animation. The first call to draw always
+        draws the initial frame of the animation. Subsequent calls draw
+        the offset into the animation by
         subtracting the initial time from the current time.
         @param canvas  The canvas to draw into.
         @param paint     The paint to draw with.
         @param time  The offset into the current animation.
         @return kNotDifferent if there are no active animations; kDifferent if there are active animations; and
-        kPartiallyDifferent if the document contains an active <bounds> element that specifies a minimal 
+        kPartiallyDifferent if the document contains an active <bounds> element that specifies a minimal
         redraw area.
     */
     DifferenceType draw(SkCanvas* canvas, SkPaint* paint, SkMSec time);
 
     /** Draws one frame of the animation, using a new Paint each time.
-        The first call to draw always 
-        draws the initial frame of the animation. Subsequent calls draw 
-        the offset into the animation by 
+        The first call to draw always
+        draws the initial frame of the animation. Subsequent calls draw
+        the offset into the animation by
         subtracting the initial time from the current time.
         @param canvas  The canvas to draw into.
         @param time  The offset into the current animation.
         @return kNotDifferent if there are no active animations; kDifferent if there are active animations; and
-        kPartiallyDifferent if the document contains an active <bounds> element that specifies a minimal 
+        kPartiallyDifferent if the document contains an active <bounds> element that specifies a minimal
         redraw area.
     */
     DifferenceType draw(SkCanvas* canvas, SkMSec time);
 
     /** Experimental:
         Helper to choose whether to return a SkView::Click handler.
         @param x ignored
         @param y ignored
         @return true if a mouseDown event handler is enabled.
     */
-    bool findClickEvent(SkScalar x, SkScalar y); 
+    bool findClickEvent(SkScalar x, SkScalar y);
 
 
     /** Get the nested animator associated with this element, if any.
         Use this to access a movie's event sink, to send events to movies.
         @param element the value returned by getElement
         @return the internal animator.
     */
     const SkAnimator* getAnimator(const SkDisplayable* element) const;
@@ -218,214 +218,214 @@ public:
         @param field the value returned by getField
         @param index the array entry
         @return the integer value to retrieve, or SK_NaN32 if unsuccessful
     */
     int32_t getArrayInt(const SkDisplayable* element, const SkMemberInfo* field, int index);
 
     /** Returns the scalar value of the specified element's attribute[index]
         @param elementID is the value of the id attribute in the XML of this element
-        @param fieldName specifies the name of the attribute  
+        @param fieldName specifies the name of the attribute
         @param index the array entry
         @return the integer value to retrieve, or SK_NaN32 if unsuccessful
     */
     int32_t getArrayInt(const char* elementID, const char* fieldName, int index);
 
     /** Returns the scalar value of the specified element's attribute[index]
         @param element the value returned by getElement
         @param field the value returned by getField
         @param index the array entry
         @return the scalar value to retrieve, or SK_ScalarNaN if unsuccessful
     */
     SkScalar getArrayScalar(const SkDisplayable* element, const SkMemberInfo* field, int index);
 
     /** Returns the scalar value of the specified element's attribute[index]
         @param elementID is the value of the id attribute in the XML of this element
-        @param fieldName specifies the name of the attribute  
+        @param fieldName specifies the name of the attribute
         @param index the array entry
         @return the scalar value to retrieve, or SK_ScalarNaN if unsuccessful
     */
     SkScalar getArrayScalar(const char* elementID, const char* fieldName, int index);
 
     /** Returns the string value of the specified element's attribute[index]
         @param element is a value returned by getElement
-        @param field is a value returned by getField  
+        @param field is a value returned by getField
         @param index the array entry
         @return the string value to retrieve, or null if unsuccessful
     */
     const char* getArrayString(const SkDisplayable* element, const SkMemberInfo* field, int index);
 
     /** Returns the string value of the specified element's attribute[index]
         @param elementID is the value of the id attribute in the XML of this element
-        @param fieldName specifies the name of the attribute  
+        @param fieldName specifies the name of the attribute
         @param index the array entry
         @return the string value to retrieve, or null if unsuccessful
     */
     const char* getArrayString(const char* elementID, const char* fieldName, int index);
 
     /** Returns the XML element corresponding to the given ID.
-        @param elementID is the value of the id attribute in the XML of this element 
+        @param elementID is the value of the id attribute in the XML of this element
         @return the element matching the ID, or null if the element can't be found
     */
     const SkDisplayable* getElement(const char* elementID);
 
     /** Returns the element type corresponding to the XML element.
         The element type matches the element name; for instance, <line> returns kElement_LineType
-        @param element is a value returned by getElement  
+        @param element is a value returned by getElement
         @return element type, or 0 if the element can't be found
     */
     SkElementType getElementType(const SkDisplayable* element);
 
     /** Returns the element type corresponding to the given ID.
-        @param elementID is the value of the id attribute in the XML of this element 
+        @param elementID is the value of the id attribute in the XML of this element
         @return element type, or 0 if the element can't be found
     */
     SkElementType getElementType(const char* elementID);
 
     /** Returns the XML field of the named attribute in the XML element.
         @param element is a value returned by getElement
-        @param fieldName is the attribute to return  
+        @param fieldName is the attribute to return
         @return the attribute matching the fieldName, or null if the element can't be found
     */
     const SkMemberInfo* getField(const SkDisplayable* element, const char* fieldName);
 
     /** Returns the XML field of the named attribute in the XML element matching the elementID.
         @param elementID is the value of the id attribute in the XML of this element
-        @param fieldName is the attribute to return  
+        @param fieldName is the attribute to return
         @return the attribute matching the fieldName, or null if the element can't be found
     */
     const SkMemberInfo* getField(const char* elementID, const char* fieldName);
 
     /** Returns the value type coresponding to the element's attribute.
         The value type matches the XML schema: and may be kField_BooleanType, kField_ScalarType, etc.
-        @param field is a value returned by getField  
+        @param field is a value returned by getField
         @return the attribute type, or 0 if the element can't be found
     */
     SkFieldType getFieldType(const SkMemberInfo* field);
 
     /** Returns the value type coresponding to the element's attribute.
         @param elementID is the value of the id attribute in the XML of this element
-        @param fieldName specifies the name of the attribute  
+        @param fieldName specifies the name of the attribute
         @return the attribute type, or 0 if the element can't be found
     */
     SkFieldType getFieldType(const char* elementID, const char* fieldName);
 
     /** Returns the recommended animation interval. Returns zero if no
         interval is specified.
     */
     SkMSec getInterval();
 
     /** Returns the partial rectangle to invalidate after drawing. Call after draw() returns
     kIsPartiallyDifferent to do a mimimal inval(). */
-    void getInvalBounds(SkRect* inval); 
+    void getInvalBounds(SkRect* inval);
 
-    /** Returns the details of any error encountered while parsing the XML. 
+    /** Returns the details of any error encountered while parsing the XML.
     */
     const SkXMLParserError* getParserError();
-    
-    /** Returns the details of any error encountered while parsing the XML as string. 
+
+    /** Returns the details of any error encountered while parsing the XML as string.
     */
     const char* getParserErrorString();
-    
+
     /** Returns the scalar value of the specified element's attribute
         @param element is a value returned by getElement
-        @param field is a value returned by getField  
+        @param field is a value returned by getField
         @return the integer value to retrieve, or SK_NaN32 if not found
     */
     int32_t getInt(const SkDisplayable* element, const SkMemberInfo* field);
 
     /** Returns the scalar value of the specified element's attribute
         @param elementID is the value of the id attribute in the XML of this element
-        @param fieldName specifies the name of the attribute  
+        @param fieldName specifies the name of the attribute
         @return the integer value to retrieve, or SK_NaN32 if not found
     */
     int32_t getInt(const char* elementID, const char* fieldName);
 
     /** Returns the scalar value of the specified element's attribute
         @param element is a value returned by getElement
-        @param field is a value returned by getField  
+        @param field is a value returned by getField
         @return the scalar value to retrieve, or SK_ScalarNaN if not found
     */
     SkScalar getScalar(const SkDisplayable* element, const SkMemberInfo* field);
 
     /** Returns the scalar value of the specified element's attribute
         @param elementID is the value of the id attribute in the XML of this element
-        @param fieldName specifies the name of the attribute  
+        @param fieldName specifies the name of the attribute
         @return the scalar value to retrieve, or SK_ScalarNaN if not found
     */
     SkScalar getScalar(const char* elementID, const char* fieldName);
 
     /** Returns the string value of the specified element's attribute
         @param element is a value returned by getElement
-        @param field is a value returned by getField  
+        @param field is a value returned by getField
         @return the string value to retrieve, or null if not found
     */
     const char* getString(const SkDisplayable* element, const SkMemberInfo* field);
 
     /** Returns the string value of the specified element's attribute
         @param elementID is the value of the id attribute in the XML of this element
-        @param fieldName specifies the name of the attribute  
+        @param fieldName specifies the name of the attribute
         @return the string value to retrieve, or null if not found
     */
     const char* getString(const char* elementID, const char* fieldName);
 
     /** Gets the file default directory of the URL base path set explicitly or by reading the last URL. */
     const char* getURIBase();
 
     /** Resets the animator to a newly created state with no animation data. */
     void initialize();
 
-    /** Experimental. Resets any active animations so that the next time passed is treated as 
+    /** Experimental. Resets any active animations so that the next time passed is treated as
         time zero. */
     void reset();
-    
+
     /** Sets the scalar value of the specified element's attribute
         @param elementID is the value of the id attribute in the XML of this element
-        @param fieldName specifies the name of the attribute  
+        @param fieldName specifies the name of the attribute
         @param array is the c-style array of integers
         @param count is the length of the array
         @return true if the value was set successfully
     */
     bool setArrayInt(const char* elementID, const char* fieldName, const int* array, int count);
-    
+
     /** Sets the scalar value of the specified element's attribute
         @param elementID is the value of the id attribute in the XML of this element
-        @param fieldName specifies the name of the attribute  
+        @param fieldName specifies the name of the attribute
         @param array is the c-style array of strings
         @param count is the length of the array
         @return true if the value was set successfully
     */
     bool setArrayString(const char* elementID, const char* fieldName, const char** array, int count);
-    
+
     /** Sets the scalar value of the specified element's attribute
         @param elementID is the value of the id attribute in the XML of this element
-        @param fieldName specifies the name of the attribute  
+        @param fieldName specifies the name of the attribute
         @param data the integer value to set
         @return true if the value was set successfully
     */
     bool setInt(const char* elementID, const char* fieldName, int32_t data);
 
     /** Sets the scalar value of the specified element's attribute
         @param elementID is the value of the id attribute in the XML of this element
-        @param fieldName specifies the name of the attribute  
+        @param fieldName specifies the name of the attribute
         @param data the scalar value to set
         @return true if the value was set successfully
     */
     bool setScalar(const char* elementID, const char* fieldName, SkScalar data);
 
     /** Sets the string value of the specified element's attribute
         @param elementID is the value of the id attribute in the XML of this element
-        @param fieldName specifies the name of the attribute  
+        @param fieldName specifies the name of the attribute
         @param data the string value to set
         @return true if the value was set successfully
     */
     bool setString(const char* elementID, const char* fieldName, const char* data);
 
-    /** Sets the file default directory of the URL base path 
-        @param path the directory path 
+    /** Sets the file default directory of the URL base path
+        @param path the directory path
     */
     void setURIBase(const char* path);
 
     typedef void* Handler;
     // This guy needs to be exported to java, so don't make it virtual
     void setHostHandler(Handler handler) {
         this->onSetHostHandler(handler);
     }
@@ -437,59 +437,59 @@ public:
     class Timeline {
     public:
         virtual ~Timeline() {}
 
         /** Returns the current time in milliseconds */
         virtual SkMSec getMSecs() const = 0;
     };
 
-    /** Sets a user class to return the current time to the animator. 
+    /** Sets a user class to return the current time to the animator.
         Optional; if not called, the system clock will be used by calling SkTime::GetMSecs instead.
         @param callBack the time function
     */
     void setTimeline(const Timeline& );
 
     static void Init(bool runUnitTests);
     static void Term();
-    
-    /** The event sink events generated by the animation are posted to. 
+
+    /** The event sink events generated by the animation are posted to.
         Screenplay also posts an inval event to this event sink after processing an
         event to force a redraw.
         @param target the event sink id
     */
     void setHostEventSinkID(SkEventSinkID hostID);
     SkEventSinkID getHostEventSinkID() const;
-    
+
     // helper
     void setHostEventSink(SkEventSink* sink) {
         this->setHostEventSinkID(sink ? sink->getSinkID() : 0);
     }
-    
+
     virtual void setJavaOwner(Handler owner);
-    
+
 #ifdef SK_DEBUG
     virtual void eventDone(const SkEvent& evt);
     virtual bool isTrackingEvents();
     static bool NoLeaks();
-#endif  
-    
+#endif
+
 protected:
     virtual void onSetHostHandler(Handler handler);
     virtual void onEventPost(SkEvent*, SkEventSinkID);
     virtual void onEventPostTime(SkEvent*, SkEventSinkID, SkMSec time);
 
 private:
 // helper functions for setters
     bool setArray(SkDisplayable* element, const SkMemberInfo* field, SkTypedArray array);
     bool setArray(const char* elementID, const char* fieldName, SkTypedArray array);
     bool setInt(SkDisplayable* element, const SkMemberInfo* field, int32_t data);
     bool setScalar(SkDisplayable* element, const SkMemberInfo* field, SkScalar data);
     bool setString(SkDisplayable* element, const SkMemberInfo* field, const char* data);
-    
+
     virtual bool onEvent(const SkEvent&);
     SkAnimateMaker* fMaker;
     friend class SkAnimateMaker;
     friend class SkAnimatorScript;
     friend class SkAnimatorScript2;
     friend class SkApply;
     friend class SkDisplayMovie;
     friend class SkDisplayType;
--- a/gfx/skia/include/config/SkUserConfig.h
+++ b/gfx/skia/include/config/SkUserConfig.h
@@ -30,43 +30,26 @@
     Below are optional defines that add, subtract, or change default behavior
     in Skia. Your port can locally edit this file to enable/disable flags as
     you choose, or these can be delared on your command line (i.e. -Dfoo).
 
     By default, this include file will always default to having all of the flags
     commented out, so including it will have no effect.
 */
 
-/*
-    Override new/delete with Mozilla's allocator, mozalloc
-
-    Ideally we shouldn't need to do this here, but until
-    http://code.google.com/p/skia/issues/detail?id=598 is fixed
-    we need to include this here to override operator new and delete
-*/
-
-#include "mozilla/mozalloc.h"
-
 ///////////////////////////////////////////////////////////////////////////////
 
 /*  Scalars (the fractional value type in skia) can be implemented either as
     floats or 16.16 integers (fixed). Exactly one of these two symbols must be
     defined.
 */
 //#define SK_SCALAR_IS_FLOAT
 //#define SK_SCALAR_IS_FIXED
 
 
-/*  Somewhat independent of how SkScalar is implemented, Skia also wants to know
-    if it can use floats at all. Naturally, if SK_SCALAR_IS_FLOAT is defined,
-    SK_CAN_USE_FLOAT must be too; but if scalars are fixed, SK_CAN_USE_FLOAT
-    can go either way.
- */
-//#define SK_CAN_USE_FLOAT
-
 /*  For some performance-critical scalar operations, skia will optionally work
     around the standard float operators if it knows that the CPU does not have
     native support for floats. If your environment uses software floating point,
     define this flag.
  */
 //#define SK_SOFTWARE_FLOAT
 
 
@@ -77,16 +60,22 @@
 
     By default, these mutually exclusive flags are defined in SkPreConfig.h,
     based on the presence or absence of NDEBUG, but that decision can be changed
     here.
  */
 //#define SK_DEBUG
 //#define SK_RELEASE
 
+/*  To assist debugging, Skia provides an instance counting utility in
+    include/core/SkInstCount.h. This flag turns on and off that utility to
+    allow instance count tracking in either debug or release builds. By
+    default it is enabled in debug but disabled in release.
+ */
+//#define SK_ENABLE_INST_COUNT
 
 /*  If, in debugging mode, Skia needs to stop (presumably to invoke a debugger)
     it will call SK_CRASH(). If this is not defined it, it is defined in
     SkPostConfig.h to write to an illegal address
  */
 //#define SK_CRASH() *(int *)(uintptr_t)0 = 0
 
 
@@ -144,37 +133,33 @@
 
 /*  Define this to provide font subsetter in PDF generation.
  */
 //#define SK_SFNTLY_SUBSETTER "sfntly/subsetter/font_subsetter.h"
 
 /*  Define this to remove dimension checks on bitmaps. Not all blits will be
     correct yet, so this is mostly for debugging the implementation.
  */
-//#define SK_ALLOW_OVER_32K_BITMAPS
+#define SK_ALLOW_OVER_32K_BITMAPS
 
 /*  Define this to set the upper limit for text to support LCD. Values that
     are very large increase the cost in the font cache and draw slower, without
     improving readability. If this is undefined, Skia will use its default
     value (e.g. 48)
  */
 //#define SK_MAX_SIZE_FOR_LCDTEXT     48
 
 /*  If SK_DEBUG is defined, then you can optionally define SK_SUPPORT_UNITTEST
     which will run additional self-tests at startup. These can take a long time,
     so this flag is optional.
  */
 #ifdef SK_DEBUG
 //#define SK_SUPPORT_UNITTEST
 #endif
 
-/*  Don't dither 32bit gradients, to match what the canvas test suite expects.
- */
-#define SK_DISABLE_DITHER_32BIT_GRADIENT
-
 /* If your system embeds skia and has complex event logging, define this
    symbol to name a file that maps the following macros to your system's
    equivalents:
        SK_TRACE_EVENT0(event)
        SK_TRACE_EVENT1(event, name1, value1)
        SK_TRACE_EVENT2(event, name1, value1, name2, value2)
    src/utils/SkDebugTrace.h has a trivial implementation that writes to
    the debug output stream. If SK_USER_TRACE_INCLUDE_FILE is not defined,
@@ -186,15 +171,29 @@
  */
 #ifdef SK_SAMPLES_FOR_X
         #define SK_R32_SHIFT    16
         #define SK_G32_SHIFT    8
         #define SK_B32_SHIFT    0
         #define SK_A32_SHIFT    24
 #endif
 
+
+/* Determines whether to build code that supports the GPU backend. Some classes
+   that are not GPU-specific, such as SkShader subclasses, have optional code
+   that is used allows them to interact with the GPU backend. If you'd like to
+   omit this code set SK_SUPPORT_GPU to 0. This also allows you to omit the gpu
+   directories from your include search path when you're not building the GPU
+   backend. Defaults to 1 (build the GPU code).
+ */
+#define SK_SUPPORT_GPU 0
+
+/*  Don't dither 32bit gradients, to match what the canvas test suite expects.
+ */
+#define SK_DISABLE_DITHER_32BIT_GRADIENT
+
 /*  Don't include stdint.h on windows as it conflicts with our build system.
  */
 #ifdef SK_BUILD_FOR_WIN32 
     #define SK_IGNORE_STDINT_DOT_H 
 #endif 
 
 #endif
--- a/gfx/skia/include/core/Sk64.h
+++ b/gfx/skia/include/core/Sk64.h
@@ -129,45 +129,45 @@ struct SK_API Sk64 {
     /** Add the specified 32 bit integer to the number */
     void add(int32_t lo) {
         int32_t  hi = lo >> 31; // 0 or -1
         uint32_t sum = fLo + (uint32_t)lo;
 
         fHi = fHi + hi + (sum < fLo);
         fLo = sum;
     }
-    
+
     /** Add the specified Sk64 to the number */
     void add(int32_t hi, uint32_t lo) {
         uint32_t sum = fLo + lo;
 
         fHi = fHi + hi + (sum < fLo);
         fLo = sum;
     }
-    
+
     /** Add the specified Sk64 to the number */
     void    add(const Sk64& other) { this->add(other.fHi, other.fLo); }
-    
+
     /** Subtract the specified Sk64 from the number. (*this) = (*this) - num
     */
     void    sub(const Sk64& num);
-    
+
     /** Subtract the number from the specified Sk64. (*this) = num - (*this)
     */
     void    rsub(const Sk64& num);
-    
+
     /** Multiply the number by the specified 32 bit integer
     */
     void    mul(int32_t);
 
     enum DivOptions {
         kTrunc_DivOption,   //!< truncate the result when calling div()
         kRound_DivOption    //!< round the result when calling div()
     };
-    
+
     /** Divide the number by the specified 32 bit integer, using the specified
         divide option (either truncate or round).
     */
     void    div(int32_t, DivOptions);
 
     /** return (this + other >> 16) as a 32bit result */
     SkFixed addGetFixed(const Sk64& other) const {
         return this->addGetFixed(other.fHi, other.fLo);
@@ -200,29 +200,29 @@ struct SK_API Sk64 {
 
     friend bool operator==(const Sk64& a, const Sk64& b) {
         return a.fHi == b.fHi && a.fLo == b.fLo;
     }
 
     friend bool operator!=(const Sk64& a, const Sk64& b) {
         return a.fHi != b.fHi || a.fLo != b.fLo;
     }
-    
+
     friend bool operator<(const Sk64& a, const Sk64& b) {
         return a.fHi < b.fHi || (a.fHi == b.fHi && a.fLo < b.fLo);
     }
-    
+
     friend bool operator<=(const Sk64& a, const Sk64& b) {
         return a.fHi < b.fHi || (a.fHi == b.fHi && a.fLo <= b.fLo);
     }
-    
+
     friend bool operator>(const Sk64& a, const Sk64& b) {
         return a.fHi > b.fHi || (a.fHi == b.fHi && a.fLo > b.fLo);
     }
-    
+
     friend bool operator>=(const Sk64& a, const Sk64& b) {
         return a.fHi > b.fHi || (a.fHi == b.fHi && a.fLo >= b.fLo);
     }
 
 #ifdef SkLONGLONG
     SkLONGLONG getLongLong() const;
 #endif
 };
old mode 100644
new mode 100755
--- a/gfx/skia/include/core/SkAdvancedTypefaceMetrics.h
+++ b/gfx/skia/include/core/SkAdvancedTypefaceMetrics.h
@@ -21,16 +21,18 @@
 
     The SkAdvancedTypefaceMetrics class is used by the PDF backend to correctly
     embed typefaces.  This class is filled in with information about a given
     typeface by the SkFontHost class.
 */
 
 class SkAdvancedTypefaceMetrics : public SkRefCnt {
 public:
+    SK_DECLARE_INST_COUNT(SkAdvancedTypefaceMetrics)
+
     SkString fFontName;
 
     enum FontType {
         kType1_Font,
         kType1CID_Font,
         kCFF_Font,
         kTrueType_Font,
         kOther_Font,
@@ -107,16 +109,19 @@ public:
     SkTScopedPtr<VerticalAdvanceRange> fVerticalMetrics;
 
     // The names of each glyph, only populated for postscript fonts.
     SkTScopedPtr<SkAutoTArray<SkString> > fGlyphNames;
 
     // The mapping from glyph to Unicode, only populated if
     // kToUnicode_PerGlyphInfo is passed to GetAdvancedTypefaceMetrics.
     SkTDArray<SkUnichar> fGlyphToUnicode;
+
+private:
+    typedef SkRefCnt INHERITED;
 };
 
 namespace skia_advanced_typeface_metrics_utils {
 
 template <typename Data>
 void resetRange(SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
                        int startId);
 
new file mode 100644
--- /dev/null
+++ b/gfx/skia/include/core/SkAnnotation.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkAnnotation_DEFINED
+#define SkAnnotation_DEFINED
+
+#include "SkFlattenable.h"
+
+class SkData;
+class SkDataSet;
+class SkStream;
+class SkWStream;
+
+/**
+ *  Experimental class for annotating draws. Do not use directly yet.
+ *  Use helper functions at the bottom of this file for now.
+ */
+class SkAnnotation : public SkFlattenable {
+public:
+    enum Flags {
+        // If set, the associated drawing primitive should not be drawn
+        kNoDraw_Flag  = 1 << 0,
+    };
+
+    SkAnnotation(SkDataSet*, uint32_t flags);
+    virtual ~SkAnnotation();
+
+    uint32_t getFlags() const { return fFlags; }
+    SkDataSet* getDataSet() const { return fDataSet; }
+
+    bool isNoDraw() const { return SkToBool(fFlags & kNoDraw_Flag); }
+
+    /**
+     *  Helper for search the annotation's dataset.
+     */
+    SkData* find(const char name[]) const;
+
+    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkAnnotation)
+
+protected:
+    SkAnnotation(SkFlattenableReadBuffer&);
+    virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE;
+
+private:
+    SkDataSet*  fDataSet;
+    uint32_t    fFlags;
+
+    void writeToStream(SkWStream*) const;
+    void readFromStream(SkStream*);
+
+    typedef SkFlattenable INHERITED;
+};
+
+/**
+ *  Experimental collection of predefined Keys into the Annotation dictionary
+ */
+class SkAnnotationKeys {
+public:
+    /**
+     *  Returns the canonical key whose payload is a URL
+     */
+    static const char* URL_Key();
+};
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Experimental helper functions to use Annotations
+//
+
+struct SkRect;
+class SkCanvas;
+
+/**
+ *  Experimental!
+ *
+ *  Annotate the canvas by associating the specified URL with the
+ *  specified rectangle (in local coordinates, just like drawRect). If the
+ *  backend of this canvas does not support annotations, this call is
+ *  safely ignored.
+ *
+ *  The caller is responsible for managing its ownership of the SkData.
+ */
+SK_API void SkAnnotateRectWithURL(SkCanvas*, const SkRect&, SkData*);
+
+#endif
deleted file mode 100644
--- a/gfx/skia/include/core/SkAutoKern.h
+++ /dev/null
@@ -1,54 +0,0 @@
-
-/*
- * Copyright 2006 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-
-#ifndef SkAutoKern_DEFINED
-#define SkAutoKern_DEFINED
-
-#include "SkScalerContext.h"
-
-#define SkAutoKern_AdjustF(prev, next)    (((next) - (prev) + 32) >> 6 << 16)
-#define SkAutoKern_AdjustS(prev, next)    SkIntToScalar(((next) - (prev) + 32) >> 6)
-
-/* this is a helper class to perform auto-kerning
- * the adjust() method returns a SkFixed corresponding
- * to a +1/0/-1 pixel adjustment
- */
-
-class SkAutoKern {
-public:
-    SkAutoKern() : fPrevRsbDelta(0) {}
-
-    SkFixed  adjust(const SkGlyph&  glyph) 
-    {
-//        if (SkAbs32(glyph.fLsbDelta) > 47 || SkAbs32(glyph.fRsbDelta) > 47)
-//            printf("------- %d> L %d R %d\n", glyph.f_GlyphID, glyph.fLsbDelta, glyph.fRsbDelta);
-
-#if 0
-        int  distort = fPrevRsbDelta - glyph.fLsbDelta;
-
-        fPrevRsbDelta = glyph.fRsbDelta;
-
-        if (distort >= 32)
-            return -SK_Fixed1;
-        else if (distort < -32)
-            return +SK_Fixed1;
-        else
-            return 0;
-#else
-        SkFixed adjust = SkAutoKern_AdjustF(fPrevRsbDelta, glyph.fLsbDelta);
-        fPrevRsbDelta = glyph.fRsbDelta;
-        return adjust;
-#endif
-    }
-private:
-    int   fPrevRsbDelta;
-};
-
-#endif
-
--- a/gfx/skia/include/core/SkBitmap.h
+++ b/gfx/skia/include/core/SkBitmap.h
@@ -7,27 +7,25 @@
  */
 
 
 #ifndef SkBitmap_DEFINED
 #define SkBitmap_DEFINED
 
 #include "Sk64.h"
 #include "SkColor.h"
+#include "SkColorTable.h"
 #include "SkPoint.h"
 #include "SkRefCnt.h"
 
 struct SkIRect;
 struct SkRect;
-class SkColorTable;
 class SkPaint;
 class SkPixelRef;
 class SkRegion;
-class SkFlattenableReadBuffer;
-class SkFlattenableWriteBuffer;
 
 // This is an opaque class, not interpreted by skia
 class SkGpuTexture;
 
 /** \class SkBitmap
 
     The SkBitmap class specifies a raster bitmap. A bitmap has an integer width
     and height, and a format (config), and a pointer to the actual pixels.
@@ -89,20 +87,20 @@ public:
     */
     //  This method is not exported to java.
     void swap(SkBitmap& other);
 
     /** Return true iff the bitmap has empty dimensions.
     */
     bool empty() const { return 0 == fWidth || 0 == fHeight; }
 
-    /** Return true iff the bitmap has no pixels nor a pixelref. Note: this can
-        return true even if the dimensions of the bitmap are > 0 (see empty()).
+    /** Return true iff the bitmap has no pixelref. Note: this can return true even if the
+        dimensions of the bitmap are > 0 (see empty()).
     */
-    bool isNull() const { return NULL == fPixels && NULL == fPixelRef; }
+    bool isNull() const { return NULL == fPixelRef; }
 
     /** Return the config for the bitmap.
     */
     Config  config() const { return (Config)fConfig; }
     /** DEPRECATED, use config()
     */
     Config  getConfig() const { return this->config(); }
     /** Return the bitmap's width, in pixels.
@@ -166,17 +164,17 @@ public:
 
     /** Returns true if this bitmap is marked as immutable, meaning that the
         contents of its pixels will not change for the lifetime of the bitmap.
     */
     bool isImmutable() const;
 
     /** Marks this bitmap as immutable, meaning that the contents of its
         pixels will not change for the lifetime of the bitmap and of the
-        underlying pixelref. This state can be set, but it cannot be 
+        underlying pixelref. This state can be set, but it cannot be
         cleared once it is set. This state propagates to all other bitmaps
         that share the same pixelref.
     */
     void setImmutable();
 
     /** Returns true if the bitmap is opaque (has no translucent/transparent pixels).
     */
     bool isOpaque() const;
@@ -185,21 +183,21 @@ public:
         that support per-pixel alpha (RGB32, A1, A8).
     */
     void setIsOpaque(bool);
 
     /** Returns true if the bitmap is volatile (i.e. should not be cached by devices.)
     */
     bool isVolatile() const;
 
-    /** Specify whether this bitmap is volatile. Bitmaps are not volatile by 
+    /** Specify whether this bitmap is volatile. Bitmaps are not volatile by
         default. Temporary bitmaps that are discarded after use should be
         marked as volatile. This provides a hint to the device that the bitmap
-        should not be cached. Providing this hint when appropriate can  
-        improve performance by avoiding unnecessary overhead and resource 
+        should not be cached. Providing this hint when appropriate can
+        improve performance by avoiding unnecessary overhead and resource
         consumption on the device.
     */
     void setIsVolatile(bool);
 
     /** Reset the bitmap to its initial state (see default constructor). If we are a (shared)
         owner of the pixels, that ownership is decremented.
     */
     void reset();
@@ -356,19 +354,19 @@ public:
     SkGpuTexture* getTexture() const;
 
     /** Return the bitmap's colortable (if any). Does not affect the colortable's
         reference count.
     */
     SkColorTable* getColorTable() const { return fColorTable; }
 
     /** Returns a non-zero, unique value corresponding to the pixels in our
-        pixelref (or raw pixels set via setPixels). Each time the pixels are
-        changed (and notifyPixelsChanged is called), a different generation ID
-        will be returned.
+        pixelref. Each time the pixels are changed (and notifyPixelsChanged
+        is called), a different generation ID will be returned. Finally, if
+        their is no pixelRef then zero is returned.
     */
     uint32_t getGenerationID() const;
 
     /** Call this if you have changed the contents of the pixels. This will in-
         turn cause a different generation ID value to be returned from
         getGenerationID().
     */
     void notifyPixelsChanged() const;
@@ -392,17 +390,18 @@ public:
     */
     void eraseColor(SkColor c) const {
         this->eraseARGB(SkColorGetA(c), SkColorGetR(c), SkColorGetG(c),
                         SkColorGetB(c));
     }
 
     /** Scroll (a subset of) the contents of this bitmap by dx/dy. If there are
         no pixels allocated (i.e. getPixels() returns null) the method will
-        still update the inval region (if present).
+        still update the inval region (if present). If the bitmap is immutable,
+        do nothing and return false.
 
         @param subset The subset of the bitmap to scroll/move. To scroll the
                       entire contents, specify [0, 0, width, height] or just
                       pass null.
         @param dx The amount to scroll in X
         @param dy The amount to scroll in Y
         @param inval Optional (may be null). Returns the area of the bitmap that
                      was scrolled away. E.g. if dx = dy = 0, then inval would
@@ -420,17 +419,17 @@ public:
     /**
      *  Return the SkColor of the specified pixel.  In most cases this will
      *  require un-premultiplying the color.  Alpha only configs (A1 and A8)
      *  return black with the appropriate alpha set.  The value is undefined
      *  for kNone_Config or if x or y are out of bounds, or if the bitmap
      *  does not have any pixels (or has not be locked with lockPixels()).
      */
     SkColor getColor(int x, int y) const;
-    
+
     /** Returns the address of the specified pixel. This performs a runtime
         check to know the size of the pixels, and will return the same answer
         as the corresponding size-specific method (e.g. getAddr16). Since the
         check happens at runtime, it is much slower than using a size-specific
         version. Unlike the size-specific methods, this routine also checks if
         getPixels() returns null, and returns that. The size-specific routines
         perform a debugging assert that getPixels() is not null, but they do
         not do any runtime checks.
@@ -545,31 +544,42 @@ public:
                          will be used.
         @param offset If not null, it is set to top-left coordinate to position
                       the returned bitmap so that it visually lines up with the
                       original
     */
     bool extractAlpha(SkBitmap* dst, const SkPaint* paint, Allocator* allocator,
                       SkIPoint* offset) const;
 
+    /** The following two functions provide the means to both flatten and
+        unflatten the bitmap AND its pixels into the provided buffer.
+        It is recommended that you do not call these functions directly,
+        but instead call the write/readBitmap functions on the respective
+        buffers as they can optimize the recording process and avoid recording
+        duplicate bitmaps and pixelRefs.
+     */
     void flatten(SkFlattenableWriteBuffer&) const;
     void unflatten(SkFlattenableReadBuffer&);
 
     SkDEBUGCODE(void validate() const;)
 
     class Allocator : public SkRefCnt {
     public:
+        SK_DECLARE_INST_COUNT(Allocator)
+
         /** Allocate the pixel memory for the bitmap, given its dimensions and
             config. Return true on success, where success means either setPixels
             or setPixelRef was called. The pixels need not be locked when this
             returns. If the config requires a colortable, it also must be
             installed via setColorTable. If false is returned, the bitmap and
             colortable should be left unchanged.
         */
         virtual bool allocPixelRef(SkBitmap*, SkColorTable*) = 0;
+    private:
+        typedef SkRefCnt INHERITED;
     };
 
     /** Subclass of Allocator that returns a pixelref that allocates its pixel
         memory from the heap. This is the default Allocator invoked by
         allocPixels().
     */
     class HeapAllocator : public Allocator {
     public:
@@ -603,20 +613,16 @@ private:
 
     mutable SkPixelRef* fPixelRef;
     mutable size_t      fPixelRefOffset;
     mutable int         fPixelLockCount;
     // either user-specified (in which case it is not treated as mutable)
     // or a cache of the returned value from fPixelRef->lockPixels()
     mutable void*       fPixels;
     mutable SkColorTable* fColorTable;    // only meaningful for kIndex8
-    // When there is no pixel ref (setPixels was called) we still need a
-    // gen id for SkDevice implementations that may cache a copy of the
-    // pixels (e.g. as a gpu texture)
-    mutable int         fRawPixelGenerationID;
 
     enum Flags {
         kImageIsOpaque_Flag     = 0x01,
         kImageIsVolatile_Flag   = 0x02,
         kImageIsImmutable_Flag  = 0x04
     };
 
     uint32_t    fRowBytes;
@@ -640,105 +646,16 @@ private:
     /*  Unreference any pixelrefs or colortables
     */
     void freePixels();
     void updatePixelsFromRef() const;
 
     static SkFixed ComputeMipLevel(SkFixed sx, SkFixed dy);
 };
 
-/** \class SkColorTable
-
-    SkColorTable holds an array SkPMColors (premultiplied 32-bit colors) used by
-    8-bit bitmaps, where the bitmap bytes are interpreted as indices into the colortable.
-*/
-class SkColorTable : public SkRefCnt {
-public:
-    /** Makes a deep copy of colors.
-     */
-    SkColorTable(const SkColorTable& src);
-    /** Preallocates the colortable to have 'count' colors, which
-     *  are initially set to 0.
-    */
-    explicit SkColorTable(int count);
-    explicit SkColorTable(SkFlattenableReadBuffer&);
-    SkColorTable(const SkPMColor colors[], int count);
-    virtual ~SkColorTable();
-
-    enum Flags {
-        kColorsAreOpaque_Flag   = 0x01  //!< if set, all of the colors in the table are opaque (alpha==0xFF)
-    };
-    /** Returns the flag bits for the color table. These can be changed with setFlags().
-    */
-    unsigned getFlags() const { return fFlags; }
-    /** Set the flags for the color table. See the Flags enum for possible values.
-    */
-    void    setFlags(unsigned flags);
-
-    bool isOpaque() const { return (fFlags & kColorsAreOpaque_Flag) != 0; }
-    void setIsOpaque(bool isOpaque);
-
-    /** Returns the number of colors in the table.
-    */
-    int count() const { return fCount; }
-
-    /** Returns the specified color from the table. In the debug build, this asserts that
-        the index is in range (0 <= index < count).
-    */
-    SkPMColor operator[](int index) const {
-        SkASSERT(fColors != NULL && (unsigned)index < fCount);
-        return fColors[index];
-    }
-
-    /** Specify the number of colors in the color table. This does not initialize the colors
-        to any value, just allocates memory for them. To initialize the values, either call
-        setColors(array, count), or follow setCount(count) with a call to
-        lockColors()/{set the values}/unlockColors(true).
-    */
-//    void    setColors(int count) { this->setColors(NULL, count); }
-//    void    setColors(const SkPMColor[], int count);
-
-    /** Return the array of colors for reading and/or writing. This must be
-        balanced by a call to unlockColors(changed?), telling the colortable if
-        the colors were changed during the lock.
-    */
-    SkPMColor* lockColors() {
-        SkDEBUGCODE(fColorLockCount += 1;)
-        return fColors;
-    }
-    /** Balancing call to lockColors(). If the colors have been changed, pass true.
-    */
-    void unlockColors(bool changed);
-
-    /** Similar to lockColors(), lock16BitCache() returns the array of
-        RGB16 colors that mirror the 32bit colors. However, this function
-        will return null if kColorsAreOpaque_Flag is not set.
-        Also, unlike lockColors(), the returned array here cannot be modified.
-    */
-    const uint16_t* lock16BitCache();
-    /** Balancing call to lock16BitCache().
-    */
-    void unlock16BitCache() {
-        SkASSERT(f16BitCacheLockCount > 0);
-        SkDEBUGCODE(f16BitCacheLockCount -= 1);
-    }
-
-    void flatten(SkFlattenableWriteBuffer&) const;
-
-private:
-    SkPMColor*  fColors;
-    uint16_t*   f16BitCache;
-    uint16_t    fCount;
-    uint8_t     fFlags;
-    SkDEBUGCODE(int fColorLockCount;)
-    SkDEBUGCODE(int f16BitCacheLockCount;)
-
-    void inval16BitCache();
-};
-
 class SkAutoLockPixels : public SkNoncopyable {
 public:
     SkAutoLockPixels(const SkBitmap& bm, bool doLock = true) : fBitmap(bm) {
         fDidLock = doLock;
         if (doLock) {
             bm.lockPixels();
         }
     }
deleted file mode 100644
--- a/gfx/skia/include/core/SkBlitter.h
+++ /dev/null
@@ -1,166 +0,0 @@
-
-/*
- * Copyright 2006 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-
-#ifndef SkBlitter_DEFINED
-#define SkBlitter_DEFINED
-
-#include "SkBitmap.h"
-#include "SkMatrix.h"
-#include "SkPaint.h"
-#include "SkRefCnt.h"
-#include "SkRegion.h"
-#include "SkMask.h"
-
-/** SkBlitter and its subclasses are responsible for actually writing pixels
-    into memory. Besides efficiency, they handle clipping and antialiasing.
-*/
-class SkBlitter {
-public:
-    virtual ~SkBlitter();
-
-    /// Blit a horizontal run of one or more pixels.
-    virtual void blitH(int x, int y, int width);
-    /// Blit a horizontal run of antialiased pixels; runs[] is a *sparse*
-    /// zero-terminated run-length encoding of spans of constant alpha values.
-    virtual void blitAntiH(int x, int y, const SkAlpha antialias[],
-                           const int16_t runs[]);
-    /// Blit a vertical run of pixels with a constant alpha value.
-    virtual void blitV(int x, int y, int height, SkAlpha alpha);
-    /// Blit a solid rectangle one or more pixels wide.
-    virtual void blitRect(int x, int y, int width, int height);
-    /** Blit a rectangle with one alpha-blended column on the left,
-        width (zero or more) opaque pixels, and one alpha-blended column
-        on the right.
-        The result will always be at least two pixels wide.
-    */
-    virtual void blitAntiRect(int x, int y, int width, int height,
-                              SkAlpha leftAlpha, SkAlpha rightAlpha);
-    /// Blit a pattern of pixels defined by a rectangle-clipped mask;
-    /// typically used for text.
-    virtual void blitMask(const SkMask&, const SkIRect& clip);
-
-    /** If the blitter just sets a single value for each pixel, return the
-        bitmap it draws into, and assign value. If not, return NULL and ignore
-        the value parameter.
-    */
-    virtual const SkBitmap* justAnOpaqueColor(uint32_t* value);
-
-    ///@name non-virtual helpers
-    void blitMaskRegion(const SkMask& mask, const SkRegion& clip);
-    void blitRectRegion(const SkIRect& rect, const SkRegion& clip);
-    void blitRegion(const SkRegion& clip);
-    ///@}
-
-    /** @name Factories
-        Return the correct blitter to use given the specified context.
-     */
-    static SkBlitter* Choose(const SkBitmap& device,
-                             const SkMatrix& matrix,
-                             const SkPaint& paint) {
-        return Choose(device, matrix, paint, NULL, 0);
-    }
-
-    static SkBlitter* Choose(const SkBitmap& device,
-                             const SkMatrix& matrix,
-                             const SkPaint& paint,
-                             void* storage, size_t storageSize);
-
-    static SkBlitter* ChooseSprite(const SkBitmap& device,
-                                   const SkPaint&,
-                                   const SkBitmap& src,
-                                   int left, int top,
-                                   void* storage, size_t storageSize);
-    ///@}
-
-private:
-};
-
-/** This blitter silently never draws anything.
-*/
-class SkNullBlitter : public SkBlitter {
-public:
-    virtual void blitH(int x, int y, int width) SK_OVERRIDE;
-    virtual void blitAntiH(int x, int y, const SkAlpha[],
-                           const int16_t runs[]) SK_OVERRIDE;
-    virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE;
-    virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE;
-    virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE;
-    virtual const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE;
-};
-
-/** Wraps another (real) blitter, and ensures that the real blitter is only
-    called with coordinates that have been clipped by the specified clipRect.
-    This means the caller need not perform the clipping ahead of time.
-*/
-class SkRectClipBlitter : public SkBlitter {
-public:
-    void init(SkBlitter* blitter, const SkIRect& clipRect) {
-        SkASSERT(!clipRect.isEmpty());
-        fBlitter = blitter;
-        fClipRect = clipRect;
-    }
-
-    virtual void blitH(int x, int y, int width) SK_OVERRIDE;
-    virtual void blitAntiH(int x, int y, const SkAlpha[],
-                           const int16_t runs[]) SK_OVERRIDE;
-    virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE;
-    virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE;
-    virtual void blitAntiRect(int x, int y, int width, int height,
-                     SkAlpha leftAlpha, SkAlpha rightAlpha) SK_OVERRIDE;
-    virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE;
-    virtual const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE;
-
-private:
-    SkBlitter*  fBlitter;
-    SkIRect     fClipRect;
-};
-
-/** Wraps another (real) blitter, and ensures that the real blitter is only
-    called with coordinates that have been clipped by the specified clipRgn.
-    This means the caller need not perform the clipping ahead of time.
-*/
-class SkRgnClipBlitter : public SkBlitter {
-public:
-    void init(SkBlitter* blitter, const SkRegion* clipRgn) {
-        SkASSERT(clipRgn && !clipRgn->isEmpty());
-        fBlitter = blitter;
-        fRgn = clipRgn;
-    }
-
-    virtual void blitH(int x, int y, int width) SK_OVERRIDE;
-    virtual void blitAntiH(int x, int y, const SkAlpha[],
-                           const int16_t runs[]) SK_OVERRIDE;
-    virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE;
-    virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE;
-    virtual void blitAntiRect(int x, int y, int width, int height,
-                     SkAlpha leftAlpha, SkAlpha rightAlpha) SK_OVERRIDE;
-    virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE;
-    virtual const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE;
-
-private:
-    SkBlitter*      fBlitter;
-    const SkRegion* fRgn;
-};
-
-/** Factory to set up the appropriate most-efficient wrapper blitter
-    to apply a clip. Returns a pointer to a member, so lifetime must
-    be managed carefully.
-*/
-class SkBlitterClipper {
-public:
-    SkBlitter*  apply(SkBlitter* blitter, const SkRegion* clip,
-                      const SkIRect* bounds = NULL);
-
-private:
-    SkNullBlitter       fNullBlitter;
-    SkRectClipBlitter   fRectBlitter;
-    SkRgnClipBlitter    fRgnBlitter;
-};
-
-#endif
--- a/gfx/skia/include/core/SkBounder.h
+++ b/gfx/skia/include/core/SkBounder.h
@@ -24,19 +24,21 @@ class SkRegion;
 
 /** \class SkBounder
 
     Base class for intercepting the device bounds of shapes before they are drawn.
     Install a subclass of this in your canvas.
 */
 class SkBounder : public SkRefCnt {
 public:
+    SK_DECLARE_INST_COUNT(SkBounder)
+
     SkBounder();
 
-    /* Call to perform a clip test before calling onIRect. 
+    /* Call to perform a clip test before calling onIRect.
        Returns the result from onIRect.
     */
     bool doIRect(const SkIRect&);
     bool doIRectGlyph(const SkIRect& , int x, int y, const SkGlyph&);
 
 protected:
     /** Override in your subclass. This is called with the device bounds of an
         object (text, geometry, image) just before it is drawn. If your method
@@ -79,12 +81,14 @@ private:
     void setClip(const SkRegion* clip) { fClip = clip; }
 
     const SkRegion* fClip;
     friend class SkAutoBounderCommit;
     friend class SkDraw;
     friend class SkDrawIter;
     friend struct Draw1Glyph;
     friend class SkMaskFilter;
+
+    typedef SkRefCnt INHERITED;
 };
 
 #endif
 
deleted file mode 100644
--- a/gfx/skia/include/core/SkBuffer.h
+++ /dev/null
@@ -1,139 +0,0 @@
-
-/*
- * Copyright 2006 The Android Open Source Project
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-
-#ifndef SkBuffer_DEFINED
-#define SkBuffer_DEFINED
-
-#include "SkScalar.h"
-
-/** \class SkRBuffer
-
-    Light weight class for reading data from a memory block.
-    The RBuffer is given the buffer to read from, with either a specified size
-    or no size (in which case no range checking is performed). It is iillegal
-    to attempt to read a value from an empty RBuffer (data == null). 
-*/
-class SkRBuffer : SkNoncopyable {
-public:
-    SkRBuffer() : fData(0), fPos(0), fStop(0) {}
-    /** Initialize RBuffer with a data pointer, but no specified length.
-        This signals the RBuffer to not perform range checks during reading.
-    */
-    SkRBuffer(const void* data) {
-        fData = (const char*)data;
-        fPos = (const char*)data;
-        fStop = 0;  // no bounds checking
-    }
-    /** Initialize RBuffer with a data point and length.
-    */
-    SkRBuffer(const void* data, size_t size) {
-        SkASSERT(data != 0 || size == 0);
-        fData = (const char*)data;
-        fPos = (const char*)data;
-        fStop = (const char*)data + size;
-    }
-    
-    /** Return the number of bytes that have been read from the beginning
-        of the data pointer.
-    */
-    size_t  pos() const { return fPos - fData; }
-    /** Return the total size of the data pointer. Only defined if the length was
-        specified in the constructor or in a call to reset().
-    */
-    size_t  size() const { return fStop - fData; }
-    /** Return true if the buffer has read to the end of the data pointer.
-        Only defined if the length was specified in the constructor or in a call
-        to reset(). Always returns true if the length was not specified.
-    */
-    bool    eof() const { return fPos >= fStop; }
-
-    /** Read the specified number of bytes from the data pointer. If buffer is not
-        null, copy those bytes into buffer.
-    */
-    void read(void* buffer, size_t size) {
-        if (size) {
-            this->readNoSizeCheck(buffer, size);
-        }
-    }
-
-    const void* skip(size_t size); // return start of skipped data
-    size_t  skipToAlign4();
-
-    void*       readPtr() { void* ptr; read(&ptr, sizeof(ptr)); return ptr; }
-    SkScalar    readScalar() { SkScalar x; read(&x, 4); return x; }
-    uint32_t    readU32() { uint32_t x; read(&x, 4); return x; }
-    int32_t     readS32() { int32_t x; read(&x, 4); return x; }
-    uint16_t    readU16() { uint16_t x; read(&x, 2); return x; }
-    int16_t     readS16() { int16_t x; read(&x, 2); return x; }
-    uint8_t     readU8() { uint8_t x; read(&x, 1); return x; }
-    bool        readBool() { return this->readU8() != 0; }
-
-protected:
-    void    readNoSizeCheck(void* buffer, size_t size);
-
-    const char* fData;
-    const char* fPos;
-    const char* fStop;
-};
-
-/** \class SkWBuffer
-
-    Light weight class for writing data to a memory block.
-    The WBuffer is given the buffer to write into, with either a specified size
-    or no size, in which case no range checking is performed. An empty WBuffer
-    is legal, in which case no data is ever written, but the relative pos()
-    is updated.
-*/
-class SkWBuffer : SkNoncopyable {
-public:
-    SkWBuffer() : fData(0), fPos(0), fStop(0) {}
-    SkWBuffer(void* data) { reset(data); }
-    SkWBuffer(void* data, size_t size) { reset(data, size); }
-
-    void reset(void* data) {
-        fData = (char*)data;
-        fPos = (char*)data;
-        fStop = 0;  // no bounds checking
-    }
-
-    void reset(void* data, size_t size) {
-        SkASSERT(data != 0 || size == 0);
-        fData = (char*)data;
-        fPos = (char*)data;
-        fStop = (char*)data + size;
-    }
-    
-    size_t  pos() const { return fPos - fData; }
-    void*   skip(size_t size); // return start of skipped data
-
-    void write(const void* buffer, size_t size) {
-        if (size) {
-            this->writeNoSizeCheck(buffer, size);
-        }
-    }
-
-    size_t  padToAlign4();
-
-    void    writePtr(const void* x) { this->writeNoSizeCheck(&x, sizeof(x)); }
-    void    writeScalar(SkScalar x) { this->writeNoSizeCheck(&x, 4); }
-    void    write32(int32_t x) { this->writeNoSizeCheck(&x, 4); }
-    void    write16(int16_t x) { this->writeNoSizeCheck(&x, 2); }
-    void    write8(int8_t x) { this->writeNoSizeCheck(&x, 1); }
-    void    writeBool(bool x) { this->write8(x); }
-
-protected:
-    void    writeNoSizeCheck(const void* buffer, size_t size);
-
-    char* fData;
-    char* fPos;
-    char* fStop;
-};
-
-#endif
-
--- a/gfx/skia/include/core/SkCanvas.h
+++ b/gfx/skia/include/core/SkCanvas.h
@@ -21,16 +21,17 @@
 #include "SkScalarCompare.h"
 #include "SkXfermode.h"
 
 class SkBounder;
 class SkDevice;
 class SkDraw;
 class SkDrawFilter;
 class SkPicture;
+class SkSurface_Base;
 
 /** \class SkCanvas
 
     A Canvas encapsulates all of the state about drawing into a device (bitmap).
     This includes a reference to the device itself, and a stack of matrix/clip
     values. For any given draw call (e.g. drawRect), the geometry of the object
     being drawn is transformed by the concatenation of all the matrices in the
     stack. The transformed geometry is clipped by the intersection of all of
@@ -39,16 +40,18 @@ class SkPicture;
     While the Canvas holds the state of the drawing device, the state (style)
     of the object being drawn is held by the Paint, which is provided as a
     parameter to each of the draw() methods. The Paint holds attributes such as
     color, typeface, textSize, strokeWidth, shader (e.g. gradients, patterns),
     etc.
 */
 class SK_API SkCanvas : public SkRefCnt {
 public:
+    SK_DECLARE_INST_COUNT(SkCanvas)
+
     SkCanvas();
 
     /** Construct a canvas with the specified device to draw into.
 
         @param device   Specifies a device for the canvas to draw into.
     */
     explicit SkCanvas(SkDevice* device);
 
@@ -379,84 +382,65 @@ public:
         for the existing clip region.
         @param deviceRgn The region to copy into the current clip.
         @return true if the new clip region is non-empty
     */
     bool setClipRegion(const SkRegion& deviceRgn) {
         return this->clipRegion(deviceRgn, SkRegion::kReplace_Op);
     }
 
-    /** Enum describing how to treat edges when performing quick-reject tests
-        of a geometry against the current clip. Treating them as antialiased
-        (kAA_EdgeType) will take into account the extra pixels that may be drawn
-        if the edge does not lie exactly on a device pixel boundary (after being
-        transformed by the current matrix).
-    */
-    enum EdgeType {
-        /** Treat the edges as B&W (not antialiased) for the purposes of testing
-            against the current clip
-        */
-        kBW_EdgeType,
-        /** Treat the edges as antialiased for the purposes of testing
-            against the current clip
-        */
-        kAA_EdgeType
-    };
-
     /** Return true if the specified rectangle, after being transformed by the
         current matrix, would lie completely outside of the current clip. Call
         this to check if an area you intend to draw into is clipped out (and
         therefore you can skip making the draw calls).
         @param rect the rect to compare with the current clip
-        @param et  specifies how to treat the edges (see EdgeType)
         @return true if the rect (transformed by the canvas' matrix) does not
                      intersect with the canvas' clip
     */
-    bool quickReject(const SkRect& rect, EdgeType et) const;
+    bool quickReject(const SkRect& rect) const;
 
     /** Return true if the specified path, after being transformed by the
         current matrix, would lie completely outside of the current clip. Call
         this to check if an area you intend to draw into is clipped out (and
         therefore you can skip making the draw calls). Note, for speed it may
         return false even if the path itself might not intersect the clip
         (i.e. the bounds of the path intersects, but the path does not).
         @param path The path to compare with the current clip
-        @param et  specifies how to treat the edges (see EdgeType)
         @return true if the path (transformed by the canvas' matrix) does not
                      intersect with the canvas' clip
     */
-    bool quickReject(const SkPath& path, EdgeType et) const;
+    bool quickReject(const SkPath& path) const;
 
     /** Return true if the horizontal band specified by top and bottom is
         completely clipped out. This is a conservative calculation, meaning
         that it is possible that if the method returns false, the band may still
         in fact be clipped out, but the converse is not true. If this method
         returns true, then the band is guaranteed to be clipped out.
         @param top  The top of the horizontal band to compare with the clip
         @param bottom The bottom of the horizontal and to compare with the clip
         @return true if the horizontal band is completely clipped out (i.e. does
                      not intersect the current clip)
     */
-    bool quickRejectY(SkScalar top, SkScalar bottom, EdgeType et) const {
+    bool quickRejectY(SkScalar top, SkScalar bottom) const {
         SkASSERT(SkScalarToCompareType(top) <= SkScalarToCompareType(bottom));
-        const SkRectCompareType& clipR = this->getLocalClipBoundsCompareType(et);
+        const SkRectCompareType& clipR = this->getLocalClipBoundsCompareType();
         // In the case where the clip is empty and we are provided with a
         // negative top and positive bottom parameter then this test will return
         // false even though it will be clipped. We have chosen to exclude that
         // check as it is rare and would result double the comparisons.
         return SkScalarToCompareType(top) >= clipR.fBottom
             || SkScalarToCompareType(bottom) <= clipR.fTop;
     }
 
     /** Return the bounds of the current clip (in local coordinates) in the
         bounds parameter, and return true if it is non-empty. This can be useful
         in a way similar to quickReject, in that it tells you that drawing
         outside of these bounds will be clipped out.
     */
-    bool getClipBounds(SkRect* bounds, EdgeType et = kAA_EdgeType) const;
+    bool getClipBounds(SkRect* bounds) const;
 
     /** Return the bounds of the current clip, in device coordinates; returns
         true if non-empty. Maybe faster than getting the clip explicitly and
         then taking its bounds.
     */
     bool getClipDeviceBounds(SkIRect* bounds) const;
 
 
@@ -881,20 +865,30 @@ public:
     /** Return the current device clip (concatenation of all clip calls).
      *  This does not account for the translate in any of the devices.
      *  @return the current device clip (concatenation of all clip calls).
      *
      *  DEPRECATED -- call getClipDeviceBounds() instead.
      */
     const SkRegion& getTotalClip() const;
 
+    /** Return the clip stack. The clip stack stores all the individual
+     *  clips organized by the save/restore frame in which they were
+     *  added.
+     *  @return the current clip stack ("list" of individual clip elements)
+     */
+    const SkClipStack* getClipStack() const {
+        return &fClipStack;
+    }
+
     void setExternalMatrix(const SkMatrix* = NULL);
 
     class ClipVisitor {
     public:
+        virtual ~ClipVisitor();
         virtual void clipRect(const SkRect&, SkRegion::Op, bool antialias) = 0;
         virtual void clipPath(const SkPath&, SkRegion::Op, bool antialias) = 0;
     };
 
     /**
      *  Replays the clip operations, back to front, that have been applied to
      *  the canvas, calling the appropriate method on the visitor for each
      *  clip. All clips have already been transformed into device space.
@@ -952,32 +946,42 @@ protected:
     void commonDrawBitmap(const SkBitmap&, const SkIRect*, const SkMatrix&,
                           const SkPaint& paint);
 
     // Clip rectangle bounds. Called internally by saveLayer.
     // returns false if the entire rectangle is entirely clipped out
     bool clipRectBounds(const SkRect* bounds, SaveFlags flags,
                         SkIRect* intersection);
 
+    // notify our surface (if we have one) that we are about to draw, so it
+    // can perform copy-on-write or invalidate any cached images
+    void predrawNotify();
+
 private:
     class MCRec;
 
     SkClipStack fClipStack;
     SkDeque     fMCStack;
     // points to top of stack
     MCRec*      fMCRec;
     // the first N recs that can fit here mean we won't call malloc
     uint32_t    fMCRecStorage[32];
 
     SkBounder*  fBounder;
     SkDevice*   fLastDeviceToGainFocus;
     int         fSaveLayerCount;    // number of successful saveLayer calls
 
-    void prepareForDeviceDraw(SkDevice*, const SkMatrix&, const SkRegion&,
-                              const SkClipStack& clipStack);
+    SkSurface_Base*  fSurfaceBase;
+    SkSurface_Base* getSurfaceBase() const { return fSurfaceBase; }
+    void setSurfaceBase(SkSurface_Base* sb) {
+        fSurfaceBase = sb;
+    }
+    friend class SkSurface_Base;
+
+    void prepareForDeviceDraw(SkDevice*, const SkMatrix&, const SkRegion&);
 
     bool fDeviceCMDirty;            // cleared by updateDeviceCMCache()
     void updateDeviceCMCache();
 
     friend class SkDrawIter;    // needs setupDrawForLayerDevice()
     friend class AutoDrawLooper;
 
     SkDevice* createLayerDevice(SkBitmap::Config, int width, int height,
@@ -1008,41 +1012,24 @@ private:
                                     SkScalar x, SkScalar y);
 
     /*  These maintain a cache of the clip bounds in local coordinates,
         (converted to 2s-compliment if floats are slow).
      */
     mutable SkRectCompareType fLocalBoundsCompareType;
     mutable bool              fLocalBoundsCompareTypeDirty;
 
-    mutable SkRectCompareType fLocalBoundsCompareTypeBW;
-    mutable bool              fLocalBoundsCompareTypeDirtyBW;
-
-    /* Get the local clip bounds with an anti-aliased edge.
-     */
     const SkRectCompareType& getLocalClipBoundsCompareType() const {
-        return getLocalClipBoundsCompareType(kAA_EdgeType);
+        if (fLocalBoundsCompareTypeDirty) {
+            this->computeLocalClipBoundsCompareType();
+            fLocalBoundsCompareTypeDirty = false;
+        }
+        return fLocalBoundsCompareType;
     }
-
-    const SkRectCompareType& getLocalClipBoundsCompareType(EdgeType et) const {
-        if (et == kAA_EdgeType) {
-            if (fLocalBoundsCompareTypeDirty) {
-                this->computeLocalClipBoundsCompareType(et);
-                fLocalBoundsCompareTypeDirty = false;
-            }
-            return fLocalBoundsCompareType;
-        } else {
-            if (fLocalBoundsCompareTypeDirtyBW) {
-                this->computeLocalClipBoundsCompareType(et);
-                fLocalBoundsCompareTypeDirtyBW = false;
-            }
-            return fLocalBoundsCompareTypeBW;
-        }
-    }
-    void computeLocalClipBoundsCompareType(EdgeType et) const;
+    void computeLocalClipBoundsCompareType() const;
 
     SkMatrix    fExternalMatrix, fExternalInverse;
     bool        fUseExternalMatrix;
 
     class AutoValidateClip : ::SkNoncopyable {
     public:
         explicit AutoValidateClip(SkCanvas* canvas) : fCanvas(canvas) {
             fCanvas->validateClip();
@@ -1053,16 +1040,18 @@ private:
         const SkCanvas* fCanvas;
     };
 
 #ifdef SK_DEBUG
     void validateClip() const;
 #else
     void validateClip() const {}
 #endif
+
+    typedef SkRefCnt INHERITED;
 };
 
 /** Stack helper class to automatically call restoreToCount() on the canvas
     when this object goes out of scope. Use this to guarantee that the canvas
     is restored to a known state.
 */
 class SkAutoCanvasRestore : SkNoncopyable {
 public:
new file mode 100644
--- /dev/null
+++ b/gfx/skia/include/core/SkChecksum.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkChecksum_DEFINED
+#define SkChecksum_DEFINED
+
+#include "SkTypes.h"
+
+class SkChecksum : SkNoncopyable {
+private:
+    /*
+     *  Our Rotate and Mash helpers are meant to automatically do the right
+     *  thing depending if sizeof(uintptr_t) is 4 or 8.
+     */
+    enum {
+        ROTR = 17,
+        ROTL = sizeof(uintptr_t) * 8 - ROTR,
+        HALFBITS = sizeof(uintptr_t) * 4
+    };
+
+    static inline uintptr_t Mash(uintptr_t total, uintptr_t value) {
+        return ((total >> ROTR) | (total << ROTL)) ^ value;
+    }
+
+public:
+    /**
+     *  Compute a 32-bit checksum for a given data block
+     *
+     *  @param data Memory address of the data block to be processed. Must be
+     *              32-bit aligned.
+     *  @param size Size of the data block in bytes. Must be a multiple of 4.
+     *  @return checksum result
+     */
+    static uint32_t Compute(const uint32_t* data, size_t size) {
+        SkASSERT(SkIsAlign4(size));
+
+        /*
+         *  We want to let the compiler use 32bit or 64bit addressing and math
+         *  so we use uintptr_t as our magic type. This makes the code a little
+         *  more obscure (we can't hard-code 32 or 64 anywhere, but have to use
+         *  sizeof()).
+         */
+        uintptr_t result = 0;
+        const uintptr_t* ptr = reinterpret_cast<const uintptr_t*>(data);
+
+        /*
+         *  count the number of quad element chunks. This takes into account
+         *  if we're on a 32bit or 64bit arch, since we use sizeof(uintptr_t)
+         *  to compute how much to shift-down the size.
+         */
+        size_t n4 = size / (sizeof(uintptr_t) << 2);
+        for (size_t i = 0; i < n4; ++i) {
+            result = Mash(result, *ptr++);
+            result = Mash(result, *ptr++);
+            result = Mash(result, *ptr++);
+            result = Mash(result, *ptr++);
+        }
+        size &= ((sizeof(uintptr_t) << 2) - 1);
+
+        data = reinterpret_cast<const uint32_t*>(ptr);
+        const uint32_t* stop = data + (size >> 2);
+        while (data < stop) {
+            result = Mash(result, *data++);
+        }
+
+        /*
+         *  smash us down to 32bits if we were 64. Note that when uintptr_t is
+         *  32bits, this code-path should go away, but I still got a warning
+         *  when I wrote
+         *      result ^= result >> 32;
+         *  since >>32 is undefined for 32bit ints, hence the wacky HALFBITS
+         *  define.
+         */
+        if (8 == sizeof(result)) {
+            result ^= result >> HALFBITS;
+        }
+        return static_cast<uint32_t>(result);
+    }
+};
+
+#endif
+
--- a/gfx/skia/include/core/SkChunkAlloc.h
+++ b/gfx/skia/include/core/SkChunkAlloc.h
@@ -22,30 +22,30 @@ public:
      *  pointers.
      */
     void reset();
 
     enum AllocFailType {
         kReturnNil_AllocFailType,
         kThrow_AllocFailType
     };
-    
+
     void* alloc(size_t bytes, AllocFailType);
     void* allocThrow(size_t bytes) {
         return this->alloc(bytes, kThrow_AllocFailType);
     }
-    
+
     /** Call this to unalloc the most-recently allocated ptr by alloc(). On
         success, the number of bytes freed is returned, or 0 if the block could
         not be unallocated. This is a hint to the underlying allocator that
         the previous allocation may be reused, but the implementation is free
         to ignore this call (and return 0).
      */
     size_t unalloc(void* ptr);
-    
+
     size_t totalCapacity() const { return fTotalCapacity; }
     int blockCount() const { return fBlockCount; }
 
     /**
      *  Returns true if the specified address is within one of the chunks, and
      *  has at least 1-byte following the address (i.e. if addr points to the
      *  end of a chunk, then contains() will return false).
      */
deleted file mode 100644
--- a/gfx/skia/include/core/SkClampRange.h
+++ /dev/null
@@ -1,39 +0,0 @@
-
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-
-#ifndef SkClampRange_DEFINED
-#define SkClampRange_DEFINED
-
-#include "SkFixed.h"
-
-/**
- *  Iteration fixed fx by dx, clamping as you go to [0..0xFFFF], this class
- *  computes the (up to) 3 spans there are:
- *
- *  range0: use constant value V0
- *  range1: iterate as usual fx += dx
- *  range2: use constant value V1
- */
-struct SkClampRange {
-    int fCount0;    // count for fV0
-    int fCount1;    // count for interpolating (fV0...fV1)
-    int fCount2;    // count for fV1
-    SkFixed fFx1;   // initial fx value for the fCount1 range.
-                    // only valid if fCount1 > 0
-    int fV0, fV1;
-    bool fOverflowed;   // true if we had to clamp due to numerical overflow
-
-    void init(SkFixed fx, SkFixed dx, int count, int v0, int v1);
-
-private:
-    void initFor1(SkFixed fx);
-};
-
-#endif
-
--- a/gfx/skia/include/core/SkClipStack.h
+++ b/gfx/skia/include/core/SkClipStack.h
@@ -5,87 +5,256 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
 #ifndef SkClipStack_DEFINED
 #define SkClipStack_DEFINED
 
 #include "SkDeque.h"
 #include "SkRegion.h"
+#include "SkTDArray.h"
 
 struct SkRect;
 class SkPath;
 
+// Because a single save/restore state can have multiple clips, this class
+// stores the stack depth (fSaveCount) and clips (fDeque) separately.