Merge mozilla-central to fx-team
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Tue, 15 Oct 2013 10:49:42 +0200
changeset 150832 344307c027959e537e5d669f1d85f33a57097135
parent 150831 7b367ca427b63d7530dd69c62112dbee2dc7cae1 (current diff)
parent 150760 febfe3c7732bfb52252e77fa293046ad2e8ec41f (diff)
child 150833 55e9f80315a634ae2353dd552974cdd7087b6be3
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
milestone27.0a1
Merge mozilla-central to fx-team
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,4 +1,4 @@
 {
-    "revision": "4a8dcbcad9433e7cb0b619d80b041219e5946130", 
+    "revision": "8c2ad9ad3192687c13efe1eb0cd986d6214b4b5d", 
     "repo_path": "/integration/gaia-central"
 }
--- a/content/canvas/src/CanvasRenderingContext2D.cpp
+++ b/content/canvas/src/CanvasRenderingContext2D.cpp
@@ -3260,55 +3260,79 @@ CanvasRenderingContext2D::DrawWindow(nsI
 
   // gfxContext-over-Azure may modify the DrawTarget's transform, so
   // save and restore it
   Matrix matrix = mTarget->GetTransform();
   double sw = matrix._11 * w;
   double sh = matrix._22 * h;
   nsRefPtr<gfxContext> thebes;
   nsRefPtr<gfxASurface> drawSurf;
+  RefPtr<DrawTarget> drawDT;
   if (gfxPlatform::GetPlatform()->SupportsAzureContentForDrawTarget(mTarget)) {
     thebes = new gfxContext(mTarget);
     thebes->SetMatrix(gfxMatrix(matrix._11, matrix._12, matrix._21,
                                 matrix._22, matrix._31, matrix._32));
+  } else if (gfxPlatform::GetPlatform()->SupportsAzureContent()) {
+    drawDT =
+      gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(IntSize(ceil(sw), ceil(sh)),
+                                                                   FORMAT_B8G8R8A8);
+    if (!drawDT) {
+      error.Throw(NS_ERROR_FAILURE);
+      return;
+    }
+
+    thebes = new gfxContext(drawDT);
+    thebes->Scale(matrix._11, matrix._22);
   } else {
     drawSurf =
       gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(ceil(sw), ceil(sh)),
                                                          GFX_CONTENT_COLOR_ALPHA);
     if (!drawSurf) {
       error.Throw(NS_ERROR_FAILURE);
       return;
     }
 
-    drawSurf->SetDeviceOffset(gfxPoint(-floor(x), -floor(y)));
     thebes = new gfxContext(drawSurf);
-    thebes->Translate(gfxPoint(floor(x), floor(y)));
     thebes->Scale(matrix._11, matrix._22);
   }
 
   nsCOMPtr<nsIPresShell> shell = presContext->PresShell();
   unused << shell->RenderDocument(r, renderDocFlags, backgroundColor, thebes);
-  if (drawSurf) {
-    gfxIntSize size = drawSurf->GetSize();
-
-    drawSurf->SetDeviceOffset(gfxPoint(0, 0));
-    nsRefPtr<gfxImageSurface> img = drawSurf->GetAsReadableARGB32ImageSurface();
-    if (!img || !img->Data()) {
-      error.Throw(NS_ERROR_FAILURE);
-      return;
+  if (drawSurf || drawDT) {
+    RefPtr<SourceSurface> source;
+
+    if (drawSurf) {
+      gfxIntSize size = drawSurf->GetSize();
+
+      drawSurf->SetDeviceOffset(gfxPoint(0, 0));
+      nsRefPtr<gfxImageSurface> img = drawSurf->GetAsReadableARGB32ImageSurface();
+      if (!img || !img->Data()) {
+        error.Throw(NS_ERROR_FAILURE);
+        return;
+      }
+
+      source =
+        mTarget->CreateSourceSurfaceFromData(img->Data(),
+                                             IntSize(size.width, size.height),
+                                             img->Stride(),
+                                             FORMAT_B8G8R8A8);
+    } else {
+      RefPtr<SourceSurface> snapshot = drawDT->Snapshot();
+      RefPtr<DataSourceSurface> data = snapshot->GetDataSurface();
+
+      source =
+        mTarget->CreateSourceSurfaceFromData(data->GetData(),
+                                             data->GetSize(),
+                                             data->Stride(),
+                                             data->GetFormat());
     }
 
-    RefPtr<SourceSurface> data =
-      mTarget->CreateSourceSurfaceFromData(img->Data(),
-                                           IntSize(size.width, size.height),
-                                           img->Stride(),
-                                           FORMAT_B8G8R8A8);
     mgfx::Rect destRect(0, 0, w, h);
     mgfx::Rect sourceRect(0, 0, sw, sh);
-    mTarget->DrawSurface(data, destRect, sourceRect,
+    mTarget->DrawSurface(source, destRect, sourceRect,
                          DrawSurfaceOptions(mgfx::FILTER_POINT),
                          DrawOptions(1.0f, OP_SOURCE, AA_NONE));
     mTarget->Flush();
   } else {
     mTarget->SetTransform(matrix);
   }
 
   // note that x and y are coordinates in the document that
--- a/content/html/content/src/HTMLInputElement.cpp
+++ b/content/html/content/src/HTMLInputElement.cpp
@@ -523,17 +523,17 @@ public:
       nsCOMPtr<nsISupports> tmp;
       while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore)) && hasMore) {
         iter->GetNext(getter_AddRefs(tmp));
         nsCOMPtr<nsIDOMFile> domFile = do_QueryInterface(tmp);
         MOZ_ASSERT(domFile);
         mFileList.AppendElement(domFile);
         mFileListLength = mFileList.Length();
         if (mCanceled) {
-          NS_ASSERTION(!mInput, "This is bad - how did this happen?");
+          MOZ_ASSERT(!mInput, "This is bad - how did this happen?");
           // There's no point dispatching to the main thread (that doesn't
           // guarantee that we'll be destroyed there).
           return NS_OK;
         }
       }
       return NS_DispatchToMainThread(this);
     }
 
--- a/content/media/webaudio/OscillatorNode.cpp
+++ b/content/media/webaudio/OscillatorNode.cpp
@@ -65,26 +65,23 @@ public:
     , mDestination(static_cast<AudioNodeStream*> (aDestination->Stream()))
     , mStart(-1)
     , mStop(TRACK_TICKS_MAX)
     // Keep the default values in sync with OscillatorNode::OscillatorNode.
     , mFrequency(440.f)
     , mDetune(0.f)
     , mType(OscillatorType::Sine)
     , mPhase(0.)
-    , mFinalFrequency(0.0)
-    , mNumberOfHarmonics(0)
-    , mSignalPeriod(0.0)
-    , mAmplitudeAtZero(0.0)
-    , mPhaseIncrement(0.0)
-    , mSquare(0.0)
-    , mTriangle(0.0)
-    , mSaw(0.0)
-    , mPhaseWrap(0.0)
-    , mRecomputeFrequency(true)
+    // mSquare, mTriangle, and mSaw are not used for default type "sine".
+    // They are initialized if and when switching to the OscillatorTypes that
+    // use them.
+    // mFinalFrequency, mNumberOfHarmonics, mSignalPeriod, mAmplitudeAtZero,
+    // mPhaseIncrement, and mPhaseWrap are initialized in
+    // UpdateParametersIfNeeded() when mRecomputeParameters is set.
+    , mRecomputeParameters(true)
     , mCustomLength(0)
   {
   }
 
   void SetSourceStream(AudioNodeStream* aSource)
   {
     mSource = aSource;
   }
@@ -96,17 +93,17 @@ public:
     PERIODICWAVE,
     START,
     STOP,
   };
   void SetTimelineParameter(uint32_t aIndex,
                             const AudioParamTimeline& aValue,
                             TrackRate aSampleRate) MOZ_OVERRIDE
   {
-    mRecomputeFrequency = true;
+    mRecomputeParameters = true;
     switch (aIndex) {
     case FREQUENCY:
       MOZ_ASSERT(mSource && mDestination);
       mFrequency = aValue;
       WebAudioUtils::ConvertAudioParamToTicks(mFrequency, mSource, mDestination);
       break;
     case DETUNE:
       MOZ_ASSERT(mSource && mDestination);
@@ -134,16 +131,17 @@ public:
       case TYPE:
         // Set the new type.
         mType = static_cast<OscillatorType>(aParam);
         if (mType != OscillatorType::Custom) {
           // Forget any previous custom data.
           mCustomLength = 0;
           mCustom = nullptr;
           mPeriodicWave = nullptr;
+          mRecomputeParameters = true;
         }
         // Update BLIT integrators with the new initial conditions.
         switch (mType) {
           case OscillatorType::Sine:
             mPhase = 0.0;
             break;
           case OscillatorType::Square:
             mPhase = 0.0;
@@ -203,42 +201,42 @@ public:
   }
 
   // Square and triangle are using a bipolar band-limited impulse train, saw is
   // using a normal band-limited impulse train.
   bool UsesBipolarBLIT() {
     return mType == OscillatorType::Square || mType == OscillatorType::Triangle;
   }
 
-  void UpdateFrequencyIfNeeded(TrackTicks ticks, size_t count)
+  void UpdateParametersIfNeeded(TrackTicks ticks, size_t count)
   {
     double frequency, detune;
 
     bool simpleFrequency = mFrequency.HasSimpleValue();
     bool simpleDetune = mDetune.HasSimpleValue();
 
     // Shortcut if frequency-related AudioParam are not automated, and we
     // already have computed the frequency information and related parameters.
-    if (simpleFrequency && simpleDetune && !mRecomputeFrequency) {
+    if (simpleFrequency && simpleDetune && !mRecomputeParameters) {
       return;
     }
 
     if (simpleFrequency) {
       frequency = mFrequency.GetValue();
     } else {
       frequency = mFrequency.GetValueAtTime(ticks, count);
     }
     if (simpleDetune) {
       detune = mDetune.GetValue();
     } else {
       detune = mDetune.GetValueAtTime(ticks, count);
     }
 
     mFinalFrequency = frequency * pow(2., detune / 1200.);
-    mRecomputeFrequency = false;
+    mRecomputeParameters = false;
 
     // When using bipolar BLIT, we divide the signal period by two, because we
     // are using two BLIT out of phase.
     mSignalPeriod = UsesBipolarBLIT() ? 0.5 * mSource->SampleRate() / mFinalFrequency
                                       : mSource->SampleRate() / mFinalFrequency;
     // Wrap the phase accordingly:
     mPhaseWrap = UsesBipolarBLIT() || mType == OscillatorType::Sine ? 2 * M_PI
                                    : M_PI;
@@ -303,59 +301,59 @@ public:
     }
 
     return blit;
   }
 
   void ComputeSine(float * aOutput, TrackTicks ticks, uint32_t aStart, uint32_t aEnd)
   {
     for (uint32_t i = aStart; i < aEnd; ++i) {
-      UpdateFrequencyIfNeeded(ticks, i);
+      UpdateParametersIfNeeded(ticks, i);
 
       aOutput[i] = sin(mPhase);
 
       IncrementPhase();
     }
   }
 
   void ComputeSquare(float * aOutput, TrackTicks ticks, uint32_t aStart, uint32_t aEnd)
   {
     for (uint32_t i = aStart; i < aEnd; ++i) {
-      UpdateFrequencyIfNeeded(ticks, i);
+      UpdateParametersIfNeeded(ticks, i);
       // Integration to get us a square. It turns out we can have a
       // pure integrator here.
       mSquare += BipolarBLIT();
       aOutput[i] = mSquare;
       // maybe we want to apply a gain, the wg has not decided yet
       aOutput[i] *= 1.5;
       IncrementPhase();
     }
   }
 
   void ComputeSawtooth(float * aOutput, TrackTicks ticks, uint32_t aStart, uint32_t aEnd)
   {
     float dcoffset;
     for (uint32_t i = aStart; i < aEnd; ++i) {
-      UpdateFrequencyIfNeeded(ticks, i);
+      UpdateParametersIfNeeded(ticks, i);
       // DC offset so the Saw does not ramp up to infinity when integrating.
       dcoffset = mFinalFrequency / mSource->SampleRate();
       // Integrate and offset so we get mAmplitudeAtZero sawtooth. We have a
       // very low frequency component somewhere here, but I'm not sure where.
       mSaw += UnipolarBLIT() - dcoffset;
       // reverse the saw so we are spec compliant
       aOutput[i] = -mSaw * 1.5;
 
       IncrementPhase();
     }
   }
 
   void ComputeTriangle(float * aOutput, TrackTicks ticks, uint32_t aStart, uint32_t aEnd)
   {
     for (uint32_t i = aStart; i < aEnd; ++i) {
-      UpdateFrequencyIfNeeded(ticks, i);
+      UpdateParametersIfNeeded(ticks, i);
       // Integrate to get a square
       mSquare += BipolarBLIT();
       // Leaky integrate to get a triangle. We get too much dc offset if we don't
       // leaky integrate here.
       // C6 = k0 / period
       // (period is samplingrate / frequency, k0 = (PI/2)/(2*PI)) = 0.25
       float C6 = 0.25 / (mSource->SampleRate() / mFinalFrequency);
       mTriangle = mTriangle * sLeak + mSquare + C6;
@@ -375,17 +373,17 @@ public:
 
     uint32_t periodicWaveSize = mPeriodicWave->periodicWaveSize();
     float* higherWaveData = nullptr;
     float* lowerWaveData = nullptr;
     float tableInterpolationFactor;
     float rate = 1.0 / mSource->SampleRate();
  
     for (uint32_t i = aStart; i < aEnd; ++i) {
-      UpdateFrequencyIfNeeded(ticks, i);
+      UpdateParametersIfNeeded(ticks, i);
       mPeriodicWave->waveDataForFundamentalFrequency(mFinalFrequency,
                                                      lowerWaveData,
                                                      higherWaveData,
                                                      tableInterpolationFactor);
       // mPhase runs 0..periodicWaveSize here instead of 0..2*M_PI.
       mPhase += periodicWaveSize * mFinalFrequency * rate;
       if (mPhase >= periodicWaveSize) {
         mPhase -= periodicWaveSize;
@@ -479,17 +477,17 @@ public:
   uint32_t mNumberOfHarmonics;
   float mSignalPeriod;
   float mAmplitudeAtZero;
   float mPhaseIncrement;
   float mSquare;
   float mTriangle;
   float mSaw;
   float mPhaseWrap;
-  bool mRecomputeFrequency;
+  bool mRecomputeParameters;
   nsRefPtr<ThreadSharedFloatArrayBufferList> mCustom;
   uint32_t mCustomLength;
   nsAutoPtr<WebCore::PeriodicWave> mPeriodicWave;
 };
 
 OscillatorNode::OscillatorNode(AudioContext* aContext)
   : AudioNode(aContext,
               2,
--- a/content/media/webaudio/test/mochitest.ini
+++ b/content/media/webaudio/test/mochitest.ini
@@ -92,16 +92,17 @@ support-files =
 [test_mediaStreamAudioSourceNodeResampling.html]
 [test_mixingRules.html]
 [test_nodeToParamConnection.html]
 [test_offlineDestinationChannelCountLess.html]
 [test_offlineDestinationChannelCountMore.html]
 [test_oscillatorNode.html]
 [test_oscillatorNode2.html]
 [test_oscillatorNodeStart.html]
+[test_oscillatorTypeChange.html]
 [test_pannerNode.html]
 [test_pannerNodeAbove.html]
 [test_pannerNodeChannelCount.html]
 [test_pannerNode_equalPower.html]
 [test_periodicWave.html]
 [test_scriptProcessorNode.html]
 [test_scriptProcessorNodeChannelCount.html]
 [test_scriptProcessorNodeZeroInputOutput.html]
new file mode 100644
--- /dev/null
+++ b/content/media/webaudio/test/test_oscillatorTypeChange.html
@@ -0,0 +1,58 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test OscillatorNode type change after it has started and triangle phase</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="webaudio.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+SimpleTest.waitForExplicitFinish();
+
+const bufferSize = 1024;
+
+function startTest() {
+  var ctx = new AudioContext();
+
+  var oscillator1 = ctx.createOscillator();
+  oscillator1.connect(ctx.destination);
+  oscillator1.start(0);
+
+  // Assuming the above Web Audio operations have already scheduled an event
+  // to run in stable state and start the graph thread, schedule a subsequent
+  // event to change the type of oscillator1.
+  SimpleTest.executeSoon(function() {
+    oscillator1.type = "triangle";
+
+    // Another triangle wave with -1 gain should cancel the first.  This is
+    // starting at the same time as the type change, assuming that the phase
+    // is reset on type change.  A negative frequency should achieve the same
+    // as the -1 gain but for bug 916285.
+    var oscillator2 = ctx.createOscillator();
+    oscillator2.type = "triangle";
+    oscillator2.start(0);
+
+    var processor = ctx.createScriptProcessor(bufferSize, 1, 0);
+    oscillator1.connect(processor);
+    var gain = ctx.createGain();
+    gain.gain.value = -1;
+    gain.connect(processor);
+    oscillator2.connect(gain);
+
+    processor.onaudioprocess = function(e) {
+      compareBuffers(e.inputBuffer.getChannelData(0),
+                     new Float32Array(bufferSize));
+      e.target.onaudioprocess = null;
+      SimpleTest.finish();
+    }
+  });
+};
+
+startTest();
+</script>
+</pre>
+</body>
+</html>
--- a/content/svg/content/src/SVGMotionSMILAnimationFunction.cpp
+++ b/content/svg/content/src/SVGMotionSMILAnimationFunction.cpp
@@ -222,42 +222,42 @@ SVGMotionSMILAnimationFunction::
   if (pathElem) {
     const SVGPathData &path = pathElem->GetAnimPathSegList()->GetAnimValue();
     // Path data must contain of at least one path segment (if the path data
     // doesn't begin with a valid "M", then it's invalid).
     if (path.Length()) {
       bool ok =
         path.GetDistancesFromOriginToEndsOfVisibleSegments(&mPathVertices);
       if (ok && mPathVertices.Length()) {
-        mPath = pathElem->GetFlattenedPath(gfxMatrix());
+        mPath = pathElem->GetPath(gfxMatrix());
       }
     }
   }
 }
 
 void
 SVGMotionSMILAnimationFunction::RebuildPathAndVerticesFromPathAttr()
 {
   const nsAString& pathSpec = GetAttr(nsGkAtoms::path)->GetStringValue();
   mPathSourceType = ePathSourceType_PathAttr;
 
-  // Generate gfxFlattenedPath from |path| attr
+  // Generate gfxPath from |path| attr
   SVGPathData path;
   nsSVGPathDataParserToInternal pathParser(&path);
 
   // We ignore any failure returned from Parse() since the SVG spec says to
   // accept all segments up to the first invalid token. Instead we must
   // explicitly check that the parse produces at least one path segment (if
   // the path data doesn't begin with a valid "M", then it's invalid).
   pathParser.Parse(pathSpec);
   if (!path.Length()) {
     return;
   }
 
-  mPath = path.ToFlattenedPath(gfxMatrix());
+  mPath = path.ToPath(gfxMatrix());
   bool ok = path.GetDistancesFromOriginToEndsOfVisibleSegments(&mPathVertices);
   if (!ok || !mPathVertices.Length()) {
     mPath = nullptr;
   }
 }
 
 // Helper to regenerate our path representation & its list of vertices
 void
@@ -287,17 +287,17 @@ SVGMotionSMILAnimationFunction::
     RebuildPathAndVerticesFromBasicAttrs(aTargetElement);
     mValueNeedsReparsingEverySample = true;
   }
   mIsPathStale = false;
 }
 
 bool
 SVGMotionSMILAnimationFunction::
-  GenerateValuesForPathAndPoints(gfxFlattenedPath* aPath,
+  GenerateValuesForPathAndPoints(gfxPath* aPath,
                                  bool aIsKeyPoints,
                                  nsTArray<double>& aPointDistances,
                                  nsTArray<nsSMILValue>& aResult)
 {
   NS_ABORT_IF_FALSE(aResult.IsEmpty(), "outparam is non-empty");
 
   // If we're using "keyPoints" as our list of input distances, then we need
   // to de-normalize from the [0, 1] scale to the [0, totalPathLen] scale.
--- a/content/svg/content/src/SVGMotionSMILAnimationFunction.h
+++ b/content/svg/content/src/SVGMotionSMILAnimationFunction.h
@@ -1,17 +1,17 @@
 /* -*- 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 MOZILLA_SVGMOTIONSMILANIMATIONFUNCTION_H_
 #define MOZILLA_SVGMOTIONSMILANIMATIONFUNCTION_H_
 
-#include "gfxPath.h"  // for gfxFlattenedPath
+#include "gfxPath.h"  // for gfxPath
 #include "nsAutoPtr.h"
 #include "nsSMILAnimationFunction.h"
 #include "nsTArray.h"
 #include "SVGMotionSMILType.h"  // for RotateType
 
 class nsAttrValue;
 class nsIAtom;
 class nsIContent;
@@ -73,30 +73,30 @@ protected:
   void     UnsetRotate();
 
   // Helpers for GetValues
   void     MarkStaleIfAttributeAffectsPath(nsIAtom* aAttribute);
   void     RebuildPathAndVertices(const nsIContent* aContextElem);
   void     RebuildPathAndVerticesFromMpathElem(dom::SVGMPathElement* aMpathElem);
   void     RebuildPathAndVerticesFromPathAttr();
   void     RebuildPathAndVerticesFromBasicAttrs(const nsIContent* aContextElem);
-  bool     GenerateValuesForPathAndPoints(gfxFlattenedPath* aPath,
+  bool     GenerateValuesForPathAndPoints(gfxPath* aPath,
                                           bool aIsKeyPoints,
                                           nsTArray<double>& aPointDistances,
                                           nsTArray<nsSMILValue>& aResult);
 
   // Members
   // -------
   nsTArray<double>           mKeyPoints; // parsed from "keyPoints" attribute.
 
   RotateType                 mRotateType;  // auto, auto-reverse, or explicit.
   float                      mRotateAngle; // the angle value, if explicit.
 
-  PathSourceType             mPathSourceType; // source of our gfxFlattenedPath.
-  nsRefPtr<gfxFlattenedPath> mPath;           // representation of motion path.
+  PathSourceType             mPathSourceType; // source of our gfxPath.
+  nsRefPtr<gfxPath> mPath;           // representation of motion path.
   nsTArray<double>           mPathVertices; // distances of vertices along path.
 
   bool                       mIsPathStale;
 };
 
 } // namespace mozilla
 
 #endif // MOZILLA_SVGMOTIONSMILANIMATIONFUNCTION_H_
--- a/content/svg/content/src/SVGMotionSMILPathUtils.cpp
+++ b/content/svg/content/src/SVGMotionSMILPathUtils.cpp
@@ -71,20 +71,20 @@ SVGMotionSMILPathUtils::PathGenerator::
   if (!ParseCoordinatePair(aCoordPairStr, xVal, yVal)) {
     return false;
   }
   mGfxContext.LineTo(mGfxContext.CurrentPoint() + gfxPoint(xVal, yVal));
   aSegmentDistance = NS_hypot(xVal, yVal);
   return true;
 }
 
-already_AddRefed<gfxFlattenedPath>
+already_AddRefed<gfxPath>
 SVGMotionSMILPathUtils::PathGenerator::GetResultingPath()
 {
-  return mGfxContext.GetFlattenedPath();
+  return mGfxContext.CopyPath();
 }
 
 //----------------------------------------------------------------------
 // Helper / protected methods
 
 bool
 SVGMotionSMILPathUtils::PathGenerator::
   ParseCoordinatePair(const nsAString& aCoordPairStr,
--- a/content/svg/content/src/SVGMotionSMILPathUtils.h
+++ b/content/svg/content/src/SVGMotionSMILPathUtils.h
@@ -12,25 +12,25 @@
 #include "mozilla/Attributes.h"
 #include "gfxContext.h"
 #include "gfxPlatform.h"
 #include "nsCOMPtr.h"
 #include "nsDebug.h"
 #include "nsSMILParserUtils.h"
 #include "nsTArray.h"
 
-class gfxFlattenedPath;
+class gfxPath;
 class nsAString;
 class nsSVGElement;
 
 namespace mozilla {
 
 class SVGMotionSMILPathUtils {
 public:
-  // Class to assist in generating a gfxFlattenedPath, based on
+  // Class to assist in generating a gfxPath, based on
   // coordinates in the <animateMotion> from/by/to/values attributes.
   class PathGenerator {
   public:
     PathGenerator(const nsSVGElement* aSVGElement)
       : mSVGElement(aSVGElement),
         mGfxContext(gfxPlatform::GetPlatform()->ScreenReferenceSurface()),
         mHaveReceivedCommands(false)
     {}
@@ -45,31 +45,31 @@ public:
     bool LineToAbsolute(const nsAString& aCoordPairStr,
                           double& aSegmentDistance);
     bool LineToRelative(const nsAString& aCoordPairStr,
                           double& aSegmentDistance);
 
     // Accessor to let clients check if we've received any commands yet.
     inline bool HaveReceivedCommands() { return mHaveReceivedCommands; }
     // Accessor to get the finalized path
-    already_AddRefed<gfxFlattenedPath> GetResultingPath();
+    already_AddRefed<gfxPath> GetResultingPath();
 
   protected:
     // Helper methods
     bool ParseCoordinatePair(const nsAString& aStr,
                                float& aXVal, float& aYVal);
 
     // Member data
     const nsSVGElement* mSVGElement; // context for converting to user units
     gfxContext    mGfxContext;
     bool          mHaveReceivedCommands;
   };
 
   // Class to assist in passing each subcomponent of a |values| attribute to
-  // a PathGenerator, for generating a corresponding gfxFlattenedPath.
+  // a PathGenerator, for generating a corresponding gfxPath.
   class MotionValueParser : public nsSMILParserUtils::GenericValueParser
   {
   public:
     MotionValueParser(PathGenerator* aPathGenerator,
                       nsTArray<double>* aPointDistances)
       : mPathGenerator(aPathGenerator),
         mPointDistances(aPointDistances),
         mDistanceSoFar(0.0)
--- a/content/svg/content/src/SVGMotionSMILType.cpp
+++ b/content/svg/content/src/SVGMotionSMILType.cpp
@@ -27,17 +27,17 @@ enum SegmentType {
 
 // Helper Structs: containers for params to define our MotionSegment
 // (either simple translation or point-on-a-path)
 struct TranslationParams {  // Simple translation
   float mX;
   float mY;
 };
 struct PathPointParams {  // Point along a path
-  gfxFlattenedPath* mPath; // NOTE: Refcounted; need to AddRef/Release.
+  gfxPath* mPath; // NOTE: Refcounted; need to AddRef/Release.
   float mDistToPoint; // Distance from path start to the point on the path that
                       // we're interested in.
 };
 
 /**
  * Helper Struct: MotionSegment
  *
  * Instances of this class represent the points that we move between during
@@ -65,17 +65,17 @@ struct MotionSegment
     : mRotateType(eRotateType_Explicit), mRotateAngle(aRotateAngle),
       mSegmentType(eSegmentType_Translation)
   {
     mU.mTranslationParams.mX = aX;
     mU.mTranslationParams.mY = aY;
   }
 
   // Constructor for a point on a path (NOTE: AddRef's)
-  MotionSegment(gfxFlattenedPath* aPath, float aDistToPoint,
+  MotionSegment(gfxPath* aPath, float aDistToPoint,
                 RotateType aRotateType, float aRotateAngle)
     : mRotateType(aRotateType), mRotateAngle(aRotateAngle),
       mSegmentType(eSegmentType_PathPoint)
   {
     mU.mPathPointParams.mPath = aPath;
     mU.mPathPointParams.mDistToPoint = aDistToPoint;
 
     NS_ADDREF(mU.mPathPointParams.mPath); // Retain a reference to path
@@ -223,17 +223,17 @@ SVGMotionSMILType::IsEqual(const nsSMILV
     }
   }
 
   return true; // If we get here, we found no differences.
 }
 
 // Helper method for Add & CreateMatrix
 inline static void
-GetAngleAndPointAtDistance(gfxFlattenedPath* aPath, float aDistance,
+GetAngleAndPointAtDistance(gfxPath* aPath, float aDistance,
                            RotateType aRotateType,
                            gfxFloat& aRotateAngle, // in & out-param.
                            gfxPoint& aPoint)       // out-param.
 {
   gfxFloat tangentAngle;
   // NOTE: "0.0" below is distance-off-the-path. (see FindPoint documentation)
   aPoint = aPath->FindPoint(gfxPoint(aDistance, 0.0), &tangentAngle);
 
@@ -282,17 +282,17 @@ SVGMotionSMILType::Add(nsSMILValue& aDes
   const PathPointParams& srcParams = srcSeg.mU.mPathPointParams;
   const PathPointParams& dstParams = dstSeg.mU.mPathPointParams;
 
   NS_ABORT_IF_FALSE(srcSeg.mRotateType  == dstSeg.mRotateType &&
                     srcSeg.mRotateAngle == dstSeg.mRotateAngle,
                     "unexpected angle mismatch");
   NS_ABORT_IF_FALSE(srcParams.mPath == dstParams.mPath,
                     "unexpected path mismatch");
-  gfxFlattenedPath* path = srcParams.mPath;
+  gfxPath* path = srcParams.mPath;
 
   // Use destination to get our rotate angle.
   gfxFloat rotateAngle = dstSeg.mRotateAngle;
   gfxPoint dstPt;
   GetAngleAndPointAtDistance(path, dstParams.mDistToPoint, dstSeg.mRotateType,
                              rotateAngle, dstPt);
 
   // NOTE: "0.0" below is distance-off-the-path. (see FindPoint documentation)
@@ -406,17 +406,17 @@ SVGMotionSMILType::Interpolate(const nsS
   const MotionSegment& endSeg = endArr[0];
   NS_ABORT_IF_FALSE(endSeg.mSegmentType == eSegmentType_PathPoint,
                     "Expecting to be interpolating along a path");
 
   const PathPointParams& endParams = endSeg.mU.mPathPointParams;
   // NOTE: path & angle should match between start & end (since presumably
   // start & end came from the same <animateMotion> element), unless start is
   // empty. (as it would be for pure 'to' animation)
-  gfxFlattenedPath* path = endParams.mPath;
+  gfxPath* path = endParams.mPath;
   RotateType rotateType  = endSeg.mRotateType;
   float rotateAngle      = endSeg.mRotateAngle;
 
   float startDist;
   if (startArr.IsEmpty()) {
     startDist = 0.0f;
   } else {
     const MotionSegment& startSeg = startArr[0];
@@ -466,17 +466,17 @@ SVGMotionSMILType::CreateMatrix(const ns
     }
     matrix.Translate(point);
     matrix.Rotate(rotateAngle);
   }
   return matrix;
 }
 
 /* static */ nsSMILValue
-SVGMotionSMILType::ConstructSMILValue(gfxFlattenedPath* aPath,
+SVGMotionSMILType::ConstructSMILValue(gfxPath* aPath,
                                       float aDist,
                                       RotateType aRotateType,
                                       float aRotateAngle)
 {
   nsSMILValue smilVal(&SVGMotionSMILType::sSingleton);
   MotionSegmentArray& arr = ExtractMotionSegmentArray(smilVal);
 
   // AppendElement has guaranteed success here, since Init() allocates 1 slot.
--- a/content/svg/content/src/SVGMotionSMILType.h
+++ b/content/svg/content/src/SVGMotionSMILType.h
@@ -7,17 +7,17 @@
 
 #ifndef MOZILLA_SVGMOTIONSMILTYPE_H_
 #define MOZILLA_SVGMOTIONSMILTYPE_H_
 
 #include "mozilla/Attributes.h"
 #include "gfxMatrix.h"
 #include "nsISMILType.h"
 
-class gfxFlattenedPath;
+class gfxPath;
 class nsSMILValue;
 
 namespace mozilla {
 
 /**
  * MotionRotateType: Enum to indicate the type of our "rotate" attribute.
  */
 enum RotateType {
@@ -60,17 +60,17 @@ protected:
                                double aUnitDistance,
                                nsSMILValue& aResult) const MOZ_OVERRIDE;
 public:
   // Used to generate a transform matrix from an <animateMotion> nsSMILValue.
   static gfxMatrix CreateMatrix(const nsSMILValue& aSMILVal);
 
   // Used to generate a nsSMILValue for the point at the given distance along
   // the given path.
-  static nsSMILValue ConstructSMILValue(gfxFlattenedPath* aPath,
+  static nsSMILValue ConstructSMILValue(gfxPath* aPath,
                                         float aDist,
                                         RotateType aRotateType,
                                         float aRotateAngle);
 
 private:
   // Private constructor: prevent instances beyond my singleton.
   MOZ_CONSTEXPR SVGMotionSMILType() {}
 };
--- a/content/svg/content/src/SVGPathData.cpp
+++ b/content/svg/content/src/SVGPathData.cpp
@@ -487,27 +487,27 @@ SVGPathData::ConstructPath(gfxContext *a
 
   NS_ABORT_IF_FALSE(i == mData.Length(), "Very, very bad - mData corrupt");
   NS_ABORT_IF_FALSE(prevSegType == segType,
                     "prevSegType should be left at the final segType");
 
   MAYBE_APPROXIMATE_ZERO_LENGTH_SUBPATH_SQUARE_CAPS;
 }
 
-already_AddRefed<gfxFlattenedPath>
-SVGPathData::ToFlattenedPath(const gfxMatrix& aMatrix) const
+already_AddRefed<gfxPath>
+SVGPathData::ToPath(const gfxMatrix& aMatrix) const
 {
   nsRefPtr<gfxContext> tmpCtx =
     new gfxContext(gfxPlatform::GetPlatform()->ScreenReferenceSurface());
 
   tmpCtx->SetMatrix(aMatrix);
   ConstructPath(tmpCtx);
   tmpCtx->IdentityMatrix();
 
-  return tmpCtx->GetFlattenedPath();
+  return tmpCtx->CopyPath();
 }
 
 static double
 AngleOfVector(const gfxPoint& aVector)
 {
   // C99 says about atan2 "A domain error may occur if both arguments are
   // zero" and "On a domain error, the function returns an implementation-
   // defined value". In the case of atan2 the implementation-defined value
--- a/content/svg/content/src/SVGPathData.h
+++ b/content/svg/content/src/SVGPathData.h
@@ -12,17 +12,17 @@
 #include "nsINode.h"
 #include "nsIWeakReferenceUtils.h"
 #include "nsSVGElement.h"
 #include "nsTArray.h"
 
 #include <string.h>
 
 class gfxContext;
-class gfxFlattenedPath;
+class gfxPath;
 class nsSVGPathDataParserToInternal; // IWYU pragma: keep
 
 struct gfxMatrix;
 struct nsSVGMark;
 
 namespace mozilla {
 
 /**
@@ -145,18 +145,18 @@ public:
    */
   bool GetSegmentLengths(nsTArray<double> *aLengths) const;
 
   /**
    * Returns true, except on OOM, in which case returns false.
    */
   bool GetDistancesFromOriginToEndsOfVisibleSegments(nsTArray<double> *aArray) const;
 
-  already_AddRefed<gfxFlattenedPath>
-  ToFlattenedPath(const gfxMatrix& aMatrix) const;
+  already_AddRefed<gfxPath>
+  ToPath(const gfxMatrix& aMatrix) const;
 
   void ConstructPath(gfxContext *aCtx) const;
 
   const_iterator begin() const { return mData.Elements(); }
   const_iterator end() const { return mData.Elements() + mData.Length(); }
 
   // Access to methods that can modify objects of this type is deliberately
   // limited. This is to reduce the chances of someone modifying objects of
--- a/content/svg/content/src/SVGPathElement.cpp
+++ b/content/svg/content/src/SVGPathElement.cpp
@@ -48,30 +48,30 @@ already_AddRefed<SVGAnimatedNumber>
 SVGPathElement::PathLength()
 {
   return mPathLength.ToDOMAnimatedNumber(this);
 }
 
 float
 SVGPathElement::GetTotalLength(ErrorResult& rv)
 {
-  nsRefPtr<gfxFlattenedPath> flat = GetFlattenedPath(gfxMatrix());
+  nsRefPtr<gfxPath> flat = GetPath(gfxMatrix());
 
   if (!flat) {
     rv.Throw(NS_ERROR_FAILURE);
     return 0.f;
   }
 
   return flat->GetLength();
 }
 
 already_AddRefed<nsISVGPoint>
 SVGPathElement::GetPointAtLength(float distance, ErrorResult& rv)
 {
-  nsRefPtr<gfxFlattenedPath> flat = GetFlattenedPath(gfxMatrix());
+  nsRefPtr<gfxPath> flat = GetPath(gfxMatrix());
   if (!flat) {
     rv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   float totalLength = flat->GetLength();
   if (mPathLength.IsExplicitlySet()) {
     float pathLength = mPathLength.GetAnimValue();
@@ -287,20 +287,20 @@ SVGPathElement::IsAttributeMapped(const 
   static const MappedAttributeEntry* const map[] = {
     sMarkersMap
   };
 
   return FindAttributeDependence(name, map) ||
     SVGPathElementBase::IsAttributeMapped(name);
 }
 
-already_AddRefed<gfxFlattenedPath>
-SVGPathElement::GetFlattenedPath(const gfxMatrix &aMatrix)
+already_AddRefed<gfxPath>
+SVGPathElement::GetPath(const gfxMatrix &aMatrix)
 {
-  return mD.GetAnimValue().ToFlattenedPath(aMatrix);
+  return mD.GetAnimValue().ToPath(aMatrix);
 }
 
 //----------------------------------------------------------------------
 // nsSVGPathGeometryElement methods
 
 bool
 SVGPathElement::AttributeDefinesGeometry(const nsIAtom *aName)
 {
@@ -336,17 +336,17 @@ SVGPathElement::GetPathLengthScale(PathL
     if (authorsPathLengthEstimate > 0) {
       gfxMatrix matrix;
       if (aFor == eForTextPath) {
         // For textPath, a transform on the referenced path affects the
         // textPath layout, so when calculating the actual path length
         // we need to take that into account.
         matrix = PrependLocalTransformsTo(matrix);
       }
-      nsRefPtr<gfxFlattenedPath> path = GetFlattenedPath(matrix);
+      nsRefPtr<gfxPath> path = GetPath(matrix);
       if (path) {
         return path->GetLength() / authorsPathLengthEstimate;
       }
     }
   }
   return 1.0;
 }
 
--- a/content/svg/content/src/SVGPathElement.h
+++ b/content/svg/content/src/SVGPathElement.h
@@ -43,17 +43,17 @@ public:
   virtual bool HasValidDimensions() const MOZ_OVERRIDE;
 
   // nsSVGPathGeometryElement methods:
   virtual bool AttributeDefinesGeometry(const nsIAtom *aName) MOZ_OVERRIDE;
   virtual bool IsMarkable() MOZ_OVERRIDE;
   virtual void GetMarkPoints(nsTArray<nsSVGMark> *aMarks) MOZ_OVERRIDE;
   virtual void ConstructPath(gfxContext *aCtx) MOZ_OVERRIDE;
 
-  virtual already_AddRefed<gfxFlattenedPath> GetFlattenedPath(const gfxMatrix &aMatrix) MOZ_OVERRIDE;
+  virtual already_AddRefed<gfxPath> GetPath(const gfxMatrix &aMatrix) MOZ_OVERRIDE;
 
   // nsIContent interface
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   virtual SVGAnimatedPathSegList* GetAnimPathSegList() MOZ_OVERRIDE {
     return &mD;
   }
 
--- a/content/svg/content/src/nsSVGPathGeometryElement.cpp
+++ b/content/svg/content/src/nsSVGPathGeometryElement.cpp
@@ -47,13 +47,13 @@ nsSVGPathGeometryElement::IsMarkable()
   return false;
 }
 
 void
 nsSVGPathGeometryElement::GetMarkPoints(nsTArray<nsSVGMark> *aMarks)
 {
 }
 
-already_AddRefed<gfxFlattenedPath>
-nsSVGPathGeometryElement::GetFlattenedPath(const gfxMatrix &aMatrix)
+already_AddRefed<gfxPath>
+nsSVGPathGeometryElement::GetPath(const gfxMatrix &aMatrix)
 {
   return nullptr;
 }
--- a/content/svg/content/src/nsSVGPathGeometryElement.h
+++ b/content/svg/content/src/nsSVGPathGeometryElement.h
@@ -3,17 +3,17 @@
  * 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 __NS_SVGPATHGEOMETRYELEMENT_H__
 #define __NS_SVGPATHGEOMETRYELEMENT_H__
 
 #include "SVGGraphicsElement.h"
 
-class gfxFlattenedPath;
+class gfxPath;
 struct gfxMatrix;
 template <class E> class nsTArray;
 
 struct nsSVGMark {
   enum Type {
     eStart,
     eMid,
     eEnd,
@@ -47,12 +47,12 @@ public:
    * This could be moved up to a more general class so it can be used for non-leaf
    * elements, but that would require care and for now there's no need.
    */
   bool GeometryDependsOnCoordCtx();
 
   virtual bool IsMarkable();
   virtual void GetMarkPoints(nsTArray<nsSVGMark> *aMarks);
   virtual void ConstructPath(gfxContext *aCtx) = 0;
-  virtual already_AddRefed<gfxFlattenedPath> GetFlattenedPath(const gfxMatrix &aMatrix);
+  virtual already_AddRefed<gfxPath> GetPath(const gfxMatrix &aMatrix);
 };
 
 #endif
--- a/dom/bindings/Exceptions.cpp
+++ b/dom/bindings/Exceptions.cpp
@@ -109,17 +109,26 @@ Throw(JSContext* aCx, nsresult aRv, cons
   }
 
   CycleCollectedJSRuntime* runtime = CycleCollectedJSRuntime::Get();
   nsCOMPtr<nsIException> existingException = runtime->GetPendingException();
   if (existingException) {
     nsresult nr;
     if (NS_SUCCEEDED(existingException->GetResult(&nr)) && 
         aRv == nr) {
-      // Just reuse the existing exception.
+      // Reuse the existing exception.
+
+      // Clear pending exception
+      runtime->SetPendingException(nullptr);
+
+      if (!ThrowExceptionObject(aCx, existingException)) {
+        // If we weren't able to throw an exception we're
+        // most likely out of memory
+        JS_ReportOutOfMemory(aCx);
+      }
       return false;
     }
   }
 
   nsRefPtr<Exception> finalException;
 
   // Do we use DOM exceptions for this error code?
   switch (NS_ERROR_GET_MODULE(aRv)) {
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -443,16 +443,21 @@ public:
    */
   virtual Rect GetStrokedBounds(const StrokeOptions &aStrokeOptions,
                                 const Matrix &aTransform = Matrix()) const = 0;
 
   /* This gets the fillrule this path's builder was created with. This is not
    * mutable.
    */
   virtual FillRule GetFillRule() const = 0;
+
+  virtual Float ComputeLength() { return 0; }
+
+  virtual Point ComputePointAtLength(Float aLength,
+                                     Point* aTangent) { return Point(); }
 };
 
 /* The PathBuilder class allows path creation. Once finish is called on the
  * pathbuilder it may no longer be written to.
  */
 class PathBuilder : public PathSink
 {
 public:
@@ -634,16 +639,29 @@ public:
    * aSourceRect Source rectangle to be copied
    * aDest Destination point to copy the surface to
    */
   virtual void CopySurface(SourceSurface *aSurface,
                            const IntRect &aSourceRect,
                            const IntPoint &aDestination) = 0;
 
   /*
+   * Same as CopySurface, except uses itself as the source.
+   *
+   * Some backends may be able to optimize this better
+   * than just taking a snapshot and using CopySurface.
+   */
+  virtual void CopyRect(const IntRect &aSourceRect,
+                        const IntPoint &aDestination)
+  {
+    RefPtr<SourceSurface> source = Snapshot();
+    CopySurface(source, aSourceRect, aDestination);
+  }
+
+  /*
    * Fill a rectangle on the DrawTarget with a certain source pattern.
    *
    * aRect Rectangle that forms the mask of this filling operation
    * aPattern Pattern that forms the source of this filling operation
    * aOptions Options that are applied to this operation
    */
   virtual void FillRect(const Rect &aRect,
                         const Pattern &aPattern,
--- a/gfx/2d/DrawTargetCairo.cpp
+++ b/gfx/2d/DrawTargetCairo.cpp
@@ -124,16 +124,35 @@ GetCairoSurfaceSize(cairo_surface_t* sur
 #endif
 
     default:
       return false;
   }
 }
 
 static bool
+SupportsSelfCopy(cairo_surface_t* surface)
+{
+  switch (cairo_surface_get_type(surface))
+  {
+#ifdef CAIRO_HAS_QUARTZ_SURFACE
+    case CAIRO_SURFACE_TYPE_QUARTZ:
+      return true;
+#endif
+#ifdef CAIRO_HAS_WIN32_SURFACE
+    case CAIRO_SURFACE_TYPE_WIN32:
+    case CAIRO_SURFACE_TYPE_WIN32_PRINTING:
+      return true;
+#endif
+    default:
+      return false;
+  }
+}
+
+static bool
 PatternIsCompatible(const Pattern& aPattern)
 {
   switch (aPattern.GetType())
   {
     case PATTERN_LINEAR_GRADIENT:
     {
       const LinearGradientPattern& pattern = static_cast<const LinearGradientPattern&>(aPattern);
       return pattern.mStops->GetBackendType() == BACKEND_CAIRO;
@@ -632,40 +651,81 @@ DrawTargetCairo::FillRect(const Rect &aR
 
   cairo_new_path(mContext);
   cairo_rectangle(mContext, aRect.x, aRect.y, aRect.Width(), aRect.Height());
 
   DrawPattern(aPattern, StrokeOptions(), aOptions, DRAW_FILL);
 }
 
 void
+DrawTargetCairo::CopySurfaceInternal(cairo_surface_t* aSurface,
+                                     const IntRect &aSource,
+                                     const IntPoint &aDest)
+{
+  cairo_identity_matrix(mContext);
+
+  cairo_set_source_surface(mContext, aSurface, aDest.x - aSource.x, aDest.y - aSource.y);
+  cairo_set_operator(mContext, CAIRO_OPERATOR_SOURCE);
+  cairo_set_antialias(mContext, CAIRO_ANTIALIAS_NONE);
+
+  cairo_reset_clip(mContext);
+  cairo_new_path(mContext);
+  cairo_rectangle(mContext, aDest.x, aDest.y, aSource.width, aSource.height);
+  cairo_fill(mContext);
+}
+
+void
 DrawTargetCairo::CopySurface(SourceSurface *aSurface,
                              const IntRect &aSource,
                              const IntPoint &aDest)
 {
   AutoPrepareForDrawing prep(this, mContext);
   AutoClearDeviceOffset clear(aSurface);
 
   if (!aSurface || aSurface->GetType() != SURFACE_CAIRO) {
     gfxWarning() << "Unsupported surface type specified";
     return;
   }
 
   cairo_surface_t* surf = static_cast<SourceSurfaceCairo*>(aSurface)->GetSurface();
 
-  cairo_identity_matrix(mContext);
+  CopySurfaceInternal(surf, aSource, aDest);
+}
+
+void
+DrawTargetCairo::CopyRect(const IntRect &aSource,
+                          const IntPoint &aDest)
+{
+  AutoPrepareForDrawing prep(this, mContext);
+
+  IntRect source = aSource;
+  cairo_surface_t* surf = mSurface;
 
-  cairo_set_source_surface(mContext, surf, aDest.x - aSource.x, aDest.y - aSource.y);
-  cairo_set_operator(mContext, CAIRO_OPERATOR_SOURCE);
-  cairo_set_antialias(mContext, CAIRO_ANTIALIAS_NONE);
+  if (!SupportsSelfCopy(mSurface) &&
+      aDest.y >= aSource.y &&
+      aDest.y < aSource.YMost()) {
+    cairo_surface_t* similar = cairo_surface_create_similar(mSurface,
+                                                            GfxFormatToCairoContent(GetFormat()),
+                                                            aSource.width, aSource.height);
+    cairo_t* ctx = cairo_create(similar);
+    cairo_set_operator(ctx, CAIRO_OPERATOR_SOURCE);
+    cairo_set_source_surface(ctx, surf, -aSource.x, -aSource.y);
+    cairo_paint(ctx);
+    cairo_destroy(ctx);
 
-  cairo_reset_clip(mContext);
-  cairo_new_path(mContext);
-  cairo_rectangle(mContext, aDest.x, aDest.y, aSource.width, aSource.height);
-  cairo_fill(mContext);
+    source.x = 0;
+    source.y = 0;
+    surf = similar;
+  }
+
+  CopySurfaceInternal(surf, source, aDest);
+
+  if (surf != mSurface) {
+    cairo_surface_destroy(surf);
+  }
 }
 
 void
 DrawTargetCairo::ClearRect(const Rect& aRect)
 {
   AutoPrepareForDrawing prep(this, mContext);
 
   cairo_set_antialias(mContext, CAIRO_ANTIALIAS_NONE);
--- a/gfx/2d/DrawTargetCairo.h
+++ b/gfx/2d/DrawTargetCairo.h
@@ -73,16 +73,18 @@ public:
                                      Float aSigma,
                                      CompositionOp aOperator);
 
   virtual void ClearRect(const Rect &aRect);
 
   virtual void CopySurface(SourceSurface *aSurface,
                            const IntRect &aSourceRect,
                            const IntPoint &aDestination);
+  virtual void CopyRect(const IntRect &aSourceRect,
+                        const IntPoint &aDestination);
 
   virtual void FillRect(const Rect &aRect,
                         const Pattern &aPattern,
                         const DrawOptions &aOptions = DrawOptions());
   virtual void StrokeRect(const Rect &aRect,
                           const Pattern &aPattern,
                           const StrokeOptions &aStrokeOptions = StrokeOptions(),
                           const DrawOptions &aOptions = DrawOptions());
@@ -156,16 +158,20 @@ private: // methods
   bool InitAlreadyReferenced(cairo_surface_t* aSurface, const IntSize& aSize);
 
   enum DrawPatternType { DRAW_FILL, DRAW_STROKE };
   void DrawPattern(const Pattern& aPattern,
                    const StrokeOptions& aStrokeOptions,
                    const DrawOptions& aOptions,
                    DrawPatternType aDrawType);
 
+  void CopySurfaceInternal(cairo_surface_t* aSurface,
+                           const IntRect& aSource,
+                           const IntPoint& aDest);
+
   // Call before you make any changes to the backing surface with which this
   // context is associated. Pass the path you're going to be using if you have
   // one.
   void WillChange(const Path* aPath = nullptr);
 
   // Call if there is any reason to disassociate the snapshot from this draw
   // target; for example, because we're going to be destroyed.
   void MarkSnapshotIndependent();
--- a/gfx/layers/ThebesLayerBuffer.cpp
+++ b/gfx/layers/ThebesLayerBuffer.cpp
@@ -652,27 +652,23 @@ ThebesLayerBuffer::BeginPaint(ThebesLaye
         // The stuff we need to redraw will wrap around an edge of the
         // buffer, so move the pixels we can keep into a position that
         // lets us redraw in just one quadrant.
         if (mBufferRotation == nsIntPoint(0,0)) {
           nsIntRect srcRect(nsIntPoint(0, 0), mBufferRect.Size());
           nsIntPoint dest = mBufferRect.TopLeft() - destBufferRect.TopLeft();
           if (IsAzureBuffer()) {
             MOZ_ASSERT(mDTBuffer);
-            RefPtr<SourceSurface> source = mDTBuffer->Snapshot();
-            mDTBuffer->CopySurface(source,
-                                   IntRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height),
-                                   IntPoint(dest.x, dest.y));
+            mDTBuffer->CopyRect(IntRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height),
+                                IntPoint(dest.x, dest.y));
             if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
               EnsureBufferOnWhite();
               MOZ_ASSERT(mDTBufferOnWhite);
-              RefPtr<SourceSurface> sourceOnWhite = mDTBufferOnWhite->Snapshot();
-              mDTBufferOnWhite->CopySurface(sourceOnWhite,
-                                            IntRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height),
-                                            IntPoint(dest.x, dest.y));
+              mDTBufferOnWhite->CopyRect(IntRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height),
+                                         IntPoint(dest.x, dest.y));
             }
           } else {
             MOZ_ASSERT(mBuffer);
             mBuffer->MovePixels(srcRect, dest);
             if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
               EnsureBufferOnWhite();
               MOZ_ASSERT(mBufferOnWhite);
               mBufferOnWhite->MovePixels(srcRect, dest);
--- a/gfx/layers/basic/BasicContainerLayer.cpp
+++ b/gfx/layers/basic/BasicContainerLayer.cpp
@@ -110,16 +110,30 @@ BasicContainerLayer::ChildrenPartitionVi
     if (!intersection.IsEmpty())
       return false;
     covered.Or(covered, childRegion);
   }
 
   return covered.Contains(rect);
 }
 
+void
+BasicContainerLayer::Validate(LayerManager::DrawThebesLayerCallback aCallback,
+                              void* aCallbackData)
+{
+  for (Layer* l = mFirstChild; l; l = l->GetNextSibling()) {
+    BasicImplData* data = ToData(l);
+    data->Validate(aCallback, aCallbackData);
+    if (l->GetMaskLayer()) {
+      data = ToData(l->GetMaskLayer());
+      data->Validate(aCallback, aCallbackData);
+    }
+  }
+}
+
 already_AddRefed<ContainerLayer>
 BasicLayerManager::CreateContainerLayer()
 {
   NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
   nsRefPtr<ContainerLayer> layer = new BasicContainerLayer(this);
   return layer.forget();
 }
 
--- a/gfx/layers/basic/BasicContainerLayer.h
+++ b/gfx/layers/basic/BasicContainerLayer.h
@@ -71,16 +71,19 @@ public:
    * circumstances.
    */
   bool ChildrenPartitionVisibleRegion(const nsIntRect& aInRect);
 
   void ForceIntermediateSurface() { mUseIntermediateSurface = true; }
 
   void SetSupportsComponentAlphaChildren(bool aSupports) { mSupportsComponentAlphaChildren = aSupports; }
 
+  virtual void Validate(LayerManager::DrawThebesLayerCallback aCallback,
+                        void* aCallbackData) MOZ_OVERRIDE;
+
 protected:
   BasicLayerManager* BasicManager()
   {
     return static_cast<BasicLayerManager*>(mManager);
   }
 };
 }
 }
--- a/gfx/layers/basic/BasicImplData.h
+++ b/gfx/layers/basic/BasicImplData.h
@@ -68,16 +68,19 @@ public:
    * effective visible region (snapped or unsnapped, it doesn't matter).
    */
   virtual void PaintThebes(gfxContext* aContext,
                            Layer* aMasklayer,
                            LayerManager::DrawThebesLayerCallback aCallback,
                            void* aCallbackData,
                            ReadbackProcessor* aReadback) {}
 
+  virtual void Validate(LayerManager::DrawThebesLayerCallback aCallback,
+                        void* aCallbackData) {}
+
   /**
    * Layers will get this call when their layer manager is destroyed, this
    * indicates they should clear resources they don't really need after their
    * LayerManager ceases to exist.
    */
   virtual void ClearCachedResources() {}
 
   /**
--- a/gfx/layers/basic/BasicLayerManager.cpp
+++ b/gfx/layers/basic/BasicLayerManager.cpp
@@ -576,82 +576,64 @@ BasicLayerManager::EndTransactionInterna
 #ifdef MOZ_LAYERS_HAVE_LOG
   MOZ_LAYERS_LOG(("  ----- (beginning paint)"));
   Log();
 #endif
 
   NS_ASSERTION(InConstruction(), "Should be in construction phase");
   mPhase = PHASE_DRAWING;
 
-  Layer* aLayer = GetRoot();
-  RenderTraceLayers(aLayer, "FF00");
+  RenderTraceLayers(mRoot, "FF00");
 
   mTransactionIncomplete = false;
 
-  if (aFlags & END_NO_COMPOSITE) {
-    if (!mDummyTarget) {
-      // XXX: We should really just set mTarget to null and make sure we can handle that further down the call chain
-      // Creating this temporary surface can be expensive on some platforms (d2d in particular), so cache it between paints.
-      nsRefPtr<gfxASurface> surf = gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(1, 1), GFX_CONTENT_COLOR);
-      mDummyTarget = new gfxContext(surf);
-    }
-    mTarget = mDummyTarget;
-  }
+  if (mRoot) {
+    // Need to do this before we call ApplyDoubleBuffering,
+    // which depends on correct effective transforms
+    mSnapEffectiveTransforms =
+      mTarget ? !(mTarget->GetFlags() & gfxContext::FLAG_DISABLE_SNAPPING) : true;
+    mRoot->ComputeEffectiveTransforms(mTarget ? gfx3DMatrix::From2D(mTarget->CurrentMatrix()) : gfx3DMatrix());
 
-  if (mTarget && mRoot && !(aFlags & END_NO_IMMEDIATE_REDRAW)) {
-    nsIntRect clipRect;
-    if (HasShadowManager()) {
-      // If this has a shadow manager, the clip extents of mTarget are meaningless.
-      // So instead just use the root layer's visible region bounds.
-      const nsIntRect& bounds = mRoot->GetVisibleRegion().GetBounds();
-      gfxRect deviceRect =
-          mTarget->UserToDevice(gfxRect(bounds.x, bounds.y, bounds.width, bounds.height));
-      clipRect = ToOutsideIntRect(deviceRect);
-    } else {
-      gfxContextMatrixAutoSaveRestore save(mTarget);
-      mTarget->SetMatrix(gfxMatrix());
-      clipRect = ToOutsideIntRect(mTarget->GetClipExtents());
+    ToData(mRoot)->Validate(aCallback, aCallbackData);
+    if (mRoot->GetMaskLayer()) {
+      ToData(mRoot->GetMaskLayer())->Validate(aCallback, aCallbackData);
     }
 
     if (aFlags & END_NO_COMPOSITE) {
       // Apply pending tree updates before recomputing effective
       // properties.
-      aLayer->ApplyPendingUpdatesToSubtree();
+      mRoot->ApplyPendingUpdatesToSubtree();
     }
+  }
 
-    // Need to do this before we call ApplyDoubleBuffering,
-    // which depends on correct effective transforms
-    mSnapEffectiveTransforms =
-      !(mTarget->GetFlags() & gfxContext::FLAG_DISABLE_SNAPPING);
-    mRoot->ComputeEffectiveTransforms(gfx3DMatrix::From2D(mTarget->CurrentMatrix()));
+  if (mTarget && mRoot &&
+      !(aFlags & END_NO_IMMEDIATE_REDRAW) &&
+      !(aFlags & END_NO_COMPOSITE)) {
+    nsIntRect clipRect;
+
+    {
+      gfxContextMatrixAutoSaveRestore save(mTarget);
+      mTarget->SetMatrix(gfxMatrix());
+      clipRect = ToOutsideIntRect(mTarget->GetClipExtents());
+    }
 
     if (IsRetained()) {
       nsIntRegion region;
       MarkLayersHidden(mRoot, clipRect, clipRect, region, ALLOW_OPAQUE);
       if (mUsingDefaultTarget && mDoubleBuffering != BUFFER_NONE) {
         ApplyDoubleBuffering(mRoot, clipRect);
       }
     }
 
-    if (aFlags & END_NO_COMPOSITE) {
-      if (IsRetained()) {
-        // Clip the destination out so that we don't draw to it, and
-        // only end up validating ThebesLayers.
-        mTarget->Clip(gfxRect(0, 0, 0, 0));
-        PaintLayer(mTarget, mRoot, aCallback, aCallbackData, nullptr);
-      }
-      // If we're not retained, then don't composite means do nothing at all.
-    } else {
-      PaintLayer(mTarget, mRoot, aCallback, aCallbackData, nullptr);
-      if (mWidget) {
-        FlashWidgetUpdateArea(mTarget);
-      }
-      RenderDebugOverlay();
-      LayerManager::PostPresent();
+    PaintLayer(mTarget, mRoot, aCallback, aCallbackData, nullptr);
+    if (mWidget) {
+      FlashWidgetUpdateArea(mTarget);
     }
+    RenderDebugOverlay();
+    LayerManager::PostPresent();
 
     if (!mTransactionIncomplete) {
       // Clear out target if we have a complete transaction.
       mTarget = nullptr;
     }
   }
 
 #ifdef MOZ_LAYERS_HAVE_LOG
@@ -849,24 +831,16 @@ Transform3D(gfxASurface* aSource, gfxCon
 }
 
 void
 BasicLayerManager::PaintSelfOrChildren(PaintLayerContext& aPaintContext,
                                        gfxContext* aGroupTarget)
 {
   BasicImplData* data = ToData(aPaintContext.mLayer);
 
-  if (aPaintContext.mLayer->GetFirstChild() &&
-      aPaintContext.mLayer->GetMaskLayer() &&
-      HasShadowManager()) {
-    // 'paint' the mask so that it gets sent to the shadow layer tree
-    static_cast<BasicImplData*>(aPaintContext.mLayer->GetMaskLayer()->ImplData())
-      ->Paint(nullptr, nullptr);
-  }
-
   /* Only paint ourself, or our children - This optimization relies on this! */
   Layer* child = aPaintContext.mLayer->GetFirstChild();
   if (!child) {
     if (aPaintContext.mLayer->AsThebesLayer()) {
       data->PaintThebes(aGroupTarget, aPaintContext.mLayer->GetMaskLayer(),
           aPaintContext.mCallback, aPaintContext.mCallbackData,
           aPaintContext.mReadback);
     } else {
@@ -905,17 +879,17 @@ BasicLayerManager::FlushGroup(PaintLayer
   if (!mTransactionIncomplete) {
     if (aNeedsClipToVisibleRegion) {
       gfxUtils::ClipToRegion(aPaintContext.mTarget,
                              aPaintContext.mLayer->GetEffectiveVisibleRegion());
     }
     BasicContainerLayer* container = static_cast<BasicContainerLayer*>(aPaintContext.mLayer);
     AutoSetOperator setOperator(aPaintContext.mTarget, container->GetOperator());
     PaintWithMask(aPaintContext.mTarget, aPaintContext.mLayer->GetEffectiveOpacity(),
-                  HasShadowManager() ? nullptr : aPaintContext.mLayer->GetMaskLayer());
+                  aPaintContext.mLayer->GetMaskLayer());
   }
 }
 
 void
 BasicLayerManager::PaintLayer(gfxContext* aTarget,
                               Layer* aLayer,
                               DrawThebesLayerCallback aCallback,
                               void* aCallbackData,
--- a/gfx/layers/basic/BasicLayers.h
+++ b/gfx/layers/basic/BasicLayers.h
@@ -92,17 +92,17 @@ public:
   virtual bool IsWidgetLayerManager() { return mWidget != nullptr; }
 
   virtual void BeginTransaction();
   virtual void BeginTransactionWithTarget(gfxContext* aTarget);
   virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT);
   virtual void EndTransaction(DrawThebesLayerCallback aCallback,
                               void* aCallbackData,
                               EndTransactionFlags aFlags = END_DEFAULT);
-  virtual bool AreComponentAlphaLayersEnabled() { return HasShadowManager() || !IsWidgetLayerManager(); }
+  virtual bool AreComponentAlphaLayersEnabled() { return !IsWidgetLayerManager(); }
 
   void AbortTransaction();
 
   virtual void SetRoot(Layer* aLayer);
 
   virtual already_AddRefed<ThebesLayer> CreateThebesLayer();
   virtual already_AddRefed<ContainerLayer> CreateContainerLayer();
   virtual already_AddRefed<ImageLayer> CreateImageLayer();
@@ -140,17 +140,16 @@ public:
                                                  bool* aNeedsClipToVisibleRegion);
   already_AddRefed<gfxContext> PushGroupWithCachedSurface(gfxContext *aTarget,
                                                           gfxContentType aContent);
   void PopGroupToSourceWithCachedSurface(gfxContext *aTarget, gfxContext *aPushed);
 
   virtual bool IsCompositingCheap() { return false; }
   virtual int32_t GetMaxTextureSize() const { return INT32_MAX; }
   bool CompositorMightResample() { return mCompositorMightResample; }
-  bool HasShadowTarget() { return !!mShadowTarget; }
 
 protected:
   enum TransactionPhase {
     PHASE_NONE, PHASE_CONSTRUCTION, PHASE_DRAWING, PHASE_FORWARD
   };
   TransactionPhase mPhase;
 
   // This is the main body of the PaintLayer routine which will if it has
@@ -182,26 +181,16 @@ protected:
 
   // Widget whose surface should be used as the basis for ThebesLayer
   // buffers.
   nsIWidget* mWidget;
   // The default context for BeginTransaction.
   nsRefPtr<gfxContext> mDefaultTarget;
   // The context to draw into.
   nsRefPtr<gfxContext> mTarget;
-  // When we're doing a transaction in order to draw to a non-default
-  // target, the layers transaction is only performed in order to send
-  // a PLayerTransaction:Update.  We save the original non-default target to
-  // mShadowTarget, and then perform the transaction using
-  // mDummyTarget as the render target.  After the transaction ends,
-  // we send a message to our remote side to capture the actual pixels
-  // being drawn to the default target, and then copy those pixels
-  // back to mShadowTarget.
-  nsRefPtr<gfxContext> mShadowTarget;
-  nsRefPtr<gfxContext> mDummyTarget;
   // Image factory we use.
   nsRefPtr<ImageFactory> mFactory;
 
   // Cached surface for double buffering
   gfxCachedTempSurface mCachedSurface;
 
   BufferMode mDoubleBuffering;
   bool mUsingDefaultTarget;
--- a/gfx/layers/basic/BasicThebesLayer.cpp
+++ b/gfx/layers/basic/BasicThebesLayer.cpp
@@ -85,35 +85,21 @@ BasicThebesLayer::PaintThebes(gfxContext
                               LayerManager::DrawThebesLayerCallback aCallback,
                               void* aCallbackData,
                               ReadbackProcessor* aReadback)
 {
   PROFILER_LABEL("BasicThebesLayer", "PaintThebes");
   NS_ASSERTION(BasicManager()->InDrawing(),
                "Can only draw in drawing phase");
 
-  if (!mContentClient) {
-    // we pass a null pointer for the Forwarder argument, which means
-    // this will not have a ContentHost on the other side.
-    mContentClient = new ContentClientBasic(nullptr, BasicManager());
-  }
-
   nsTArray<ReadbackProcessor::Update> readbackUpdates;
   if (aReadback && UsedForReadback()) {
     aReadback->GetThebesLayerUpdates(this, &readbackUpdates);
   }
-  //TODO: This is going to copy back pixels that we might end up
-  // drawing over anyway. It would be nice if we could avoid
-  // this duplication.
-  mContentClient->SyncFrontBufferToBackBuffer();
 
-  bool canUseOpaqueSurface = CanUseOpaqueSurface();
-  ContentType contentType =
-    canUseOpaqueSurface ? GFX_CONTENT_COLOR :
-                          GFX_CONTENT_COLOR_ALPHA;
   float opacity = GetEffectiveOpacity();
   gfxContext::GraphicsOperator mixBlendMode = GetEffectiveMixBlendMode();
 
   if (!BasicManager()->IsRetained()) {
     NS_ASSERTION(readbackUpdates.IsEmpty(), "Can't do readback for non-retained layer");
 
     mValidRegion.SetEmpty();
     mContentClient->Clear();
@@ -157,64 +143,16 @@ BasicThebesLayer::PaintThebes(gfxContext
 
       aContext->Restore();
     }
 
     RenderTraceInvalidateEnd(this, "FFFF00");
     return;
   }
 
-  {
-    uint32_t flags = 0;
-#ifndef MOZ_WIDGET_ANDROID
-    if (BasicManager()->CompositorMightResample()) {
-      flags |= ThebesLayerBuffer::PAINT_WILL_RESAMPLE;
-    }
-    if (!(flags & ThebesLayerBuffer::PAINT_WILL_RESAMPLE)) {
-      if (MayResample()) {
-        flags |= ThebesLayerBuffer::PAINT_WILL_RESAMPLE;
-      }
-    }
-#endif
-    if (mDrawAtomically) {
-      flags |= ThebesLayerBuffer::PAINT_NO_ROTATION;
-    }
-    PaintState state =
-      mContentClient->BeginPaintBuffer(this, contentType, flags);
-    mValidRegion.Sub(mValidRegion, state.mRegionToInvalidate);
-
-    if (state.mContext) {
-      // The area that became invalid and is visible needs to be repainted
-      // (this could be the whole visible area if our buffer switched
-      // from RGB to RGBA, because we might need to repaint with
-      // subpixel AA)
-      state.mRegionToInvalidate.And(state.mRegionToInvalidate,
-                                    GetEffectiveVisibleRegion());
-      nsIntRegion extendedDrawRegion = state.mRegionToDraw;
-      SetAntialiasingFlags(this, state.mContext);
-
-      RenderTraceInvalidateStart(this, "FFFF00", state.mRegionToDraw.GetBounds());
-
-      PaintBuffer(state.mContext,
-                  state.mRegionToDraw, extendedDrawRegion, state.mRegionToInvalidate,
-                  state.mDidSelfCopy,
-                  aCallback, aCallbackData);
-      MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PaintThebes", this));
-      Mutated();
-
-      RenderTraceInvalidateEnd(this, "FFFF00");
-    } else {
-      // It's possible that state.mRegionToInvalidate is nonempty here,
-      // if we are shrinking the valid region to nothing. So use mRegionToDraw
-      // instead.
-      NS_WARN_IF_FALSE(state.mRegionToDraw.IsEmpty(),
-                       "No context when we have something to draw, resource exhaustion?");
-    }
-  }
-
   if (BasicManager()->IsTransactionIncomplete())
     return;
 
   gfxRect clipExtents;
   clipExtents = aContext->GetClipExtents();
 
   // Pull out the mask surface and transform here, because the mask
   // is internal to basic layers
@@ -241,16 +179,82 @@ BasicThebesLayer::PaintThebes(gfxContext
       NS_ASSERTION(opacity == 1.0, "Should only read back opaque layers");
       ctx->Translate(gfxPoint(offset.x, offset.y));
       mContentClient->DrawTo(this, ctx, 1.0, maskSurface, maskTransform);
       update.mLayer->GetSink()->EndUpdate(ctx, update.mUpdateRect + offset);
     }
   }
 }
 
+void
+BasicThebesLayer::Validate(LayerManager::DrawThebesLayerCallback aCallback,
+                           void* aCallbackData)
+{
+  if (!mContentClient) {
+    // we pass a null pointer for the Forwarder argument, which means
+    // this will not have a ContentHost on the other side.
+    mContentClient = new ContentClientBasic(nullptr, BasicManager());
+  }
+
+  if (!BasicManager()->IsRetained()) {
+    return;
+  }
+
+  bool canUseOpaqueSurface = CanUseOpaqueSurface();
+  ContentType contentType =
+    canUseOpaqueSurface ? GFX_CONTENT_COLOR :
+                          GFX_CONTENT_COLOR_ALPHA;
+
+  uint32_t flags = 0;
+#ifndef MOZ_WIDGET_ANDROID
+  if (BasicManager()->CompositorMightResample()) {
+    flags |= ThebesLayerBuffer::PAINT_WILL_RESAMPLE;
+  }
+  if (!(flags & ThebesLayerBuffer::PAINT_WILL_RESAMPLE)) {
+    if (MayResample()) {
+      flags |= ThebesLayerBuffer::PAINT_WILL_RESAMPLE;
+    }
+  }
+#endif
+  if (mDrawAtomically) {
+    flags |= ThebesLayerBuffer::PAINT_NO_ROTATION;
+  }
+  PaintState state =
+    mContentClient->BeginPaintBuffer(this, contentType, flags);
+  mValidRegion.Sub(mValidRegion, state.mRegionToInvalidate);
+
+  if (state.mContext) {
+    // The area that became invalid and is visible needs to be repainted
+    // (this could be the whole visible area if our buffer switched
+    // from RGB to RGBA, because we might need to repaint with
+    // subpixel AA)
+    state.mRegionToInvalidate.And(state.mRegionToInvalidate,
+                                  GetEffectiveVisibleRegion());
+    nsIntRegion extendedDrawRegion = state.mRegionToDraw;
+    SetAntialiasingFlags(this, state.mContext);
+
+    RenderTraceInvalidateStart(this, "FFFF00", state.mRegionToDraw.GetBounds());
+
+    PaintBuffer(state.mContext,
+                state.mRegionToDraw, extendedDrawRegion, state.mRegionToInvalidate,
+                state.mDidSelfCopy,
+                aCallback, aCallbackData);
+    MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PaintThebes", this));
+    Mutated();
+
+    RenderTraceInvalidateEnd(this, "FFFF00");
+  } else {
+    // It's possible that state.mRegionToInvalidate is nonempty here,
+    // if we are shrinking the valid region to nothing. So use mRegionToDraw
+    // instead.
+    NS_WARN_IF_FALSE(state.mRegionToDraw.IsEmpty(),
+                     "No context when we have something to draw, resource exhaustion?");
+  }
+}
+
 already_AddRefed<ThebesLayer>
 BasicLayerManager::CreateThebesLayer()
 {
   NS_ASSERTION(InConstruction(), "Only allowed in construction phase");
   nsRefPtr<ThebesLayer> layer = new BasicThebesLayer(this);
   return layer.forget();
 }
 
--- a/gfx/layers/basic/BasicThebesLayer.h
+++ b/gfx/layers/basic/BasicThebesLayer.h
@@ -59,16 +59,19 @@ public:
   }
 
   virtual void PaintThebes(gfxContext* aContext,
                            Layer* aMaskLayer,
                            LayerManager::DrawThebesLayerCallback aCallback,
                            void* aCallbackData,
                            ReadbackProcessor* aReadback);
 
+  virtual void Validate(LayerManager::DrawThebesLayerCallback aCallback,
+                        void* aCallbackData) MOZ_OVERRIDE;
+
   virtual void ClearCachedResources()
   {
     if (mContentClient) {
       mContentClient->Clear();
     }
     mValidRegion.SetEmpty();
   }
   
--- a/gfx/tests/crashtests/crashtests.list
+++ b/gfx/tests/crashtests/crashtests.list
@@ -33,17 +33,17 @@ load 385719-1.html
 load 389326-1.html
 skip load 390476.html # bug 585185
 load 393746-1.xhtml
 load 393749-1.html
 load 393822-1.html
 load 394384-1.html
 load 394246-1.html
 load 394246-2.html
-load 394751.xhtml
+skip-if(Android&&AndroidVersion<15) load 394751.xhtml # bug 922976
 load 395335-1.xhtml
 load 395458-1.html
 load 396321-1.svg
 load 398042-1.xhtml
 load 398042-2.xhtml
 load 402307-1.html
 load 403464-1.html
 load 404112-1.html
--- a/gfx/thebes/gfxContext.cpp
+++ b/gfx/thebes/gfxContext.cpp
@@ -270,35 +270,41 @@ gfxContext::ClosePath()
   if (mCairo) {
     cairo_close_path(mCairo);
   } else {
     EnsurePathBuilder();
     mPathBuilder->Close();
   }
 }
 
-already_AddRefed<gfxPath> gfxContext::CopyPath() const
+already_AddRefed<gfxPath> gfxContext::CopyPath()
+{
+  nsRefPtr<gfxPath> path;
+  if (mCairo) {
+    path = new gfxPath(cairo_copy_path(mCairo));
+  } else {
+    EnsurePath();
+    path = new gfxPath(mPath);
+  }
+  return path.forget();
+}
+
+void gfxContext::SetPath(gfxPath* path)
 {
   if (mCairo) {
-    nsRefPtr<gfxPath> path = new gfxPath(cairo_copy_path(mCairo));
-    return path.forget();
-  } else {
-    // XXX - This is not yet supported for Azure.
-    return nullptr;
-  }
-}
-
-void gfxContext::AppendPath(gfxPath* path)
-{
-  if (mCairo) {
+    cairo_new_path(mCairo);
     if (path->mPath->status == CAIRO_STATUS_SUCCESS && path->mPath->num_data != 0)
         cairo_append_path(mCairo, path->mPath);
   } else {
-    // XXX - This is not yet supported for Azure.
-    return;
+    MOZ_ASSERT(path->mMoz2DPath, "Can't mix cairo and azure paths!");
+    MOZ_ASSERT(path->mMoz2DPath->GetBackendType() == mDT->GetType());
+    mPath = path->mMoz2DPath;
+    mPathBuilder = nullptr;
+    mPathIsRect = false;
+    mTransformChanged = false;
   }
 }
 
 gfxPoint
 gfxContext::CurrentPoint()
 {
   if (mCairo) {
     double x, y;
@@ -1746,29 +1752,16 @@ gfxContext::GetUserStrokeExtent()
     double xmin, ymin, xmax, ymax;
     cairo_stroke_extents(mCairo, &xmin, &ymin, &xmax, &ymax);
     return gfxRect(xmin, ymin, xmax - xmin, ymax - ymin);
   } else {
     return ThebesRect(mPath->GetStrokedBounds(CurrentState().strokeOptions, mTransform));
   }
 }
 
-already_AddRefed<gfxFlattenedPath>
-gfxContext::GetFlattenedPath()
-{
-  if (mCairo) {
-    nsRefPtr<gfxFlattenedPath> path =
-        new gfxFlattenedPath(cairo_copy_path_flat(mCairo));
-    return path.forget();
-  } else {
-    // XXX - Used by SVG, needs fixing.
-    return nullptr;
-  }
-}
-
 bool
 gfxContext::HasError()
 {
   if (mCairo) {
     return cairo_status(mCairo) != CAIRO_STATUS_SUCCESS;
   } else {
     // As far as this is concerned, an Azure context is never in error.
     return false;
--- a/gfx/thebes/gfxContext.h
+++ b/gfx/thebes/gfxContext.h
@@ -126,22 +126,22 @@ public:
      *
      * Filling a path will implicitly close it.
      */
     void ClosePath();
 
     /**
      * Copies the current path and returns the copy.
      */
-    already_AddRefed<gfxPath> CopyPath() const;
+    already_AddRefed<gfxPath> CopyPath();
 
     /**
      * Appends the given path to the current path.
      */
-    void AppendPath(gfxPath* path);
+    void SetPath(gfxPath* path);
 
     /**
      * Moves the pen to a new point without drawing a line.
      */
     void MoveTo(const gfxPoint& pt);
 
     /**
      * Creates a new subpath starting at the current point.
@@ -641,21 +641,16 @@ public:
     /**
      ** Extents - returns user space extent of current path
      **/
     gfxRect GetUserPathExtent();
     gfxRect GetUserFillExtent();
     gfxRect GetUserStrokeExtent();
 
     /**
-     ** Obtaining a "flattened" path - path converted to all line segments
-     **/
-    already_AddRefed<gfxFlattenedPath> GetFlattenedPath();
-
-    /**
      ** Flags
      **/
 
     enum {
         /* If this flag is set, operators other than CLEAR, SOURCE, or
          * OVER will be converted to OVER before being sent to cairo.
          *
          * This is most useful with a printing surface, where
@@ -881,18 +876,17 @@ public:
 
     /**
      * If no path is saved, does nothing. Else replaces the context's path with
      * a copy of the saved one, and clears the saved path.
      */
     void Restore()
     {
         if (mPath) {
-            mContext->NewPath();
-            mContext->AppendPath(mPath);
+            mContext->SetPath(mPath);
             mPath = nullptr;
         }
     }
 
 private:
     gfxContext *mContext;
 
     nsRefPtr<gfxPath> mPath;
--- a/gfx/thebes/gfxPath.cpp
+++ b/gfx/thebes/gfxPath.cpp
@@ -1,33 +1,54 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * 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 "gfxPath.h"
 #include "gfxPoint.h"
+#include "gfxPlatform.h"
+#include "gfxASurface.h"
+#include "mozilla/gfx/2D.h"
 
 #include "cairo.h"
 
-gfxPath::gfxPath(cairo_path_t* aPath) : mPath(aPath)
+using namespace mozilla::gfx;
+
+gfxPath::gfxPath(cairo_path_t* aPath)
+  : mPath(aPath)
+  , mFlattenedPath(nullptr)
+{
+}
+
+gfxPath::gfxPath(Path* aPath)
+  : mPath(nullptr)
+  , mFlattenedPath(nullptr)
+  , mMoz2DPath(aPath)
 {
 }
 
 gfxPath::~gfxPath()
 {
     cairo_path_destroy(mPath);
+    cairo_path_destroy(mFlattenedPath);
 }
 
-gfxFlattenedPath::gfxFlattenedPath(cairo_path_t* aPath) : gfxPath(aPath)
+void
+gfxPath::EnsureFlattenedPath()
 {
-}
+    if (mFlattenedPath) {
+        return;
+    }
 
-gfxFlattenedPath::~gfxFlattenedPath()
-{
+    gfxASurface* surf = gfxPlatform::GetPlatform()->ScreenReferenceSurface();
+    cairo_t* cr = cairo_create(surf->CairoSurface());
+    cairo_append_path(cr, mPath);
+    mFlattenedPath = cairo_copy_path_flat(cr);
+    cairo_destroy(cr);
 }
 
 static gfxFloat
 CalcSubLengthAndAdvance(cairo_path_data_t *aData,
                         gfxPoint &aPathStart, gfxPoint &aCurrent)
 {
     float sublength = 0;
 
@@ -57,43 +78,65 @@ CalcSubLengthAndAdvance(cairo_path_data_
             aCurrent = aPathStart;
             break;
         }
     }
     return sublength;
 }
 
 gfxFloat
-gfxFlattenedPath::GetLength()
+gfxPath::GetLength()
 {
+    if (mMoz2DPath) {
+        return mMoz2DPath->ComputeLength();
+    }
+
+    EnsureFlattenedPath();
+
     gfxPoint start(0, 0);     // start of current subpath
     gfxPoint current(0, 0);   // current point
     gfxFloat length = 0;      // current summed length
 
     for (int32_t i = 0;
-         i < mPath->num_data;
-         i += mPath->data[i].header.length) {
-        length += CalcSubLengthAndAdvance(&mPath->data[i], start, current);
+         i < mFlattenedPath->num_data;
+         i += mFlattenedPath->data[i].header.length) {
+        length += CalcSubLengthAndAdvance(&mFlattenedPath->data[i], start, current);
     }
     return length;
 }
 
 gfxPoint
-gfxFlattenedPath::FindPoint(gfxPoint aOffset, gfxFloat *aAngle)
+gfxPath::FindPoint(gfxPoint aOffset, gfxFloat *aAngle)
 {
+    if (mMoz2DPath) {
+        Point tangent; // Unit vector tangent to the point we find.
+        Point result = mMoz2DPath->ComputePointAtLength(aOffset.x, &tangent);
+
+        // The y value of aOffset is the offset along the normal vector to apply
+        Point normal(-tangent.y, tangent.x);
+        result += normal * aOffset.y;
+
+        if (aAngle)
+            *aAngle = atan2(tangent.y, tangent.x);
+
+        return gfxPoint(result.x, result.y);
+    }
+
+    EnsureFlattenedPath();
+
     gfxPoint start(0, 0);     // start of current subpath
     gfxPoint current(0, 0);   // current point
     gfxFloat length = 0;      // current summed length
 
     for (int32_t i = 0;
-         i < mPath->num_data;
-         i += mPath->data[i].header.length) {
+         i < mFlattenedPath->num_data;
+         i += mFlattenedPath->data[i].header.length) {
         gfxPoint prev = current;
 
-        gfxFloat sublength = CalcSubLengthAndAdvance(&mPath->data[i],
+        gfxFloat sublength = CalcSubLengthAndAdvance(&mFlattenedPath->data[i],
                                                      start, current);
 
         gfxPoint diff = current - prev;
         if (aAngle)
             *aAngle = atan2(diff.y, diff.x);
 
         if (sublength != 0 && length + sublength >= aOffset.x) {
             gfxFloat ratio = (aOffset.x - length) / sublength;
--- a/gfx/thebes/gfxPath.h
+++ b/gfx/thebes/gfxPath.h
@@ -3,62 +3,60 @@
  * 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 GFX_PATH_H
 #define GFX_PATH_H
 
 #include "gfxTypes.h"
 #include "nsISupportsImpl.h"
+#include "mozilla/RefPtr.h"
 
 class gfxContext;
 struct gfxPoint;
 typedef struct cairo_path cairo_path_t;
 
+namespace mozilla {
+namespace gfx {
+class Path;
+}
+}
+
 /**
  * Class representing a path. Can be created by copying the current path
  * of a gfxContext.
  */
 class gfxPath {
     NS_INLINE_DECL_REFCOUNTING(gfxPath)
 
     friend class gfxContext;
 
 protected:
     gfxPath(cairo_path_t* aPath);
+    gfxPath(mozilla::gfx::Path* aPath);
+
+    void EnsureFlattenedPath();
 
 public:
     virtual ~gfxPath();
-
-protected:
-    cairo_path_t* mPath;
-};
-
-/**
- * Specialization of a path that only contains linear pieces. Can be created
- * from the existing path of a gfxContext.
- */
-class gfxFlattenedPath : public gfxPath {
-    friend class gfxContext;
-
-protected:
-    gfxFlattenedPath(cairo_path_t* aPath);
-
-public:
-    virtual ~gfxFlattenedPath();
-
+    
     /**
      * Returns calculated total length of path
      */
     gfxFloat GetLength();
 
     /**
      * Returns a point a certain distance along the path.  Return is
      * first or last point of the path if the requested length offset
      * is outside the range for the path.
      * @param aOffset offset inpath parameter space (x=length, y=normal offset)
      * @param aAngle optional - output tangent
      */
     gfxPoint FindPoint(gfxPoint aOffset,
                        gfxFloat* aAngle = nullptr);
+
+protected:
+    cairo_path_t* mPath;
+    cairo_path_t* mFlattenedPath;
+    mozilla::RefPtr<mozilla::gfx::Path> mMoz2DPath;
 };
 
 #endif
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -236,34 +236,39 @@ LOCAL_INCLUDES += \
   -I$(topsrcdir)/../../intl/icu/source/i18n \
   $(NULL)
 endif
 
 ifdef ENABLE_INTL_API
 ifndef MOZ_NATIVE_ICU
 
 ifeq ($(OS_ARCH),WINNT)
-  # Parallel gmake is buggy on Windows
-  ICU_GMAKE_OPTIONS="-j1"
   # Library names: On Windows, ICU uses modified library names for static
   # and debug libraries.
   ifdef MOZ_DEBUG
     ICU_LIB_SUFFIX=d
   endif
   ICU_LIB_RENAME = $(foreach libname,$(ICU_LIB_NAMES),\
                      cp -p intl/icu/lib/s$(libname)$(ICU_LIB_SUFFIX).lib intl/icu/lib/$(libname).lib;)
 endif
 
+ifdef .PYMAKE
+ICU_MAKE = $(GMAKE)
+else
+ICU_MAKE = $(MAKE)
+endif
+
 # - ICU requires GNU make according to its readme.html. pymake can't be used
 #   because it doesn't support order only dependencies.
 # - Force ICU to use the standard suffix for object files because expandlibs
 #   will discard all files with a non-standard suffix (bug 857450).
 # - Options for genrb: -k strict parsing; -R omit collation tailoring rules.
 buildicu:
-	$(GMAKE) $(ICU_GMAKE_OPTIONS) -C intl/icu STATIC_O=$(OBJ_SUFFIX) GENRBOPTS='-k -R'
+# ICU's build system is full of races, so force non-parallel build.
+	+$(ICU_MAKE) -j1 -C intl/icu STATIC_O=$(OBJ_SUFFIX) GENRBOPTS='-k -R'
 	$(ICU_LIB_RENAME)
 
 distclean clean::
 	$(call SUBMAKE,$@,intl/icu)
 
 endif
 endif
 
--- a/layout/svg/nsSVGGlyphFrame.cpp
+++ b/layout/svg/nsSVGGlyphFrame.cpp
@@ -733,17 +733,17 @@ nsSVGGlyphFrame::GetCharacterPositions(n
   GetEffectiveRotate(strLength, rotateList);
 
   gfxPoint pos = mPosition;
   gfxFloat angle = 0.0;
 
   nsSVGTextPathFrame *textPath = FindTextPathParent();
 
   if (textPath) {
-    nsRefPtr<gfxFlattenedPath> data = textPath->GetFlattenedPath();
+    nsRefPtr<gfxPath> data = textPath->GetPath();
 
     // textPath frame, but invalid target
     if (!data)
       return false;
 
     if (!aCharacterPositions->SetLength(strLength))
       return false;
 
--- a/layout/svg/nsSVGTextFrame2.cpp
+++ b/layout/svg/nsSVGTextFrame2.cpp
@@ -4632,26 +4632,26 @@ nsSVGTextFrame2::GetTextPathPathFrame(ns
                                                  nsSVGEffects::HrefProperty());
     if (!property)
       return nullptr;
   }
 
   return property->GetReferencedFrame(nsGkAtoms::svgPathGeometryFrame, nullptr);
 }
 
-already_AddRefed<gfxFlattenedPath>
-nsSVGTextFrame2::GetFlattenedTextPath(nsIFrame* aTextPathFrame)
+already_AddRefed<gfxPath>
+nsSVGTextFrame2::GetTextPath(nsIFrame* aTextPathFrame)
 {
   nsIFrame *path = GetTextPathPathFrame(aTextPathFrame);
 
   if (path) {
     nsSVGPathGeometryElement *element =
       static_cast<nsSVGPathGeometryElement*>(path->GetContent());
 
-    return element->GetFlattenedPath(element->PrependLocalTransformsTo(gfxMatrix()));
+    return element->GetPath(element->PrependLocalTransformsTo(gfxMatrix()));
   }
   return nullptr;
 }
 
 gfxFloat
 nsSVGTextFrame2::GetOffsetScale(nsIFrame* aTextPathFrame)
 {
   nsIFrame *pathFrame = GetTextPathPathFrame(aTextPathFrame);
@@ -4666,17 +4666,17 @@ gfxFloat
 nsSVGTextFrame2::GetStartOffset(nsIFrame* aTextPathFrame)
 {
   dom::SVGTextPathElement *tp =
     static_cast<dom::SVGTextPathElement*>(aTextPathFrame->GetContent());
   nsSVGLength2 *length =
     &tp->mLengthAttributes[dom::SVGTextPathElement::STARTOFFSET];
 
   if (length->IsPercentage()) {
-    nsRefPtr<gfxFlattenedPath> data = GetFlattenedTextPath(aTextPathFrame);
+    nsRefPtr<gfxPath> data = GetTextPath(aTextPathFrame);
     return data ?
              length->GetAnimValInSpecifiedUnits() * data->GetLength() / 100.0 :
              0.0;
   }
   return length->GetAnimValue(tp) * GetOffsetScale(aTextPathFrame);
 }
 
 void
@@ -4689,17 +4689,17 @@ nsSVGTextFrame2::DoTextPathLayout()
     nsIFrame* textPathFrame = it.TextPathFrame();
     if (!textPathFrame) {
       // Skip past this frame if we're not in a text path.
       it.AdvancePastCurrentFrame();
       continue;
     }
 
     // Get the path itself.
-    nsRefPtr<gfxFlattenedPath> data = GetFlattenedTextPath(textPathFrame);
+    nsRefPtr<gfxPath> data = GetTextPath(textPathFrame);
     if (!data) {
       it.AdvancePastCurrentTextPathFrame();
       continue;
     }
 
     nsIContent* textPath = textPathFrame->GetContent();
 
     gfxFloat offset = GetStartOffset(textPathFrame);
--- a/layout/svg/nsSVGTextFrame2.h
+++ b/layout/svg/nsSVGTextFrame2.h
@@ -13,17 +13,17 @@
 #include "nsStubMutationObserver.h"
 #include "nsSVGGlyphFrame.h" // for SVGTextContextPaint
 #include "nsSVGTextContainerFrame.h"
 
 class nsDisplaySVGText;
 class nsRenderingContext;
 class nsSVGTextFrame2;
 class nsTextFrame;
-class gfxFlattenedPath;
+class gfxPath;
 
 typedef nsSVGDisplayContainerFrame nsSVGTextFrame2Base;
 
 namespace mozilla {
 
 class CharIterator;
 class TextFrameIterator;
 class TextNodeCorrespondenceRecorder;
@@ -512,17 +512,17 @@ private:
    * @param aShouldPaintSVGGlyphs (out) Whether SVG glyphs in the text
    *   should be painted.
    */
   bool ShouldRenderAsPath(nsRenderingContext* aContext, nsTextFrame* aFrame,
                           bool& aShouldPaintSVGGlyphs);
 
   // Methods to get information for a <textPath> frame.
   nsIFrame* GetTextPathPathFrame(nsIFrame* aTextPathFrame);
-  already_AddRefed<gfxFlattenedPath> GetFlattenedTextPath(nsIFrame* aTextPathFrame);
+  already_AddRefed<gfxPath> GetTextPath(nsIFrame* aTextPathFrame);
   gfxFloat GetOffsetScale(nsIFrame* aTextPathFrame);
   gfxFloat GetStartOffset(nsIFrame* aTextPathFrame);
 
   DrawMode SetupCairoState(gfxContext* aContext,
                            nsIFrame* aFrame,
                            gfxTextContextPaint* aOuterContextPaint,
                            gfxTextContextPaint** aThisContextPaint);
 
--- a/layout/svg/nsSVGTextPathFrame.cpp
+++ b/layout/svg/nsSVGTextPathFrame.cpp
@@ -106,38 +106,38 @@ nsSVGTextPathFrame::GetPathFrame()
     if (!property)
       return nullptr;
   }
 
   nsIFrame *frame = property->GetReferencedFrame(nsGkAtoms::svgPathGeometryFrame, nullptr);
   return frame && frame->GetContent()->Tag() == nsGkAtoms::path ? frame : nullptr;
 }
 
-already_AddRefed<gfxFlattenedPath>
-nsSVGTextPathFrame::GetFlattenedPath()
+already_AddRefed<gfxPath>
+nsSVGTextPathFrame::GetPath()
 {
   nsIFrame *path = GetPathFrame();
 
   if (path) {
     nsSVGPathGeometryElement *element =
       static_cast<nsSVGPathGeometryElement*>(path->GetContent());
 
-    return element->GetFlattenedPath(element->PrependLocalTransformsTo(gfxMatrix()));
+    return element->GetPath(element->PrependLocalTransformsTo(gfxMatrix()));
   }
   return nullptr;
 }
  
 gfxFloat
 nsSVGTextPathFrame::GetStartOffset()
 {
   SVGTextPathElement *tp = static_cast<SVGTextPathElement*>(mContent);
   nsSVGLength2 *length = &tp->mLengthAttributes[SVGTextPathElement::STARTOFFSET];
 
   if (length->IsPercentage()) {
-    nsRefPtr<gfxFlattenedPath> data = GetFlattenedPath();
+    nsRefPtr<gfxPath> data = GetPath();
     return data ? (length->GetAnimValInSpecifiedUnits() * data->GetLength() / 100.0) : 0.0;
   }
   return length->GetAnimValue(tp) * GetOffsetScale();
 }
 
 gfxFloat
 nsSVGTextPathFrame::GetOffsetScale()
 {
--- a/layout/svg/nsSVGTextPathFrame.h
+++ b/layout/svg/nsSVGTextPathFrame.h
@@ -10,17 +10,17 @@
 #include "gfxTypes.h"
 #include "nsCOMPtr.h"
 #include "nsFrame.h"
 #include "nsISVGChildFrame.h"
 #include "nsLiteralString.h"
 #include "nsQueryFrame.h"
 #include "nsSVGTSpanFrame.h"
 
-class gfxFlattenedPath;
+class gfxPath;
 class nsIAtom;
 class nsIContent;
 class nsIFrame;
 class nsIPresShell;
 class nsStyleContext;
 
 namespace mozilla {
 class SVGNumberList;
@@ -60,17 +60,17 @@ public:
 #ifdef DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE
   {
     return MakeFrameName(NS_LITERAL_STRING("SVGTextPath"), aResult);
   }
 #endif
 
   // nsSVGTextPathFrame methods:
-  already_AddRefed<gfxFlattenedPath> GetFlattenedPath();
+  already_AddRefed<gfxPath> GetPath();
   nsIFrame *GetPathFrame();
 
   /**
    * Gets the scale by which offsets along this textPath must be scaled. This
    * scaling is due to the user provided 'pathLength' attribute on the <path>
    * element, which is a user provided estimate of the path length.
    */
   gfxFloat GetOffsetScale();
--- a/modules/libjar/zipwriter/src/nsZipHeader.cpp
+++ b/modules/libjar/zipwriter/src/nsZipHeader.cpp
@@ -128,17 +128,17 @@ NS_IMETHODIMP nsZipHeader::GetIsSyntheti
 }
 
 /* readonly attribute unsigned long permissions; */
 NS_IMETHODIMP nsZipHeader::GetPermissions(uint32_t *aPermissions)
 {
     NS_ASSERTION(mInited, "Not initalised");
 
     // Always give user read access at least, this matches nsIZipReader's behaviour
-    *aPermissions = ((mEAttr >> 16) & 0xfff | 0x100);
+    *aPermissions = ((mEAttr >> 16) & 0xfff) | 0x100;
     return NS_OK;
 }
 
 void nsZipHeader::Init(const nsACString & aPath, PRTime aDate, uint32_t aAttr,
                        uint32_t aOffset)
 {
     NS_ASSERTION(!mInited, "Already initalised");
 
--- a/toolkit/mozapps/update/common/pathhash.cpp
+++ b/toolkit/mozapps/update/common/pathhash.cpp
@@ -37,23 +37,23 @@ BinaryDataToHexString(const BYTE *hash, 
 */
 static BOOL
 CalculateMD5(const char *data, DWORD dataSize, 
              BYTE **hash, DWORD &hashSize)
 {
   HCRYPTPROV hProv = 0;
   HCRYPTHASH hHash = 0;
 
-  if (!CryptAcquireContext(&hProv, nullptr, nullptr, PROV_RSA_FULL, 0)) {
+  if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) {
     if (NTE_BAD_KEYSET != GetLastError()) {
       return FALSE;
     }
  
     // Maybe it doesn't exist, try to create it.
-    if (!CryptAcquireContext(&hProv, nullptr, nullptr, PROV_RSA_FULL, 
+    if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 
                             CRYPT_NEWKEYSET)) {
       return FALSE;
     }
   }
 
   if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) {
     return FALSE;
   }
--- a/toolkit/mozapps/update/common/readstrings.cpp
+++ b/toolkit/mozapps/update/common/readstrings.cpp
@@ -57,38 +57,38 @@ NS_strspnp(const char *delims, const cha
 
   return str;
 }
 
 static char*
 NS_strtok(const char *delims, char **str)
 {
   if (!*str)
-    return nullptr;
+    return NULL;
 
   char *ret = (char*) NS_strspnp(delims, *str);
 
   if (!*ret) {
     *str = ret;
-    return nullptr;
+    return NULL;
   }
 
   char *i = ret;
   do {
     for (const char *d = delims; *d != '\0'; ++d) {
       if (*i == *d) {
         *i = '\0';
         *str = ++i;
         return ret;
       }
     }
     ++i;
   } while (*i);
 
-  *str = nullptr;
+  *str = NULL;
   return ret;
 }
 
 /**
  * Find a key in a keyList containing zero-delimited keys ending with "\0\0".
  * Returns a zero-based index of the key in the list, or -1 if the key is not found.
  */
 static int
--- a/toolkit/mozapps/update/common/readstrings.h
+++ b/toolkit/mozapps/update/common/readstrings.h
@@ -2,18 +2,16 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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 READSTRINGS_H__
 #define READSTRINGS_H__
 
-#include "mozilla/NullPtr.h"
-
 #define MAX_TEXT_LEN 600
 
 #ifdef XP_WIN
 # include <windows.h>
   typedef WCHAR NS_tchar;
 #else
   typedef char NS_tchar;
 #endif
@@ -35,11 +33,11 @@ int ReadStrings(const NS_tchar *path, St
 
 /**
  * This function reads in localized strings corresponding to the keys from a given .ini
  */
 int ReadStrings(const NS_tchar *path,
                 const char *keyList,
                 unsigned int numStrings,
                 char results[][MAX_TEXT_LEN],
-                const char *section = nullptr);
+                const char *section = NULL);
 
 #endif  // READSTRINGS_H__
--- a/toolkit/mozapps/update/common/uachelper.cpp
+++ b/toolkit/mozapps/update/common/uachelper.cpp
@@ -75,42 +75,42 @@ UACHelper::IsVistaOrLater()
  * @param  sessionID  The session ID for the token to obtain
  * @return A handle to the token to obtain which will be primary if enough
  *         permissions exist.  Caller should close the handle.
  */
 HANDLE
 UACHelper::OpenUserToken(DWORD sessionID)
 {
   HMODULE module = LoadLibraryW(L"wtsapi32.dll");
-  HANDLE token = nullptr;
+  HANDLE token = NULL;
   LPWTSQueryUserToken wtsQueryUserToken = 
     (LPWTSQueryUserToken)GetProcAddress(module, "WTSQueryUserToken");
   if (wtsQueryUserToken) {
     wtsQueryUserToken(sessionID, &token);
   }
   FreeLibrary(module);
   return token;
 }
 
 /**
  * Opens a linked token for the specified token.
  *
  * @param  token The token to get the linked token from
- * @return A linked token or nullptr if one does not exist.
+ * @return A linked token or NULL if one does not exist.
  *         Caller should close the handle.
  */
 HANDLE
 UACHelper::OpenLinkedToken(HANDLE token)
 {
   // Magic below...
   // UAC creates 2 tokens.  One is the restricted token which we have.
   // the other is the UAC elevated one. Since we are running as a service
   // as the system account we have access to both.
   TOKEN_LINKED_TOKEN tlt;
-  HANDLE hNewLinkedToken = nullptr;
+  HANDLE hNewLinkedToken = NULL;
   DWORD len;
   if (GetTokenInformation(token, (TOKEN_INFORMATION_CLASS)TokenLinkedToken, 
                           &tlt, sizeof(TOKEN_LINKED_TOKEN), &len)) {
     token = tlt.LinkedToken;
     hNewLinkedToken = token;
   }
   return hNewLinkedToken;
 }
@@ -123,50 +123,50 @@ UACHelper::OpenLinkedToken(HANDLE token)
  * @param  priv   The privilege to adjust.
  * @param  enable Whether to enable or disable it
  * @return TRUE if the token was adjusted to the specified value.
  */
 BOOL 
 UACHelper::SetPrivilege(HANDLE token, LPCTSTR priv, BOOL enable)
 {
   LUID luidOfPriv;
-  if (!LookupPrivilegeValue(nullptr, priv, &luidOfPriv)) {
+  if (!LookupPrivilegeValue(NULL, priv, &luidOfPriv)) {
     return FALSE; 
   }
 
   TOKEN_PRIVILEGES tokenPriv;
   tokenPriv.PrivilegeCount = 1;
   tokenPriv.Privileges[0].Luid = luidOfPriv;
   tokenPriv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
 
   SetLastError(ERROR_SUCCESS);
   if (!AdjustTokenPrivileges(token, false, &tokenPriv,
-                             sizeof(tokenPriv), nullptr, nullptr)) {
+                             sizeof(tokenPriv), NULL, NULL)) {
     return FALSE; 
   } 
 
   return GetLastError() == ERROR_SUCCESS;
 }
 
 /**
  * For each privilege that is specified, an attempt will be made to 
  * drop the privilege. 
  * 
  * @param  token         The token to adjust the privilege on. 
- *         Pass nullptr for current token.
+ *         Pass NULL for current token.
  * @param  unneededPrivs An array of unneeded privileges.
  * @param  count         The size of the array
  * @return TRUE if there were no errors
  */
 BOOL
 UACHelper::DisableUnneededPrivileges(HANDLE token, 
                                      LPCTSTR *unneededPrivs, 
                                      size_t count)
 {
-  HANDLE obtainedToken = nullptr;
+  HANDLE obtainedToken = NULL;
   if (!token) {
     // Note: This handle is a pseudo-handle and need not be closed
     HANDLE process = GetCurrentProcess();
     if (!OpenProcessToken(process, TOKEN_ALL_ACCESS_P, &obtainedToken)) {
       LOG_WARN(("Could not obtain token for current process, no "
                 "privileges changed. (%d)", GetLastError()));
       return FALSE;
     }
@@ -193,17 +193,17 @@ UACHelper::DisableUnneededPrivileges(HAN
 
 /**
  * Disables privileges for the specified token.
  * The privileges to disable are in PrivsToDisable.
  * In the future there could be new privs and we are not sure if we should
  * explicitly disable these or not. 
  * 
  * @param  token The token to drop the privilege on.
- *         Pass nullptr for current token.
+ *         Pass NULL for current token.
  * @return TRUE if there were no errors
  */
 BOOL
 UACHelper::DisablePrivileges(HANDLE token)
 {
   static const size_t PrivsToDisableSize = 
     sizeof(UACHelper::PrivsToDisable) / sizeof(UACHelper::PrivsToDisable[0]);
 
--- a/toolkit/mozapps/update/common/updatehelper.cpp
+++ b/toolkit/mozapps/update/common/updatehelper.cpp
@@ -65,18 +65,18 @@ PathGetSiblingFilePath(LPWSTR destinatio
  * It takes in the path of the callback application to calculate the path
  * of helper.exe.  For service updates this is called from both the system
  * account and the current user account.
  *
  * @param  installationDir The path to the callback application binary.
  * @param  updateInfoDir   The directory where update info is stored.
  * @param  forceSync       If true even if the ini file specifies async, the
  *                         process will wait for termination of PostUpdate.
- * @param  userToken       The user token to run as, if nullptr the current
- *                         user will be used.
+ * @param  userToken       The user token to run as, if NULL the current user
+ *                         will be used.
  * @return TRUE if there was no error starting the process.
  */
 BOOL
 LaunchWinPostProcess(const WCHAR *installationDir,
                      const WCHAR *updateInfoDir,
                      bool forceSync,
                      HANDLE userToken)
 {
@@ -90,22 +90,22 @@ LaunchWinPostProcess(const WCHAR *instal
   if (!PathAppendSafe(inifile, L"updater.ini")) {
     return FALSE;
   }
 
   WCHAR exefile[MAX_PATH + 1];
   WCHAR exearg[MAX_PATH + 1];
   WCHAR exeasync[10];
   bool async = true;
-  if (!GetPrivateProfileStringW(L"PostUpdateWin", L"ExeRelPath", nullptr,
-                                exefile, MAX_PATH + 1, inifile)) {
+  if (!GetPrivateProfileStringW(L"PostUpdateWin", L"ExeRelPath", NULL, exefile,
+                                MAX_PATH + 1, inifile)) {
     return FALSE;
   }
 
-  if (!GetPrivateProfileStringW(L"PostUpdateWin", L"ExeArg", nullptr, exearg,
+  if (!GetPrivateProfileStringW(L"PostUpdateWin", L"ExeArg", NULL, exearg,
                                 MAX_PATH + 1, inifile)) {
     return FALSE;
   }
 
   if (!GetPrivateProfileStringW(L"PostUpdateWin", L"ExeAsync", L"TRUE",
                                 exeasync,
                                 sizeof(exeasync)/sizeof(exeasync[0]),
                                 inifile)) {
@@ -156,32 +156,32 @@ LaunchWinPostProcess(const WCHAR *instal
   si.lpDesktop = L"";
   PROCESS_INFORMATION pi = {0};
 
   bool ok;
   if (userToken) {
     ok = CreateProcessAsUserW(userToken,
                               exefullpath,
                               cmdline,
-                              nullptr,  // no special security attributes
-                              nullptr,  // no special thread attributes
-                              false,    // don't inherit filehandles
-                              0,        // No special process creation flags
-                              nullptr,  // inherit my environment
+                              NULL,  // no special security attributes
+                              NULL,  // no special thread attributes
+                              false, // don't inherit filehandles
+                              0,     // No special process creation flags
+                              NULL,  // inherit my environment
                               workingDirectory,
                               &si,
                               &pi);
   } else {
     ok = CreateProcessW(exefullpath,
                         cmdline,
-                        nullptr,  // no special security attributes
-                        nullptr,  // no special thread attributes
-                        false,    // don't inherit filehandles
-                        0,        // No special process creation flags
-                        nullptr,  // inherit my environment
+                        NULL,  // no special security attributes
+                        NULL,  // no special thread attributes
+                        false, // don't inherit filehandles
+                        0,     // No special process creation flags
+                        NULL,  // inherit my environment
                         workingDirectory,
                         &si,
                         &pi);
   }
   free(cmdline);
   if (ok) {
     if (!async)
       WaitForSingleObject(pi.hProcess, INFINITE);
@@ -198,17 +198,17 @@ LaunchWinPostProcess(const WCHAR *instal
  * @param  installDir the installation directory where
  *         maintenanceservice_installer.exe is located.
  * @return TRUE if successful
  */
 BOOL
 StartServiceUpdate(LPCWSTR installDir)
 {
   // Get a handle to the local computer SCM database
-  SC_HANDLE manager = OpenSCManager(nullptr, nullptr,
+  SC_HANDLE manager = OpenSCManager(NULL, NULL,
                                     SC_MANAGER_ALL_ACCESS);
   if (!manager) {
     return FALSE;
   }
 
   // Open the service
   SC_HANDLE svc = OpenServiceW(manager, SVC_NAME,
                                SERVICE_ALL_ACCESS);
@@ -232,19 +232,19 @@ StartServiceUpdate(LPCWSTR installDir)
   wcsncpy(maintserviceInstallerPath, installDir, MAX_PATH);
   PathAppendSafe(maintserviceInstallerPath,
                  L"maintenanceservice_installer.exe");
   WCHAR cmdLine[64] = { '\0' };
   wcsncpy(cmdLine, L"dummyparam.exe /Upgrade",
           sizeof(cmdLine) / sizeof(cmdLine[0]) - 1);
   BOOL svcUpdateProcessStarted = CreateProcessW(maintserviceInstallerPath,
                                                 cmdLine,
-                                                nullptr, nullptr, FALSE,
+                                                NULL, NULL, FALSE,
                                                 0,
-                                                nullptr, installDir, &si, &pi);
+                                                NULL, installDir, &si, &pi);
   if (svcUpdateProcessStarted) {
     CloseHandle(pi.hProcess);
     CloseHandle(pi.hThread);
   }
   return svcUpdateProcessStarted;
 }
 
 #endif
@@ -265,17 +265,17 @@ DWORD
 StartServiceCommand(int argc, LPCWSTR* argv)
 {
   DWORD lastState = WaitForServiceStop(SVC_NAME, 5);
   if (lastState != SERVICE_STOPPED) {
     return 20000 + lastState;
   }
 
   // Get a handle to the SCM database.
-  SC_HANDLE serviceManager = OpenSCManager(nullptr, nullptr,
+  SC_HANDLE serviceManager = OpenSCManager(NULL, NULL,
                                            SC_MANAGER_CONNECT |
                                            SC_MANAGER_ENUMERATE_SERVICE);
   if (!serviceManager)  {
     return 17001;
   }
 
   // Get a handle to the service.
   SC_HANDLE service = OpenServiceW(serviceManager,
@@ -370,24 +370,24 @@ WriteStatusPending(LPCWSTR updateDirPath
   WCHAR updateStatusFilePath[MAX_PATH + 1] = { L'\0' };
   wcsncpy(updateStatusFilePath, updateDirPath, MAX_PATH);
   if (!PathAppendSafe(updateStatusFilePath, L"update.status")) {
     return FALSE;
   }
 
   const char pending[] = "pending";
   HANDLE statusFile = CreateFileW(updateStatusFilePath, GENERIC_WRITE, 0,
-                                  nullptr, CREATE_ALWAYS, 0, nullptr);
+                                  NULL, CREATE_ALWAYS, 0, NULL);
   if (statusFile == INVALID_HANDLE_VALUE) {
     return FALSE;
   }
 
   DWORD wrote;
   BOOL ok = WriteFile(statusFile, pending,
-                      sizeof(pending) - 1, &wrote, nullptr);
+                      sizeof(pending) - 1, &wrote, NULL);
   CloseHandle(statusFile);
   return ok && (wrote == sizeof(pending) - 1);
 }
 
 /**
  * Sets update.status to a specific failure code
  *
  * @param  updateDirPath The path of the update directory
@@ -398,27 +398,27 @@ WriteStatusFailure(LPCWSTR updateDirPath
 {
   WCHAR updateStatusFilePath[MAX_PATH + 1] = { L'\0' };
   wcsncpy(updateStatusFilePath, updateDirPath, MAX_PATH);
   if (!PathAppendSafe(updateStatusFilePath, L"update.status")) {
     return FALSE;
   }
 
   HANDLE statusFile = CreateFileW(updateStatusFilePath, GENERIC_WRITE, 0,
-                                  nullptr, CREATE_ALWAYS, 0, nullptr);
+                                  NULL, CREATE_ALWAYS, 0, NULL);
   if (statusFile == INVALID_HANDLE_VALUE) {
     return FALSE;
   }
   char failure[32];
   sprintf(failure, "failed: %d", errorCode);
 
   DWORD toWrite = strlen(failure);
   DWORD wrote;
   BOOL ok = WriteFile(statusFile, failure,
-                      toWrite, &wrote, nullptr);
+                      toWrite, &wrote, NULL);
   CloseHandle(statusFile);
   return ok && wrote == toWrite;
 }
 
 #endif
 
 /**
  * Waits for a service to enter a stopped state.
@@ -454,17 +454,17 @@ WriteStatusFailure(LPCWSTR updateDirPath
  */
 DWORD
 WaitForServiceStop(LPCWSTR serviceName, DWORD maxWaitSeconds)
 {
   // 0x000000CF is defined above to be not set
   DWORD lastServiceState = 0x000000CF;
 
   // Get a handle to the SCM database.
-  SC_HANDLE serviceManager = OpenSCManager(nullptr, nullptr,
+  SC_HANDLE serviceManager = OpenSCManager(NULL, NULL,
                                            SC_MANAGER_CONNECT |
                                            SC_MANAGER_ENUMERATE_SERVICE);
   if (!serviceManager)  {
     DWORD lastError = GetLastError();
     switch(lastError) {
     case ERROR_ACCESS_DENIED:
       return 0x000000FD;
     case ERROR_DATABASE_DOES_NOT_EXIST:
@@ -669,17 +669,17 @@ IsLocalFile(LPCWSTR file, BOOL &isLocal)
  * @param valueName The name of the value
  * @param retValue  Out parameter which will hold the value
  * @return TRUE on success
 */
 static BOOL
 GetDWORDValue(HKEY key, LPCWSTR valueName, DWORD &retValue)
 {
   DWORD regDWORDValueSize = sizeof(DWORD);
-  LONG retCode = RegQueryValueExW(key, valueName, 0, nullptr,
+  LONG retCode = RegQueryValueExW(key, valueName, 0, NULL,
                                   reinterpret_cast<LPBYTE>(&retValue),
                                   &regDWORDValueSize);
   return ERROR_SUCCESS == retCode;
 }
 
 /**
  * Determines if the the system's elevation type allows
  * unprmopted elevation.  This may not 100% reflect reality since
@@ -731,51 +731,51 @@ IsUnpromptedElevation(BOOL &isUnprompted
 
     HKEY key;
     if (RegOpenKeyExW(HKEY_CLASSES_ROOT, kDefaultMetroBrowserIDPathKey,
                       0, KEY_READ, &key) != ERROR_SUCCESS) {
       return false;
     }
     DWORD len = aCharLength * sizeof(WCHAR);
     memset(aIDBuffer, 0, len);
-    if (RegQueryValueExW(key, L"AppUserModelID", nullptr, nullptr,
+    if (RegQueryValueExW(key, L"AppUserModelID", NULL, NULL,
                          (LPBYTE)aIDBuffer, &len) != ERROR_SUCCESS || !len) {
       RegCloseKey(key);
       return false;
     }
     RegCloseKey(key);
     return true;
   }
 
   HRESULT
   LaunchDefaultMetroBrowser()
   {
-    CoInitialize(nullptr);
+    CoInitialize(NULL);
     HRESULT hr = E_FAIL;
     // The interface that allows us to activate the browser
     IApplicationActivationManager *activateMgr;
-    if (FAILED(hr = CoCreateInstance(CLSID_ApplicationActivationManager,
-                                     nullptr, CLSCTX_LOCAL_SERVER,
+    if (FAILED(hr = CoCreateInstance(CLSID_ApplicationActivationManager, NULL,
+                                     CLSCTX_LOCAL_SERVER,
                                      IID_IApplicationActivationManager,
                                      (void**)&activateMgr))) {
       CoUninitialize();
       return hr;
     }
 
     // Activation is based on the browser's registered app model id
     WCHAR appModelID[256];
     if (!GetDefaultBrowserAppModelID(appModelID, (sizeof(appModelID)/sizeof(WCHAR)))) {
       activateMgr->Release();
       CoUninitialize();
       return hr;
     }
 
     // Hand off focus rights to the out-of-process activation server. Without
     // this the metro interface won't launch.
-    CoAllowSetForegroundWindow(activateMgr, nullptr);
+    CoAllowSetForegroundWindow(activateMgr, NULL);
 
     // Launch default browser in Metro
     DWORD processID;
     hr = activateMgr->ActivateApplication(appModelID, L"", AO_NOERRORUI,
                                           &processID);
     activateMgr->Release();
     CoUninitialize();
     return hr;
--- a/toolkit/mozapps/update/common/updatelogging.cpp
+++ b/toolkit/mozapps/update/common/updatelogging.cpp
@@ -9,17 +9,17 @@
 
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdarg.h>
 
 #include "updatelogging.h"
 
-UpdateLog::UpdateLog() : logFP(nullptr)
+UpdateLog::UpdateLog() : logFP(NULL)
 {
 }
 
 void UpdateLog::Init(NS_tchar* sourcePath,
                      const NS_tchar* fileName,
                      const NS_tchar* alternateFileName,
                      bool append)
 {
@@ -40,17 +40,17 @@ void UpdateLog::Init(NS_tchar* sourcePat
 }
 
 void UpdateLog::Finish()
 {
   if (!logFP)
     return;
 
   fclose(logFP);
-  logFP = nullptr;
+  logFP = NULL;
 }
 
 void UpdateLog::Flush()
 {
   if (!logFP)
     return;
 
   fflush(logFP);
--- a/toolkit/mozapps/update/test/TestAUSHelper.cpp
+++ b/toolkit/mozapps/update/test/TestAUSHelper.cpp
@@ -47,17 +47,16 @@
 # define NS_tstrcmp strcmp
 # define NS_ttoi atoi
 # define NS_tstat stat
 # define NS_tgetcwd getcwd
 # define NS_tfputs fputs
 # define LOG_S "%s"
 #endif
 
-#include "mozilla/NullPtr.h"
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 
 #ifndef MAXPATHLEN
 # ifdef PATH_MAX
@@ -77,17 +76,17 @@ static void
 WriteMsg(const NS_tchar *path, const char *status)
 {
   FILE* outFP = NS_tfopen(path, NS_T("wb"));
   if (!outFP)
     return;
 
   fprintf(outFP, "%s\n", status);
   fclose(outFP);
-  outFP = nullptr;
+  outFP = NULL;
 }
 
 static bool
 CheckMsg(const NS_tchar *path, const char *expected)
 {
   if (NS_taccess(path, F_OK)) {
     return false;
   }
@@ -114,17 +113,17 @@ CheckMsg(const NS_tchar *path, const cha
   rb += c;
   if (c == 0 && r) {
     return false;
   }
   mbuf[ms.st_size] = '\0';
   rb = mbuf;
 
   fclose(inFP);
-  inFP = nullptr;
+  inFP = NULL;
   return strcmp(rb, expected) == 0;
 }
 
 #ifdef XP_WIN
 /**
  * Verifies the trust of the specified file path.
  *
  * @param  filePath  The file path to check.
@@ -138,31 +137,31 @@ VerifyCertificateTrustForFile(LPCWSTR fi
   ZeroMemory(&fileToCheck, sizeof(fileToCheck));
   fileToCheck.cbStruct = sizeof(WINTRUST_FILE_INFO);
   fileToCheck.pcwszFilePath = filePath;
 
   // Setup what to check, we want to check it is signed and trusted.
   WINTRUST_DATA trustData;
   ZeroMemory(&trustData, sizeof(trustData));
   trustData.cbStruct = sizeof(trustData);
-  trustData.pPolicyCallbackData = nullptr;
-  trustData.pSIPClientData = nullptr;
+  trustData.pPolicyCallbackData = NULL;
+  trustData.pSIPClientData = NULL;
   trustData.dwUIChoice = WTD_UI_NONE;
   trustData.fdwRevocationChecks = WTD_REVOKE_NONE; 
   trustData.dwUnionChoice = WTD_CHOICE_FILE;
   trustData.dwStateAction = 0;
-  trustData.hWVTStateData = nullptr;
-  trustData.pwszURLReference = nullptr;
+  trustData.hWVTStateData = NULL;
+  trustData.pwszURLReference = NULL;
   // no UI
   trustData.dwUIContext = 0;
   trustData.pFile = &fileToCheck;
 
   GUID policyGUID = WINTRUST_ACTION_GENERIC_VERIFY_V2;
   // Check if the file is signed by something that is trusted.
-  return WinVerifyTrust(nullptr, &policyGUID, &trustData);
+  return WinVerifyTrust(NULL, &policyGUID, &trustData);
 }
 
 #endif
 
 int NS_main(int argc, NS_tchar **argv)
 {
 
   if (argc < 3) {
@@ -309,31 +308,31 @@ int NS_main(int argc, NS_tchar **argv)
   int i = 0;
 
   if (NS_tchdir(argv[1]) != 0) {
     return 1;
   }
 
   // File in use test helper section
   if (!NS_tstrcmp(argv[4], NS_T("-s"))) {
-    NS_tchar *cwd = NS_tgetcwd(nullptr, 0);
+    NS_tchar *cwd = NS_tgetcwd(NULL, 0);
     NS_tchar inFilePath[MAXPATHLEN];
     NS_tsnprintf(inFilePath, sizeof(inFilePath)/sizeof(inFilePath[0]),
                  NS_T("%s/%s"), cwd, argv[2]);
     NS_tchar outFilePath[MAXPATHLEN];
     NS_tsnprintf(outFilePath, sizeof(outFilePath)/sizeof(outFilePath[0]),
                  NS_T("%s/%s"), cwd, argv[3]);
 
     int seconds = NS_ttoi(argv[5]);
 #ifdef XP_WIN
     HANDLE hFile = INVALID_HANDLE_VALUE;
     if (argc == 7) {
       hFile = CreateFileW(argv[6],
                           DELETE | GENERIC_WRITE, 0,
-                          nullptr, OPEN_EXISTING, 0, nullptr);
+                          NULL, OPEN_EXISTING, 0, NULL);
       if (hFile == INVALID_HANDLE_VALUE) {
         WriteMsg(outFilePath, "error_locking");
         return 1;
       }
     }
 
     WriteMsg(outFilePath, "sleeping");
     while (!CheckMsg(inFilePath, "finish\n") && i++ <= seconds)  {
@@ -359,12 +358,12 @@ int NS_main(int argc, NS_tchar **argv)
                NS_T("%s"), argv[2]);
 
   FILE* logFP = NS_tfopen(logFilePath, NS_T("wb"));
   for (i = 1; i < argc; ++i) {
     fprintf(logFP, LOG_S "\n", argv[i]);
   }
 
   fclose(logFP);
-  logFP = nullptr;
+  logFP = NULL;
 
   return 0;
 } 
--- a/toolkit/mozapps/update/updater/archivereader.cpp
+++ b/toolkit/mozapps/update/updater/archivereader.cpp
@@ -22,18 +22,18 @@
 #if defined(XP_UNIX)
 # include <sys/types.h>
 #elif defined(XP_WIN)
 # include <io.h>
 #endif
 
 static int inbuf_size  = 262144;
 static int outbuf_size = 262144;
-static char *inbuf  = nullptr;
-static char *outbuf = nullptr;
+static char *inbuf  = NULL;
+static char *outbuf = NULL;
 
 #ifdef XP_WIN
 #include "resource.h"
 
 /**
  * Obtains the data of the specified resource name and type.
  *
  * @param  name The name ID of the resource
@@ -41,17 +41,17 @@ static char *outbuf = nullptr;
  * @param  data Out parameter which sets the pointer to a buffer containing
  *                  the needed data.
  * @param  size Out parameter which sets the size of the returned data buffer 
  * @return TRUE on success
 */
 BOOL
 LoadFileInResource(int name, int type, const uint8_t *&data, uint32_t& size)
 {
-  HMODULE handle = GetModuleHandle(nullptr);
+  HMODULE handle = GetModuleHandle(NULL);
   if (!handle) {
     return FALSE;
   }
 
   HRSRC resourceInfoBlockHandle = FindResource(handle, 
                                                MAKEINTRESOURCE(name),
                                                MAKEINTRESOURCE(type));
   if (!resourceInfoBlockHandle) {
@@ -79,17 +79,17 @@ LoadFileInResource(int name, int type, c
  * @param  name      The name ID of the resource
  * @param  type      THe type ID of the resource
  * @return OK on success, CERT_LOAD_ERROR or CERT_VERIFY_ERROR on failure.
 */
 int
 VerifyLoadedCert(MarFile *archive, int name, int type)
 {
   uint32_t size = 0;
-  const uint8_t *data = nullptr;
+  const uint8_t *data = NULL;
   if (!LoadFileInResource(name, type, data, size) || !data || !size) {
     return CERT_LOAD_ERROR;
   }
 
   if (mar_verify_signaturesW(archive, &data, &size, 1)) {
     return CERT_VERIFY_ERROR;
   }
 
@@ -178,17 +178,17 @@ ArchiveReader::VerifyProductInformation(
     strncpy(channelCopy, MARChannelID, sizeof(channelCopy) - 1);
     char *channel = strtok(channelCopy, delimiter);
     rv = MAR_CHANNEL_MISMATCH_ERROR;
     while(channel) {
       if (!strcmp(channel, productInfoBlock.MARChannelID)) {
         rv = OK;
         break;
       }
-      channel = strtok(nullptr, delimiter);
+      channel = strtok(NULL, delimiter);
     }
   }
 
   if (rv == OK) {
     /* Compare both versions to ensure we don't have a downgrade
         -1 if appVersion is older than productInfoBlock.productVersion
         1 if appVersion is newer than productInfoBlock.productVersion
         0 if appVersion is the same as productInfoBlock.productVersion
@@ -248,27 +248,27 @@ ArchiveReader::Open(const NS_tchar *path
   return OK;
 }
 
 void
 ArchiveReader::Close()
 {
   if (mArchive) {
     mar_close(mArchive);
-    mArchive = nullptr;
+    mArchive = NULL;
   }
 
   if (inbuf) {
     free(inbuf);
-    inbuf = nullptr;
+    inbuf = NULL;
   }
 
   if (outbuf) {
     free(outbuf);
-    outbuf = nullptr;
+    outbuf = NULL;
   }
 }
 
 int
 ArchiveReader::ExtractFile(const char *name, const NS_tchar *dest)
 {
   const MarItem *item = mar_find_item(mArchive, name);
   if (!item)
--- a/toolkit/mozapps/update/updater/archivereader.h
+++ b/toolkit/mozapps/update/updater/archivereader.h
@@ -2,31 +2,30 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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 ArchiveReader_h__
 #define ArchiveReader_h__
 
-#include "mozilla/NullPtr.h"
 #include <stdio.h>
 #include "mar.h"
 
 #ifdef XP_WIN
   typedef WCHAR NS_tchar;
 #else
   typedef char NS_tchar;
 #endif
 
 // This class provides an API to extract files from an update archive.
 class ArchiveReader
 {
 public:
-  ArchiveReader() : mArchive(nullptr) {}
+  ArchiveReader() : mArchive(NULL) {}
   ~ArchiveReader() { Close(); }
 
   int Open(const NS_tchar *path);
   int VerifySignature();
   int VerifyProductInformation(const char *MARChannelID, 
                                const char *appVersion);
   void Close();
 
--- a/toolkit/mozapps/update/updater/automounter_gonk.cpp
+++ b/toolkit/mozapps/update/updater/automounter_gonk.cpp
@@ -24,17 +24,17 @@
   __android_log_print(level, LOG_TAG, format, ##__VA_ARGS__)
 
 #define LOGI(format, ...) GONK_LOG(ANDROID_LOG_INFO, format, ##__VA_ARGS__)
 #define LOGE(format, ...) GONK_LOG(ANDROID_LOG_ERROR, format, ##__VA_ARGS__)
 
 const char *kGonkMountsPath = "/proc/mounts";
 const char *kGonkSystemPath = "/system";
 
-GonkAutoMounter::GonkAutoMounter() : mDevice(nullptr), mAccess(Unknown)
+GonkAutoMounter::GonkAutoMounter() : mDevice(NULL), mAccess(Unknown)
 {
   if (!RemountSystem(ReadWrite)) {
     LOGE("Could not remount %s as read-write.", kGonkSystemPath);
   }
 }
 
 GonkAutoMounter::~GonkAutoMounter()
 {
@@ -53,17 +53,17 @@ GonkAutoMounter::Reboot()
   // The android_reboot wrapper provides more safety, doing fancier read-only
   // remounting and attempting to sync() the filesystem first. If this fails
   // our only hope is to force a reboot directly without these protections.
   // For more, see system/core/libcutils/android_reboot.c
   LOGE("Could not remount %s as read-only, forcing a system reboot.",
        kGonkSystemPath);
   LogFlush();
 
-  if (android_reboot(ANDROID_RB_RESTART, 0, nullptr) != 0) {
+  if (android_reboot(ANDROID_RB_RESTART, 0, NULL) != 0) {
     LOGE("Safe system reboot failed, attempting to force");
     LogFlush();
 
     if (reboot(RB_AUTOBOOT) != 0) {
       LOGE("CRITICAL: Failed to force restart");
     }
   }
 }
@@ -115,17 +115,17 @@ GonkAutoMounter::RemountSystem(MountAcce
   return true;
 }
 
 bool
 GonkAutoMounter::UpdateMountStatus()
 {
   FILE *mountsFile = NS_tfopen(kGonkMountsPath, "r");
 
-  if (mountsFile == nullptr) {
+  if (mountsFile == NULL) {
     LOGE("Error opening %s: %s", kGonkMountsPath, strerror(errno));
     return false;
   }
 
   // /proc/mounts returns a 0 size from fstat, so we use the same
   // pre-allocated buffer size that ADB does here
   const int mountsMaxSize = 4096;
   char mountData[mountsMaxSize];
@@ -138,17 +138,17 @@ GonkAutoMounter::UpdateMountStatus()
     return false;
   }
 
   char *token, *tokenContext;
   bool foundSystem = false;
 
   for (token = strtok_r(mountData, "\n", &tokenContext);
        token;
-       token = strtok_r(nullptr, "\n", &tokenContext))
+       token = strtok_r(NULL, "\n", &tokenContext))
   {
     if (ProcessMount(token)) {
       foundSystem = true;
       break;
     }
   }
 
   fclose(mountsFile);
@@ -183,17 +183,17 @@ GonkAutoMounter::ProcessMount(const char
 
   free(mDevice);
   mDevice = strdup(mountDev);
   mAccess = Unknown;
 
   char *option, *optionContext;
   for (option = strtok_r(mountAccess, ",", &optionContext);
        option;
-       option = strtok_r(nullptr, ",", &optionContext))
+       option = strtok_r(NULL, ",", &optionContext))
   {
     if (strcmp("ro", option) == 0) {
       mAccess = ReadOnly;
       break;
     } else if (strcmp("rw", option) == 0) {
       mAccess = ReadWrite;
       break;
     }
@@ -206,17 +206,17 @@ bool
 GonkAutoMounter::MountSystem(unsigned long flags)
 {
   if (!mDevice) {
     LOGE("No device was found for %s", kGonkSystemPath);
     return false;
   }
 
   const char *readOnly = flags & MS_RDONLY ? "read-only" : "read-write";
-  int result = mount(mDevice, kGonkSystemPath, "none", flags, nullptr);
+  int result = mount(mDevice, kGonkSystemPath, "none", flags, NULL);
 
   if (result != 0) {
     LOGE("Error mounting %s as %s: %s", kGonkSystemPath, readOnly,
          strerror(errno));
     return false;
   }
 
   LOGI("Mounted %s partition as %s", kGonkSystemPath, readOnly);
--- a/toolkit/mozapps/update/updater/loaddlls.cpp
+++ b/toolkit/mozapps/update/updater/loaddlls.cpp
@@ -31,17 +31,17 @@ struct AutoLoadSystemDependencies
     // normal search path.
     GetSystemDirectory(systemDirectory, MAX_PATH + 1);
     size_t systemDirLen = wcslen(systemDirectory);
 
     // Make the system directory path terminate with a slash
     if (systemDirectory[systemDirLen - 1] != L'\\' && systemDirLen) {
       systemDirectory[systemDirLen] = L'\\';
       ++systemDirLen;
-      // No need to re-null terminate
+      // No need to re-NULL terminate
     }
 
     // For each known DLL ensure it is loaded from the system32 directory
     for (size_t i = 0; i < sizeof(delayDLLs) / sizeof(delayDLLs[0]); ++i) {
       size_t fileLen = wcslen(delayDLLs[i]);
       wcsncpy(systemDirectory + systemDirLen, delayDLLs[i], 
               MAX_PATH - systemDirLen);
       if (systemDirLen + fileLen <= MAX_PATH) {
--- a/toolkit/mozapps/update/updater/progressui_gtk.cpp
+++ b/toolkit/mozapps/update/updater/progressui_gtk.cpp
@@ -81,37 +81,37 @@ ShowProgressUI()
   if (!sWin)
     return -1;
 
   static GdkPixbuf *pixbuf;
   char icon_path[PATH_MAX];
   snprintf(icon_path, sizeof(icon_path), "%s.png", sProgramPath);
 
   g_signal_connect(G_OBJECT(sWin), "delete_event",
-                   G_CALLBACK(OnDeleteEvent), nullptr);
+                   G_CALLBACK(OnDeleteEvent), NULL);
 
   gtk_window_set_title(GTK_WINDOW(sWin), strings.title);
   gtk_window_set_type_hint(GTK_WINDOW(sWin), GDK_WINDOW_TYPE_HINT_DIALOG);
   gtk_window_set_position(GTK_WINDOW(sWin), GTK_WIN_POS_CENTER_ALWAYS);
   gtk_window_set_resizable(GTK_WINDOW(sWin), FALSE);
   gtk_window_set_decorated(GTK_WINDOW(sWin), TRUE);
   gtk_window_set_deletable(GTK_WINDOW(sWin),FALSE);
-  pixbuf = gdk_pixbuf_new_from_file (icon_path, nullptr);
+  pixbuf = gdk_pixbuf_new_from_file (icon_path, NULL);
   gtk_window_set_icon(GTK_WINDOW(sWin), pixbuf);
   g_object_unref(pixbuf);
 
   GtkWidget *vbox = gtk_vbox_new(TRUE, 6);
   sLabel = gtk_label_new(strings.info);
   gtk_misc_set_alignment(GTK_MISC(sLabel), 0.0f, 0.0f);
   sProgressBar = gtk_progress_bar_new();
 
   gtk_box_pack_start(GTK_BOX(vbox), sLabel, FALSE, FALSE, 0);
   gtk_box_pack_start(GTK_BOX(vbox), sProgressBar, TRUE, TRUE, 0);
 
-  sTimerID = g_timeout_add(TIMER_INTERVAL, UpdateDialog, nullptr);
+  sTimerID = g_timeout_add(TIMER_INTERVAL, UpdateDialog, NULL);
 
   gtk_container_set_border_width(GTK_CONTAINER(sWin), 10);
   gtk_container_add(GTK_CONTAINER(sWin), vbox);
   gtk_widget_show_all(sWin);
 
   gtk_main();
   return 0;
 }
--- a/toolkit/mozapps/update/updater/progressui_win.cpp
+++ b/toolkit/mozapps/update/updater/progressui_win.cpp
@@ -42,17 +42,17 @@
 static float sProgress;  // between 0 and 100
 static BOOL  sQuit = FALSE;
 static BOOL sIndeterminate = FALSE;
 static StringTable sUIStrings;
 
 static BOOL
 GetStringsFile(WCHAR filename[MAX_PATH])
 {
-  if (!GetModuleFileNameW(nullptr, filename, MAX_PATH))
+  if (!GetModuleFileNameW(NULL, filename, MAX_PATH))
     return FALSE;
  
   WCHAR *dot = wcsrchr(filename, '.');
   if (!dot || wcsicmp(dot + 1, L"exe"))
     return FALSE;
 
   wcscpy(dot + 1, L"ini");
   return TRUE;
@@ -110,18 +110,17 @@ InitDialog(HWND hDlg)
                       sizeof(szwTitle)/sizeof(szwTitle[0]));
   MultiByteToWideChar(CP_UTF8, 0, sUIStrings.info, -1, szwInfo,
                       sizeof(szwInfo)/sizeof(szwInfo[0]));
 
   SetWindowTextW(hDlg, szwTitle);
   SetWindowTextW(GetDlgItem(hDlg, IDC_INFO), szwInfo);
 
   // Set dialog icon
-  HICON hIcon = LoadIcon(GetModuleHandle(nullptr),
-                         MAKEINTRESOURCE(IDI_DIALOG));
+  HICON hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_DIALOG));
   if (hIcon)
     SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM) hIcon);
 
   HWND hWndPro = GetDlgItem(hDlg, IDC_PROGRESS);
   SendMessage(hWndPro, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
   if (sIndeterminate) {
     LONG_PTR val = GetWindowLongPtr(hWndPro, GWL_STYLE);
     SetWindowLongPtr(hWndPro, GWL_STYLE, val|PBS_MARQUEE); 
@@ -167,17 +166,17 @@ InitDialog(HWND hDlg)
 
   if (hOldFont)
     SelectObject(hDCInfo, hOldFont);
 
   ReleaseDC(hWndInfo, hDCInfo);
 
   CenterDialog(hDlg);  // make dialog appear in the center of the screen
 
-  SetTimer(hDlg, TIMER_ID, TIMER_INTERVAL, nullptr);
+  SetTimer(hDlg, TIMER_ID, TIMER_INTERVAL, NULL);
 }
 
 // Message handler for update dialog.
 static LRESULT CALLBACK
 DialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
 {
   switch (message)
   {
@@ -250,18 +249,18 @@ ShowProgressUI(bool indeterminate, bool 
   }
 
   INITCOMMONCONTROLSEX icc = {
     sizeof(INITCOMMONCONTROLSEX),
     ICC_PROGRESS_CLASS
   };
   InitCommonControlsEx(&icc);
 
-  DialogBox(GetModuleHandle(nullptr),
-            MAKEINTRESOURCE(IDD_DIALOG), nullptr,
+  DialogBox(GetModuleHandle(NULL),
+            MAKEINTRESOURCE(IDD_DIALOG), NULL,
             (DLGPROC) DialogProc);
 
   return 0;
 }
 
 void
 QuitProgressUI()
 {
--- a/toolkit/mozapps/update/updater/updater.cpp
+++ b/toolkit/mozapps/update/updater/updater.cpp
@@ -156,22 +156,22 @@ crc32(const unsigned char *buf, unsigned
 
 //-----------------------------------------------------------------------------
 
 // A simple stack based container for a FILE struct that closes the
 // file descriptor from its destructor.
 class AutoFile
 {
 public:
-  AutoFile(FILE* file = nullptr)
+  AutoFile(FILE* file = NULL)
     : mFile(file) {
   }
 
   ~AutoFile() {
-    if (mFile != nullptr)
+    if (mFile != NULL)
       fclose(mFile);
   }
 
   AutoFile &operator=(FILE* file) {
     if (mFile != 0)
       fclose(mFile);
     mFile = file;
     return *this;
@@ -210,18 +210,17 @@ class Thread
 public:
   int Run(ThreadFunc func, void *param)
   {
     mThreadFunc = func;
     mThreadParam = param;
 
     unsigned int threadID;
 
-    mThread = (HANDLE) _beginthreadex(nullptr, 0, ThreadMain, this, 0,
-                                      &threadID);
+    mThread = (HANDLE) _beginthreadex(NULL, 0, ThreadMain, this, 0, &threadID);
 
     return mThread ? 0 : -1;
   }
   int Join()
   {
     WaitForSingleObject(mThread, INFINITE);
     CloseHandle(mThread);
     return 0;
@@ -241,17 +240,17 @@ private:
 #elif defined(XP_UNIX)
 #include <pthread.h>
 
 class Thread
 {
 public:
   int Run(ThreadFunc func, void *param)
   {
-    return pthread_create(&thr, nullptr, (void* (*)(void *)) func, param);
+    return pthread_create(&thr, NULL, (void* (*)(void *)) func, param);
   }
   int Join()
   {
     void *result;
     return pthread_join(thr, &result);
   }
 private:
   pthread_t thr;
@@ -262,17 +261,17 @@ private:
 class Thread
 {
 public:
   int Run(ThreadFunc func, void *param)
   {
     mThreadFunc = func;
     mThreadParam = param;
 
-    mThread = _beginthread(ThreadMain, nullptr, 16384, (void *)this);
+    mThread = _beginthread(ThreadMain, NULL, 16384, (void *)this);
 
     return mThread ? 0 : -1;
   }
   int Join()
   {
     int status;
     waitpid(mThread, &status, 0);
     return 0;
@@ -319,145 +318,145 @@ mmin(size_t a, size_t b)
 {
   return (a > b) ? b : a;
 }
 
 static NS_tchar*
 mstrtok(const NS_tchar *delims, NS_tchar **str)
 {
   if (!*str || !**str)
-    return nullptr;
+    return NULL;
 
   // skip leading "whitespace"
   NS_tchar *ret = *str;
   const NS_tchar *d;
   do {
     for (d = delims; *d != NS_T('\0'); ++d) {
       if (*ret == *d) {
         ++ret;
         break;
       }
     }
   } while (*d);
 
   if (!*ret) {
     *str = ret;
-    return nullptr;
+    return NULL;
   }
 
   NS_tchar *i = ret;
   do {
     for (d = delims; *d != NS_T('\0'); ++d) {
       if (*i == *d) {
         *i = NS_T('\0');
         *str = ++i;
         return ret;
       }
     }
     ++i;
   } while (*i);
 
-  *str = nullptr;
+  *str = NULL;
   return ret;
 }
 
 #ifdef XP_WIN
 /**
  * Coverts a relative update path to a full path for Windows.
  *
  * @param  relpath
  *         The relative path to convert to a full path.
- * @return valid filesystem full path or nullptr if memory allocation fails.
+ * @return valid filesystem full path or NULL memory allocation fails.
  */
 static NS_tchar*
 get_full_path(const NS_tchar *relpath)
 {
   size_t lendestpath = NS_tstrlen(gDestPath);
   size_t lenrelpath = NS_tstrlen(relpath);
   NS_tchar *s = (NS_tchar *) malloc((lendestpath + lenrelpath + 1) * sizeof(NS_tchar));
   if (!s)
-    return nullptr;
+    return NULL;
 
   NS_tchar *c = s;
 
   NS_tstrcpy(c, gDestPath);
   c += lendestpath;
   NS_tstrcat(c, relpath);
   c += lenrelpath;
   *c = NS_T('\0');
   c++;
   return s;
 }
 #endif
 
 /**
  * Gets the platform specific path and performs simple checks to the path. If
- * the path checks don't pass nullptr will be returned.
+ * the path checks don't pass NULL will be returned.
  *
  * @param  line
  *         The line from the manifest that contains the path.
  * @param  isdir
  *         Whether the path is a directory path. Defaults to false.
- * @return valid filesystem path or nullptr if the path checks fail.
+ * @return valid filesystem path or NULL if the path checks fail.
  */
 static NS_tchar*
 get_valid_path(NS_tchar **line, bool isdir = false)
 {
   NS_tchar *path = mstrtok(kQuote, line);
   if (!path) {
     LOG(("get_valid_path: unable to determine path: " LOG_S, line));
-    return nullptr;
+    return NULL;
   }
 
   // All paths must be relative from the current working directory
   if (path[0] == NS_T('/')) {
     LOG(("get_valid_path: path must be relative: " LOG_S, path));
-    return nullptr;
+    return NULL;
   }
 
 #ifdef XP_WIN
   // All paths must be relative from the current working directory
   if (path[0] == NS_T('\\') || path[1] == NS_T(':')) {
     LOG(("get_valid_path: path must be relative: " LOG_S, path));
-    return nullptr;
+    return NULL;
   }
 #endif
 
   if (isdir) {
     // Directory paths must have a trailing forward slash.
     if (path[NS_tstrlen(path) - 1] != NS_T('/')) {
       LOG(("get_valid_path: directory paths must have a trailing forward " \
            "slash: " LOG_S, path));
-      return nullptr;
+      return NULL;
     }
 
     // Remove the trailing forward slash because stat on Windows will return
     // ENOENT if the path has a trailing slash.
     path[NS_tstrlen(path) - 1] = NS_T('\0');
   }
 
   // Don't allow relative paths that resolve to a parent directory.
-  if (NS_tstrstr(path, NS_T("..")) != nullptr) {
+  if (NS_tstrstr(path, NS_T("..")) != NULL) {
     LOG(("get_valid_path: paths must not contain '..': " LOG_S, path));
-    return nullptr;
+    return NULL;
   }
 
   return path;
 }
 
 static NS_tchar*
 get_quoted_path(const NS_tchar *path)
 {
   size_t lenQuote = NS_tstrlen(kQuote);
   size_t lenPath = NS_tstrlen(path);
   size_t len = lenQuote + lenPath + lenQuote + 1;
 
   NS_tchar *s = (NS_tchar *) malloc(len * sizeof(NS_tchar));
   if (!s)
-    return nullptr;
+    return NULL;
 
   NS_tchar *c = s;
   NS_tstrcpy(c, kQuote);
   c += lenQuote;
   NS_tstrcat(c, path);
   c += lenPath;
   NS_tstrcat(c, kQuote);
   c += lenQuote;
@@ -565,27 +564,27 @@ static FILE* ensure_open(const NS_tchar 
   ensure_write_permissions(path);
   FILE* f = NS_tfopen(path, flags);
   if (is_read_only(flags)) {
     // Don't attempt to modify the file permissions if the file is being opened
     // in read-only mode.
     return f;
   }
   if (NS_tchmod(path, options) != 0) {
-    if (f != nullptr) {
+    if (f != NULL) {
       fclose(f);
     }
-    return nullptr;
+    return NULL;
   }
   struct stat ss;
   if (NS_tstat(path, &ss) != 0 || ss.st_mode != options) {
-    if (f != nullptr) {
+    if (f != NULL) {
       fclose(f);
     }
-    return nullptr;
+    return NULL;
   }
   return f;
 }
 
 // Ensure that the directory containing this file exists.
 static int ensure_parent_dir(const NS_tchar *path)
 {
   int rv = OK;
@@ -915,17 +914,17 @@ static int backup_discard(const NS_tchar
            backup, path));
       return WRITE_ERROR;
     }
     // The MoveFileEx call to remove the file on OS reboot will fail if the
     // process doesn't have write access to the HKEY_LOCAL_MACHINE registry key
     // but this is ok since the installer / uninstaller will delete the
     // directory containing the file along with its contents after an update is
     // applied, on reinstall, and on uninstall.
-    if (MoveFileEx(path, nullptr, MOVEFILE_DELAY_UNTIL_REBOOT)) {
+    if (MoveFileEx(path, NULL, MOVEFILE_DELAY_UNTIL_REBOOT)) {
       LOG(("backup_discard: file renamed and will be removed on OS " \
            "reboot: " LOG_S, path));
     } else {
       LOG(("backup_discard: failed to schedule OS reboot removal of " \
            "file: " LOG_S, path));
     }
   }
 #else
@@ -947,17 +946,17 @@ static void backup_finish(const NS_tchar
 
 //-----------------------------------------------------------------------------
 
 static int DoUpdate();
 
 class Action
 {
 public:
-  Action() : mProgressCost(1), mNext(nullptr) { }
+  Action() : mProgressCost(1), mNext(NULL) { }
   virtual ~Action() { }
 
   virtual int Parse(NS_tchar *line) = 0;
 
   // Do any preprocessing to ensure that the action can be performed.  Execute
   // will be called if this Action and all others return OK from this method.
   virtual int Prepare() = 0;
 
@@ -975,17 +974,17 @@ private:
   Action* mNext;
 
   friend class ActionList;
 };
 
 class RemoveFile : public Action
 {
 public:
-  RemoveFile() : mFile(nullptr), mSkip(0) { }
+  RemoveFile() : mFile(NULL), mSkip(0) { }
 
   int Parse(NS_tchar *line);
   int Prepare();
   int Execute();
   void Finish(int status);
 
 private:
   const NS_tchar *mFile;
@@ -1084,17 +1083,17 @@ RemoveFile::Finish(int status)
   LOG(("FINISH REMOVEFILE " LOG_S, mFile));
 
   backup_finish(mFile, status);
 }
 
 class RemoveDir : public Action
 {
 public:
-  RemoveDir() : mDir(nullptr), mSkip(0) { }
+  RemoveDir() : mDir(NULL), mSkip(0) { }
 
   virtual int Parse(NS_tchar *line);
   virtual int Prepare(); // check that the source dir exists
   virtual int Execute();
   virtual void Finish(int status);
 
 private:
   const NS_tchar *mDir;
@@ -1191,17 +1190,17 @@ RemoveDir::Finish(int status)
            mDir, rv, errno));
     }
   }
 }
 
 class AddFile : public Action
 {
 public:
-  AddFile() : mFile(nullptr)
+  AddFile() : mFile(NULL)
             , mAdded(false)
             { }
 
   virtual int Parse(NS_tchar *line);
   virtual int Prepare();
   virtual int Execute();
   virtual void Finish(int status);
 
@@ -1247,17 +1246,17 @@ AddFile::Execute()
     rv = ensure_parent_dir(mFile);
     if (rv)
       return rv;
   }
 
 #ifdef XP_WIN
   char sourcefile[MAXPATHLEN];
   if (!WideCharToMultiByte(CP_UTF8, 0, mFile, -1, sourcefile, MAXPATHLEN,
-                           nullptr, nullptr)) {
+                           NULL, NULL)) {
     LOG(("error converting wchar to utf8: %d", GetLastError()));
     return STRING_CONVERSION_ERROR;
   }
 
   rv = gArchiveReader.ExtractFile(sourcefile, mFile);
 #else
   rv = gArchiveReader.ExtractFile(mFile, mFile);
 #endif
@@ -1276,17 +1275,17 @@ AddFile::Finish(int status)
   if (status && mAdded)
     NS_tremove(mFile);
   backup_finish(mFile, status);
 }
 
 class PatchFile : public Action
 {
 public:
-  PatchFile() : mPatchIndex(-1), buf(nullptr) { }
+  PatchFile() : mPatchIndex(-1), buf(NULL) { }
 
   virtual ~PatchFile();
 
   virtual int Parse(NS_tchar *line);
   virtual int Prepare(); // should check for patch file and for checksum here
   virtual int Execute();
   virtual void Finish(int status);
 
@@ -1401,17 +1400,17 @@ PatchFile::Prepare()
 
   FILE *fp = NS_tfopen(spath, NS_T("wb"));
   if (!fp)
     return WRITE_ERROR;
 
 #ifdef XP_WIN
   char sourcefile[MAXPATHLEN];
   if (!WideCharToMultiByte(CP_UTF8, 0, mPatchFile, -1, sourcefile, MAXPATHLEN,
-                           nullptr, nullptr)) {
+                           NULL, NULL)) {
     LOG(("error converting wchar to utf8: %d", GetLastError()));
     return STRING_CONVERSION_ERROR;
   }
 
   int rv = gArchiveReader.ExtractFileToStream(sourcefile, fp);
 #else
   int rv = gArchiveReader.ExtractFileToStream(mPatchFile, fp);
 #endif
@@ -1420,24 +1419,24 @@ PatchFile::Prepare()
 }
 
 int
 PatchFile::Execute()
 {
   LOG(("EXECUTE PATCH " LOG_S, mFile));
 
   AutoFile pfile = NS_tfopen(spath, NS_T("rb"));
-  if (pfile == nullptr)
+  if (pfile == NULL)
     return READ_ERROR;
 
   int rv = MBS_ReadHeader(pfile, &header);
   if (rv)
     return rv;
 
-  FILE *origfile = nullptr;
+  FILE *origfile = NULL;
 #ifdef XP_WIN
   if (NS_tstrcmp(mFile, gCallbackRelPath) == 0) {
     // Read from the copy of the callback when patching since the callback can't
     // be opened for reading to prevent the application from being launched.
     origfile = NS_tfopen(gCallbackBackupPath, NS_T("rb"));
   } else {
     origfile = NS_tfopen(mFile, NS_T("rb"));
   }
@@ -1482,24 +1481,23 @@ PatchFile::Execute()
   // have been tested are:
   // 1. _chsize / _chsize_s reduced fragmentation but though not completely.
   // 2. _get_osfhandle and then setting the size reduced fragmentation though
   //    not completely. There are also reports of _get_osfhandle failing on
   //    mingw.
   HANDLE hfile = CreateFileW(mFile,
                              GENERIC_WRITE,
                              0,
-                             nullptr,
+                             NULL,
                              CREATE_ALWAYS,
                              FILE_ATTRIBUTE_NORMAL,
-                             nullptr);
+                             NULL);
 
   if (hfile != INVALID_HANDLE_VALUE) {
-    if (SetFilePointer(hfile, header.dlen,
-                       nullptr, FILE_BEGIN) != INVALID_SET_FILE_POINTER &&
+    if (SetFilePointer(hfile, header.dlen, NULL, FILE_BEGIN) != INVALID_SET_FILE_POINTER &&
         SetEndOfFile(hfile) != 0) {
       shouldTruncate = false;
     }
     CloseHandle(hfile);
   }
 
   AutoFile ofile = ensure_open(mFile, shouldTruncate ? NS_T("wb+") : NS_T("rb+"), ss.st_mode);
 #elif defined(XP_MACOSX)
@@ -1516,53 +1514,53 @@ PatchFile::Execute()
 
   if (rv != -1) {
     ftruncate(fileno((FILE *)ofile), header.dlen);
   }
 #else
   AutoFile ofile = ensure_open(mFile, NS_T("wb+"), ss.st_mode);
 #endif
 
-  if (ofile == nullptr) {
+  if (ofile == NULL) {
     LOG(("unable to create new file: " LOG_S ", err: %d", mFile, errno));
     return WRITE_ERROR;
   }
 
 #ifdef XP_WIN
   if (!shouldTruncate) {
     fseek(ofile, 0, SEEK_SET);
   }
 #endif
 
   rv = MBS_ApplyPatch(&header, pfile, buf, ofile);
 
   // Go ahead and do a bit of cleanup now to minimize runtime overhead.
-  // Set pfile to nullptr to make AutoFile close the file so it can be deleted
-  // on Windows.
-  pfile = nullptr;
+  // Set pfile to NULL to make AutoFile close the file so it can be deleted on
+  // Windows.
+  pfile = NULL;
   NS_tremove(spath);
   spath[0] = NS_T('\0');
   free(buf);
-  buf = nullptr;
+  buf = NULL;
 
   return rv;
 }
 
 void
 PatchFile::Finish(int status)
 {
   LOG(("FINISH PATCH " LOG_S, mFile));
 
   backup_finish(mFile, status);
 }
 
 class AddIfFile : public AddFile
 {
 public:
-  AddIfFile() : mTestFile(nullptr) { }
+  AddIfFile() : mTestFile(NULL) { }
 
   virtual int Parse(NS_tchar *line);
   virtual int Prepare();
   virtual int Execute();
   virtual void Finish(int status);
 
 protected:
   const NS_tchar *mTestFile;
@@ -1585,17 +1583,17 @@ AddIfFile::Parse(NS_tchar *line)
   return AddFile::Parse(line);
 }
 
 int
 AddIfFile::Prepare()
 {
   // If the test file does not exist, then skip this action.
   if (NS_taccess(mTestFile, F_OK)) {
-    mTestFile = nullptr;
+    mTestFile = NULL;
     return OK;
   }
 
   return AddFile::Prepare();
 }
 
 int
 AddIfFile::Execute()
@@ -1613,17 +1611,17 @@ AddIfFile::Finish(int status)
     return;
 
   AddFile::Finish(status);
 }
 
 class PatchIfFile : public PatchFile
 {
 public:
-  PatchIfFile() : mTestFile(nullptr) { }
+  PatchIfFile() : mTestFile(NULL) { }
 
   virtual int Parse(NS_tchar *line);
   virtual int Prepare(); // should check for patch file and for checksum here
   virtual int Execute();
   virtual void Finish(int status);
 
 private:
   const NS_tchar *mTestFile;
@@ -1646,17 +1644,17 @@ PatchIfFile::Parse(NS_tchar *line)
   return PatchFile::Parse(line);
 }
 
 int
 PatchIfFile::Prepare()
 {
   // If the test file does not exist, then skip this action.
   if (NS_taccess(mTestFile, F_OK)) {
-    mTestFile = nullptr;
+    mTestFile = NULL;
     return OK;
   }
 
   return PatchFile::Prepare();
 }
 
 int
 PatchIfFile::Execute()
@@ -1729,17 +1727,17 @@ LaunchCallbackApp(const NS_tchar *workin
 #if defined(MOZ_METRO)
     // If our callback application is the default metro browser, then
     // launch it now.
     if (IsUpdateFromMetro(argc, argv)) {
       LaunchDefaultMetroBrowser();
       return;
     }
 #endif
-    WinLaunchChild(argv[0], argc, argv, nullptr);
+    WinLaunchChild(argv[0], argc, argv, NULL);
   }
 #else
 # warning "Need implementaton of LaunchCallbackApp"
 #endif
 }
 
 static bool
 WriteStatusFile(const char* aStatus)
@@ -1748,17 +1746,17 @@ WriteStatusFile(const char* aStatus)
   NS_tsnprintf(filename, sizeof(filename)/sizeof(filename[0]),
                NS_T("%s/update.status"), gSourcePath);
 
   // Make sure that the directory for the update status file exists
   if (ensure_parent_dir(filename))
     return false;
 
   AutoFile file = NS_tfopen(filename, NS_T("wb+"));
-  if (file == nullptr)
+  if (file == NULL)
     return false;
 
   if (fwrite(aStatus, strlen(aStatus), 1, file) != 1)
     return false;
 
   return true;
 }
 
@@ -1795,17 +1793,17 @@ WriteStatusFile(int status)
 static bool
 IsUpdateStatusPendingService()
 {
   NS_tchar filename[MAXPATHLEN];
   NS_tsnprintf(filename, sizeof(filename)/sizeof(filename[0]),
                NS_T("%s/update.status"), gSourcePath);
 
   AutoFile file = NS_tfopen(filename, NS_T("rb"));
-  if (file == nullptr)
+  if (file == NULL)
     return false;
 
   char buf[32] = { 0 };
   fread(buf, sizeof(buf), 1, file);
 
   const char kPendingService[] = "pending-service";
   const char kAppliedService[] = "applied-service";
 
@@ -1829,17 +1827,17 @@ static bool
 IsUpdateStatusSucceeded(bool &isSucceeded)
 {
   isSucceeded = false;
   NS_tchar filename[MAXPATHLEN];
   NS_tsnprintf(filename, sizeof(filename)/sizeof(filename[0]),
                NS_T("%s/update.status"), gSourcePath);
 
   AutoFile file = NS_tfopen(filename, NS_T("rb"));
-  if (file == nullptr)
+  if (file == NULL)
     return false;
 
   char buf[32] = { 0 };
   fread(buf, sizeof(buf), 1, file);
 
   const char kSucceeded[] = "succeeded";
   isSucceeded = strncmp(buf, kSucceeded, 
                         sizeof(kSucceeded) - 1) == 0;
@@ -2008,17 +2006,17 @@ ProcessReplaceRequest()
     return rv;
   }
 
   LOG(("Now, remove the tmpDir"));
   rv = ensure_remove_recursive(tmpDir);
   if (rv) {
     LOG(("Removing tmpDir failed, err: %d", rv));
 #ifdef XP_WIN
-    if (MoveFileExW(tmpDir, nullptr, MOVEFILE_DELAY_UNTIL_REBOOT)) {
+    if (MoveFileExW(tmpDir, NULL, MOVEFILE_DELAY_UNTIL_REBOOT)) {
       LOG(("tmpDir will be removed on OS reboot: " LOG_S, tmpDir));
     } else {
       LOG(("Failed to schedule OS reboot removal of directory: " LOG_S,
            tmpDir));
     }
 #endif
   }
 
@@ -2141,17 +2139,17 @@ GetUpdateFileName(NS_tchar *fileName, in
 {
 #if defined(MOZ_WIDGET_GONK)  // If an update.link file exists, then it will contain the name
   // of the update file (terminated by a newline).
 
   NS_tchar linkFileName[MAXPATHLEN];
   NS_tsnprintf(linkFileName, sizeof(linkFileName)/sizeof(linkFileName[0]),
                NS_T("%s/update.link"), gSourcePath);
   AutoFile linkFile = NS_tfopen(linkFileName, NS_T("rb"));
-  if (linkFile == nullptr) {
+  if (linkFile == NULL) {
     NS_tsnprintf(fileName, maxChars,
                  NS_T("%s/update.mar"), gSourcePath);
     return OK;
   }
 
   char dataFileName[MAXPATHLEN];
   size_t bytesRead;
 
@@ -2272,19 +2270,19 @@ UpdateThreadFunc(void *param)
       LOG(("failed: %d", rv));
     }
     else {
 #ifdef XP_MACOSX
       // If the update was successful we need to update the timestamp
       // on the top-level Mac OS X bundle directory so that Mac OS X's
       // Launch Services picks up any major changes. Here we assume that
       // the current working directory is the top-level bundle directory.
-      char* cwd = getcwd(nullptr, 0);
+      char* cwd = getcwd(NULL, 0);
       if (cwd) {
-        if (utimes(cwd, nullptr) != 0) {
+        if (utimes(cwd, NULL) != 0) {
           LOG(("Couldn't set access/modification time on application bundle."));
         }
         free(cwd);
       }
       else {
         LOG(("Couldn't get current working directory for setting "
              "access/modification time on application bundle."));
       }
@@ -2348,40 +2346,40 @@ int NS_main(int argc, NS_tchar **argv)
   NS_tchar *slash = NS_tstrrchr(gDestinationPath, NS_SLASH);
   if (slash && !slash[1]) {
     *slash = NS_T('\0');
   }
 
 #ifdef XP_WIN
   bool useService = false;
   bool testOnlyFallbackKeyExists = false;
-  bool noServiceFallback = getenv("MOZ_NO_SERVICE_FALLBACK") != nullptr;
+  bool noServiceFallback = getenv("MOZ_NO_SERVICE_FALLBACK") != NULL;
   putenv(const_cast<char*>("MOZ_NO_SERVICE_FALLBACK="));
 
   // We never want the service to be used unless we build with
   // the maintenance service.
 #ifdef MOZ_MAINTENANCE_SERVICE
   useService = IsUpdateStatusPendingService();
   // Our tests run with a different apply directory for each test.
   // We use this registry key on our test slaves to store the 
   // allowed name/issuers.
   testOnlyFallbackKeyExists = DoesFallbackKeyExist();
 #endif
 
   // Remove everything except close window from the context menu
   {
     HKEY hkApp;
     RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\Classes\\Applications",
-                    0, nullptr, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, nullptr,
-                    &hkApp, nullptr);
+                    0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL,
+                    &hkApp, NULL);
     RegCloseKey(hkApp);
     if (RegCreateKeyExW(HKEY_CURRENT_USER,
                         L"Software\\Classes\\Applications\\updater.exe",
-                        0, nullptr, REG_OPTION_VOLATILE, KEY_SET_VALUE, nullptr,
-                        &hkApp, nullptr) == ERROR_SUCCESS) {
+                        0, NULL, REG_OPTION_VOLATILE, KEY_SET_VALUE, NULL,
+                        &hkApp, NULL) == ERROR_SUCCESS) {
       RegSetValueExW(hkApp, L"IsHostApp", 0, REG_NONE, 0, 0);
       RegSetValueExW(hkApp, L"NoOpenWith", 0, REG_NONE, 0, 0);
       RegSetValueExW(hkApp, L"NoStartPage", 0, REG_NONE, 0, 0);
       RegCloseKey(hkApp);
     }
   }
 #endif
 
@@ -2478,17 +2476,17 @@ int NS_main(int argc, NS_tchar **argv)
       }
     }
   }
 #endif
 
 #ifdef XP_WIN
   if (pid > 0) {
     HANDLE parent = OpenProcess(SYNCHRONIZE, false, (DWORD) pid);
-    // May return nullptr if the parent process has already gone away.
+    // May return NULL if the parent process has already gone away.
     // Otherwise, wait for the parent process to exit before starting the
     // update.
     if (parent) {
       bool updateFromMetro = false;
 #ifdef MOZ_METRO
       updateFromMetro = IsUpdateFromMetro(argc, argv);
 #endif
       DWORD waitTime = updateFromMetro ?
@@ -2496,17 +2494,17 @@ int NS_main(int argc, NS_tchar **argv)
       DWORD result = WaitForSingleObject(parent, waitTime);
       CloseHandle(parent);
       if (result != WAIT_OBJECT_0 && !updateFromMetro)
         return 1;
     }
   }
 #else
   if (pid > 0)
-    waitpid(pid, nullptr, 0);
+    waitpid(pid, NULL, 0);
 #endif
 
   if (sReplaceRequest) {
 #ifdef XP_WIN
     // On Windows, the current working directory of the process should be changed
     // so that it's not locked.
     NS_tchar tmpDir[MAXPATHLEN];
     if (GetTempPathW(MAXPATHLEN, tmpDir)) {
@@ -2516,17 +2514,17 @@ int NS_main(int argc, NS_tchar **argv)
   }
 
   // The callback is the remaining arguments starting at callbackIndex.
   // The argument specified by callbackIndex is the callback executable and the
   // argument prior to callbackIndex is the working directory.
   const int callbackIndex = 5;
 
 #if defined(XP_WIN)
-  sUsingService = getenv("MOZ_USING_SERVICE") != nullptr;
+  sUsingService = getenv("MOZ_USING_SERVICE") != NULL;
   putenv(const_cast<char*>("MOZ_USING_SERVICE="));
   // lastFallbackError keeps track of the last error for the service not being 
   // used, in case of an error when fallback is not enabled we write the 
   // error to the update.status file. 
   // When fallback is disabled (MOZ_NO_SERVICE_FALLBACK does not exist) then
   // we will instead fallback to not using the service and display a UAC prompt.
   int lastFallbackError = FALLBACKKEY_UNKNOWN_ERROR;
 
@@ -2577,20 +2575,20 @@ int NS_main(int argc, NS_tchar **argv)
       }
       LOG(("Update already in progress! Exiting"));
       return 1;
     }
 
     updateLockFileHandle = CreateFileW(updateLockFilePath,
                                        GENERIC_READ | GENERIC_WRITE,
                                        0,
-                                       nullptr,
+                                       NULL,
                                        OPEN_ALWAYS,
                                        FILE_FLAG_DELETE_ON_CLOSE,
-                                       nullptr);
+                                       NULL);
 
     NS_tsnprintf(elevatedLockFilePath,
                  sizeof(elevatedLockFilePath)/sizeof(elevatedLockFilePath[0]),
                  NS_T("%s/update_elevated.lock"), gSourcePath);
 
 
     // Even if a file has no sharing access, you can still get its attributes
     bool startedFromUnelevatedUpdater =
@@ -2600,35 +2598,35 @@ int NS_main(int argc, NS_tchar **argv)
     // token as the service so the permissions are already dropped.  If we're
     // running from an elevated updater that was started from an unelevated 
     // updater, then we drop the permissions here. We do not drop the 
     // permissions on the originally called updater because we use its token
     // to start the callback application.
     if(startedFromUnelevatedUpdater) {
       // Disable every privilege we don't need. Processes started using
       // CreateProcess will use the same token as this process.
-      UACHelper::DisablePrivileges(nullptr);
+      UACHelper::DisablePrivileges(NULL);
     }
 
     if (updateLockFileHandle == INVALID_HANDLE_VALUE || 
         (useService && testOnlyFallbackKeyExists && noServiceFallback)) {
       if (!_waccess(elevatedLockFilePath, F_OK) &&
           NS_tremove(elevatedLockFilePath) != 0) {
         fprintf(stderr, "Unable to create elevated lock file! Exiting\n");
         return 1;
       }
 
       HANDLE elevatedFileHandle;
       elevatedFileHandle = CreateFileW(elevatedLockFilePath,
                                        GENERIC_READ | GENERIC_WRITE,
                                        0,
-                                       nullptr,
+                                       NULL,
                                        OPEN_ALWAYS,
                                        FILE_FLAG_DELETE_ON_CLOSE,
-                                       nullptr);
+                                       NULL);
 
       if (elevatedFileHandle == INVALID_HANDLE_VALUE) {
         LOG(("Unable to create elevated lock file! Exiting"));
         return 1;
       }
 
       PRUnichar *cmdLine = MakeCommandLine(argc - 1, argv + 1);
       if (!cmdLine) {
@@ -2709,17 +2707,17 @@ int NS_main(int argc, NS_tchar **argv)
             showProgressUI = !InitProgressUIStrings();
           }
 
           // Wait for the service to stop for 5 seconds.  If the service
           // has still not stopped then show an indeterminate progress bar.
           DWORD lastState = WaitForServiceStop(SVC_NAME, 5);
           if (lastState != SERVICE_STOPPED) {
             Thread t1;
-            if (t1.Run(WaitForServiceFinishThread, nullptr) == 0 && 
+            if (t1.Run(WaitForServiceFinishThread, NULL) == 0 && 
                 showProgressUI) {
               ShowProgressUI(true, false);
             }
             t1.Join();
           }
 
           lastState = WaitForServiceStop(SVC_NAME, 1);
           if (lastState != SERVICE_STOPPED) {
@@ -2752,17 +2750,17 @@ int NS_main(int argc, NS_tchar **argv)
       // current process is running as.
       // Note that we don't need to do this if we're just staging the
       // update in the background, as the PostUpdate step runs when
       // performing the replacing in that case.
       if (useService && !sBackgroundUpdate) {
         bool updateStatusSucceeded = false;
         if (IsUpdateStatusSucceeded(updateStatusSucceeded) && 
             updateStatusSucceeded) {
-          if (!LaunchWinPostProcess(installDir, gSourcePath, false, nullptr)) {
+          if (!LaunchWinPostProcess(installDir, gSourcePath, false, NULL)) {
             fprintf(stderr, "The post update process which runs as the user"
                     " for service update could not be launched.");
           }
         }
       }
 
       // If we didn't want to use the service at all, or if an update was 
       // already happening, or launching the service command failed, then 
@@ -2773,17 +2771,17 @@ int NS_main(int argc, NS_tchar **argv)
       if (!useService && !noServiceFallback && 
           updateLockFileHandle == INVALID_HANDLE_VALUE) {
         SHELLEXECUTEINFO sinfo;
         memset(&sinfo, 0, sizeof(SHELLEXECUTEINFO));
         sinfo.cbSize       = sizeof(SHELLEXECUTEINFO);
         sinfo.fMask        = SEE_MASK_FLAG_NO_UI |
                              SEE_MASK_FLAG_DDEWAIT |
                              SEE_MASK_NOCLOSEPROCESS;
-        sinfo.hwnd         = nullptr;
+        sinfo.hwnd         = NULL;
         sinfo.lpFile       = argv[0];
         sinfo.lpParameters = cmdLine;
         sinfo.lpVerb       = L"runas";
         sinfo.nShow        = SW_SHOWNORMAL;
 
         bool result = ShellExecuteEx(&sinfo);
         free(cmdLine);
 
@@ -2922,38 +2920,34 @@ int NS_main(int argc, NS_tchar **argv)
     NS_tchar callbackLongPath[MAXPATHLEN];
     ZeroMemory(callbackLongPath, sizeof(callbackLongPath));
     NS_tchar *targetPath = argv[callbackIndex];
     NS_tchar buffer[MAXPATHLEN * 2] = { NS_T('\0') };
     size_t bufferLeft = MAXPATHLEN * 2;
     if (sReplaceRequest) {
       // In case of replace requests, we should look for the callback file in
       // the destination directory.
-      size_t commonPrefixLength = PathCommonPrefixW(argv[callbackIndex],
-                                                    gDestinationPath,
-                                                    nullptr);
+      size_t commonPrefixLength = PathCommonPrefixW(argv[callbackIndex], gDestinationPath, NULL);
       NS_tchar *p = buffer;
       NS_tstrncpy(p, argv[callbackIndex], commonPrefixLength);
       p += commonPrefixLength;
       bufferLeft -= commonPrefixLength;
       NS_tstrncpy(p, gDestinationPath + commonPrefixLength, bufferLeft);
 
       size_t len = NS_tstrlen(gDestinationPath + commonPrefixLength);
       p += len;
       bufferLeft -= len;
       *p = NS_T('\\');
       ++p;
       bufferLeft--;
       *p = NS_T('\0');
       NS_tchar installDir[MAXPATHLEN];
       if (!GetInstallationDir(installDir))
         return 1;
-      size_t callbackPrefixLength = PathCommonPrefixW(argv[callbackIndex],
-                                                      installDir,
-                                                      nullptr);
+      size_t callbackPrefixLength = PathCommonPrefixW(argv[callbackIndex], installDir, NULL);
       NS_tstrncpy(p, argv[callbackIndex] + max(callbackPrefixLength, commonPrefixLength), bufferLeft);
       targetPath = buffer;
     }
     if (!GetLongPathNameW(targetPath, callbackLongPath,
                           sizeof(callbackLongPath)/sizeof(callbackLongPath[0]))) {
       LOG(("NS_main: unable to find callback file: " LOG_S, targetPath));
       LogFinish();
       WriteStatusFile(WRITE_ERROR);
@@ -3008,17 +3002,17 @@ int NS_main(int argc, NS_tchar **argv)
       do {
         // By opening a file handle wihout FILE_SHARE_READ to the callback
         // executable, the OS will prevent launching the process while it is
         // being updated.
         callbackFile = CreateFileW(targetPath,
                                    DELETE | GENERIC_WRITE,
                                    // allow delete, rename, and write
                                    FILE_SHARE_DELETE | FILE_SHARE_WRITE,
-                                   nullptr, OPEN_EXISTING, 0, nullptr);
+                                   NULL, OPEN_EXISTING, 0, NULL);
         if (callbackFile != INVALID_HANDLE_VALUE)
           break;
 
         lastWriteError = GetLastError();
         LOG(("NS_main: callback app open attempt %d failed. " \
              "File: " LOG_S ". Last error: %d", retries,
              targetPath, lastWriteError));
 
@@ -3063,17 +3057,17 @@ int NS_main(int argc, NS_tchar **argv)
     }
   }
 #endif /* XP_WIN */
 
   // Run update process on a background thread.  ShowProgressUI may return
   // before QuitProgressUI has been called, so wait for UpdateThreadFunc to
   // terminate.  Avoid showing the progress UI for background updates.
   Thread t;
-  if (t.Run(UpdateThreadFunc, nullptr) == 0) {
+  if (t.Run(UpdateThreadFunc, NULL) == 0) {
     if (!sBackgroundUpdate && !sReplaceRequest) {
       ShowProgressUI();
     }
   }
   t.Join();
 
 #ifdef XP_WIN
   if (argc > callbackIndex && !sReplaceRequest) {
@@ -3091,17 +3085,17 @@ int NS_main(int argc, NS_tchar **argv)
     // that are in use and will be removed on OS reboot. The call to remove the
     // directory on OS reboot is done after the calls to remove the files so the
     // files are removed first on OS reboot since the directory must be empty
     // for the directory removal to be successful. The MoveFileEx call to remove
     // the directory on OS reboot will fail if the process doesn't have write
     // access to the HKEY_LOCAL_MACHINE registry key but this is ok since the
     // installer / uninstaller will delete the directory along with its contents
     // after an update is applied, on reinstall, and on uninstall.
-    if (MoveFileEx(DELETE_DIR, nullptr, MOVEFILE_DELAY_UNTIL_REBOOT)) {
+    if (MoveFileEx(DELETE_DIR, NULL, MOVEFILE_DELAY_UNTIL_REBOOT)) {
       LOG(("NS_main: directory will be removed on OS reboot: " LOG_S,
            DELETE_DIR));
     } else {
       LOG(("NS_main: failed to schedule OS reboot removal of " \
            "directory: " LOG_S, DELETE_DIR));
     }
   }
 #endif /* XP_WIN */
@@ -3120,17 +3114,17 @@ int NS_main(int argc, NS_tchar **argv)
       // the PostUpdate process. We do the service update process here 
       // because it's possible we are updating with updater.exe without the 
       // service if the service failed to apply the update. We want to update
       // the service to a newer version in that case. If we are not running
       // through the service, then MOZ_USING_SERVICE will not exist.
       if (!sUsingService) {
         NS_tchar installDir[MAXPATHLEN];
         if (GetInstallationDir(installDir)) {
-          if (!LaunchWinPostProcess(installDir, gSourcePath, false, nullptr)) {
+          if (!LaunchWinPostProcess(installDir, gSourcePath, false, NULL)) {
             LOG(("NS_main: The post update process could not be launched."));
           }
 
           StartServiceUpdate(installDir);
         }
       }
     }
     EXIT_WHEN_ELEVATED(elevatedLockFilePath, updateLockFileHandle, 0);
@@ -3148,17 +3142,17 @@ int NS_main(int argc, NS_tchar **argv)
   }
 
   return gSucceeded ? 0 : 1;
 }
 
 class ActionList
 {
 public:
-  ActionList() : mFirst(nullptr), mLast(nullptr), mCount(0) { }
+  ActionList() : mFirst(NULL), mLast(NULL), mCount(0) { }
   ~ActionList();
 
   void Append(Action* action);
   int Prepare();
   int Execute();
   void Finish(int status);
 
 private:
@@ -3432,29 +3426,29 @@ int add_dir_entries(const NS_tchar *dirp
   FTSENT *ftsdirEntry;
   NS_tchar searchpath[MAXPATHLEN];
 
   NS_tsnprintf(searchpath, sizeof(searchpath)/sizeof(searchpath[0]), NS_T("%s"),
                dirpath);
   // Remove the trailing slash so the paths don't contain double slashes. The
   // existence of the slash has already been checked in DoUpdate.
   searchpath[NS_tstrlen(searchpath) - 1] = NS_T('\0');
-  char* const pathargv[] = {searchpath, nullptr};
+  char* const pathargv[] = {searchpath, NULL};
 
   // FTS_NOCHDIR is used so relative paths from the destination directory are
   // returned.
   if (!(ftsdir = fts_open(pathargv,
                           FTS_PHYSICAL | FTS_NOSTAT | FTS_XDEV | FTS_NOCHDIR,
-                          nullptr)))
+                          NULL)))
     return UNEXPECTED_FILE_OPERATION_ERROR;
 
-  while ((ftsdirEntry = fts_read(ftsdir)) != nullptr) {
+  while ((ftsdirEntry = fts_read(ftsdir)) != NULL) {
     NS_tchar foundpath[MAXPATHLEN];
     NS_tchar *quotedpath;
-    Action *action = nullptr;
+    Action *action = NULL;
 
     switch (ftsdirEntry->fts_info) {
       // Filesystem objects that shouldn't be in the application's directories
       case FTS_SL:
       case FTS_SLNONE:
       case FTS_DEFAULT:
         LOG(("add_dir_entries: found a non-standard file: " LOG_S,
              ftsdirEntry->fts_path));
@@ -3534,76 +3528,76 @@ int add_dir_entries(const NS_tchar *dirp
   return rv;
 }
 #endif
 
 static NS_tchar*
 GetManifestContents(const NS_tchar *manifest)
 {
   AutoFile mfile = NS_tfopen(manifest, NS_T("rb"));
-  if (mfile == nullptr) {
+  if (mfile == NULL) {
     LOG(("GetManifestContents: error opening manifest file: " LOG_S, manifest));
-    return nullptr;
+    return NULL;
   }
 
   struct stat ms;
   int rv = fstat(fileno((FILE *)mfile), &ms);
   if (rv) {
     LOG(("GetManifestContents: error stating manifest file: " LOG_S, manifest));
-    return nullptr;
+    return NULL;
   }
 
   char *mbuf = (char *) malloc(ms.st_size + 1);
   if (!mbuf)
-    return nullptr;
+    return NULL;
 
   size_t r = ms.st_size;
   char *rb = mbuf;
   while (r) {
     const size_t count = mmin(SSIZE_MAX, r);
     size_t c = fread(rb, 1, count, mfile);
     if (c != count) {
       LOG(("GetManifestContents: error reading manifest file: " LOG_S, manifest));
-      return nullptr;
+      return NULL;
     }
 
     r -= c;
     rb += c;
   }
   mbuf[ms.st_size] = '\0';
   rb = mbuf;
 
 #ifndef XP_WIN
   return rb;
 #else
   NS_tchar *wrb = (NS_tchar *) malloc((ms.st_size + 1) * sizeof(NS_tchar));
   if (!wrb)
-    return nullptr;
+    return NULL;
 
   if (!MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, rb, -1, wrb,
                            ms.st_size + 1)) {
     LOG(("GetManifestContents: error converting utf8 to utf16le: %d", GetLastError()));
     free(mbuf);
     free(wrb);
-    return nullptr;
+    return NULL;
   }
   free(mbuf);
 
   return wrb;
 #endif
 }
 
 int AddPreCompleteActions(ActionList *list)
 {
   if (sIsOSUpdate) {
     return OK;
   }
 
   NS_tchar *rb = GetManifestContents(NS_T("precomplete"));
-  if (rb == nullptr) {
+  if (rb == NULL) {
     LOG(("AddPreCompleteActions: error getting contents of precomplete " \
          "manifest"));
     // Applications aren't required to have a precomplete manifest yet.
     return OK;
   }
 
   int rv;
   NS_tchar *line;
@@ -3613,17 +3607,17 @@ int AddPreCompleteActions(ActionList *li
       continue;
 
     NS_tchar *token = mstrtok(kWhitespace, &line);
     if (!token) {
       LOG(("AddPreCompleteActions: token not found in manifest"));
       return PARSE_ERROR;
     }
 
-    Action *action = nullptr;
+    Action *action = NULL;
     if (NS_tstrcmp(token, NS_T("remove")) == 0) { // rm file
       action = new RemoveFile();
     }
     else if (NS_tstrcmp(token, NS_T("remove-cc")) == 0) { // no longer supported
       continue;
     }
     else if (NS_tstrcmp(token, NS_T("rmdir")) == 0) { // rmdir if  empty
       action = new RemoveDir();
@@ -3658,17 +3652,17 @@ int DoUpdate()
     rv = gArchiveReader.ExtractFile("update.manifest", manifest);
     if (rv) {
       LOG(("DoUpdate: error extracting manifest file"));
       return rv;
     }
   }
 
   NS_tchar *rb = GetManifestContents(manifest);
-  if (rb == nullptr) {
+  if (rb == NULL) {
     LOG(("DoUpdate: error opening manifest file: " LOG_S, manifest));
     return READ_ERROR;
   }
 
 
   ActionList list;
   NS_tchar *line;
   bool isFirstAction = true;
@@ -3693,17 +3687,17 @@ int DoUpdate()
           return rv;
       }
       isFirstAction = false;
       continue;
     }
 
     isFirstAction = false;
 
-    Action *action = nullptr;
+    Action *action = NULL;
     if (NS_tstrcmp(token, NS_T("remove")) == 0) { // rm file
       action = new RemoveFile();
     }
     else if (NS_tstrcmp(token, NS_T("rmdir")) == 0) { // rmdir if  empty
       action = new RemoveDir();
     }
     else if (NS_tstrcmp(token, NS_T("rmrfdir")) == 0) { // rmdir recursive
       const NS_tchar *reldirpath = mstrtok(kQuote, &line);
--- a/toolkit/profile/nsToolkitProfileService.cpp
+++ b/toolkit/profile/nsToolkitProfileService.cpp
@@ -1021,17 +1021,17 @@ nsresult
 XRE_GetFileFromPath(const char *aPath, nsIFile* *aResult)
 {
 #if defined(XP_MACOSX)
     int32_t pathLen = strlen(aPath);
     if (pathLen > MAXPATHLEN)
         return NS_ERROR_INVALID_ARG;
 
     CFURLRef fullPath =
-        CFURLCreateFromFileSystemRepresentation(nullptr, (const UInt8 *) aPath,
+        CFURLCreateFromFileSystemRepresentation(NULL, (const UInt8 *) aPath,
                                                 pathLen, true);
     if (!fullPath)
         return NS_ERROR_FAILURE;
 
     nsCOMPtr<nsIFile> lf;
     nsresult rv = NS_NewNativeLocalFile(EmptyCString(), true,
                                         getter_AddRefs(lf));
     if (NS_SUCCEEDED(rv)) {
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -20,17 +20,19 @@
 #include "nsAppShell.h"
 #include "nsOSHelperAppService.h"
 #include "nsWindow.h"
 #include "mozilla/Preferences.h"
 #include "nsThreadUtils.h"
 #include "nsIThreadManager.h"
 #include "mozilla/dom/mobilemessage/PSms.h"
 #include "gfxImageSurface.h"
+#include "gfxPlatform.h"
 #include "gfxContext.h"
+#include "mozilla/gfx/2D.h"
 #include "gfxUtils.h"
 #include "nsPresContext.h"
 #include "nsIDocShell.h"
 #include "nsPIDOMWindow.h"
 #include "mozilla/dom/ScreenOrientation.h"
 #include "nsIDOMWindowUtils.h"
 #include "nsIDOMClientRect.h"
 #include "StrongPointer.h"
@@ -39,16 +41,17 @@
 
 #ifdef DEBUG
 #define ALOG_BRIDGE(args...) ALOG(args)
 #else
 #define ALOG_BRIDGE(args...) ((void)0)
 #endif
 
 using namespace mozilla;
+using namespace mozilla::gfx;
 
 NS_IMPL_ISUPPORTS0(nsFilePickerCallback)
 
 StaticRefPtr<AndroidBridge> AndroidBridge::sBridge;
 static unsigned sJavaEnvThreadIndex = 0;
 static jobject sGlobalContext = nullptr;
 static void JavaThreadDetachFunc(void *arg);
 
@@ -1843,17 +1846,30 @@ nsresult AndroidBridge::CaptureThumbnail
     nsRefPtr<gfxImageSurface> surf =
         new gfxImageSurface(static_cast<unsigned char*>(data), nsIntSize(bufW, bufH), stride,
                             is24bit ? gfxImageFormatRGB24 :
                                       gfxImageFormatRGB16_565);
     if (surf->CairoStatus() != 0) {
         ALOG_BRIDGE("Error creating gfxImageSurface");
         return NS_ERROR_FAILURE;
     }
-    nsRefPtr<gfxContext> context = new gfxContext(surf);
+
+    nsRefPtr<gfxContext> context;
+    if (gfxPlatform::GetPlatform()->SupportsAzureContentForType(BACKEND_CAIRO)) {
+        RefPtr<DrawTarget> dt =
+            gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(surf, IntSize(bufW, bufH));
+
+        if (!dt) {
+            ALOG_BRIDGE("Error creating DrawTarget");
+            return NS_ERROR_FAILURE;
+        }
+        context = new gfxContext(dt);
+    } else {
+        context = new gfxContext(surf);
+    }
     gfxPoint pt(0, 0);
     context->Translate(pt);
     context->Scale(scale * bufW / srcW, scale * bufH / srcH);
     rv = presShell->RenderDocument(r, renderDocFlags, bgColor, context);
     if (is24bit) {
         gfxUtils::ConvertBGRAtoRGBA(surf);
     }
     NS_ENSURE_SUCCESS(rv, rv);
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -2262,17 +2262,17 @@ nsWindow::UpdateAlpha(gfxPattern* aPatte
                                            aBoundsRect.width);
       int32_t bufferSize = stride * aBoundsRect.height;
       nsAutoArrayPtr<uint8_t> imageBuffer(new (std::nothrow) uint8_t[bufferSize]);
       RefPtr<DrawTarget> drawTarget = gfxPlatform::GetPlatform()->
           CreateDrawTargetForData(imageBuffer, ToIntSize(aBoundsRect.Size()),
                                   stride, FORMAT_A8);
 
       if (drawTarget) {
-          drawTarget->FillRect(ToRect(aBoundsRect),
+          drawTarget->FillRect(Rect(0, 0, aBoundsRect.width, aBoundsRect.height),
                                *aPattern->GetPattern(drawTarget),
                                DrawOptions(1.0, OP_SOURCE));
       }
       UpdateTranslucentWindowAlphaInternal(aBoundsRect, imageBuffer, stride);
   } else {
       nsRefPtr<gfxImageSurface> img =
           new gfxImageSurface(ThebesIntSize(aBoundsRect.Size()),
                               gfxImageFormatA8);