Merge mozilla-central to fx-team
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Tue, 15 Oct 2013 10:49:42 +0200
changeset 165599 344307c027959e537e5d669f1d85f33a57097135
parent 165598 7b367ca427b63d7530dd69c62112dbee2dc7cae1 (current diff)
parent 165527 febfe3c7732bfb52252e77fa293046ad2e8ec41f (diff)
child 165600 55e9f80315a634ae2353dd552974cdd7087b6be3
push id428
push userbbajaj@mozilla.com
push dateTue, 28 Jan 2014 00:16:25 +0000
treeherdermozilla-release@cd72a7ff3a75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone27.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge 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);