diff --git a/BUILD.gn b/BUILD.gn
index aa706be..5384e51 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -711,15 +711,15 @@
         "//third_party/libjpeg_turbo:simd_asm",
       ]
     }
-    if (use_ozone) {
-      deps += [ "//ui/ozone/demo" ]
-    }
-
     if (is_linux && current_toolchain == host_toolchain) {
       deps += [ "//v8:d8" ]
     }
   }
 
+  if (use_ozone) {
+    deps += [ "//ui/ozone/demo" ]
+  }
+
   if (enable_nacl) {
     deps += [ "//native_client_sdk/src:nacl_core_sdk" ]
   }
diff --git a/DEPS b/DEPS
index 2c4278ffe..3de58a4 100644
--- a/DEPS
+++ b/DEPS
@@ -39,11 +39,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '52b88cc61780425a9f86201bc727558ee08a921a',
+  'skia_revision': 'c416912da4840af0c49bd8cdcf00044ed39500f6',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': 'a759160b4d5f9f4e02ead371d846ba7705080d1d',
+  'v8_revision': '167dc63b4c9a1d0f0fe1b19af93644ac9a561e83',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -51,7 +51,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '0c0d8006a9dd31552079b521a16db072526901db',
+  'angle_revision': 'd4102f0994bd8c30aa043999517b3c401623537d',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling build tools
   # and whatever else without interference from each other.
@@ -100,7 +100,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '887fc947dfb49be0a7b83bd88ed38cacbe6c65ec',
+  'catapult_revision': 'dc924aae80a2ae72acfff1472baac64fbc64b7df',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -220,7 +220,7 @@
    Var('chromium_git') + '/native_client/src/third_party/scons-2.0.1.git' + '@' + '1c1550e17fc26355d08627fbdec13d8291227067',
 
   'src/third_party/webrtc':
-    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '9ba6023665446b7150131573ff96e6fe475906ae', # commit position 12237
+    Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '01047c5200ab33bf79e953f5f1bb05772169837f', # commit position 12264
 
   'src/third_party/openmax_dl':
     Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' +  Var('openmax_dl_revision'),
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn
index 65fd6db..02991cf 100644
--- a/android_webview/BUILD.gn
+++ b/android_webview/BUILD.gn
@@ -358,16 +358,31 @@
   ]
 }
 
-shared_library("libwebviewchromium") {
+source_set("webview_entry_point") {
   deps = [
     ":common",
   ]
   sources = [
     "lib/main/webview_entry_point.cc",
   ]
+}
+
+shared_library("libwebviewchromium") {
+  deps = [
+    ":webview_entry_point",
+  ]
   configs -= [ "//build/config/android:hide_native_jni_exports" ]
 }
 
+if (defined(webview_only_libmonochrome) && webview_only_libmonochrome) {
+  shared_library("libmonochrome") {
+    deps = [
+      ":webview_entry_point",
+    ]
+    configs -= [ "//build/config/android:hide_native_jni_exports" ]
+  }
+}
+
 source_set("common") {
   sources = [
     "browser/aw_browser_context.cc",
diff --git a/android_webview/browser/aw_render_thread_context_provider.cc b/android_webview/browser/aw_render_thread_context_provider.cc
index fe115c6d..e89b78a 100644
--- a/android_webview/browser/aw_render_thread_context_provider.cc
+++ b/android_webview/browser/aw_render_thread_context_provider.cc
@@ -100,9 +100,9 @@
   if (gr_context_)
     return gr_context_.get();
 
-  skia::RefPtr<GrGLInterface> interface =
-      skia_bindings::CreateGLES2InterfaceBindings(ContextGL());
-  gr_context_ = skia::AdoptRef(GrContext::Create(
+  sk_sp<GrGLInterface> interface(
+      skia_bindings::CreateGLES2InterfaceBindings(ContextGL()));
+  gr_context_ = sk_sp<::GrContext>(GrContext::Create(
       // GrContext takes ownership of |interface|.
       kOpenGL_GrBackend, reinterpret_cast<GrBackendContext>(interface.get())));
   return gr_context_.get();
diff --git a/android_webview/browser/aw_render_thread_context_provider.h b/android_webview/browser/aw_render_thread_context_provider.h
index 839f1a9..f9df881 100644
--- a/android_webview/browser/aw_render_thread_context_provider.h
+++ b/android_webview/browser/aw_render_thread_context_provider.h
@@ -14,7 +14,8 @@
 #include "base/threading/thread_checker.h"
 #include "cc/output/context_provider.h"
 #include "gpu/command_buffer/service/in_process_command_buffer.h"
-#include "skia/ext/refptr.h"
+#include "third_party/skia/include/core/SkRefCnt.h"
+#include "third_party/skia/include/gpu/GrContext.h"
 
 namespace gfx {
 class GLSurface;
@@ -56,7 +57,7 @@
   base::ThreadChecker main_thread_checker_;
 
   std::unique_ptr<gpu::GLInProcessContext> context_;
-  skia::RefPtr<class GrContext> gr_context_;
+  sk_sp<class GrContext> gr_context_;
 
   cc::ContextProvider::Capabilities capabilities_;
 
diff --git a/ash/display/mirror_window_controller.cc b/ash/display/mirror_window_controller.cc
index 7633e13..ce7fba1 100644
--- a/ash/display/mirror_window_controller.cc
+++ b/ash/display/mirror_window_controller.cc
@@ -39,7 +39,7 @@
 #include "ui/gfx/screen.h"
 
 #if defined(USE_X11)
-#include "ui/gfx/x/x11_types.h"
+#include "ui/gfx/x/x11_types.h"  // nogncheck
 #endif
 
 namespace ash {
diff --git a/ash/display/window_tree_host_manager.cc b/ash/display/window_tree_host_manager.cc
index b24022e..e919e9b 100644
--- a/ash/display/window_tree_host_manager.cc
+++ b/ash/display/window_tree_host_manager.cc
@@ -51,7 +51,7 @@
 
 #if defined(USE_X11)
 #include "ui/base/x/x11_util.h"
-#include "ui/gfx/x/x11_types.h"
+#include "ui/gfx/x/x11_types.h"  // nogncheck
 
 // Including this at the bottom to avoid other
 // potential conflict with chrome headers.
diff --git a/ash/shell.cc b/ash/shell.cc
index 66a9b622..2f49a8d0 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -116,7 +116,7 @@
 
 #if defined(OS_CHROMEOS)
 #if defined(USE_X11)
-#include "ui/gfx/x/x11_types.h"
+#include "ui/gfx/x/x11_types.h"  // nogncheck
 #endif  // defined(USE_X11)
 #include "ash/accelerators/magnifier_key_scroller.h"
 #include "ash/accelerators/spoken_feedback_toggler.h"
diff --git a/ash/test/ash_test_base.cc b/ash/test/ash_test_base.cc
index 296923fc..25d10b8e 100644
--- a/ash/test/ash_test_base.cc
+++ b/ash/test/ash_test_base.cc
@@ -44,7 +44,7 @@
 #endif
 
 #if defined(USE_X11)
-#include "ui/gfx/x/x11_connection.h"
+#include "ui/gfx/x/x11_connection.h"  // nogncheck
 #endif
 
 namespace ash {
diff --git a/ash/virtual_keyboard_controller.cc b/ash/virtual_keyboard_controller.cc
index 6025409..31d2a642 100644
--- a/ash/virtual_keyboard_controller.cc
+++ b/ash/virtual_keyboard_controller.cc
@@ -6,16 +6,15 @@
 
 #include <vector>
 
+#include "ash/ash_switches.h"
 #include "ash/shell.h"
 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
-#include "ash_switches.h"
 #include "base/command_line.h"
 #include "base/strings/string_util.h"
 #include "ui/events/devices/device_data_manager.h"
 #include "ui/events/devices/input_device.h"
 #include "ui/events/devices/keyboard_device.h"
 #include "ui/events/devices/touchscreen_device.h"
-#include "ui/gfx/x/x11_types.h"
 #include "ui/keyboard/keyboard_switches.h"
 #include "ui/keyboard/keyboard_util.h"
 
diff --git a/base/metrics/histogram_unittest.cc b/base/metrics/histogram_unittest.cc
index a908d78..da115133 100644
--- a/base/metrics/histogram_unittest.cc
+++ b/base/metrics/histogram_unittest.cc
@@ -614,7 +614,7 @@
   // Calculate cost of creating histograms.
   TimeTicks create_start = TimeTicks::Now();
   for (int i = 0; i < kTestCreateCount; ++i) {
-    Histogram::FactoryGet(histogram_names[i], 0, 100, 10,
+    Histogram::FactoryGet(histogram_names[i], 1, 100, 10,
                           HistogramBase::kNoFlags);
   }
   TimeDelta create_ticks = TimeTicks::Now() - create_start;
@@ -634,7 +634,7 @@
     const int i_mult = 6007;
     static_assert(i_mult < INT_MAX / kTestCreateCount, "Multiplier too big");
     int index = (i * i_mult) & (kTestCreateCount - 1);
-    Histogram::FactoryGet(histogram_names[index], 0, 100, 10,
+    Histogram::FactoryGet(histogram_names[index], 1, 100, 10,
                           HistogramBase::kNoFlags);
   }
   TimeDelta lookup_ticks = TimeTicks::Now() - lookup_start;
@@ -647,7 +647,7 @@
 
   // Calculate cost of accessing histograms.
   HistogramBase* histogram = Histogram::FactoryGet(
-      histogram_names[0], 0, 100, 10, HistogramBase::kNoFlags);
+      histogram_names[0], 1, 100, 10, HistogramBase::kNoFlags);
   ASSERT_TRUE(histogram);
   TimeTicks add_start = TimeTicks::Now();
   for (int i = 0; i < kTestAddCount; ++i)
diff --git a/base/metrics/persistent_histogram_allocator.cc b/base/metrics/persistent_histogram_allocator.cc
index 730116e..864753ba 100644
--- a/base/metrics/persistent_histogram_allocator.cc
+++ b/base/metrics/persistent_histogram_allocator.cc
@@ -111,16 +111,26 @@
   char name[1];
 };
 
+PersistentHistogramAllocator::Iterator::Iterator(
+    PersistentHistogramAllocator* allocator)
+    : allocator_(allocator), memory_iter_(allocator->memory_allocator()) {}
+
+std::unique_ptr<HistogramBase>
+PersistentHistogramAllocator::Iterator::GetNextWithIgnore(Reference ignore) {
+  PersistentMemoryAllocator::Reference ref;
+  while ((ref = memory_iter_.GetNextOfType(kTypeIdHistogram)) != 0) {
+    if (ref != ignore)
+      return allocator_->GetHistogram(ref);
+  }
+  return nullptr;
+}
+
 PersistentHistogramAllocator::PersistentHistogramAllocator(
     std::unique_ptr<PersistentMemoryAllocator> memory)
     : memory_allocator_(std::move(memory)) {}
 
 PersistentHistogramAllocator::~PersistentHistogramAllocator() {}
 
-void PersistentHistogramAllocator::CreateIterator(Iterator* iter) {
-  memory_allocator_->CreateIterator(&iter->memory_iter);
-}
-
 void PersistentHistogramAllocator::CreateTrackingHistograms(StringPiece name) {
   memory_allocator_->CreateTrackingHistograms(name);
 }
@@ -320,21 +330,6 @@
   return CreateHistogram(histogram_data);
 }
 
-std::unique_ptr<HistogramBase>
-PersistentHistogramAllocator::GetNextHistogramWithIgnore(Iterator* iter,
-                                                         Reference ignore) {
-  PersistentMemoryAllocator::Reference ref;
-  uint32_t type_id;
-  while ((ref = memory_allocator_->GetNextIterable(&iter->memory_iter,
-                                                   &type_id)) != 0) {
-    if (ref == ignore)
-      continue;
-    if (type_id == kTypeIdHistogram)
-      return GetHistogram(ref);
-  }
-  return nullptr;
-}
-
 void PersistentHistogramAllocator::FinalizeHistogram(Reference ref,
                                                      bool registered) {
   // If the created persistent histogram was registered then it needs to
@@ -543,27 +538,23 @@
   // Before releasing the memory, it's necessary to have the Statistics-
   // Recorder forget about the histograms contained therein; otherwise,
   // some operations will try to access them and the released memory.
-  PersistentMemoryAllocator::Iterator iter;
+  PersistentMemoryAllocator::Iterator iter(memory_allocator);
   PersistentMemoryAllocator::Reference ref;
-  uint32_t type_id;
-  memory_allocator->CreateIterator(&iter);
-  while ((ref = memory_allocator->GetNextIterable(&iter, &type_id)) != 0) {
-    if (type_id == kTypeIdHistogram) {
-      PersistentHistogramData* histogram_data =
-          memory_allocator->GetAsObject<PersistentHistogramData>(
-              ref, kTypeIdHistogram);
-      DCHECK(histogram_data);
-      StatisticsRecorder::ForgetHistogramForTesting(histogram_data->name);
+  while ((ref = iter.GetNextOfType(kTypeIdHistogram)) != 0) {
+    PersistentHistogramData* histogram_data =
+        memory_allocator->GetAsObject<PersistentHistogramData>(
+            ref, kTypeIdHistogram);
+    DCHECK(histogram_data);
+    StatisticsRecorder::ForgetHistogramForTesting(histogram_data->name);
 
-      // If a test breaks here then a memory region containing a histogram
-      // actively used by this code is being released back to the test.
-      // If that memory segment were to be deleted, future calls to create
-      // persistent histograms would crash. To avoid this, have the test call
-      // the method GetCreateHistogramResultHistogram() *before* setting
-      // the (temporary) memory allocator via SetGlobalAllocator() so that
-      // histogram is instead allocated from the process heap.
-      DCHECK_NE(kResultHistogram, histogram_data->name);
-    }
+    // If a test breaks here then a memory region containing a histogram
+    // actively used by this code is being released back to the test.
+    // If that memory segment were to be deleted, future calls to create
+    // persistent histograms would crash. To avoid this, have the test call
+    // the method GetCreateHistogramResultHistogram() *before* setting
+    // the (temporary) memory allocator via SetGlobalAllocator() so that
+    // histogram is instead allocated from the process heap.
+    DCHECK_NE(kResultHistogram, histogram_data->name);
   }
 
   g_allocator = nullptr;
@@ -572,9 +563,8 @@
 
 GlobalHistogramAllocator::GlobalHistogramAllocator(
     std::unique_ptr<PersistentMemoryAllocator> memory)
-    : PersistentHistogramAllocator(std::move(memory)) {
-  CreateIterator(&import_iterator_);
-}
+    : PersistentHistogramAllocator(std::move(memory)),
+      import_iterator_(this) {}
 
 void GlobalHistogramAllocator::ImportHistogramsToStatisticsRecorder() {
   // Skip the import if it's the histogram that was last created. Should a
@@ -589,7 +579,7 @@
   // the StatisticsRecorder which has its own lock.
   while (true) {
     std::unique_ptr<HistogramBase> histogram =
-        GetNextHistogramWithIgnore(&import_iterator_, record_to_ignore);
+        import_iterator_.GetNextWithIgnore(record_to_ignore);
     if (!histogram)
       break;
     StatisticsRecorder::RegisterOrDeleteDuplicate(histogram.release());
diff --git a/base/metrics/persistent_histogram_allocator.h b/base/metrics/persistent_histogram_allocator.h
index 570d5c0..12ac6850 100644
--- a/base/metrics/persistent_histogram_allocator.h
+++ b/base/metrics/persistent_histogram_allocator.h
@@ -23,20 +23,40 @@
 // This class manages histograms created within a PersistentMemoryAllocator.
 class BASE_EXPORT PersistentHistogramAllocator {
  public:
-  // This iterator is used for fetching persistent histograms from an allocator.
-  class Iterator {
+  // A reference to a histogram. While this is implemented as PMA::Reference,
+  // it is not conceptually the same thing. Outside callers should always use
+  // a Reference matching the class it is for and not mix the two.
+  using Reference = PersistentMemoryAllocator::Reference;
+
+  // Iterator used for fetching persistent histograms from an allocator.
+  // It is lock-free and thread-safe.
+  // See PersistentMemoryAllocator::Iterator for more information.
+  class BASE_EXPORT Iterator {
    public:
-    bool is_clear() { return memory_iter.is_clear(); }
+    // Constructs an iterator on a given |allocator|, starting at the beginning.
+    // The allocator must live beyond the lifetime of the iterator.
+    explicit Iterator(PersistentHistogramAllocator* allocator);
+
+    // Gets the next histogram from persistent memory; returns null if there
+    // are no more histograms to be found. This may still be called again
+    // later to retrieve any new histograms added in the meantime.
+    std::unique_ptr<HistogramBase> GetNext() { return GetNextWithIgnore(0); }
+
+    // Gets the next histogram from persistent memory, ignoring one particular
+    // reference in the process. Pass |ignore| of zero (0) to ignore nothing.
+    std::unique_ptr<HistogramBase> GetNextWithIgnore(Reference ignore);
 
    private:
-    friend class PersistentHistogramAllocator;
+    // Weak-pointer to histogram allocator being iterated over.
+    PersistentHistogramAllocator* allocator_;
 
-    // The iterator used for stepping through persistent memory iterables.
-    PersistentMemoryAllocator::Iterator memory_iter;
+    // The iterator used for stepping through objects in persistent memory.
+    // It is lock-free and thread-safe which is why this class is also such.
+    PersistentMemoryAllocator::Iterator memory_iter_;
+
+    DISALLOW_COPY_AND_ASSIGN(Iterator);
   };
 
-  using Reference = PersistentMemoryAllocator::Reference;
-
   // A PersistentHistogramAllocator is constructed from a PersistentMemory-
   // Allocator object of which it takes ownership.
   PersistentHistogramAllocator(
@@ -65,14 +85,6 @@
   // This method will return null if any problem is detected with the data.
   std::unique_ptr<HistogramBase> GetHistogram(Reference ref);
 
-  // Get the next histogram in persistent data based on iterator.
-  std::unique_ptr<HistogramBase> GetNextHistogram(Iterator* iter) {
-    return GetNextHistogramWithIgnore(iter, 0);
-  }
-
-  // Create an iterator for going through all histograms in an allocator.
-  void CreateIterator(Iterator* iter);
-
   // Allocate a new persistent histogram. The returned histogram will not
   // be able to be located by other allocators until it is "finalized".
   std::unique_ptr<HistogramBase> AllocateHistogram(
diff --git a/base/metrics/persistent_histogram_allocator_unittest.cc b/base/metrics/persistent_histogram_allocator_unittest.cc
index 4f0d4468..24a0753 100644
--- a/base/metrics/persistent_histogram_allocator_unittest.cc
+++ b/base/metrics/persistent_histogram_allocator_unittest.cc
@@ -86,40 +86,38 @@
   allocator_->GetMemoryInfo(&meminfo4);
   EXPECT_GT(meminfo3.free, meminfo4.free);
 
-  PersistentMemoryAllocator::Iterator iter;
+  PersistentMemoryAllocator::Iterator iter(allocator_);
   uint32_t type;
-  allocator_->CreateIterator(&iter);
-  EXPECT_NE(0U, allocator_->GetNextIterable(&iter, &type));  // Histogram
-  EXPECT_NE(0U, allocator_->GetNextIterable(&iter, &type));  // LinearHistogram
-  EXPECT_NE(0U, allocator_->GetNextIterable(&iter, &type));  // BooleanHistogram
-  EXPECT_NE(0U, allocator_->GetNextIterable(&iter, &type));  // CustomHistogram
-  EXPECT_EQ(0U, allocator_->GetNextIterable(&iter, &type));
+  EXPECT_NE(0U, iter.GetNext(&type));  // Histogram
+  EXPECT_NE(0U, iter.GetNext(&type));  // LinearHistogram
+  EXPECT_NE(0U, iter.GetNext(&type));  // BooleanHistogram
+  EXPECT_NE(0U, iter.GetNext(&type));  // CustomHistogram
+  EXPECT_EQ(0U, iter.GetNext(&type));
 
   // Create a second allocator and have it access the memory of the first.
   std::unique_ptr<HistogramBase> recovered;
   PersistentHistogramAllocator recovery(
       WrapUnique(new PersistentMemoryAllocator(
           allocator_memory_.get(), kAllocatorMemorySize, 0, 0, "", false)));
-  PersistentHistogramAllocator::Iterator histogram_iter;
-  recovery.CreateIterator(&histogram_iter);
+  PersistentHistogramAllocator::Iterator histogram_iter(&recovery);
 
-  recovered = recovery.GetNextHistogram(&histogram_iter);
+  recovered = histogram_iter.GetNext();
   ASSERT_TRUE(recovered);
   recovered->CheckName("TestHistogram");
 
-  recovered = recovery.GetNextHistogram(&histogram_iter);
+  recovered = histogram_iter.GetNext();
   ASSERT_TRUE(recovered);
   recovered->CheckName("TestLinearHistogram");
 
-  recovered = recovery.GetNextHistogram(&histogram_iter);
+  recovered = histogram_iter.GetNext();
   ASSERT_TRUE(recovered);
   recovered->CheckName("TestBooleanHistogram");
 
-  recovered = recovery.GetNextHistogram(&histogram_iter);
+  recovered = histogram_iter.GetNext();
   ASSERT_TRUE(recovered);
   recovered->CheckName("TestCustomHistogram");
 
-  recovered = recovery.GetNextHistogram(&histogram_iter);
+  recovered = histogram_iter.GetNext();
   EXPECT_FALSE(recovered);
 }
 
diff --git a/base/metrics/persistent_memory_allocator.cc b/base/metrics/persistent_memory_allocator.cc
index 1d5df333..6edbc2f 100644
--- a/base/metrics/persistent_memory_allocator.cc
+++ b/base/metrics/persistent_memory_allocator.cc
@@ -45,12 +45,12 @@
 };
 
 bool CheckFlag(const volatile std::atomic<uint32_t>* flags, int flag) {
-  uint32_t loaded_flags = flags->load();
+  uint32_t loaded_flags = flags->load(std::memory_order_relaxed);
   return (loaded_flags & flag) != 0;
 }
 
 void SetFlag(volatile std::atomic<uint32_t>* flags, int flag) {
-  uint32_t loaded_flags = flags->load();
+  uint32_t loaded_flags = flags->load(std::memory_order_relaxed);
   for (;;) {
     uint32_t new_flags = (loaded_flags & ~flag) | flag;
     // In the failue case, actual "flags" value stored in loaded_flags.
@@ -119,6 +119,115 @@
 const PersistentMemoryAllocator::Reference
     PersistentMemoryAllocator::kReferenceNull = 0;
 
+PersistentMemoryAllocator::Iterator::Iterator(
+    const PersistentMemoryAllocator* allocator)
+    : allocator_(allocator), last_record_(kReferenceQueue), record_count_(0) {}
+
+PersistentMemoryAllocator::Iterator::Iterator(
+    const PersistentMemoryAllocator* allocator,
+    Reference starting_after)
+    : allocator_(allocator), last_record_(starting_after), record_count_(0) {
+  // Ensure that the starting point is a valid, iterable block (meaning it can
+  // be read and has a non-zero "next" pointer).
+  const volatile BlockHeader* block =
+      allocator_->GetBlock(starting_after, 0, 0, false, false);
+  if (!block || block->next.load(std::memory_order_relaxed) == 0) {
+    NOTREACHED();
+    last_record_.store(kReferenceQueue, std::memory_order_release);
+  }
+}
+
+PersistentMemoryAllocator::Reference
+PersistentMemoryAllocator::Iterator::GetNext(uint32_t* type_return) {
+  // Make a copy of the existing count of found-records, acquiring all changes
+  // made to the allocator, notably "freeptr" (see comment in loop for why
+  // the load of that value cannot be moved above here) that occurred during
+  // any previous runs of this method, including those by parallel threads
+  // that interrupted it. It pairs with the Release at the end of this method.
+  //
+  // Otherwise, if the compiler were to arrange the two loads such that
+  // "count" was fetched _after_ "freeptr" then it would be possible for
+  // this thread to be interrupted between them and other threads perform
+  // multiple allocations, make-iterables, and iterations (with the included
+  // increment of |record_count_|) culminating in the check at the bottom
+  // mistakenly determining that a loop exists. Isn't this stuff fun?
+  uint32_t count = record_count_.load(std::memory_order_acquire);
+
+  Reference last = last_record_.load(std::memory_order_acquire);
+  Reference next;
+  while (true) {
+    const volatile BlockHeader* block =
+        allocator_->GetBlock(last, 0, 0, true, false);
+    if (!block)  // Invalid iterator state.
+      return kReferenceNull;
+
+    // The compiler and CPU can freely reorder all memory accesses on which
+    // there are no dependencies. It could, for example, move the load of
+    // "freeptr" to above this point because there are no explicit dependencies
+    // between it and "next". If it did, however, then another block could
+    // be queued after that but before the following load meaning there is
+    // one more queued block than the future "detect loop by having more
+    // blocks that could fit before freeptr" will allow.
+    //
+    // By "acquiring" the "next" value here, it's synchronized to the enqueue
+    // of the node which in turn is synchronized to the allocation (which sets
+    // freeptr). Thus, the scenario above cannot happen.
+    next = block->next.load(std::memory_order_acquire);
+    if (next == kReferenceQueue)  // No next allocation in queue.
+      return kReferenceNull;
+    block = allocator_->GetBlock(next, 0, 0, false, false);
+    if (!block) {  // Memory is corrupt.
+      allocator_->SetCorrupt();
+      return kReferenceNull;
+    }
+
+    // Update the "last_record" pointer to be the reference being returned.
+    // If it fails then another thread has already iterated past it so loop
+    // again. Failing will also load the existing value into "last" so there
+    // is no need to do another such load when the while-loop restarts. A
+    // "strong" compare-exchange is used because failing unnecessarily would
+    // mean repeating some fairly costly validations above.
+    if (last_record_.compare_exchange_strong(last, next)) {
+      *type_return = block->type_id;
+      break;
+    }
+  }
+
+  // Memory corruption could cause a loop in the list. Such must be detected
+  // so as to not cause an infinite loop in the caller. This is done by simply
+  // making sure it doesn't iterate more times than the absolute maximum
+  // number of allocations that could have been made. Callers are likely
+  // to loop multiple times before it is detected but at least it stops.
+  const uint32_t freeptr = std::min(
+      allocator_->shared_meta()->freeptr.load(std::memory_order_relaxed),
+      allocator_->mem_size_);
+  const uint32_t max_records =
+      freeptr / (sizeof(BlockHeader) + kAllocAlignment);
+  if (count > max_records) {
+    allocator_->SetCorrupt();
+    return kReferenceNull;
+  }
+
+  // Increment the count and release the changes made above. It pairs with
+  // the Acquire at the top of this method. Note that this operation is not
+  // strictly synchonized with fetching of the object to return, which would
+  // have to be done inside the loop and is somewhat complicated to achieve.
+  // It does not matter if it falls behind temporarily so long as it never
+  // gets ahead.
+  record_count_.fetch_add(1, std::memory_order_release);
+  return next;
+}
+
+PersistentMemoryAllocator::Reference
+PersistentMemoryAllocator::Iterator::GetNextOfType(uint32_t type_match) {
+  Reference ref;
+  uint32_t type_found;
+  while ((ref = GetNext(&type_found)) != 0) {
+    if (type_found == type_match)
+      return ref;
+  }
+  return kReferenceNull;
+}
 
 // static
 bool PersistentMemoryAllocator::IsMemoryAcceptable(const void* base,
@@ -177,13 +286,13 @@
     if (shared_meta()->cookie != 0 ||
         shared_meta()->size != 0 ||
         shared_meta()->version != 0 ||
-        shared_meta()->freeptr.load() != 0 ||
-        shared_meta()->flags.load() != 0 ||
+        shared_meta()->freeptr.load(std::memory_order_relaxed) != 0 ||
+        shared_meta()->flags.load(std::memory_order_relaxed) != 0 ||
         shared_meta()->id != 0 ||
         shared_meta()->name != 0 ||
         shared_meta()->tailptr != 0 ||
         shared_meta()->queue.cookie != 0 ||
-        shared_meta()->queue.next.load() != 0 ||
+        shared_meta()->queue.next.load(std::memory_order_relaxed) != 0 ||
         first_block->size != 0 ||
         first_block->cookie != 0 ||
         first_block->type_id != 0 ||
@@ -199,13 +308,14 @@
     shared_meta()->page_size = mem_page_;
     shared_meta()->version = kGlobalVersion;
     shared_meta()->id = id;
-    shared_meta()->freeptr.store(sizeof(SharedMetadata));
+    shared_meta()->freeptr.store(sizeof(SharedMetadata),
+                                 std::memory_order_release);
 
     // Set up the queue of iterable allocations.
     shared_meta()->queue.size = sizeof(BlockHeader);
     shared_meta()->queue.cookie = kBlockCookieQueue;
-    shared_meta()->queue.next.store(kReferenceQueue);
-    shared_meta()->tailptr.store(kReferenceQueue);
+    shared_meta()->queue.next.store(kReferenceQueue, std::memory_order_release);
+    shared_meta()->tailptr.store(kReferenceQueue, std::memory_order_release);
 
     // Allocate space for the name so other processes can learn it.
     if (!name.empty()) {
@@ -218,10 +328,10 @@
   } else {
     if (shared_meta()->size == 0 ||
         shared_meta()->version == 0 ||
-        shared_meta()->freeptr.load() == 0 ||
+        shared_meta()->freeptr.load(std::memory_order_relaxed) == 0 ||
         shared_meta()->tailptr == 0 ||
         shared_meta()->queue.cookie == 0 ||
-        shared_meta()->queue.next.load() == 0) {
+        shared_meta()->queue.next.load(std::memory_order_relaxed) == 0) {
       SetCorrupt();
     }
     if (!readonly) {
@@ -281,7 +391,8 @@
 }
 
 size_t PersistentMemoryAllocator::used() const {
-  return std::min(shared_meta()->freeptr.load(), mem_size_);
+  return std::min(shared_meta()->freeptr.load(std::memory_order_relaxed),
+                  mem_size_);
 }
 
 size_t PersistentMemoryAllocator::GetAllocSize(Reference ref) const {
@@ -354,7 +465,8 @@
   // the code below but recognize that any failed compare-exchange operation
   // involving it will cause it to be loaded with a more recent value. The
   // code should either exit or restart the loop in that case.
-  /* const */ uint32_t freeptr = shared_meta()->freeptr.load();
+  /* const */ uint32_t freeptr =
+      shared_meta()->freeptr.load(std::memory_order_acquire);
 
   // Allocation is lockless so we do all our caculation and then, if saving
   // indicates a change has occurred since we started, scrap everything and
@@ -424,7 +536,7 @@
     if (block->size != 0 ||
         block->cookie != kBlockCookieFree ||
         block->type_id != 0 ||
-        block->next.load() != 0) {
+        block->next.load(std::memory_order_relaxed) != 0) {
       SetCorrupt();
       return kReferenceNull;
     }
@@ -437,8 +549,9 @@
 }
 
 void PersistentMemoryAllocator::GetMemoryInfo(MemoryInfo* meminfo) const {
-  uint32_t remaining = std::max(mem_size_ - shared_meta()->freeptr.load(),
-                                (uint32_t)sizeof(BlockHeader));
+  uint32_t remaining = std::max(
+      mem_size_ - shared_meta()->freeptr.load(std::memory_order_relaxed),
+      (uint32_t)sizeof(BlockHeader));
   meminfo->total = mem_size_;
   meminfo->free = IsCorrupt() ? 0 : remaining - sizeof(BlockHeader);
 }
@@ -501,68 +614,6 @@
   }
 }
 
-void PersistentMemoryAllocator::CreateIterator(Iterator* state,
-                                               Reference starting_after) const {
-  if (starting_after) {
-    // Ensure that the starting point is a valid, iterable block.
-    const volatile BlockHeader* block =
-        GetBlock(starting_after, 0, 0, false, false);
-    if (!block || !block->next.load()) {
-      NOTREACHED();
-      starting_after = kReferenceQueue;
-    }
-  } else {
-    // A zero beginning is really the Queue reference.
-    starting_after = kReferenceQueue;
-  }
-
-  state->last = starting_after;
-  state->niter = 0;
-}
-
-PersistentMemoryAllocator::Reference PersistentMemoryAllocator::GetNextIterable(
-    Iterator* state,
-    uint32_t* type_id) const {
-  const volatile BlockHeader* block = GetBlock(state->last, 0, 0, true, false);
-  if (!block)  // invalid iterator state
-    return kReferenceNull;
-
-  // The compiler and CPU can freely reorder all memory accesses on which
-  // there are no dependencies. It could, for example, move the load of
-  // "freeptr" above this point because there are no explicit dependencies
-  // between it and "next". If it did, however, then another block could
-  // be queued after that but before the following load meaning there is
-  // one more queued block than the future "detect loop by having more
-  // blocks that could fit before freeptr" will allow.
-  //
-  // By "acquiring" the "next" value here, it's synchronized to the enqueue
-  // of the node which in turn is synchronized to the allocation (which sets
-  // freeptr). Thus, the scenario above cannot happen.
-  uint32_t next = block->next.load(std::memory_order_acquire);
-  block = GetBlock(next, 0, 0, false, false);
-  if (!block)  // no next allocation in queue
-    return kReferenceNull;
-
-  // Memory corruption could cause a loop in the list. We need to detect
-  // that so as to not cause an infinite loop in the caller. We do this
-  // simply by making sure we don't iterate more than the absolute maximum
-  // number of allocations that could have been made. Callers are likely
-  // to loop multiple times before it is detected but at least it stops.
-  uint32_t freeptr = std::min(
-      shared_meta()->freeptr.load(std::memory_order_acquire),
-      mem_size_);
-  if (state->niter > freeptr / (sizeof(BlockHeader) + kAllocAlignment)) {
-    SetCorrupt();
-    return kReferenceNull;
-  }
-
-  state->last = next;
-  state->niter++;
-  *type_id = block->type_id;
-
-  return next;
-}
-
 // The "corrupted" state is held both locally and globally (shared). The
 // shared flag can't be trusted since a malicious actor could overwrite it.
 // Because corruption can be detected during read-only operations such as
@@ -571,7 +622,8 @@
 // maybe even the shared flag if the underlying data isn't actually read-only.
 void PersistentMemoryAllocator::SetCorrupt() const {
   LOG(ERROR) << "Corruption detected in shared-memory segment.";
-  const_cast<std::atomic<bool>*>(&corrupt_)->store(true);
+  const_cast<std::atomic<bool>*>(&corrupt_)->store(true,
+                                                   std::memory_order_relaxed);
   if (!readonly_) {
     SetFlag(const_cast<volatile std::atomic<uint32_t>*>(&shared_meta()->flags),
             kFlagCorrupt);
@@ -579,7 +631,8 @@
 }
 
 bool PersistentMemoryAllocator::IsCorrupt() const {
-  if (corrupt_.load() || CheckFlag(&shared_meta()->flags, kFlagCorrupt)) {
+  if (corrupt_.load(std::memory_order_relaxed) ||
+      CheckFlag(&shared_meta()->flags, kFlagCorrupt)) {
     SetCorrupt();  // Make sure all indicators are set.
     return true;
   }
@@ -610,13 +663,16 @@
 
   // Validation of referenced block-header.
   if (!free_ok) {
-    uint32_t freeptr = shared_meta()->freeptr.load();
+    uint32_t freeptr = std::min(
+        shared_meta()->freeptr.load(std::memory_order_relaxed), mem_size_);
     if (ref + size > freeptr)
       return nullptr;
     const volatile BlockHeader* const block =
         reinterpret_cast<volatile BlockHeader*>(mem_base_ + ref);
     if (block->size < size)
       return nullptr;
+    if (ref + block->size > freeptr)
+      return nullptr;
     if (ref != kReferenceQueue && block->cookie != kBlockCookieAllocated)
       return nullptr;
     if (type_id != 0 && block->type_id != type_id)
diff --git a/base/metrics/persistent_memory_allocator.h b/base/metrics/persistent_memory_allocator.h
index 8c849b6..45777fe4 100644
--- a/base/metrics/persistent_memory_allocator.h
+++ b/base/metrics/persistent_memory_allocator.h
@@ -50,22 +50,66 @@
  public:
   typedef uint32_t Reference;
 
-  // Internal state information when iterating over memory allocations.
-  class Iterator {
+  // Iterator for going through all iterable memory records in an allocator.
+  // Like the allocator itself, iterators are lock-free and thread-secure.
+  // That means that multiple threads can share an iterator and the same
+  // reference will not be returned twice.
+  //
+  // Iteration, in general, is tolerant of corrupted memory. It will return
+  // what it can and stop only when corruption forces it to. Bad corruption
+  // could cause the same object to be returned many times but it will
+  // eventually quit.
+  class BASE_EXPORT Iterator {
    public:
-    Iterator() : last(0) {}
+    // Constructs an iterator on a given |allocator|, starting at the beginning.
+    // The allocator must live beyond the lifetime of the iterator. This class
+    // has read-only access to the allocator (hence "const") but the returned
+    // references can be used on a read/write version, too.
+    explicit Iterator(const PersistentMemoryAllocator* allocator);
 
-    bool operator==(const Iterator& rhs) const { return last == rhs.last; }
-    bool operator!=(const Iterator& rhs) const { return last != rhs.last; }
+    // As above but resuming from the |starting_after| reference. The first call
+    // to GetNext() will return the next object found after that reference. The
+    // reference must be to an "iterable" object; references to non-iterable
+    // objects (those that never had MakeIterable() called for them) will cause
+    // a run-time error.
+    Iterator(const PersistentMemoryAllocator* allocator,
+             Reference starting_after);
 
-    void clear() { last = 0; }
-    bool is_clear() const { return last == 0; }
+    // Gets the next iterable, storing that type in |type_return|. The actual
+    // return value is a reference to the allocation inside the allocator or
+    // zero if there are no more. GetNext() may still be called again at a
+    // later time to retrieve any new allocations that have been added.
+    Reference GetNext(uint32_t* type_return);
+
+    // Similar to above but gets the next iterable of a specific |type_match|.
+    // This should not be mixed with calls to GetNext() because any allocations
+    // skipped here due to a type mis-match will never be returned by later
+    // calls to GetNext() meaning it's possible to completely miss entries.
+    Reference GetNextOfType(uint32_t type_match);
+
+    // Converts references to objects. This is a convenience method so that
+    // users of the iterator don't need to also have their own pointer to the
+    // allocator over which the iterator runs in order to retrieve objects.
+    // Because the iterator is not read/write, only "const" objects can be
+    // fetched. Non-const objects can be fetched using the reference on a
+    // non-const (external) pointer to the same allocator (or use const_cast
+    // to remove the qualifier).
+    template <typename T>
+    const T* GetAsObject(Reference ref, uint32_t type_id) const {
+      return allocator_->GetAsObject<T>(ref, type_id);
+    }
 
    private:
-    friend class PersistentMemoryAllocator;
+    // Weak-pointer to memory allocator being iterated over.
+    const PersistentMemoryAllocator* allocator_;
 
-    Reference last;
-    uint32_t niter;
+    // The last record that was returned.
+    std::atomic<Reference> last_record_;
+
+    // The number of records found; used for detecting loops.
+    std::atomic<uint32_t> record_count_;
+
+    DISALLOW_COPY_AND_ASSIGN(Iterator);
   };
 
   // Returned information about the internal state of the heap.
@@ -212,17 +256,6 @@
   // also make the true amount less than what is reported.
   void GetMemoryInfo(MemoryInfo* meminfo) const;
 
-  // Iterating uses a |state| structure (initialized by CreateIterator) and
-  // returns both the reference to the object as well as the |type_id| of
-  // that object. A zero return value indicates there are currently no more
-  // objects to be found but future attempts can be made without having to
-  // reset the iterator to "first". Creating an iterator |starting_after|
-  // a known iterable object allows "resume" from that point with the next
-  // call to GetNextIterable returning the object after it.
-  void CreateIterator(Iterator* state) const { CreateIterator(state, 0); };
-  void CreateIterator(Iterator* state, Reference starting_after) const;
-  Reference GetNextIterable(Iterator* state, uint32_t* type_id) const;
-
   // If there is some indication that the memory has become corrupted,
   // calling this will attempt to prevent further damage by indicating to
   // all processes that something is not as expected.
diff --git a/base/metrics/persistent_memory_allocator_unittest.cc b/base/metrics/persistent_memory_allocator_unittest.cc
index 6ec5a03..70e13921 100644
--- a/base/metrics/persistent_memory_allocator_unittest.cc
+++ b/base/metrics/persistent_memory_allocator_unittest.cc
@@ -14,6 +14,8 @@
 #include "base/metrics/histogram.h"
 #include "base/rand_util.h"
 #include "base/strings/safe_sprintf.h"
+#include "base/synchronization/condition_variable.h"
+#include "base/synchronization/lock.h"
 #include "base/threading/simple_thread.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
@@ -69,12 +71,11 @@
   }
 
   unsigned CountIterables() {
-    PersistentMemoryAllocator::Iterator iter;
+    PersistentMemoryAllocator::Iterator iter(allocator_.get());
     uint32_t type;
     unsigned count = 0;
-    for (allocator_->CreateIterator(&iter);
-         allocator_->GetNextIterable(&iter, &type) != 0;) {
-      count++;
+    while (iter.GetNext(&type) != 0) {
+      ++count;
     }
     return count;
   }
@@ -115,14 +116,13 @@
   EXPECT_GT(meminfo0.free, meminfo1.free);
 
   // Ensure that the test-object can be made iterable.
-  PersistentMemoryAllocator::Iterator iter;
+  PersistentMemoryAllocator::Iterator iter1a(allocator_.get());
   uint32_t type;
-  allocator_->CreateIterator(&iter);
-  EXPECT_EQ(0U, allocator_->GetNextIterable(&iter, &type));
+  EXPECT_EQ(0U, iter1a.GetNext(&type));
   allocator_->MakeIterable(block1);
-  EXPECT_EQ(block1, allocator_->GetNextIterable(&iter, &type));
+  EXPECT_EQ(block1, iter1a.GetNext(&type));
   EXPECT_EQ(1U, type);
-  EXPECT_EQ(0U, allocator_->GetNextIterable(&iter, &type));
+  EXPECT_EQ(0U, iter1a.GetNext(&type));
 
   // Create second test-object and ensure everything is good and it cannot
   // be confused with test-object of another type.
@@ -140,14 +140,14 @@
 
   // Ensure that second test-object can also be made iterable.
   allocator_->MakeIterable(block2);
-  EXPECT_EQ(block2, allocator_->GetNextIterable(&iter, &type));
+  EXPECT_EQ(block2, iter1a.GetNext(&type));
   EXPECT_EQ(2U, type);
-  EXPECT_EQ(0U, allocator_->GetNextIterable(&iter, &type));
+  EXPECT_EQ(0U, iter1a.GetNext(&type));
 
   // Check that iteration can begin after an arbitrary location.
-  allocator_->CreateIterator(&iter, block1);
-  EXPECT_EQ(block2, allocator_->GetNextIterable(&iter, &type));
-  EXPECT_EQ(0U, allocator_->GetNextIterable(&iter, &type));
+  PersistentMemoryAllocator::Iterator iter1b(allocator_.get(), block1);
+  EXPECT_EQ(block2, iter1b.GetNext(&type));
+  EXPECT_EQ(0U, iter1b.GetNext(&type));
 
   // Ensure nothing has gone noticably wrong.
   EXPECT_FALSE(allocator_->IsFull());
@@ -192,10 +192,10 @@
   EXPECT_NE(allocator2->allocs_histogram_, allocator_->allocs_histogram_);
 
   // Ensure that iteration and access through second allocator works.
-  allocator2->CreateIterator(&iter);
-  EXPECT_EQ(block1, allocator2->GetNextIterable(&iter, &type));
-  EXPECT_EQ(block2, allocator2->GetNextIterable(&iter, &type));
-  EXPECT_EQ(0U, allocator2->GetNextIterable(&iter, &type));
+  PersistentMemoryAllocator::Iterator iter2(allocator2.get());
+  EXPECT_EQ(block1, iter2.GetNext(&type));
+  EXPECT_EQ(block2, iter2.GetNext(&type));
+  EXPECT_EQ(0U, iter2.GetNext(&type));
   EXPECT_NE(nullptr, allocator2->GetAsObject<TestObject1>(block1, 1));
   EXPECT_NE(nullptr, allocator2->GetAsObject<TestObject2>(block2, 2));
 
@@ -208,12 +208,17 @@
   EXPECT_FALSE(allocator3->allocs_histogram_);
 
   // Ensure that iteration and access through third allocator works.
-  allocator3->CreateIterator(&iter);
-  EXPECT_EQ(block1, allocator3->GetNextIterable(&iter, &type));
-  EXPECT_EQ(block2, allocator3->GetNextIterable(&iter, &type));
-  EXPECT_EQ(0U, allocator3->GetNextIterable(&iter, &type));
+  PersistentMemoryAllocator::Iterator iter3(allocator3.get());
+  EXPECT_EQ(block1, iter3.GetNext(&type));
+  EXPECT_EQ(block2, iter3.GetNext(&type));
+  EXPECT_EQ(0U, iter3.GetNext(&type));
   EXPECT_NE(nullptr, allocator3->GetAsObject<TestObject1>(block1, 1));
   EXPECT_NE(nullptr, allocator3->GetAsObject<TestObject2>(block2, 2));
+
+  // Ensure that GetNextOfType works.
+  PersistentMemoryAllocator::Iterator iter1c(allocator_.get());
+  EXPECT_EQ(block2, iter1c.GetNextOfType(2));
+  EXPECT_EQ(0U, iter1c.GetNextOfType(2));
 }
 
 TEST_F(PersistentMemoryAllocatorTest, PageTest) {
@@ -305,6 +310,103 @@
             t5.iterable());
 }
 
+// A simple thread that counts objects by iterating through an allocator.
+class CounterThread : public SimpleThread {
+ public:
+  CounterThread(const std::string& name,
+                PersistentMemoryAllocator::Iterator* iterator,
+                Lock* lock,
+                ConditionVariable* condition)
+      : SimpleThread(name, Options()),
+        iterator_(iterator),
+        lock_(lock),
+        condition_(condition),
+        count_(0) {}
+
+  void Run() override {
+    // Wait so all threads can start at approximately the same time.
+    // Best performance comes from releasing a single worker which then
+    // releases the next, etc., etc.
+    {
+      AutoLock autolock(*lock_);
+      condition_->Wait();
+      condition_->Signal();
+    }
+
+    uint32_t type;
+    while (iterator_->GetNext(&type) != 0) {
+      ++count_;
+    }
+  }
+
+  unsigned count() { return count_; }
+
+ private:
+  PersistentMemoryAllocator::Iterator* iterator_;
+  Lock* lock_;
+  ConditionVariable* condition_;
+  unsigned count_;
+};
+
+// Ensure that parallel iteration returns the same number of objects as
+// single-threaded iteration.
+TEST_F(PersistentMemoryAllocatorTest, IteratorParallelismTest) {
+  // Fill the memory segment with random allocations.
+  unsigned iterable_count = 0;
+  for (;;) {
+    uint32_t size = RandInt(1, 99);
+    uint32_t type = RandInt(100, 999);
+    Reference block = allocator_->Allocate(size, type);
+    if (!block)
+      break;
+    allocator_->MakeIterable(block);
+    ++iterable_count;
+  }
+  EXPECT_FALSE(allocator_->IsCorrupt());
+  EXPECT_TRUE(allocator_->IsFull());
+  EXPECT_EQ(iterable_count, CountIterables());
+
+  PersistentMemoryAllocator::Iterator iter(allocator_.get());
+  Lock lock;
+  ConditionVariable condition(&lock);
+
+  CounterThread t1("t1", &iter, &lock, &condition);
+  CounterThread t2("t2", &iter, &lock, &condition);
+  CounterThread t3("t3", &iter, &lock, &condition);
+  CounterThread t4("t4", &iter, &lock, &condition);
+  CounterThread t5("t5", &iter, &lock, &condition);
+
+  t1.Start();
+  t2.Start();
+  t3.Start();
+  t4.Start();
+  t5.Start();
+
+  // This will release all the waiting threads.
+  condition.Signal();
+
+  t1.Join();
+  t2.Join();
+  t3.Join();
+  t4.Join();
+  t5.Join();
+
+  EXPECT_EQ(iterable_count,
+            t1.count() + t2.count() + t3.count() + t4.count() + t5.count());
+
+#if 0
+  // These ensure that the threads don't run sequentially. It shouldn't be
+  // enabled in general because it could lead to a flaky test if it happens
+  // simply by chance but it is useful during development to ensure that the
+  // test is working correctly.
+  EXPECT_NE(iterable_count, t1.count());
+  EXPECT_NE(iterable_count, t2.count());
+  EXPECT_NE(iterable_count, t3.count());
+  EXPECT_NE(iterable_count, t4.count());
+  EXPECT_NE(iterable_count, t5.count());
+#endif
+}
+
 // This test doesn't verify anything other than it doesn't crash. Its goal
 // is to find coding errors that aren't otherwise tested for, much like a
 // "fuzzer" would.
@@ -427,12 +529,11 @@
   EXPECT_FALSE(shalloc2.IsFull());
   EXPECT_FALSE(shalloc2.IsCorrupt());
 
-  PersistentMemoryAllocator::Iterator iter2;
+  PersistentMemoryAllocator::Iterator iter2(&shalloc2);
   uint32_t type;
-  shalloc2.CreateIterator(&iter2);
-  EXPECT_EQ(r123, shalloc2.GetNextIterable(&iter2, &type));
-  EXPECT_EQ(r789, shalloc2.GetNextIterable(&iter2, &type));
-  EXPECT_EQ(0U, shalloc2.GetNextIterable(&iter2, &type));
+  EXPECT_EQ(r123, iter2.GetNext(&type));
+  EXPECT_EQ(r789, iter2.GetNext(&type));
+  EXPECT_EQ(0U, iter2.GetNext(&type));
 
   EXPECT_EQ(123U, shalloc2.GetType(r123));
   EXPECT_EQ(654U, shalloc2.GetType(r456));
@@ -454,11 +555,10 @@
   EXPECT_FALSE(shalloc3.IsFull());
   EXPECT_FALSE(shalloc3.IsCorrupt());
 
-  PersistentMemoryAllocator::Iterator iter3;
-  shalloc3.CreateIterator(&iter3);
-  EXPECT_EQ(r123, shalloc3.GetNextIterable(&iter3, &type));
-  EXPECT_EQ(r789, shalloc3.GetNextIterable(&iter3, &type));
-  EXPECT_EQ(0U, shalloc3.GetNextIterable(&iter3, &type));
+  PersistentMemoryAllocator::Iterator iter3(&shalloc3);
+  EXPECT_EQ(r123, iter3.GetNext(&type));
+  EXPECT_EQ(r789, iter3.GetNext(&type));
+  EXPECT_EQ(0U, iter3.GetNext(&type));
 
   EXPECT_EQ(123U, shalloc3.GetType(r123));
   EXPECT_EQ(654U, shalloc3.GetType(r456));
@@ -473,7 +573,7 @@
   Reference obj = shalloc3.Allocate(42, 42);
   ASSERT_TRUE(obj);
   shalloc3.MakeIterable(obj);
-  EXPECT_EQ(obj, shalloc2.GetNextIterable(&iter2, &type));
+  EXPECT_EQ(obj, iter2.GetNext(&type));
   EXPECT_EQ(42U, type);
 }
 
@@ -517,12 +617,11 @@
   EXPECT_FALSE(file.IsFull());
   EXPECT_FALSE(file.IsCorrupt());
 
-  PersistentMemoryAllocator::Iterator iter;
+  PersistentMemoryAllocator::Iterator iter(&file);
   uint32_t type;
-  file.CreateIterator(&iter);
-  EXPECT_EQ(r123, file.GetNextIterable(&iter, &type));
-  EXPECT_EQ(r789, file.GetNextIterable(&iter, &type));
-  EXPECT_EQ(0U, file.GetNextIterable(&iter, &type));
+  EXPECT_EQ(r123, iter.GetNext(&type));
+  EXPECT_EQ(r789, iter.GetNext(&type));
+  EXPECT_EQ(0U, iter.GetNext(&type));
 
   EXPECT_EQ(123U, file.GetType(r123));
   EXPECT_EQ(654U, file.GetType(r456));
@@ -542,8 +641,8 @@
   FilePath file_path_base = temp_dir.path().AppendASCII("persistent_memory_");
 
   LocalPersistentMemoryAllocator local(TEST_MEMORY_SIZE, TEST_ID, "");
-  local.Allocate(1, 1);
-  local.Allocate(11, 11);
+  local.MakeIterable(local.Allocate(1, 1));
+  local.MakeIterable(local.Allocate(11, 11));
   const size_t minsize = local.used();
   std::unique_ptr<char[]> garbage(new char[minsize]);
   RandBytes(garbage.get(), minsize);
@@ -569,12 +668,10 @@
       // error messages warning about about a corrupted memory segment.
       FilePersistentMemoryAllocator allocator(std::move(mmfile), 0, "");
       // Also make sure that iteration doesn't crash.
-      PersistentMemoryAllocator::Iterator iter;
-      allocator.CreateIterator(&iter);
-      for (;;) {
-        Reference ref = allocator.GetNextIterable(&iter, 0);
-        if (!ref)
-          break;
+      PersistentMemoryAllocator::Iterator iter(&allocator);
+      uint32_t type_id;
+      Reference ref;
+      while ((ref = iter.GetNext(&type_id)) != 0) {
         const char* data = allocator.GetAsObject<char>(ref, 0);
         uint32_t type = allocator.GetType(ref);
         size_t size = allocator.GetAllocSize(ref);
@@ -582,9 +679,9 @@
         (void)data;
         (void)type;
         (void)size;
-        // Ensure that corruption-detected flag gets properly set.
-        EXPECT_EQ(filesize != minsize, allocator.IsCorrupt());
       }
+      // Ensure that short files are detected as corrupt and full files are not.
+      EXPECT_EQ(filesize != minsize, allocator.IsCorrupt());
     } else {
       // For filesize >= minsize, the file must be acceptable. This
       // else clause (file-not-acceptable) should be reached only if
diff --git a/base/metrics/persistent_sample_map.cc b/base/metrics/persistent_sample_map.cc
index ae8ff32..3bd447a 100644
--- a/base/metrics/persistent_sample_map.cc
+++ b/base/metrics/persistent_sample_map.cc
@@ -96,11 +96,8 @@
     PersistentMemoryAllocator* allocator,
     Metadata* meta)
     : HistogramSamples(id, meta),
-      allocator_(allocator) {
-  // This is created once but will continue to return new iterables even when
-  // it has previously reached the end.
-  allocator->CreateIterator(&sample_iter_);
-
+      allocator_(allocator),
+      sample_iter_(allocator) {
   // Load all existing samples during construction. It's no worse to do it
   // here than at some point in the future and could be better if construction
   // takes place on some background thread. New samples could be created at
@@ -231,35 +228,32 @@
   //
   // This will be addressed in a future CL.
 
-  uint32_t type_id;
   PersistentMemoryAllocator::Reference ref;
-  while ((ref = allocator_->GetNextIterable(&sample_iter_, &type_id)) != 0) {
-    if (type_id == kTypeIdSampleRecord) {
-      SampleRecord* record =
-          allocator_->GetAsObject<SampleRecord>(ref, kTypeIdSampleRecord);
-      if (!record)
-        continue;
+  while ((ref = sample_iter_.GetNextOfType(kTypeIdSampleRecord)) != 0) {
+    SampleRecord* record =
+        allocator_->GetAsObject<SampleRecord>(ref, kTypeIdSampleRecord);
+    if (!record)
+      continue;
 
-      // A sample record has been found but may not be for this histogram.
-      if (record->id != id())
-        continue;
+    // A sample record has been found but may not be for this histogram.
+    if (record->id != id())
+      continue;
 
-      // Check if the record's value is already known.
-      if (!ContainsKey(sample_counts_, record->value)) {
-        // No: Add it to map of known values if the value is valid.
-        if (record->value >= 0)
-          sample_counts_[record->value] = &record->count;
-      } else {
-        // Yes: Ignore it; it's a duplicate caused by a race condition -- see
-        // code & comment in GetOrCreateSampleCountStorage() for details.
-        // Check that nothing ever operated on the duplicate record.
-        DCHECK_EQ(0, record->count);
-      }
-
-      // Stop if it's the value being searched for.
-      if (record->value == until_value)
-        return &record->count;
+    // Check if the record's value is already known.
+    if (!ContainsKey(sample_counts_, record->value)) {
+      // No: Add it to map of known values if the value is valid.
+      if (record->value >= 0)
+        sample_counts_[record->value] = &record->count;
+    } else {
+      // Yes: Ignore it; it's a duplicate caused by a race condition -- see
+      // code & comment in GetOrCreateSampleCountStorage() for details.
+      // Check that nothing ever operated on the duplicate record.
+      DCHECK_EQ(0, record->count);
     }
+
+    // Stop if it's the value being searched for.
+    if (record->value == until_value)
+      return &record->count;
   }
 
   return nullptr;
diff --git a/blimp/client/feature/compositor/blimp_context_provider.cc b/blimp/client/feature/compositor/blimp_context_provider.cc
index 2e2874b..f4a963e8 100644
--- a/blimp/client/feature/compositor/blimp_context_provider.cc
+++ b/blimp/client/feature/compositor/blimp_context_provider.cc
@@ -89,8 +89,8 @@
   if (gr_context_)
     return gr_context_.get();
 
-  skia::RefPtr<GrGLInterface> interface =
-      skia_bindings::CreateGLES2InterfaceBindings(ContextGL());
+  sk_sp<GrGLInterface> interface(
+      skia_bindings::CreateGLES2InterfaceBindings(ContextGL()));
 
   gr_context_ = skia::AdoptRef(GrContext::Create(
       // GrContext takes ownership of |interface|.
diff --git a/build/android/test_runner.py b/build/android/test_runner.py
index 1f3752a4..390baba 100755
--- a/build/android/test_runner.py
+++ b/build/android/test_runner.py
@@ -320,7 +320,8 @@
   """Adds the Java test options to |option_parser|."""
 
   argument_group.add_argument(
-      '-f', '--test-filter', dest='test_filter',
+      '-f', '--test-filter', '--gtest_filter', '--gtest-filter',
+      dest='test_filter',
       help=('Test filter (if not fully qualified, will run all matches).'))
   argument_group.add_argument(
       '--repeat', dest='repeat', type=int, default=0,
diff --git a/build/linux/system.gyp b/build/linux/system.gyp
index a325aca..db29cff 100644
--- a/build/linux/system.gyp
+++ b/build/linux/system.gyp
@@ -1190,29 +1190,29 @@
             ['_toolset=="target"', {
               'direct_dependent_settings': {
                 'cflags': [
-                  '<!@(<(pkg-config) --cflags pangocairo pangoft2)',
+                  '<!@(<(pkg-config) --cflags pangocairo)',
                 ],
               },
               'link_settings': {
                 'ldflags': [
-                  '<!@(<(pkg-config) --libs-only-L --libs-only-other pangocairo pangoft2)',
+                  '<!@(<(pkg-config) --libs-only-L --libs-only-other pangocairo)',
                 ],
                 'libraries': [
-                  '<!@(<(pkg-config) --libs-only-l pangocairo pangoft2)',
+                  '<!@(<(pkg-config) --libs-only-l pangocairo)',
                 ],
               },
             }, {
               'direct_dependent_settings': {
                 'cflags': [
-                  '<!@(<(pkg-config) --cflags pangocairo pangoft2)',
+                  '<!@(<(pkg-config) --cflags pangocairo)',
                 ],
               },
               'link_settings': {
                 'ldflags': [
-                  '<!@(<(pkg-config) --libs-only-L --libs-only-other pangocairo pangoft2)',
+                  '<!@(<(pkg-config) --libs-only-L --libs-only-other pangocairo)',
                 ],
                 'libraries': [
-                  '<!@(<(pkg-config) --libs-only-l pangocairo pangoft2)',
+                  '<!@(<(pkg-config) --libs-only-l pangocairo)',
                 ],
               },
             }],
diff --git a/cc/layers/heads_up_display_layer_impl.cc b/cc/layers/heads_up_display_layer_impl.cc
index c2f8a1b5..610be60e 100644
--- a/cc/layers/heads_up_display_layer_impl.cc
+++ b/cc/layers/heads_up_display_layer_impl.cc
@@ -179,8 +179,8 @@
       !hud_surface_) {
     TRACE_EVENT0("cc", "ResizeHudCanvas");
 
-    hud_surface_ = skia::AdoptRef(SkSurface::NewRasterN32Premul(
-        internal_content_bounds_.width(), internal_content_bounds_.height()));
+    hud_surface_ = SkSurface::MakeRasterN32Premul(
+        internal_content_bounds_.width(), internal_content_bounds_.height());
   }
 
   UpdateHudContents();
@@ -200,7 +200,7 @@
   TRACE_EVENT0("cc", "UploadHudTexture");
   SkImageInfo info;
   size_t row_bytes = 0;
-  const void* pixels = hud_surface_->getCanvas()->peekPixels(&info, &row_bytes);
+  const void* pixels = hud_surface_->peekPixels(&info, &row_bytes);
   DCHECK(pixels);
   DCHECK(info.colorType() == kN32_SkColorType);
   resource_provider->CopyToResource(resources_.back()->id(),
diff --git a/cc/layers/heads_up_display_layer_impl.h b/cc/layers/heads_up_display_layer_impl.h
index dfe9b0d..b97eb141 100644
--- a/cc/layers/heads_up_display_layer_impl.h
+++ b/cc/layers/heads_up_display_layer_impl.h
@@ -130,7 +130,7 @@
   void ReleaseUnmatchedSizeResources(ResourceProvider* resource_provider);
 
   std::vector<scoped_ptr<ScopedResource>> resources_;
-  skia::RefPtr<SkSurface> hud_surface_;
+  sk_sp<SkSurface> hud_surface_;
 
   skia::RefPtr<SkTypeface> typeface_;
 
diff --git a/cc/layers/picture_image_layer_unittest.cc b/cc/layers/picture_image_layer_unittest.cc
index fb5c482..fb0f206 100644
--- a/cc/layers/picture_image_layer_unittest.cc
+++ b/cc/layers/picture_image_layer_unittest.cc
@@ -29,8 +29,8 @@
   unsigned char image_pixels[4 * 200 * 200] = {0};
   SkImageInfo info =
       SkImageInfo::MakeN32Premul(layer_rect.width(), layer_rect.height());
-  skia::RefPtr<SkSurface> image_surface = skia::AdoptRef(
-      SkSurface::NewRasterDirect(info, image_pixels, info.minRowBytes()));
+  sk_sp<SkSurface> image_surface =
+      SkSurface::MakeRasterDirect(info, image_pixels, info.minRowBytes());
   SkCanvas* image_canvas = image_surface->getCanvas();
   image_canvas->clear(SK_ColorRED);
   SkPaint blue_paint;
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
index feef7e2..f618cfd 100644
--- a/cc/output/gl_renderer.cc
+++ b/cc/output/gl_renderer.cc
@@ -639,8 +639,8 @@
   // Create surface to draw into.
   SkImageInfo dst_info =
       SkImageInfo::MakeN32Premul(dst_rect.width(), dst_rect.height());
-  skia::RefPtr<SkSurface> surface = skia::AdoptRef(SkSurface::NewRenderTarget(
-      use_gr_context->context(), SkBudgeted::kYes, dst_info, 0));
+  sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(
+      use_gr_context->context(), SkBudgeted::kYes, dst_info);
   if (!surface) {
     TRACE_EVENT_INSTANT0("cc", "ApplyImageFilter surface allocation failed",
                          TRACE_EVENT_SCOPE_THREAD);
diff --git a/cc/output/renderer_pixeltest.cc b/cc/output/renderer_pixeltest.cc
index 6240da2..b9472b35 100644
--- a/cc/output/renderer_pixeltest.cc
+++ b/cc/output/renderer_pixeltest.cc
@@ -2486,8 +2486,7 @@
   scoped_ptr<RenderPass> pass =
       CreateTestRenderPass(id, viewport, transform_to_root);
 
-  skia::RefPtr<SkSurface> surface =
-      skia::AdoptRef(SkSurface::NewRasterN32Premul(2, 2));
+  sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(2, 2);
   ASSERT_NE(surface, nullptr);
   SkCanvas* canvas = surface->getCanvas();
   canvas->drawPoint(0, 0, SK_ColorGREEN);
@@ -2536,8 +2535,7 @@
   scoped_ptr<RenderPass> pass =
       CreateTestRenderPass(id, viewport, transform_to_root);
 
-  skia::RefPtr<SkSurface> surface =
-      skia::AdoptRef(SkSurface::NewRasterN32Premul(2, 2));
+  sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(2, 2);
   ASSERT_NE(surface, nullptr);
   SkCanvas* canvas = surface->getCanvas();
   canvas->drawPoint(0, 0, SK_ColorGREEN);
diff --git a/cc/output/software_output_device.cc b/cc/output/software_output_device.cc
index 0712938..449fa307 100644
--- a/cc/output/software_output_device.cc
+++ b/cc/output/software_output_device.cc
@@ -26,7 +26,7 @@
                                           viewport_pixel_size.height(),
                                           kOpaque_SkAlphaType);
   viewport_pixel_size_ = viewport_pixel_size;
-  surface_ = skia::AdoptRef(SkSurface::NewRaster(info));
+  surface_ = SkSurface::MakeRaster(info);
 }
 
 SkCanvas* SoftwareOutputDevice::BeginPaint(const gfx::Rect& damage_rect) {
diff --git a/cc/output/software_output_device.h b/cc/output/software_output_device.h
index 722a1928..3972297 100644
--- a/cc/output/software_output_device.h
+++ b/cc/output/software_output_device.h
@@ -8,7 +8,6 @@
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 #include "cc/base/cc_export.h"
-#include "skia/ext/refptr.h"
 #include "third_party/skia/include/core/SkSurface.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
@@ -60,7 +59,7 @@
   gfx::Size viewport_pixel_size_;
   float scale_factor_;
   gfx::Rect damage_rect_;
-  skia::RefPtr<SkSurface> surface_;
+  sk_sp<SkSurface> surface_;
   scoped_ptr<gfx::VSyncProvider> vsync_provider_;
 
  private:
diff --git a/cc/output/software_renderer.cc b/cc/output/software_renderer.cc
index a975c797..51c75014 100644
--- a/cc/output/software_renderer.cc
+++ b/cc/output/software_renderer.cc
@@ -636,8 +636,7 @@
 
   SkImageInfo dst_info =
       SkImageInfo::MakeN32Premul(to_filter->width(), to_filter->height());
-  skia::RefPtr<SkSurface> surface =
-      skia::AdoptRef(SkSurface::NewRaster(dst_info));
+  sk_sp<SkSurface> surface = SkSurface::MakeRaster(dst_info);
 
   SkMatrix localM;
   localM.setTranslate(SkIntToScalar(-quad->rect.origin().x()),
diff --git a/cc/playback/display_item_list_unittest.cc b/cc/playback/display_item_list_unittest.cc
index 4e454f61..67d890f 100644
--- a/cc/playback/display_item_list_unittest.cc
+++ b/cc/playback/display_item_list_unittest.cc
@@ -423,8 +423,7 @@
   scoped_refptr<DisplayItemList> list =
       DisplayItemList::Create(layer_rect, settings);
 
-  skia::RefPtr<SkSurface> source_surface =
-      skia::AdoptRef(SkSurface::NewRasterN32Premul(50, 50));
+  sk_sp<SkSurface> source_surface = SkSurface::MakeRasterN32Premul(50, 50);
   SkCanvas* source_canvas = source_surface->getCanvas();
   source_canvas->clear(SkColorSetRGB(128, 128, 128));
   skia::RefPtr<SkImage> source_image =
diff --git a/cc/raster/tile_task_worker_pool.cc b/cc/raster/tile_task_worker_pool.cc
index 510862a..2efd928 100644
--- a/cc/raster/tile_task_worker_pool.cc
+++ b/cc/raster/tile_task_worker_pool.cc
@@ -9,7 +9,6 @@
 #include "base/trace_event/trace_event.h"
 #include "cc/playback/raster_source.h"
 #include "cc/raster/texture_compressor.h"
-#include "skia/ext/refptr.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkSurface.h"
 
@@ -92,8 +91,8 @@
   switch (format) {
     case RGBA_8888:
     case BGRA_8888: {
-      skia::RefPtr<SkSurface> surface = skia::AdoptRef(
-          SkSurface::NewRasterDirect(info, memory, stride, &surface_props));
+      sk_sp<SkSurface> surface =
+          SkSurface::MakeRasterDirect(info, memory, stride, &surface_props);
       raster_source->PlaybackToCanvas(surface->getCanvas(), canvas_bitmap_rect,
                                       canvas_playback_rect, scale,
                                       playback_settings);
@@ -101,8 +100,7 @@
     }
     case RGBA_4444:
     case ETC1: {
-      skia::RefPtr<SkSurface> surface =
-          skia::AdoptRef(SkSurface::NewRaster(info, &surface_props));
+      sk_sp<SkSurface> surface = SkSurface::MakeRaster(info, &surface_props);
       // TODO(reveman): Improve partial raster support by reducing the size of
       // playback rect passed to PlaybackToCanvas. crbug.com/519070
       raster_source->PlaybackToCanvas(surface->getCanvas(), canvas_bitmap_rect,
@@ -127,8 +125,7 @@
         SkImageInfo dst_info = SkImageInfo::Make(
             info.width(), info.height(), ResourceFormatToSkColorType(format),
             info.alphaType(), info.profileType());
-        bool rv =
-            surface->getCanvas()->readPixels(dst_info, memory, stride, 0, 0);
+        bool rv = surface->readPixels(dst_info, memory, stride, 0, 0);
         DCHECK(rv);
       }
       return;
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc
index 759c2444..b4e821d5 100644
--- a/cc/resources/resource_provider.cc
+++ b/cc/resources/resource_provider.cc
@@ -1139,14 +1139,14 @@
     surface_props =
         SkSurfaceProps(flags, SkSurfaceProps::kLegacyFontHost_InitType);
   }
-  sk_surface_ = skia::AdoptRef(SkSurface::NewFromBackendTextureAsRenderTarget(
-      gr_context, desc, &surface_props));
+  sk_surface_ = SkSurface::MakeFromBackendTextureAsRenderTarget(
+      gr_context, desc, &surface_props);
 }
 
 void ResourceProvider::ScopedWriteLockGr::ReleaseSkSurface() {
   DCHECK(sk_surface_);
   sk_surface_->prepareForExternalIO();
-  sk_surface_.clear();
+  sk_surface_.reset();
 }
 
 ResourceProvider::SynchronousFence::SynchronousFence(
diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h
index 399ac1d..0c6d3b7 100644
--- a/cc/resources/resource_provider.h
+++ b/cc/resources/resource_provider.h
@@ -357,7 +357,7 @@
     ResourceProvider* resource_provider_;
     ResourceProvider::Resource* resource_;
     base::ThreadChecker thread_checker_;
-    skia::RefPtr<SkSurface> sk_surface_;
+    sk_sp<SkSurface> sk_surface_;
     bool set_sync_token_;
     gpu::SyncToken sync_token_;
 
diff --git a/cc/test/test_in_process_context_provider.cc b/cc/test/test_in_process_context_provider.cc
index c9358b1f..dd05be3 100644
--- a/cc/test/test_in_process_context_provider.cc
+++ b/cc/test/test_in_process_context_provider.cc
@@ -89,8 +89,8 @@
   if (gr_context_)
     return gr_context_.get();
 
-  skia::RefPtr<GrGLInterface> interface =
-      skia_bindings::CreateGLES2InterfaceBindings(ContextGL());
+  sk_sp<GrGLInterface> interface(
+      skia_bindings::CreateGLES2InterfaceBindings(ContextGL()));
 
   gr_context_ = skia::AdoptRef(GrContext::Create(
       // GrContext takes ownership of |interface|.
diff --git a/cc/tiles/tile_manager_unittest.cc b/cc/tiles/tile_manager_unittest.cc
index 29d24557..ba8f369 100644
--- a/cc/tiles/tile_manager_unittest.cc
+++ b/cc/tiles/tile_manager_unittest.cc
@@ -1744,8 +1744,8 @@
     SCOPED_TRACE(resolutions[i]);
 
     // Make a RasterSource that will draw a blue bitmap image.
-    skia::RefPtr<SkSurface> surface = skia::AdoptRef(
-        SkSurface::NewRasterN32Premul(size.width(), size.height()));
+    sk_sp<SkSurface> surface =
+        SkSurface::MakeRasterN32Premul(size.width(), size.height());
     ASSERT_NE(surface, nullptr);
     surface->getCanvas()->clear(SK_ColorBLUE);
     skia::RefPtr<SkImage> blue_image =
diff --git a/cc/trees/layer_tree_host_pixeltest_blending.cc b/cc/trees/layer_tree_host_pixeltest_blending.cc
index a53963ea..9d356c48 100644
--- a/cc/trees/layer_tree_host_pixeltest_blending.cc
+++ b/cc/trees/layer_tree_host_pixeltest_blending.cc
@@ -131,8 +131,8 @@
     // Draw the backdrop with horizontal lanes.
     const int kLaneWidth = width;
     const int kLaneHeight = height / kCSSTestColorsCount;
-    skia::RefPtr<SkSurface> backing_store =
-        skia::AdoptRef(SkSurface::NewRasterN32Premul(width, height));
+    sk_sp<SkSurface> backing_store =
+        SkSurface::MakeRasterN32Premul(width, height);
     SkCanvas* canvas = backing_store->getCanvas();
     canvas->clear(SK_ColorTRANSPARENT);
     for (int i = 0; i < kCSSTestColorsCount; ++i) {
@@ -158,8 +158,8 @@
     mask->SetIsMask(true);
     mask->SetBounds(bounds);
 
-    skia::RefPtr<SkSurface> surface = skia::AdoptRef(
-        SkSurface::NewRasterN32Premul(bounds.width(), bounds.height()));
+    sk_sp<SkSurface> surface =
+        SkSurface::MakeRasterN32Premul(bounds.width(), bounds.height());
     SkCanvas* canvas = surface->getCanvas();
     SkPaint paint;
     paint.setColor(SK_ColorWHITE);
diff --git a/cc/trees/layer_tree_host_pixeltest_masks.cc b/cc/trees/layer_tree_host_pixeltest_masks.cc
index 3a6f1278..4b95013 100644
--- a/cc/trees/layer_tree_host_pixeltest_masks.cc
+++ b/cc/trees/layer_tree_host_pixeltest_masks.cc
@@ -102,8 +102,7 @@
   mask->SetIsMask(true);
   mask->SetBounds(mask_bounds);
 
-  skia::RefPtr<SkSurface> surface =
-      skia::AdoptRef(SkSurface::NewRasterN32Premul(200, 200));
+  sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(200, 200);
   SkCanvas* canvas = surface->getCanvas();
   canvas->scale(SkIntToScalar(4), SkIntToScalar(4));
   MaskContentLayerClient client(mask_bounds);
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index 7f56ae4a..5525263 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -725,11 +725,11 @@
   LayerImpl* root_scroll_layer = OuterViewportScrollLayer()
                                      ? OuterViewportScrollLayer()
                                      : InnerViewportScrollLayer();
-  if (!root_scroll_layer || root_scroll_layer->children().empty())
+  if (!root_scroll_layer)
     return gfx::Rect();
-  LayerImpl* layer = root_scroll_layer->children()[0];
-  return MathUtil::MapEnclosingClippedRect(layer->ScreenSpaceTransform(),
-                                           gfx::Rect(layer->bounds()));
+  return MathUtil::MapEnclosingClippedRect(
+      root_scroll_layer->ScreenSpaceTransform(),
+      gfx::Rect(root_scroll_layer->bounds()));
 }
 
 void LayerTreeImpl::ApplySentScrollAndScaleDeltasFromAbortedCommit() {
@@ -988,11 +988,10 @@
   LayerImpl* root_scroll_layer = OuterViewportScrollLayer()
                                      ? OuterViewportScrollLayer()
                                      : InnerViewportScrollLayer();
-  if (!root_scroll_layer || root_scroll_layer->children().empty())
+  if (!root_scroll_layer)
     return gfx::SizeF();
 
-  gfx::SizeF content_size =
-      root_scroll_layer->children()[0]->BoundsForScrolling();
+  gfx::SizeF content_size = root_scroll_layer->BoundsForScrolling();
   gfx::SizeF viewport_size =
       root_scroll_layer->scroll_clip_layer()->BoundsForScrolling();
 
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 38b7ea7..37b22b7 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -605,6 +605,5 @@
     ":chrome_sync_shell_test_apk_java",
     ":chrome_sync_shell_test_apk_manifest",
   ]
-  isolate_file = "../chrome_sync_shell_test_apk.isolate"
   proguard_enabled = !is_debug
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java
index 86bc1c2..10a9ba7 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java
@@ -387,25 +387,18 @@
 
     private MediaSessionCompat mMediaSession;
 
-    private static final class MediaSessionCallback extends MediaSessionCompat.Callback {
-        private final MediaNotificationManager mManager;
+    private final MediaSessionCompat.Callback mMediaSessionCallback =
+            new MediaSessionCompat.Callback() {
+                @Override
+                public void onPlay() {
+                    onPlay(MediaNotificationListener.ACTION_SOURCE_MEDIA_SESSION);
+                }
 
-        private MediaSessionCallback(MediaNotificationManager manager) {
-            mManager = manager;
-        }
-
-        @Override
-        public void onPlay() {
-            mManager.onPlay(MediaNotificationListener.ACTION_SOURCE_MEDIA_SESSION);
-        }
-
-        @Override
-        public void onPause() {
-            mManager.onPause(MediaNotificationListener.ACTION_SOURCE_MEDIA_SESSION);
-        }
-    }
-
-    private final MediaSessionCallback mMediaSessionCallback = new MediaSessionCallback(this);
+                @Override
+                public void onPause() {
+                    onPause(MediaNotificationListener.ACTION_SOURCE_MEDIA_SESSION);
+                }
+            };
 
     private MediaNotificationManager(Context context, int notificationId) {
         mContext = context;
@@ -473,6 +466,7 @@
         manager.cancel(mMediaNotificationInfo.id);
 
         if (mMediaSession != null) {
+            mMediaSession.setCallback(null);
             mMediaSession.setActive(false);
             mMediaSession.release();
             mMediaSession = null;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java
index 2fbb9e6..a3b8e69d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountSigninView.java
@@ -234,14 +234,6 @@
     }
 
     @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        // Ensure that the spinner's dropdown is the same width and vertically aligned with the
-        // spinner. The spinner's start and end padding must be 0 for this to work.
-        mSpinner.setDropDownWidth(mSpinner.getWidth());
-    }
-
-    @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         updateAccounts();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/ConfirmImportSyncDataDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/ConfirmImportSyncDataDialog.java
index c83e7bf..2941cf4f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/ConfirmImportSyncDataDialog.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/ConfirmImportSyncDataDialog.java
@@ -190,5 +190,10 @@
             mListener.onCancel();
         }
     }
+
+    @Override
+    public void onDismiss(DialogInterface dialog) {
+        if (mListener != null) mListener.onCancel();
+    }
 }
 
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 1822034..ab15b94 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -6072,14 +6072,6 @@
       </message>
 
       <!-- Data Reduction Proxy -->
-      <if expr="is_android">
-        <message name="IDS_FLAGS_DATA_REDUCTION_PROXY_DEV_NAME" desc="An about::flags experiment title to enable/disable the development version of the data reduction proxy" translateable="false">
-          Experiment Data Reduction Proxy
-        </message>
-        <message name="IDS_FLAGS_DATA_REDUCTION_PROXY_DEV_DESCRIPTION" desc="Describes an about:flags experiment to enable/disable the development version of the data reduction proxy" translateable="false">
-         Enable or disable using the development version of the data reduction proxy.
-        </message>
-      </if>
       <message name="IDS_FLAGS_DATA_REDUCTION_PROXY_LO_FI_NAME" desc="An about::flags experiment title to enable/disable Data Saver Lo-Fi" translateable="false">
          Data Saver Lo-Fi mode
       </message>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index da3131b..4844d3f 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1328,11 +1328,6 @@
      SINGLE_VALUE_TYPE(extensions::switches::kEnableScriptsRequireAction)},
 #endif
 #if defined(OS_ANDROID)
-    {"enable-data-reduction-proxy-dev", IDS_FLAGS_DATA_REDUCTION_PROXY_DEV_NAME,
-     IDS_FLAGS_DATA_REDUCTION_PROXY_DEV_DESCRIPTION, kOsAndroid,
-     ENABLE_DISABLE_VALUE_TYPE(
-         data_reduction_proxy::switches::kEnableDataReductionProxyDev,
-         data_reduction_proxy::switches::kDisableDataReductionProxyDev)},
     {"enable-data-reduction-proxy-carrier-test",
      IDS_FLAGS_DATA_REDUCTION_PROXY_CARRIER_TEST_NAME,
      IDS_FLAGS_DATA_REDUCTION_PROXY_CARRIER_TEST_DESCRIPTION, kOsAndroid,
diff --git a/chrome/browser/ntp_snippets/ntp_snippets_service_factory.cc b/chrome/browser/ntp_snippets/ntp_snippets_service_factory.cc
index 7cc20a4..4c75fc8 100644
--- a/chrome/browser/ntp_snippets/ntp_snippets_service_factory.cc
+++ b/chrome/browser/ntp_snippets/ntp_snippets_service_factory.cc
@@ -8,15 +8,13 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search/suggestions/suggestions_service_factory.h"
-#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
-#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/common/channel_info.h"
 #include "components/keyed_service/content/browser_context_dependency_manager.h"
 #include "components/ntp_snippets/ntp_snippets_fetcher.h"
 #include "components/ntp_snippets/ntp_snippets_scheduler.h"
 #include "components/ntp_snippets/ntp_snippets_service.h"
 #include "components/safe_json/safe_json_parser.h"
-#include "components/signin/core/browser/profile_oauth2_token_service.h"
-#include "components/signin/core/browser/signin_manager.h"
+#include "components/version_info/version_info.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
 #include "net/url_request/url_request_context_getter.h"
@@ -46,8 +44,6 @@
     : BrowserContextKeyedServiceFactory(
           "NTPSnippetsService",
           BrowserContextDependencyManager::GetInstance()) {
-  DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance());
-  DependsOn(SigninManagerFactory::GetInstance());
   DependsOn(SuggestionsServiceFactory::GetInstance());
 }
 
@@ -56,10 +52,6 @@
 KeyedService* NTPSnippetsServiceFactory::BuildServiceInstanceFor(
     content::BrowserContext* context) const {
   Profile* profile = Profile::FromBrowserContext(context);
-  SigninManagerBase* signin_manager =
-      SigninManagerFactory::GetForProfile(profile);
-  OAuth2TokenService* token_service =
-      ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
   scoped_refptr<net::URLRequestContextGetter> request_context =
       context->GetRequestContext();
   SuggestionsService* suggestions_service =
@@ -80,6 +72,7 @@
       profile->GetPrefs(), suggestions_service, task_runner,
       g_browser_process->GetApplicationLocale(), scheduler,
       make_scoped_ptr(new ntp_snippets::NTPSnippetsFetcher(
-          task_runner, signin_manager, token_service, request_context)),
+          task_runner, request_context,
+          chrome::GetChannel() == version_info::Channel::STABLE)),
       base::Bind(&safe_json::SafeJsonParser::Parse));
 }
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc
index d282cf14..02190dca 100644
--- a/chrome/browser/password_manager/password_manager_browsertest.cc
+++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -2874,6 +2874,37 @@
                              base::ASCIIToUTF16("new_pw"));
 }
 
+IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
+                       NoCrashWhenNavigatingWithOpenAccountPicker) {
+  ASSERT_TRUE(ChromePasswordManagerClient::IsTheHotNewBubbleUIEnabled());
+  // Save credentials with 'skip_zero_click'.
+  scoped_refptr<password_manager::TestPasswordStore> password_store =
+      static_cast<password_manager::TestPasswordStore*>(
+          PasswordStoreFactory::GetForProfile(
+              browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS)
+              .get());
+  autofill::PasswordForm signin_form;
+  signin_form.signon_realm = embedded_test_server()->base_url().spec();
+  signin_form.password_value = base::ASCIIToUTF16("password");
+  signin_form.username_value = base::ASCIIToUTF16("user");
+  signin_form.origin = embedded_test_server()->base_url();
+  signin_form.skip_zero_click = true;
+  password_store->AddLogin(signin_form);
+
+  NavigateToFile("/password/password_form.html");
+
+  // Call the API to trigger the notification to the client, which raises the
+  // account picker dialog.
+  ASSERT_TRUE(content::ExecuteScript(
+      RenderViewHost(),
+      "navigator.credentials.get({password: true})"));
+
+  // Navigate while the picker is open.
+  NavigateToFile("/password/password_form.html");
+
+  // No crash!
+}
+
 // Tests that the prompt to save the password is still shown if the fields have
 // the "autocomplete" attribute set off.
 IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase,
diff --git a/chrome/browser/prerender/prerender_message_filter.cc b/chrome/browser/prerender/prerender_message_filter.cc
index d8d04de..f69a1be 100644
--- a/chrome/browser/prerender/prerender_message_filter.cc
+++ b/chrome/browser/prerender/prerender_message_filter.cc
@@ -55,6 +55,7 @@
 }
 
 PrerenderMessageFilter::~PrerenderMessageFilter() {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 }
 
 // static
@@ -91,6 +92,11 @@
       base::Bind(&PrerenderMessageFilter::OnChannelClosingInUIThread, this));
 }
 
+void PrerenderMessageFilter::OnDestruct() const {
+  // |shutdown_notifier_| needs to be destroyed on the UI thread.
+  BrowserThread::DeleteOnUIThread::Destruct(this);
+}
+
 void PrerenderMessageFilter::OnAddPrerender(
     int prerender_id,
     const PrerenderAttributes& attributes,
diff --git a/chrome/browser/prerender/prerender_message_filter.h b/chrome/browser/prerender/prerender_message_filter.h
index 76ae753ef..049db7db 100644
--- a/chrome/browser/prerender/prerender_message_filter.h
+++ b/chrome/browser/prerender/prerender_message_filter.h
@@ -37,6 +37,10 @@
   static void EnsureShutdownNotifierFactoryBuilt();
 
  private:
+  friend struct content::BrowserThread::DeleteOnThread<
+      content::BrowserThread::UI>;
+  friend class base::DeleteHelper<PrerenderMessageFilter>;
+
   ~PrerenderMessageFilter() override;
 
   // Overridden from content::BrowserMessageFilter.
@@ -44,6 +48,7 @@
   void OverrideThreadForMessage(const IPC::Message& message,
                                 content::BrowserThread::ID* thread) override;
   void OnChannelClosing() override;
+  void OnDestruct() const override;
 
   void OnAddPrerender(int prerender_id,
                       const PrerenderAttributes& attributes,
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/js/event_page.js b/chrome/browser/resources/chromeos/wallpaper_manager/js/event_page.js
index 982b45e..4fd4193 100644
--- a/chrome/browser/resources/chromeos/wallpaper_manager/js/event_page.js
+++ b/chrome/browser/resources/chromeos/wallpaper_manager/js/event_page.js
@@ -334,12 +334,29 @@
             wpDocument.querySelector('#wallpaper-grid').classList.add('small');
             if (wpDocument.querySelector('.check'))
               wpDocument.querySelector('.check').style.visibility = 'hidden';
+            wpDocument.querySelector('#checkbox').classList.remove('checked');
+            wpDocument.querySelector('#categories-list').disabled = false;
+            wpDocument.querySelector('#wallpaper-grid').disabled = false;
           });
         } else {
           wpDocument.querySelector('#wallpaper-set-by-message').textContent =
               '';
           wpDocument.querySelector('#wallpaper-grid').classList.remove('small');
-          wpDocument.querySelector('.check').style.visibility = 'visible';
+          Constants.WallpaperSyncStorage.get(
+              Constants.AccessSyncSurpriseMeEnabledKey, function(item) {
+            var enable = item[Constants.AccessSyncSurpriseMeEnabledKey];
+            if (enable) {
+              wpDocument.querySelector('#checkbox').classList.add('checked');
+              if (wpDocument.querySelector('.check'))
+                wpDocument.querySelector('.check').style.visibility = 'hidden';
+            } else {
+              wpDocument.querySelector('#checkbox').classList.remove('checked');
+              if (wpDocument.querySelector('.check'))
+                wpDocument.querySelector('.check').style.visibility = 'visible';
+            }
+            wpDocument.querySelector('#categories-list').disabled = enable;
+            wpDocument.querySelector('#wallpaper-grid').disabled = enable;
+          });
         }
       };
 
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chrome/browser/resources/settings/privacy_page/privacy_page.html
index 0b66963c..8d52d8f 100644
--- a/chrome/browser/resources/settings/privacy_page/privacy_page.html
+++ b/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -215,13 +215,12 @@
         </settings-subpage>
       </template>
 
-      <!-- TODO(finnur): switch to settings-subpage (crbug.com/597314). -->
-      <neon-animatable id="site-details">
-        <site-details
-            site="{{selectedSite}}"
-            current-route="{{currentRoute}}">
-        </site-details>
-      </neon-animatable>
+      <template is="dom-if" name="site-details">
+        <settings-subpage
+            page-title="[[i18n('siteSettingsSiteDetailsPageTitle')]]">
+          <site-details site="[[selectedSite]]"></site-details>
+        </settings-subpage>
+      </template>
     </settings-animated-pages>
   </template>
   <script src="privacy_page.js"></script>
diff --git a/chrome/browser/resources/settings/site_settings/site_details.css b/chrome/browser/resources/settings/site_settings/site_details.css
index 8d0ff67..5bc1409 100644
--- a/chrome/browser/resources/settings/site_settings/site_details.css
+++ b/chrome/browser/resources/settings/site_settings/site_details.css
@@ -7,7 +7,10 @@
 }
 
 .origin {
-  font-weight: bold;
+  font-size: 110%;
+  font-weight: 500;
+  margin-bottom: 20px;
+  margin-top: 35px;
 }
 
 .reset-button {
diff --git a/chrome/browser/resources/settings/site_settings/site_details.js b/chrome/browser/resources/settings/site_settings/site_details.js
index 931af44..5fa7764 100644
--- a/chrome/browser/resources/settings/site_settings/site_details.js
+++ b/chrome/browser/resources/settings/site_settings/site_details.js
@@ -34,14 +34,6 @@
      * The type of storage for the origin.
      */
     storageType_: Number,
-
-    /**
-     * The current active route.
-     */
-    currentRoute: {
-      type: Object,
-      notify: true,
-    },
   },
 
   listeners: {
diff --git a/chrome/browser/resources/settings/site_settings/site_details_permission.js b/chrome/browser/resources/settings/site_settings/site_details_permission.js
index b2f4ce64..5a3fa05 100644
--- a/chrome/browser/resources/settings/site_settings/site_details_permission.js
+++ b/chrome/browser/resources/settings/site_settings/site_details_permission.js
@@ -17,10 +17,7 @@
      * The site that this widget is showing details for.
      * @type {SiteException}
      */
-    site: {
-      type: Object,
-      observer: 'siteChanged_',
-    },
+    site: Object,
 
     i18n_: {
       readOnly: true,
@@ -34,6 +31,8 @@
     },
   },
 
+  observers: ['siteChanged_(site, category)'],
+
   /** @override */
   attached: function() {
     this.addWebUIListener('contentSettingSitePermissionChanged',
diff --git a/chrome/browser/thumbnails/simple_thumbnail_crop.cc b/chrome/browser/thumbnails/simple_thumbnail_crop.cc
index debdfa4..c47554c4 100644
--- a/chrome/browser/thumbnails/simple_thumbnail_crop.cc
+++ b/chrome/browser/thumbnails/simple_thumbnail_crop.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/thumbnails/simple_thumbnail_crop.h"
 
+#include <algorithm>
+
 #include "base/metrics/histogram.h"
 #include "content/public/browser/browser_thread.h"
 #include "skia/ext/platform_canvas.h"
diff --git a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.mm b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.mm
index 7d8cb9a..122ad6a 100644
--- a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.mm
+++ b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.mm
@@ -120,7 +120,9 @@
         observer->CreatePasteboardItem());
     base::scoped_nsobject<NSDraggingItem> dragItem(
         [[NSDraggingItem alloc] initWithPasteboardWriter:item]);
-    [dragItem setDraggingFrame:[self bounds] contents:image];
+    NSRect draggingFrame =
+        NSMakeRect(0, 0, image.size.width, image.size.height);
+    [dragItem setDraggingFrame:draggingFrame contents:image];
     [self beginDraggingSessionWithItems:@[ dragItem.get() ]
                                   event:event
                                  source:self];
diff --git a/chrome/browser/ui/webui/supervised_user_internals_message_handler.cc b/chrome/browser/ui/webui/supervised_user_internals_message_handler.cc
index ba2bef35..89ddaaa 100644
--- a/chrome/browser/ui/webui/supervised_user_internals_message_handler.cc
+++ b/chrome/browser/ui/webui/supervised_user_internals_message_handler.cc
@@ -266,18 +266,20 @@
 
   AccountTrackerService* account_tracker =
       AccountTrackerServiceFactory::GetForProfile(profile);
-
-  for (const auto& account: account_tracker->GetAccounts()) {
-    base::ListValue* section_user = AddSection(section_list.get(),
-        "User Information for " + account.full_name);
-    AddSectionEntry(section_user, "Account id", account.account_id);
-    AddSectionEntry(section_user, "Gaia", account.gaia);
-    AddSectionEntry(section_user, "Email", account.email);
-    AddSectionEntry(section_user, "Given name", account.given_name);
-    AddSectionEntry(section_user, "Hosted domain", account.hosted_domain);
-    AddSectionEntry(section_user, "Locale", account.locale);
-    AddSectionEntry(section_user, "Is child", account.is_child_account);
-    AddSectionEntry(section_user, "Is valid", account.IsValid());
+  // |account_tracker| is null in incognito and guest profiles.
+  if (account_tracker) {
+    for (const auto& account: account_tracker->GetAccounts()) {
+      base::ListValue* section_user = AddSection(section_list.get(),
+          "User Information for " + account.full_name);
+      AddSectionEntry(section_user, "Account id", account.account_id);
+      AddSectionEntry(section_user, "Gaia", account.gaia);
+      AddSectionEntry(section_user, "Email", account.email);
+      AddSectionEntry(section_user, "Given name", account.given_name);
+      AddSectionEntry(section_user, "Hosted domain", account.hosted_domain);
+      AddSectionEntry(section_user, "Locale", account.locale);
+      AddSectionEntry(section_user, "Is child", account.is_child_account);
+      AddSectionEntry(section_user, "Is valid", account.IsValid());
+    }
   }
 
   base::DictionaryValue result;
diff --git a/chrome/renderer/pepper/pepper_flash_renderer_host.cc b/chrome/renderer/pepper/pepper_flash_renderer_host.cc
index d4213dbd..f270407 100644
--- a/chrome/renderer/pepper/pepper_flash_renderer_host.cc
+++ b/chrome/renderer/pepper/pepper_flash_renderer_host.cc
@@ -29,6 +29,7 @@
 #include "ppapi/thunk/enter.h"
 #include "ppapi/thunk/ppb_image_data_api.h"
 #include "skia/ext/platform_canvas.h"
+#include "skia/ext/refptr.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkMatrix.h"
 #include "third_party/skia/include/core/SkPaint.h"
diff --git a/chrome/test/data/webui/settings/site_details_permission_tests.js b/chrome/test/data/webui/settings/site_details_permission_tests.js
index 0e5bb88..c0796de 100644
--- a/chrome/test/data/webui/settings/site_details_permission_tests.js
+++ b/chrome/test/data/webui/settings/site_details_permission_tests.js
@@ -122,7 +122,7 @@
           assertFalse(testElement.$.details.hidden);
 
           browserProxy.setPrefs(prefsEmpty);
-          browserProxy.whenCalled('getExceptionList').then(function() {
+          return browserProxy.whenCalled('getExceptionList').then(function() {
             assertTrue(testElement.$.details.hidden);
           }.bind(this));
         }.bind(this));
diff --git a/components/crash/content/app/crashpad_win.cc b/components/crash/content/app/crashpad_win.cc
index 419a0511..1896b178 100644
--- a/components/crash/content/app/crashpad_win.cc
+++ b/components/crash/content/app/crashpad_win.cc
@@ -57,6 +57,7 @@
   bool result;
 
   const char kPipeNameVar[] = "CHROME_CRASHPAD_PIPE_NAME";
+  const char kServerUrlVar[] = "CHROME_CRASHPAD_SERVER_URL";
   scoped_ptr<base::Environment> env(base::Environment::Create());
 
   if (initial_client) {
@@ -72,6 +73,10 @@
     std::string url;
 #endif
 
+    // Allow the crash server to be overridden for testing. If the variable
+    // isn't present in the environment then the default URL will remain.
+    env->GetVar(kServerUrlVar, &url);
+
     base::FilePath exe_file;
     CHECK(PathService::Get(base::FILE_EXE, &exe_file));
 
diff --git a/components/cronet/tools/cr_cronet.py b/components/cronet/tools/cr_cronet.py
index bb19362d6..f447e94 100755
--- a/components/cronet/tools/cr_cronet.py
+++ b/components/cronet/tools/cr_cronet.py
@@ -25,7 +25,9 @@
 
 def install(release_arg):
   return run('build/android/adb_install_apk.py ' + release_arg + \
-             ' --apk=CronetTest.apk')
+             ' --apk=CronetTest.apk') or \
+             run('build/android/adb_install_apk.py ' + release_arg + \
+             ' --apk=ChromiumNetTestSupport.apk')
 
 
 def test(release_arg, extra_options):
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc
index 2fda7a2..1c222b0 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client.cc
@@ -472,16 +472,6 @@
   std::vector<net::ProxyServer> proxies =
       GetProxiesForHTTP(config.proxy_config());
 
-  if (params_ && params::IsDevRolloutEnabled()) {
-    // If dev rollout is enabled, proxies returned by client config API are
-    // discarded.
-    proxies.clear();
-    proxies.push_back(net::ProxyServer::FromURI(params_->GetDefaultDevOrigin(),
-                                                net::ProxyServer::SCHEME_HTTP));
-    proxies.push_back(net::ProxyServer::FromURI(
-        params_->GetDefaultDevFallbackOrigin(), net::ProxyServer::SCHEME_HTTP));
-  }
-
   if (proxies.empty())
     return false;
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc
index c77e837a..c58f726 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc
@@ -344,38 +344,25 @@
   DISALLOW_COPY_AND_ASSIGN(DataReductionProxyConfigServiceClientTest);
 };
 
-// Tests the interaction of client config with dev rollout and QUIC field trial.
-TEST_F(DataReductionProxyConfigServiceClientTest, DevRolloutAndQuic) {
+// Tests the interaction of client config with QUIC field trial.
+TEST_F(DataReductionProxyConfigServiceClientTest, QuicFieldTrial) {
   Init(true);
   const struct {
-    bool enable_dev;
     bool enable_quic;
     bool enable_trusted_spdy_proxy_field_trial;
     std::string expected_primary_proxy;
     std::string expected_fallback_proxy;
     net::ProxyServer::Scheme expected_primary_proxy_scheme;
   } tests[] = {
-      {false, false, false, kSuccessOrigin, kSuccessFallback,
+      {false, false, kSuccessOrigin, kSuccessFallback,
        net::ProxyServer::SCHEME_HTTPS},
-      {false, false, true, kSuccessOrigin, kSuccessFallback,
+      {false, true, kSuccessOrigin, kSuccessFallback,
        net::ProxyServer::SCHEME_HTTPS},
-      {false, true, true, kSuccessOrigin, kSuccessFallback,
-       net::ProxyServer::SCHEME_QUIC},
-      {true, false, true, TestDataReductionProxyParams::DefaultDevOrigin(),
-       TestDataReductionProxyParams::DefaultDevFallbackOrigin(),
-       net::ProxyServer::SCHEME_HTTPS},
-      {true, true, true, TestDataReductionProxyParams::DefaultDevOrigin(),
-       TestDataReductionProxyParams::DefaultDevFallbackOrigin(),
+      {true, true, kSuccessOrigin, kSuccessFallback,
        net::ProxyServer::SCHEME_QUIC},
   };
 
   for (size_t i = 0; i < arraysize(tests); ++i) {
-    if (tests[i].enable_dev) {
-      base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
-      command_line->AppendSwitch(
-          data_reduction_proxy::switches::kEnableDataReductionProxyDev);
-    }
-
     base::FieldTrialList field_trial_list(new base::MockEntropyProvider());
     base::FieldTrialList::CreateFieldTrial(
         params::GetTrustedSpdyProxyFieldTrialName(),
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.cc
index fee0df86..5e86c1ec 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.cc
@@ -69,9 +69,7 @@
 void TestDataReductionProxyConfig::ResetParamFlagsForTest(int flags) {
   config_values_ = make_scoped_ptr(new TestDataReductionProxyParams(
       flags, TestDataReductionProxyParams::HAS_EVERYTHING &
-                 ~TestDataReductionProxyParams::HAS_SSL_ORIGIN &
-                 ~TestDataReductionProxyParams::HAS_DEV_ORIGIN &
-                 ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN));
+                 ~TestDataReductionProxyParams::HAS_SSL_ORIGIN));
 }
 
 TestDataReductionProxyParams* TestDataReductionProxyConfig::test_params() {
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
index 3c5fb84..3146f03 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_unittest.cc
@@ -62,9 +62,7 @@
             DataReductionProxyParams::kFallbackAllowed |
             DataReductionProxyParams::kPromoAllowed,
         TestDataReductionProxyParams::HAS_EVERYTHING &
-            ~TestDataReductionProxyParams::HAS_SSL_ORIGIN &
-            ~TestDataReductionProxyParams::HAS_DEV_ORIGIN &
-            ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN));
+            ~TestDataReductionProxyParams::HAS_SSL_ORIGIN));
   }
 
   void ResetSettings(bool allowed,
@@ -469,10 +467,7 @@
       flags |= DataReductionProxyParams::kAllowed;
     if (tests[i].fallback_allowed)
       flags |= DataReductionProxyParams::kFallbackAllowed;
-    unsigned int has_definitions =
-        TestDataReductionProxyParams::HAS_EVERYTHING &
-        ~TestDataReductionProxyParams::HAS_DEV_ORIGIN &
-        ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN;
+    unsigned int has_definitions = TestDataReductionProxyParams::HAS_EVERYTHING;
     scoped_ptr<TestDataReductionProxyParams> params(
         new TestDataReductionProxyParams(flags, has_definitions));
     scoped_ptr<DataReductionProxyConfig> config =
@@ -518,10 +513,7 @@
   int flags = 0;
   flags |= DataReductionProxyParams::kAllowed;
   flags |= DataReductionProxyParams::kFallbackAllowed;
-  unsigned int has_definitions =
-      TestDataReductionProxyParams::HAS_EVERYTHING &
-      ~TestDataReductionProxyParams::HAS_DEV_ORIGIN &
-      ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN;
+  unsigned int has_definitions = TestDataReductionProxyParams::HAS_EVERYTHING;
   scoped_ptr<TestDataReductionProxyParams> params(
       new TestDataReductionProxyParams(flags, has_definitions));
   scoped_ptr<DataReductionProxyConfig> config = BuildConfig(std::move(params));
@@ -565,7 +557,6 @@
   const struct {
     net::HostPortPair host_port_pair;
     bool fallback_allowed;
-    bool set_dev_origin;
     bool expected_result;
     net::HostPortPair expected_first;
     net::HostPortPair expected_second;
@@ -576,7 +567,6 @@
                                  net::ProxyServer::SCHEME_HTTP)
            .host_port_pair(),
        true,
-       false,
        true,
        net::ProxyServer::FromURI(TestDataReductionProxyParams::DefaultOrigin(),
                                  net::ProxyServer::SCHEME_HTTP)
@@ -590,7 +580,6 @@
                                  net::ProxyServer::SCHEME_HTTP)
            .host_port_pair(),
        false,
-       false,
        true,
        net::ProxyServer::FromURI(TestDataReductionProxyParams::DefaultOrigin(),
                                  net::ProxyServer::SCHEME_HTTP)
@@ -602,7 +591,6 @@
            TestDataReductionProxyParams::DefaultFallbackOrigin(),
            net::ProxyServer::SCHEME_HTTP).host_port_pair(),
        true,
-       false,
        true,
        net::ProxyServer::FromURI(
            TestDataReductionProxyParams::DefaultFallbackOrigin(),
@@ -615,7 +603,6 @@
            net::ProxyServer::SCHEME_HTTP).host_port_pair(),
        false,
        false,
-       false,
        net::HostPortPair::FromURL(GURL()),
        net::HostPortPair::FromURL(GURL()),
        false,
@@ -624,7 +611,6 @@
            TestDataReductionProxyParams::DefaultSSLOrigin(),
            net::ProxyServer::SCHEME_HTTP).host_port_pair(),
        true,
-       false,
        true,
        net::ProxyServer::FromURI(
            TestDataReductionProxyParams::DefaultSSLOrigin(),
@@ -632,40 +618,12 @@
        net::HostPortPair::FromURL(GURL()),
        false,
        true},
-      {net::ProxyServer::FromURI(
-           TestDataReductionProxyParams::DefaultDevOrigin(),
-           net::ProxyServer::SCHEME_HTTP).host_port_pair(),
-       true,
-       true,
-       true,
-       net::ProxyServer::FromURI(
-           TestDataReductionProxyParams::DefaultDevOrigin(),
-           net::ProxyServer::SCHEME_HTTP).host_port_pair(),
-       net::ProxyServer::FromURI(
-           TestDataReductionProxyParams::DefaultDevFallbackOrigin(),
-           net::ProxyServer::SCHEME_HTTP).host_port_pair(),
-       false,
-       false},
-      {net::ProxyServer::FromURI(TestDataReductionProxyParams::DefaultOrigin(),
-                                 net::ProxyServer::SCHEME_HTTP)
-           .host_port_pair(),
-       true,
-       true,
-       false,
-       net::HostPortPair::FromURL(GURL()),
-       net::HostPortPair::FromURL(GURL()),
-       false,
-       false},
   };
   for (size_t i = 0; i < arraysize(tests); ++i) {
     int flags = DataReductionProxyParams::kAllowed;
     if (tests[i].fallback_allowed)
       flags |= DataReductionProxyParams::kFallbackAllowed;
     unsigned int has_definitions = TestDataReductionProxyParams::HAS_EVERYTHING;
-    if (!tests[i].set_dev_origin) {
-      has_definitions &= ~TestDataReductionProxyParams::HAS_DEV_ORIGIN;
-      has_definitions &= ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN;
-    }
     scoped_ptr<TestDataReductionProxyParams> params(
         new TestDataReductionProxyParams(flags, has_definitions));
     DataReductionProxyTypeInfo proxy_type_info;
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc
index 310ffc9..8268474f 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options_unittest.cc
@@ -136,11 +136,8 @@
     test_context_ =
         DataReductionProxyTestContext::Builder()
             .WithParamsFlags(
-                 DataReductionProxyParams::kAllowAllProxyConfigurations)
-            .WithParamsDefinitions(
-                 TestDataReductionProxyParams::HAS_EVERYTHING &
-                 ~TestDataReductionProxyParams::HAS_DEV_ORIGIN &
-                 ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN)
+                DataReductionProxyParams::kAllowAllProxyConfigurations)
+            .WithParamsDefinitions(TestDataReductionProxyParams::HAS_EVERYTHING)
             .Build();
   }
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
index 8af0b73..fa03b6b2 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.cc
@@ -274,11 +274,8 @@
     : params_flags_(DataReductionProxyParams::kAllowed |
                     DataReductionProxyParams::kFallbackAllowed |
                     DataReductionProxyParams::kPromoAllowed),
-      params_definitions_(
-          TestDataReductionProxyParams::HAS_EVERYTHING &
-          ~TestDataReductionProxyParams::HAS_SSL_ORIGIN &
-          ~TestDataReductionProxyParams::HAS_DEV_ORIGIN &
-          ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN),
+      params_definitions_(TestDataReductionProxyParams::HAS_EVERYTHING &
+                          ~TestDataReductionProxyParams::HAS_SSL_ORIGIN),
       client_(Client::UNKNOWN),
       request_context_(nullptr),
       mock_socket_factory_(nullptr),
@@ -288,8 +285,7 @@
       use_mock_request_options_(false),
       use_config_client_(false),
       use_test_config_client_(false),
-      skip_settings_initialization_(false) {
-}
+      skip_settings_initialization_(false) {}
 
 DataReductionProxyTestContext::Builder&
 DataReductionProxyTestContext::Builder::WithParamsFlags(int params_flags) {
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc
index 4e94d36b..d4eedb0f 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.cc
@@ -34,8 +34,6 @@
 // available.
 const char kCarrierTestOrigin[] =
     "http://o-o.preferred.nttdocomodcp-hnd1.proxy-dev.googlezip.net:80";
-const char kDevOrigin[] = "https://proxy-dev.googlezip.net:443";
-const char kDevFallbackOrigin[] = "proxy-dev.googlezip.net:80";
 const char kDefaultFallbackOrigin[] = "compress.googlezip.net:80";
 const char kDefaultSecureProxyCheckUrl[] = "http://check.googlezip.net/connect";
 const char kDefaultWarmupUrl[] = "http://www.gstatic.com/generate_204";
@@ -43,7 +41,6 @@
 const char kAndroidOneIdentifier[] = "sprout";
 
 const char kQuicFieldTrial[] = "DataReductionProxyUseQuic";
-const char kDevRolloutFieldTrial[] = "DataCompressionProxyDevRollout";
 
 const char kLoFiFieldTrial[] = "DataCompressionProxyLoFi";
 const char kLoFiFlagFieldTrial[] = "DataCompressionProxyLoFiFlag";
@@ -174,16 +171,6 @@
   return kQuicFieldTrial;
 }
 
-bool IsDevRolloutEnabled() {
-  const base::CommandLine& command_line =
-      *base::CommandLine::ForCurrentProcess();
-  if (command_line.HasSwitch(switches::kDisableDataReductionProxyDev))
-    return false;
-
-  return command_line.HasSwitch(switches::kEnableDataReductionProxyDev) ||
-         (FieldTrialList::FindFullName(kDevRolloutFieldTrial) == kEnabled);
-}
-
 bool IsConfigClientEnabled() {
   // Config client is enabled by default. It can be disabled only if Chromium
   // belongs to a field trial group whose name starts with "Disabled".
@@ -306,8 +293,7 @@
 void DataReductionProxyParams::EnableQuic(bool enable) {
   quic_enabled_ = enable;
   DCHECK(!quic_enabled_ || params::IsIncludedInQuicFieldTrial());
-  if (!params::IsDevRolloutEnabled() && override_quic_origin_.empty() &&
-      quic_enabled_) {
+  if (override_quic_origin_.empty() && quic_enabled_) {
     origin_ = net::ProxyServer::FromURI(kDefaultQuicOrigin,
                                         net::ProxyServer::SCHEME_HTTP);
     proxies_for_http_.clear();
@@ -393,12 +379,7 @@
   const base::CommandLine& command_line =
       *base::CommandLine::ForCurrentProcess();
   std::string origin;
-  if (!command_line.HasSwitch(switches::kDisableDataReductionProxyDev)) {
-      origin = command_line.GetSwitchValueASCII(
-          switches::kDataReductionProxyDev);
-  }
-  if (origin.empty())
-    origin = command_line.GetSwitchValueASCII(switches::kDataReductionProxy);
+  origin = command_line.GetSwitchValueASCII(switches::kDataReductionProxy);
   std::string fallback_origin =
       command_line.GetSwitchValueASCII(switches::kDataReductionProxyFallback);
   std::string ssl_origin =
@@ -419,14 +400,10 @@
 
   // Set from preprocessor constants those params that are not specified on the
   // command line.
-  if (origin.empty())
-    origin = GetDefaultDevOrigin();
   override_quic_origin_ = origin;
   if (origin.empty())
     origin = GetDefaultOrigin();
   if (fallback_origin.empty())
-    fallback_origin = GetDefaultDevFallbackOrigin();
-  if (fallback_origin.empty())
     fallback_origin = GetDefaultFallbackOrigin();
   if (ssl_origin.empty())
     ssl_origin = GetDefaultSSLOrigin();
@@ -498,14 +475,6 @@
   return holdback_;
 }
 
-std::string DataReductionProxyParams::GetDefaultDevOrigin() const {
-  return params::IsDevRolloutEnabled() ? kDevOrigin : std::string();
-}
-
-std::string DataReductionProxyParams::GetDefaultDevFallbackOrigin() const {
-  return params::IsDevRolloutEnabled() ? kDevFallbackOrigin : std::string();
-}
-
 // TODO(kundaji): Remove tests for macro definitions.
 std::string DataReductionProxyParams::GetDefaultOrigin() const {
   const base::CommandLine& command_line =
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h
index 0e5df1a..8080df1 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params.h
@@ -107,10 +107,6 @@
 // proxy server as quic://proxy.googlezip.net.
 bool IsIncludedInQuicFieldTrial();
 
-// Returns true if dev rollout is enabled on this client either through command
-// line switch or as a part of field trial.
-bool IsDevRolloutEnabled();
-
 std::string GetQuicFieldTrialName();
 
 // Returns true if the Data Reduction Proxy config client should be used.
@@ -216,11 +212,6 @@
 
   bool quic_enabled() const { return quic_enabled_; }
 
-  // Returns the corresponding string from preprocessor constants if defined,
-  // and an empty string otherwise.
-  virtual std::string GetDefaultDevOrigin() const;
-  virtual std::string GetDefaultDevFallbackOrigin() const;
-
  protected:
   // Test constructor that optionally won't call Init();
   DataReductionProxyParams(int flags,
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.cc
index 5f62aee..6ee0a7ce 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.cc
@@ -6,8 +6,6 @@
 
 namespace {
 // Test values to replace the values specified in preprocessor defines.
-static const char kDefaultDevOrigin[] = "https://dev.net:443";
-static const char kDefaultDevFallbackOrigin[] = "dev.net:80";
 static const char kDefaultOrigin[] = "origin.net:80";
 static const char kDefaultFallbackOrigin[] = "fallback.net:80";
 static const char kDefaultSSLOrigin[] = "ssl.net:1080";
@@ -37,14 +35,6 @@
   proxies_for_http_ = proxies;
 }
 // Test values to replace the values specified in preprocessor defines.
-std::string TestDataReductionProxyParams::DefaultDevOrigin() {
-  return kDefaultDevOrigin;
-}
-
-std::string TestDataReductionProxyParams::DefaultDevFallbackOrigin() {
-  return kDefaultDevFallbackOrigin;
-}
-
 std::string TestDataReductionProxyParams::DefaultOrigin() {
   return kDefaultOrigin;
 }
@@ -77,17 +67,6 @@
   return kFlagSecureProxyCheckURL;
 }
 
-std::string TestDataReductionProxyParams::GetDefaultDevOrigin() const {
-  return GetDefinition(
-      TestDataReductionProxyParams::HAS_DEV_ORIGIN, kDefaultDevOrigin);
-}
-
-std::string TestDataReductionProxyParams::GetDefaultDevFallbackOrigin() const {
-  return GetDefinition(
-      TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN,
-      kDefaultDevFallbackOrigin);
-}
-
 std::string TestDataReductionProxyParams::GetDefaultOrigin() const {
   return GetDefinition(
       TestDataReductionProxyParams::HAS_ORIGIN, kDefaultOrigin);
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h
index 83c7c64d..9096364 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h
@@ -26,12 +26,10 @@
   // Used to emulate having constants defined by the preprocessor.
   enum HasNames {
     HAS_NOTHING = 0x0,
-    HAS_DEV_ORIGIN = 0x1,
     HAS_ORIGIN = 0x2,
     HAS_FALLBACK_ORIGIN = 0x4,
     HAS_SSL_ORIGIN = 0x08,
     HAS_SECURE_PROXY_CHECK_URL = 0x40,
-    HAS_DEV_FALLBACK_ORIGIN = 0x80,
     HAS_EVERYTHING = 0xff,
   };
 
@@ -42,8 +40,6 @@
   void SetProxiesForHttp(const std::vector<net::ProxyServer>& proxies);
 
   // Test values to replace the values specified in preprocessor defines.
-  static std::string DefaultDevOrigin();
-  static std::string DefaultDevFallbackOrigin();
   static std::string DefaultOrigin();
   static std::string DefaultFallbackOrigin();
   static std::string DefaultSSLOrigin();
@@ -55,10 +51,6 @@
   static std::string FlagSecureProxyCheckURL();
 
  protected:
-  std::string GetDefaultDevOrigin() const override;
-
-  std::string GetDefaultDevFallbackOrigin() const override;
-
   std::string GetDefaultOrigin() const override;
 
   std::string GetDefaultFallbackOrigin() const override;
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc
index fb3be91..662390d 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_params_unittest.cc
@@ -71,21 +71,6 @@
       DataReductionProxyParams::kPromoAllowed,
       TestDataReductionProxyParams::HAS_EVERYTHING);
   CheckParams(params, true, true, true, true);
-  CheckValues(params, TestDataReductionProxyParams::DefaultDevOrigin(),
-              TestDataReductionProxyParams::DefaultDevFallbackOrigin(),
-              TestDataReductionProxyParams::DefaultSSLOrigin(),
-              TestDataReductionProxyParams::DefaultSecureProxyCheckURL());
-}
-
-TEST_F(DataReductionProxyParamsTest, NoDevOrigin) {
-  TestDataReductionProxyParams params(
-      DataReductionProxyParams::kAllowed |
-      DataReductionProxyParams::kFallbackAllowed |
-      DataReductionProxyParams::kPromoAllowed,
-      TestDataReductionProxyParams::HAS_EVERYTHING &
-      ~TestDataReductionProxyParams::HAS_DEV_ORIGIN &
-      ~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN);
-  CheckParams(params, true, true, true, true);
   CheckValues(params, TestDataReductionProxyParams::DefaultOrigin(),
               TestDataReductionProxyParams::DefaultFallbackOrigin(),
               TestDataReductionProxyParams::DefaultSSLOrigin(),
@@ -142,65 +127,22 @@
       {true, true, true, TestDataReductionProxyParams::HAS_NOTHING, true},
       {true, false, true, TestDataReductionProxyParams::HAS_NOTHING, true},
       {false, true, true, TestDataReductionProxyParams::HAS_NOTHING, false},
-      {true, true, true, TestDataReductionProxyParams::HAS_ORIGIN, true},
-      {true,
-       true,
-       true,
-       TestDataReductionProxyParams::HAS_ORIGIN |
-           TestDataReductionProxyParams::HAS_DEV_ORIGIN |
-           TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN,
-       false},
-      {true,
-       false,
-       true,
-       TestDataReductionProxyParams::HAS_ORIGIN |
-           TestDataReductionProxyParams::HAS_DEV_ORIGIN |
-           TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN,
-       false},
-      {false,
-       true,
-       true,
-       TestDataReductionProxyParams::HAS_ORIGIN |
-           TestDataReductionProxyParams::HAS_DEV_ORIGIN |
-           TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN,
-       false},
-      {true,
-       true,
-       true,
-       TestDataReductionProxyParams::HAS_DEV_ORIGIN |
-           TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN,
+      {true, true, true, TestDataReductionProxyParams::HAS_ORIGIN, false},
+      {true, false, true, TestDataReductionProxyParams::HAS_ORIGIN, false},
+      {false, true, true, TestDataReductionProxyParams::HAS_ORIGIN, false},
+      {true, true, true, TestDataReductionProxyParams::HAS_NOTHING, true},
+      {true, false, true, TestDataReductionProxyParams::HAS_FALLBACK_ORIGIN,
        true},
-      {true,
-       false,
-       true,
-       TestDataReductionProxyParams::HAS_FALLBACK_ORIGIN,
-       true},
-      {false,
-       true,
-       true,
-       TestDataReductionProxyParams::HAS_FALLBACK_ORIGIN,
+      {false, true, true, TestDataReductionProxyParams::HAS_FALLBACK_ORIGIN,
        false},
-      {true,
-       true,
-       true,
-       TestDataReductionProxyParams::HAS_FALLBACK_ORIGIN |
-           TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN,
+      {true, true, true, TestDataReductionProxyParams::HAS_FALLBACK_ORIGIN,
        false},
-      {true,
-       true,
-       true,
-       TestDataReductionProxyParams::HAS_SECURE_PROXY_CHECK_URL,
-       false},
-      {true,
-       false,
-       true,
-       TestDataReductionProxyParams::HAS_SECURE_PROXY_CHECK_URL,
-       false},
-      {false,
-       true,
-       true,
-       TestDataReductionProxyParams::HAS_SECURE_PROXY_CHECK_URL,
-       false},
+      {true, true, true,
+       TestDataReductionProxyParams::HAS_SECURE_PROXY_CHECK_URL, false},
+      {true, false, true,
+       TestDataReductionProxyParams::HAS_SECURE_PROXY_CHECK_URL, false},
+      {false, true, true,
+       TestDataReductionProxyParams::HAS_SECURE_PROXY_CHECK_URL, false},
       {true, true, true, TestDataReductionProxyParams::HAS_SSL_ORIGIN, true},
       {true, false, true, TestDataReductionProxyParams::HAS_SSL_ORIGIN, true},
       {false, true, true, TestDataReductionProxyParams::HAS_SSL_ORIGIN, false},
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.cc b/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.cc
index d608ad7..0b21423 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.cc
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.cc
@@ -17,9 +17,6 @@
 // The URL from which to retrieve the Data Reduction Proxy configuration.
 const char kDataReductionProxyConfigURL[] = "data-reduction-proxy-config-url";
 
-// The origin of the data reduction proxy dev.
-const char kDataReductionProxyDev[]      = "spdy-proxy-dev-auth-origin";
-
 // The name of a Data Reduction Proxy experiment to run. These experiments are
 // defined by the proxy server. Use --force-fieldtrials for Data Reduction
 // Proxy field trials.
@@ -68,10 +65,6 @@
 // The origin of the data reduction SSL proxy.
 const char kDataReductionSSLProxy[] = "data-reduction-ssl-proxy";
 
-// Disables the origin of the data reduction proxy dev.
-const char kDisableDataReductionProxyDev[] =
-    "disable-spdy-proxy-dev-auth-origin";
-
 // Enable the data reduction proxy.
 const char kEnableDataReductionProxy[] = "enable-spdy-proxy-auth";
 
@@ -83,9 +76,6 @@
 const char kEnableDataReductionProxyCarrierTest[] =
     "enable-data-reduction-proxy-carrier-test";
 
-// Enables the origin of the data reduction proxy dev.
-const char kEnableDataReductionProxyDev[] = "enable-spdy-proxy-dev-auth-origin";
-
 // Enables preview mode for Lo-Fi. This means a preview should be requested
 // instead of placeholders whenever Lo-Fi mode is on. Lo-Fi must also be enabled
 // via a flag or field trial.
diff --git a/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h b/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h
index 79c1455..b4d0c8f 100644
--- a/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h
+++ b/components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h
@@ -14,7 +14,6 @@
 extern const char kClearDataReductionProxyDataSavings[];
 extern const char kDataReductionProxy[];
 extern const char kDataReductionProxyConfigURL[];
-extern const char kDataReductionProxyDev[];
 extern const char kDataReductionProxyExperiment[];
 extern const char kDataReductionProxyFallback[];
 extern const char kDataReductionProxyHttpProxies[];
@@ -28,11 +27,9 @@
 extern const char kDataReductionProxyStartSecureDisabled[];
 extern const char kDataReductionProxyWarmupURL[];
 extern const char kDataReductionSSLProxy[];
-extern const char kDisableDataReductionProxyDev[];
 extern const char kEnableDataReductionProxy[];
 extern const char kEnableDataReductionProxyBypassWarning[];
 extern const char kEnableDataReductionProxyCarrierTest[];
-extern const char kEnableDataReductionProxyDev[];
 extern const char kEnableDataReductionProxyLoFiPreview[];
 
 }  // namespace switches
diff --git a/components/metrics/file_metrics_provider.cc b/components/metrics/file_metrics_provider.cc
index fcfb7acf..78fb90a 100644
--- a/components/metrics/file_metrics_provider.cc
+++ b/components/metrics/file_metrics_provider.cc
@@ -174,13 +174,12 @@
     base::HistogramSnapshotManager* snapshot_manager,
     FileInfo* file) {
   DCHECK(thread_checker_.CalledOnValidThread());
-  base::PersistentHistogramAllocator::Iterator histogram_iter;
-  file->allocator->CreateIterator(&histogram_iter);
+  base::PersistentHistogramAllocator::Iterator histogram_iter(
+      file->allocator.get());
 
   int histogram_count = 0;
   while (true) {
-    scoped_ptr<base::HistogramBase> histogram =
-        file->allocator->GetNextHistogram(&histogram_iter);
+    scoped_ptr<base::HistogramBase> histogram = histogram_iter.GetNext();
     if (!histogram)
       break;
     if (file->type == FILE_HISTOGRAMS_ATOMIC)
diff --git a/components/mus/public/cpp/tests/window_server_test_suite.cc b/components/mus/public/cpp/tests/window_server_test_suite.cc
index ea1a04c0..41a68a19 100644
--- a/components/mus/public/cpp/tests/window_server_test_suite.cc
+++ b/components/mus/public/cpp/tests/window_server_test_suite.cc
@@ -7,7 +7,7 @@
 #include "base/i18n/icu_util.h"
 
 #if defined(USE_X11)
-#include "ui/gfx/x/x11_connection.h"
+#include "ui/gfx/x/x11_connection.h"  // nogncheck
 #endif
 
 namespace mus {
diff --git a/components/nacl/loader/nonsfi/nonsfi_sandbox_unittest.cc b/components/nacl/loader/nonsfi/nonsfi_sandbox_unittest.cc
index c6ba01d..998cd3b 100644
--- a/components/nacl/loader/nonsfi/nonsfi_sandbox_unittest.cc
+++ b/components/nacl/loader/nonsfi/nonsfi_sandbox_unittest.cc
@@ -25,6 +25,8 @@
 #include <time.h>
 #include <unistd.h>
 
+#include <memory>
+
 #include "base/at_exit.h"
 #include "base/bind.h"
 #include "base/callback.h"
@@ -607,14 +609,14 @@
   TgkillDelegate() {}
   ~TgkillDelegate() override {}
 
-  scoped_ptr<sandbox::bpf_dsl::Policy> GetSandboxBPFPolicy() override {
+  std::unique_ptr<sandbox::bpf_dsl::Policy> GetSandboxBPFPolicy() override {
     // These two values must be obtained when running in the sandboxed process.
     // They cannot be set in the constructor and are also not available from
     // within |RunTestFunction|.
     pid_ = getpid();
     tid_ = syscall(__NR_gettid);
 
-    return scoped_ptr<sandbox::bpf_dsl::Policy>(
+    return std::unique_ptr<sandbox::bpf_dsl::Policy>(
         new nacl::nonsfi::NaClNonSfiBPFSandboxPolicy());
   }
 
diff --git a/components/ntp_snippets/DEPS b/components/ntp_snippets/DEPS
index fc61093f1..38ff3b8 100644
--- a/components/ntp_snippets/DEPS
+++ b/components/ntp_snippets/DEPS
@@ -6,5 +6,5 @@
   "+net/base",
   "+net/http",
   "+net/url_request",
-  "+google_apis/gaia",
+  "+google_apis",
 ]
diff --git a/components/ntp_snippets/ntp_snippets_fetcher.cc b/components/ntp_snippets/ntp_snippets_fetcher.cc
index b0f81d1..10e48b0b 100644
--- a/components/ntp_snippets/ntp_snippets_fetcher.cc
+++ b/components/ntp_snippets/ntp_snippets_fetcher.cc
@@ -10,9 +10,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/task_runner_util.h"
-#include "components/signin/core/browser/profile_oauth2_token_service.h"
-#include "components/signin/core/browser/signin_manager.h"
-#include "components/signin/core/browser/signin_tracker.h"
+#include "google_apis/google_api_keys.h"
 #include "net/base/load_flags.h"
 #include "net/http/http_request_headers.h"
 #include "net/http/http_response_headers.h"
@@ -26,10 +24,8 @@
 
 namespace ntp_snippets {
 
-const char kApiScope[] = "https://www.googleapis.com/auth/webhistory";
-const char kContentSnippetsServer[] =
-    "https://chromereader-pa.googleapis.com/v1/fetch";
-const char kAuthorizationRequestHeaderFormat[] = "Bearer %s";
+const char kContentSnippetsServerFormat[] =
+    "https://chromereader-pa.googleapis.com/v1/fetch?key=%s";
 
 const char kRequestParameterFormat[] =
     "{"
@@ -55,20 +51,14 @@
 
 NTPSnippetsFetcher::NTPSnippetsFetcher(
     scoped_refptr<base::SequencedTaskRunner> file_task_runner,
-    SigninManagerBase* signin_manager,
-    OAuth2TokenService* token_service,
-    scoped_refptr<URLRequestContextGetter> url_request_context_getter)
-    : OAuth2TokenService::Consumer("NTP_snippets"),
-      file_task_runner_(file_task_runner),
+    scoped_refptr<URLRequestContextGetter> url_request_context_getter,
+    bool is_stable_channel)
+    : file_task_runner_(file_task_runner),
       url_request_context_getter_(url_request_context_getter),
-      signin_manager_(signin_manager),
-      token_service_(token_service),
-      waiting_for_refresh_token_(false),
+      is_stable_channel_(is_stable_channel),
       weak_ptr_factory_(this) {}
 
 NTPSnippetsFetcher::~NTPSnippetsFetcher() {
-  if (waiting_for_refresh_token_)
-    token_service_->RemoveObserver(this);
 }
 
 scoped_ptr<NTPSnippetsFetcher::SnippetsAvailableCallbackList::Subscription>
@@ -78,45 +68,20 @@
 
 void NTPSnippetsFetcher::FetchSnippets(const std::vector<std::string>& hosts) {
   // TODO(treib): What to do if there's already a pending request?
-  hosts_ = hosts;
-  if (signin_manager_->IsAuthenticated()) {
-    StartTokenRequest();
-  } else {
-    if (!waiting_for_refresh_token_) {
-      // Wait until we get a refresh token.
-      waiting_for_refresh_token_ = true;
-      token_service_->AddObserver(this);
-    }
-  }
-}
-
-void NTPSnippetsFetcher::StartTokenRequest() {
-  OAuth2TokenService::ScopeSet scopes;
-  scopes.insert(kApiScope);
-  oauth_request_ = token_service_->StartRequest(
-      signin_manager_->GetAuthenticatedAccountId(), scopes, this);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// OAuth2TokenService::Consumer overrides
-void NTPSnippetsFetcher::OnGetTokenSuccess(
-    const OAuth2TokenService::Request* request,
-    const std::string& access_token,
-    const base::Time& expiration_time) {
-  oauth_request_.reset();
-  url_fetcher_ =
-      URLFetcher::Create(GURL(kContentSnippetsServer), URLFetcher::POST, this);
+  const std::string& key = is_stable_channel_
+                               ? google_apis::GetAPIKey()
+                               : google_apis::GetNonStableAPIKey();
+  std::string url =
+      base::StringPrintf(kContentSnippetsServerFormat, key.c_str());
+  url_fetcher_ = URLFetcher::Create(GURL(url), URLFetcher::POST, this);
   url_fetcher_->SetRequestContext(url_request_context_getter_.get());
   url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
                              net::LOAD_DO_NOT_SAVE_COOKIES);
   HttpRequestHeaders headers;
-  headers.SetHeader("Authorization",
-                    base::StringPrintf(kAuthorizationRequestHeaderFormat,
-                                       access_token.c_str()));
   headers.SetHeader("Content-Type", "application/json; charset=UTF-8");
   url_fetcher_->SetExtraRequestHeaders(headers.ToString());
   std::string host_restricts;
-  for (const std::string& host : hosts_)
+  for (const std::string& host : hosts)
     host_restricts += base::StringPrintf(kHostRestrictFormat, host.c_str());
   url_fetcher_->SetUploadData("application/json",
                               base::StringPrintf(kRequestParameterFormat,
@@ -129,22 +94,6 @@
   url_fetcher_->Start();
 }
 
-void NTPSnippetsFetcher::OnGetTokenFailure(
-    const OAuth2TokenService::Request* request,
-    const GoogleServiceAuthError& error) {
-  oauth_request_.reset();
-  DLOG(ERROR) << "Unable to get token: " << error.ToString();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// OAuth2TokenService::Observer overrides
-void NTPSnippetsFetcher::OnRefreshTokenAvailable(
-    const std::string& account_id) {
-  token_service_->RemoveObserver(this);
-  waiting_for_refresh_token_ = false;
-  StartTokenRequest();
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // URLFetcherDelegate overrides
 void NTPSnippetsFetcher::OnURLFetchComplete(const URLFetcher* source) {
diff --git a/components/ntp_snippets/ntp_snippets_fetcher.h b/components/ntp_snippets/ntp_snippets_fetcher.h
index c41e4bbb..1fd2877 100644
--- a/components/ntp_snippets/ntp_snippets_fetcher.h
+++ b/components/ntp_snippets/ntp_snippets_fetcher.h
@@ -10,26 +10,15 @@
 
 #include "base/callback.h"
 #include "base/callback_list.h"
-#include "base/files/file_path.h"
 #include "base/memory/weak_ptr.h"
-#include "base/observer_list.h"
 #include "base/sequenced_task_runner.h"
-#include "google_apis/gaia/oauth2_token_service.h"
+#include "net/url_request/url_fetcher_delegate.h"
 #include "net/url_request/url_request_context_getter.h"
 
-namespace net {
-class URLFetcher;
-class URLFetcherDelegate;
-}  // namespace net
-
-class SigninManagerBase;
-
 namespace ntp_snippets {
 
 // Fetches snippet data for the NTP from the server
-class NTPSnippetsFetcher : public OAuth2TokenService::Consumer,
-                           public OAuth2TokenService::Observer,
-                           public net::URLFetcherDelegate {
+class NTPSnippetsFetcher : public net::URLFetcherDelegate {
  public:
   using SnippetsAvailableCallback = base::Callback<void(const std::string&)>;
   using SnippetsAvailableCallbackList =
@@ -37,9 +26,8 @@
 
   NTPSnippetsFetcher(
       scoped_refptr<base::SequencedTaskRunner> file_task_runner,
-      SigninManagerBase* signin_manager,
-      OAuth2TokenService* oauth2_token_service,
-      scoped_refptr<net::URLRequestContextGetter> url_request_context_getter);
+      scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
+      bool is_stable_channel);
   ~NTPSnippetsFetcher() override;
 
   // Adds a callback that is called when a new set of snippets are downloaded.
@@ -52,18 +40,6 @@
   void FetchSnippets(const std::vector<std::string>& hosts);
 
  private:
-  void StartTokenRequest();
-
-  // OAuth2TokenService::Consumer overrides:
-  void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
-                         const std::string& access_token,
-                         const base::Time& expiration_time) override;
-  void OnGetTokenFailure(const OAuth2TokenService::Request* request,
-                         const GoogleServiceAuthError& error) override;
-
-  // OAuth2TokenService::Observer overrides:
-  void OnRefreshTokenAvailable(const std::string& account_id) override;
-
   // URLFetcherDelegate implementation.
   void OnURLFetchComplete(const net::URLFetcher* source) override;
 
@@ -73,17 +49,15 @@
   // Holds the URL request context.
   scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
 
-  std::vector<std::string> hosts_;
-
+  // The fetcher for downloading the snippets.
   scoped_ptr<net::URLFetcher> url_fetcher_;
-  scoped_ptr<SigninManagerBase> signin_manager_;
-  scoped_ptr<OAuth2TokenService> token_service_;
-  scoped_ptr<OAuth2TokenService::Request> oauth_request_;
 
-  bool waiting_for_refresh_token_;
-
+  // The callbacks to notify when new snippets get fetched.
   SnippetsAvailableCallbackList callback_list_;
 
+  // Flag for picking the right (stable/non-stable) API key for Chrome Reader
+  bool is_stable_channel_;
+
   base::WeakPtrFactory<NTPSnippetsFetcher> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(NTPSnippetsFetcher);
diff --git a/components/ntp_snippets/ntp_snippets_service.h b/components/ntp_snippets/ntp_snippets_service.h
index c93c441..ff2b039c0 100644
--- a/components/ntp_snippets/ntp_snippets_service.h
+++ b/components/ntp_snippets/ntp_snippets_service.h
@@ -10,6 +10,7 @@
 #include <string>
 #include <vector>
 
+#include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
@@ -39,7 +40,7 @@
 class NTPSnippetsServiceObserver;
 
 // Stores and vends fresh content data for the NTP.
-class NTPSnippetsService : public KeyedService, NTPSnippetsFetcher::Observer {
+class NTPSnippetsService : public KeyedService {
  public:
   using NTPSnippetStorage = std::vector<scoped_ptr<NTPSnippet>>;
   using const_iterator =
diff --git a/components/ntp_snippets/ntp_snippets_service_unittest.cc b/components/ntp_snippets/ntp_snippets_service_unittest.cc
index c732d19..18f4a2ee 100644
--- a/components/ntp_snippets/ntp_snippets_service_unittest.cc
+++ b/components/ntp_snippets/ntp_snippets_service_unittest.cc
@@ -13,10 +13,6 @@
 #include "components/ntp_snippets/ntp_snippets_fetcher.h"
 #include "components/ntp_snippets/ntp_snippets_service.h"
 #include "components/prefs/testing_pref_service.h"
-#include "components/signin/core/browser/account_tracker_service.h"
-#include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
-#include "components/signin/core/browser/fake_signin_manager.h"
-#include "components/signin/core/browser/test_signin_client.h"
 #include "net/url_request/url_request_test_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -109,9 +105,7 @@
 class NTPSnippetsServiceTest : public testing::Test {
  public:
   NTPSnippetsServiceTest()
-      : pref_service_(new TestingPrefServiceSimple()),
-        signin_client_(new TestSigninClient(nullptr)),
-        account_tracker_(new AccountTrackerService()) {}
+      : pref_service_(new TestingPrefServiceSimple()) {}
   ~NTPSnippetsServiceTest() override {}
 
   void SetUp() override {
@@ -125,16 +119,11 @@
         base::ThreadTaskRunnerHandle::Get());
     scoped_refptr<net::TestURLRequestContextGetter> request_context_getter =
         new net::TestURLRequestContextGetter(task_runner.get());
-    FakeSigninManagerBase* signin_manager =  new FakeSigninManagerBase(
-        signin_client_.get(), account_tracker_.get());
-    FakeProfileOAuth2TokenService* token_service =
-        new FakeProfileOAuth2TokenService();
 
     service_.reset(new NTPSnippetsService(
         pref_service_.get(), nullptr, task_runner, std::string("fr"), nullptr,
-        make_scoped_ptr(
-            new NTPSnippetsFetcher(task_runner, signin_manager, token_service,
-                                   std::move(request_context_getter))),
+        make_scoped_ptr(new NTPSnippetsFetcher(
+            task_runner, std::move(request_context_getter), true)),
         base::Bind(&ParseJson)));
   }
 
@@ -154,8 +143,6 @@
  private:
   base::MessageLoop message_loop_;
   scoped_ptr<TestingPrefServiceSimple> pref_service_;
-  scoped_ptr<TestSigninClient> signin_client_;
-  scoped_ptr<AccountTrackerService> account_tracker_;
   scoped_ptr<NTPSnippetsService> service_;
 
   DISALLOW_COPY_AND_ASSIGN(NTPSnippetsServiceTest);
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index 45006a3..48cf1b8 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -420,8 +420,8 @@
         {
           'name': 'NetworkPredictionWifiOnly',
           'value': 1,
-          'caption': '''Predict network actions on any network that is not
-          cellular''',
+          'caption': '''Predict network actions on any network that is not cellular.
+          (Deprecated in 50, removed in 52. After 52, if value 1 is set, it will be treated as 0 - predict network actions on any network connection.)''',
         },
         {
           'name': 'NetworkPredictionNever',
diff --git a/components/quirks/quirks_client.cc b/components/quirks/quirks_client.cc
index 16ea594..93775e8 100644
--- a/components/quirks/quirks_client.cc
+++ b/components/quirks/quirks_client.cc
@@ -22,7 +22,7 @@
 namespace {
 
 const char kQuirksUrlFormat[] =
-    "https://qa-quirksserver-pa.sandbox.googleapis.com/v2/display/%s/clients"
+    "https://chromeosquirksserver-pa.googleapis.com/v2/display/%s/clients"
     "/chromeos/M%d";
 
 const net::BackoffEntry::Policy kDefaultBackoffPolicy = {
diff --git a/components/test_runner/layout_test_runtime_flags.h b/components/test_runner/layout_test_runtime_flags.h
index 2b189e7..d3e7732 100644
--- a/components/test_runner/layout_test_runtime_flags.h
+++ b/components/test_runner/layout_test_runtime_flags.h
@@ -27,7 +27,6 @@
   void Reset();
 
   TrackedDictionary& tracked_dictionary() { return dict_; }
-  const TrackedDictionary& tracked_dictionary() const { return dict_; }
 
 #define DEFINE_BOOL_LAYOUT_TEST_RUNTIME_FLAG(name)                  \
   bool name() const {                                               \
diff --git a/components/test_runner/mock_web_media_stream_center.cc b/components/test_runner/mock_web_media_stream_center.cc
index 24d5268..a675f8a 100644
--- a/components/test_runner/mock_web_media_stream_center.cc
+++ b/components/test_runner/mock_web_media_stream_center.cc
@@ -40,8 +40,7 @@
 
 MockWebMediaStreamCenter::MockWebMediaStreamCenter(
     blink::WebMediaStreamCenterClient* client,
-    TestInterfaces* interfaces)
-    : interfaces_(interfaces) {
+    TestInterfaces* interfaces) {
 }
 
 MockWebMediaStreamCenter::~MockWebMediaStreamCenter() {
diff --git a/components/test_runner/mock_web_media_stream_center.h b/components/test_runner/mock_web_media_stream_center.h
index cc2fc65..7826bde 100644
--- a/components/test_runner/mock_web_media_stream_center.h
+++ b/components/test_runner/mock_web_media_stream_center.h
@@ -40,12 +40,8 @@
   blink::WebAudioSourceProvider* createWebAudioSourceFromMediaStreamTrack(
       const blink::WebMediaStreamTrack& track) override;
 
-  // Task related methods
-  WebTaskList* mutable_task_list() { return &task_list_; }
-
  private:
   WebTaskList task_list_;
-  TestInterfaces* interfaces_;
 
   DISALLOW_COPY_AND_ASSIGN(MockWebMediaStreamCenter);
 };
diff --git a/components/test_runner/mock_web_user_media_client.cc b/components/test_runner/mock_web_user_media_client.cc
index a5f8bdc..f39357a 100644
--- a/components/test_runner/mock_web_user_media_client.cc
+++ b/components/test_runner/mock_web_user_media_client.cc
@@ -127,8 +127,6 @@
 };
 
 class MockExtraData : public WebMediaStream::ExtraData {
- public:
-  int foo;
 };
 
 MockWebUserMediaClient::MockWebUserMediaClient(WebTestDelegate* delegate)
diff --git a/components/test_runner/pixel_dump.cc b/components/test_runner/pixel_dump.cc
index 1b49c178..8587f18 100644
--- a/components/test_runner/pixel_dump.cc
+++ b/components/test_runner/pixel_dump.cc
@@ -95,8 +95,8 @@
   int totalHeight = page_count * (page_size_in_pixels.height + 1) - 1;
 
   bool is_opaque = false;
-  skia::RefPtr<SkCanvas> canvas(skia::AdoptRef(skia::TryCreateBitmapCanvas(
-      page_size_in_pixels.width, totalHeight, is_opaque)));
+  sk_sp<SkCanvas> canvas(skia::TryCreateBitmapCanvas(
+      page_size_in_pixels.width, totalHeight, is_opaque));
   if (!canvas) {
     dump_request->callback.Run(SkBitmap());
     return;
diff --git a/components/test_runner/spell_check_client.h b/components/test_runner/spell_check_client.h
index b770a1a..8eac3c1 100644
--- a/components/test_runner/spell_check_client.h
+++ b/components/test_runner/spell_check_client.h
@@ -32,7 +32,6 @@
   void SetDelegate(WebTestDelegate* delegate);
 
   WebTaskList* mutable_task_list() { return &task_list_; }
-  MockSpellCheck* MockSpellCheckWord() { return &spell_check_; }
 
   // blink::WebSpellCheckClient implementation.
   void spellCheck(
diff --git a/components/test_runner/test_preferences.h b/components/test_runner/test_preferences.h
index 8d13340..cf06d50 100644
--- a/components/test_runner/test_preferences.h
+++ b/components/test_runner/test_preferences.h
@@ -23,7 +23,6 @@
     bool allow_display_of_insecure_content;
     bool allow_file_access_from_file_urls;
     bool allow_running_of_insecure_content;
-    bool author_and_user_styles_enabled;
     blink::WebString default_text_encoding_name;
     bool experimental_webgl_enabled;
     bool experimental_css_grid_layout_enabled;
diff --git a/components/test_runner/test_runner.cc b/components/test_runner/test_runner.cc
index bd5c07d..c925801 100644
--- a/components/test_runner/test_runner.cc
+++ b/components/test_runner/test_runner.cc
@@ -1909,10 +1909,6 @@
   return test_is_running_ && dump_ping_loader_callbacks_;
 }
 
-void TestRunner::setShouldDumpPingLoaderCallbacks(bool value) {
-  dump_ping_loader_callbacks_ = value;
-}
-
 void TestRunner::setShouldEnableViewSource(bool value) {
   web_view_->mainFrame()->enableViewSourceMode(value);
 }
@@ -1941,10 +1937,6 @@
   return test_is_running_ && dump_resource_load_callbacks_;
 }
 
-bool TestRunner::shouldDumpResourceRequestCallbacks() const {
-  return test_is_running_ && dump_resource_request_callbacks_;
-}
-
 bool TestRunner::shouldDumpResourceResponseMIMETypes() const {
   return test_is_running_ && dump_resource_response_mime_types_;
 }
diff --git a/components/test_runner/test_runner.h b/components/test_runner/test_runner.h
index ca8761f..065fc1f 100644
--- a/components/test_runner/test_runner.h
+++ b/components/test_runner/test_runner.h
@@ -99,7 +99,6 @@
   MockWebUserMediaClient* getMockWebUserMediaClient();
   MockWebSpeechRecognizer* getMockWebSpeechRecognizer();
   bool isPrinting() const;
-  bool shouldDumpAsTextWithPixelResults();
   bool shouldDumpAsCustomText() const;
   std:: string customDumpText() const;
   void ShowDevTools(const std::string& settings,
@@ -110,7 +109,6 @@
   void setCustomTextOutput(const std::string& text);
   void setShouldGeneratePixelResults(bool);
   void setShouldDumpFrameLoadCallbacks(bool);
-  void setShouldDumpPingLoaderCallbacks(bool);
   void setShouldEnableViewSource(bool);
   bool shouldDumpEditingCallbacks() const;
   bool shouldDumpFrameLoadCallbacks() const;
@@ -121,7 +119,6 @@
   bool shouldDumpCreateView() const;
   bool canOpenWindows() const;
   bool shouldDumpResourceLoadCallbacks() const;
-  bool shouldDumpResourceRequestCallbacks() const;
   bool shouldDumpResourceResponseMIMETypes() const;
   bool shouldDumpStatusCallbacks() const;
   bool shouldDumpSpellCheckCallbacks() const;
diff --git a/components/test_runner/web_test_interfaces.cc b/components/test_runner/web_test_interfaces.cc
index 4df7bd29..748b3ef0 100644
--- a/components/test_runner/web_test_interfaces.cc
+++ b/components/test_runner/web_test_interfaces.cc
@@ -95,10 +95,6 @@
   return std::move(client);
 }
 
-AppBannerClient* WebTestInterfaces::GetAppBannerClient() {
-  return interfaces_->GetAppBannerClient();
-}
-
 scoped_ptr<WebFrameTestClient> WebTestInterfaces::CreateWebFrameTestClient() {
   return make_scoped_ptr(new WebFrameTestClient(
         interfaces_->GetTestRunner(),
diff --git a/components/test_runner/web_test_interfaces.h b/components/test_runner/web_test_interfaces.h
index 8b93aa89..0c12ef6 100644
--- a/components/test_runner/web_test_interfaces.h
+++ b/components/test_runner/web_test_interfaces.h
@@ -63,7 +63,6 @@
   blink::WebAudioDevice* CreateAudioDevice(double sample_rate);
 
   scoped_ptr<blink::WebAppBannerClient> CreateAppBannerClient();
-  AppBannerClient* GetAppBannerClient();
 
   TestInterfaces* GetTestInterfaces();
 
diff --git a/content/browser/blob_storage/blob_async_builder_host_unittest.cc b/content/browser/blob_storage/blob_async_builder_host_unittest.cc
index 4086a90..d40cc7c 100644
--- a/content/browser/blob_storage/blob_async_builder_host_unittest.cc
+++ b/content/browser/blob_storage/blob_async_builder_host_unittest.cc
@@ -526,20 +526,9 @@
 
   // The first blob shouldn't be building anymore.
   EXPECT_FALSE(host_.IsBeingBuilt(kBlob1));
-  // Test we get BAD_IPC.
-  std::vector<DataElement> descriptions;
-  AddShortcutMemoryItem(2, &descriptions);
-  DataElement element;
-  element.SetToBlob(kBlob1);
-  descriptions.push_back(element);
-  EXPECT_EQ(BlobTransportResult::BAD_IPC,
-            host_.StartBuildingBlob(
-                kBlob1, descriptions, 2, &context_,
-                base::Bind(&BlobAsyncBuilderHostTest::RequestMemoryCallback,
-                           base::Unretained(this))));
 
   // Try to finish the second one, without a reference to the first.
-  descriptions.clear();
+  std::vector<DataElement> descriptions;
   AddShortcutMemoryItem(2, &descriptions);
   EXPECT_EQ(BlobTransportResult::BAD_IPC,
             host_.StartBuildingBlob(
@@ -551,6 +540,7 @@
   // Try to finish the third one with the reference we didn't declare earlier.
   descriptions.clear();
   AddShortcutMemoryItem(2, &descriptions);
+  DataElement element;
   element.SetToBlob(kGoodBlob);
   descriptions.push_back(element);
   EXPECT_EQ(BlobTransportResult::BAD_IPC,
@@ -620,21 +610,6 @@
   EXPECT_FALSE(host_.IsBeingBuilt(kBlob2));
   EXPECT_FALSE(IsBeingBuiltInContext(kBlob2));
   EXPECT_TRUE(context_.GetBlobDataFromUUID(kBlob2)->IsBroken());
-
-  // Try to finish the second one, but we should get a BAD_IPC, as we are no
-  // longer being constructed.
-  std::vector<DataElement> descriptions;
-  AddShortcutMemoryItem(2, &descriptions);
-  DataElement element;
-  element.SetToBlob(kBlob1);
-  descriptions.push_back(element);
-  EXPECT_EQ(BlobTransportResult::BAD_IPC,
-            host_.StartBuildingBlob(
-                kBlob2, descriptions, 2, &context_,
-                base::Bind(&BlobAsyncBuilderHostTest::RequestMemoryCallback,
-                           base::Unretained(this))));
-  EXPECT_FALSE(request_called_);
-  EXPECT_TRUE(context_.GetBlobDataFromUUID(kBlob2)->IsBroken());
 };
 
 }  // namespace storage
diff --git a/content/browser/blob_storage/blob_dispatcher_host.cc b/content/browser/blob_storage/blob_dispatcher_host.cc
index 00ef8b4..8b3741b1 100644
--- a/content/browser/blob_storage/blob_dispatcher_host.cc
+++ b/content/browser/blob_storage/blob_dispatcher_host.cc
@@ -188,9 +188,11 @@
     // Second, if the last dereference of the blob happened on a different host,
     // then we still haven't gotten rid of the 'building' state in the original
     // host. So we call cancel just in case this happens.
-    async_builder_.CancelBuildingBlob(
-        uuid, IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING,
-        context);
+    if (async_builder_.IsBeingBuilt(uuid)) {
+      async_builder_.CancelBuildingBlob(
+          uuid, IPCBlobCreationCancelCode::BLOB_DEREFERENCED_WHILE_BUILDING,
+          context);
+    }
     return;
   }
   if (!async_builder_.IsBeingBuilt(uuid)) {
diff --git a/content/browser/blob_storage/blob_dispatcher_host.h b/content/browser/blob_storage/blob_dispatcher_host.h
index 526704d..bf1a03c 100644
--- a/content/browser/blob_storage/blob_dispatcher_host.h
+++ b/content/browser/blob_storage/blob_dispatcher_host.h
@@ -66,6 +66,7 @@
   friend class base::RefCountedThreadSafe<BlobDispatcherHost>;
   friend class BlobDispatcherHostTest;
   FRIEND_TEST_ALL_PREFIXES(BlobDispatcherHostTest, EmptyUUIDs);
+  FRIEND_TEST_ALL_PREFIXES(BlobDispatcherHostTest, MultipleTransfers);
   FRIEND_TEST_ALL_PREFIXES(BlobDispatcherHostTest, SharedMemoryTransfer);
   FRIEND_TEST_ALL_PREFIXES(BlobDispatcherHostTest, OnCancelBuildingBlob);
   FRIEND_TEST_ALL_PREFIXES(BlobDispatcherHostTest,
diff --git a/content/browser/blob_storage/blob_dispatcher_host_unittest.cc b/content/browser/blob_storage/blob_dispatcher_host_unittest.cc
index 6e062db..43cdf8a 100644
--- a/content/browser/blob_storage/blob_dispatcher_host_unittest.cc
+++ b/content/browser/blob_storage/blob_dispatcher_host_unittest.cc
@@ -298,6 +298,46 @@
   ExpectHandleEqualsData(handle.get(), elements);
 }
 
+TEST_F(BlobDispatcherHostTest, MultipleTransfers) {
+  const std::string kId = "uuid";
+  const int kNumIters = 10;
+  for (int i = 0; i < kNumIters; i++) {
+    std::string id = kId;
+    id += ('0' + i);
+    ExpectBlobNotExist(id);
+    host_->OnRegisterBlobUUID(id, std::string(kContentType),
+                              std::string(kContentDisposition),
+                              std::set<std::string>());
+    EXPECT_FALSE(host_->shutdown_for_bad_message_);
+  }
+  sink_.ClearMessages();
+  for (int i = 0; i < kNumIters; i++) {
+    std::string id = kId;
+    id += ('0' + i);
+    DataElement element;
+    element.SetToBytesDescription(kDataSize);
+    std::vector<DataElement> elements = {element};
+    host_->OnStartBuildingBlob(id, elements);
+    EXPECT_FALSE(host_->shutdown_for_bad_message_);
+    // Expect our request.
+    std::vector<BlobItemBytesRequest> expected_requests = {
+        BlobItemBytesRequest::CreateIPCRequest(0, 0, 0, kDataSize)};
+    ExpectRequest(id, expected_requests);
+    sink_.ClearMessages();
+  }
+  for (int i = 0; i < kNumIters; i++) {
+    std::string id = kId;
+    id += ('0' + i);
+    // Send results;
+    BlobItemBytesResponse response(0);
+    std::memcpy(response.allocate_mutable_data(kDataSize), kData, kDataSize);
+    std::vector<BlobItemBytesResponse> responses = {response};
+    host_->OnMemoryItemResponse(id, responses);
+    ExpectDone(id);
+    sink_.ClearMessages();
+  }
+}
+
 TEST_F(BlobDispatcherHostTest, SharedMemoryTransfer) {
   const std::string kId = "uuid1";
   const size_t kLargeSize = kTestBlobStorageMaxSharedMemoryBytes * 2;
@@ -307,6 +347,7 @@
   host_->OnRegisterBlobUUID(kId, std::string(kContentType),
                             std::string(kContentDisposition),
                             std::set<std::string>());
+
   // Grab the handle.
   scoped_ptr<BlobDataHandle> blob_data_handle =
       context_->GetBlobDataFromUUID(kId);
@@ -425,6 +466,7 @@
 
   // Get rid of it in the host.
   host_->OnDecrementBlobRefCount(kId);
+  EXPECT_FALSE(host_->shutdown_for_bad_message_);
   ExpectBlobNotExist(kId);
 
   // Create blob again to verify we don't have any old construction state lying
diff --git a/content/browser/compositor/software_output_device_mac.h b/content/browser/compositor/software_output_device_mac.h
index a613ab4..84e0987 100644
--- a/content/browser/compositor/software_output_device_mac.h
+++ b/content/browser/compositor/software_output_device_mac.h
@@ -10,6 +10,8 @@
 #include "base/mac/scoped_cftyperef.h"
 #include "base/macros.h"
 #include "cc/output/software_output_device.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkRefCnt.h"
 #include "third_party/skia/include/core/SkRegion.h"
 #include "ui/gfx/vsync_provider.h"
 
@@ -63,7 +65,7 @@
 
   // The SkCanvas wrapps the mapped current IOSurface. It is valid only between
   // BeginPaint and EndPaint.
-  skia::RefPtr<SkCanvas> canvas_;
+  sk_sp<SkCanvas> canvas_;
 
   gfx::VSyncProvider::UpdateVSyncCallback update_vsync_callback_;
 
diff --git a/content/browser/compositor/software_output_device_mac.mm b/content/browser/compositor/software_output_device_mac.mm
index e71f678..4fd7993 100644
--- a/content/browser/compositor/software_output_device_mac.mm
+++ b/content/browser/compositor/software_output_device_mac.mm
@@ -123,7 +123,7 @@
       IOSurfaceGetBaseAddress(io_surfaces_[current_index_]));
   size_t stride = IOSurfaceGetBytesPerRow(io_surfaces_[current_index_]);
 
-  canvas_ = skia::AdoptRef(SkCanvas::NewRasterDirectN32(
+  canvas_ = sk_sp<SkCanvas>(SkCanvas::NewRasterDirectN32(
       pixel_size_.width(), pixel_size_.height(), pixels, stride));
 
   CopyPreviousBufferDamage(SkRegion(gfx::RectToSkIRect(new_damage_rect)));
diff --git a/content/browser/compositor/software_output_device_win.cc b/content/browser/compositor/software_output_device_win.cc
index adbbd69..3ab7677 100644
--- a/content/browser/compositor/software_output_device_win.cc
+++ b/content/browser/compositor/software_output_device_win.cc
@@ -122,7 +122,7 @@
   viewport_pixel_size_ = viewport_pixel_size;
   if (backing_)
     backing_->Resized();
-  contents_.clear();
+  contents_.reset();
 }
 
 SkCanvas* SoftwareOutputDeviceWin::BeginPaint(const gfx::Rect& damage_rect) {
@@ -141,7 +141,7 @@
       }
     }
     if (can_create_contents) {
-      contents_ = skia::AdoptRef(skia::CreatePlatformCanvas(
+      contents_ = sk_sp<SkCanvas>(skia::CreatePlatformCanvas(
           viewport_pixel_size_.width(), viewport_pixel_size_.height(), true,
           shared_section, skia::CRASH_ON_FAILURE));
     }
@@ -196,7 +196,7 @@
 void SoftwareOutputDeviceWin::ReleaseContents() {
   DCHECK(!contents_ || contents_->unique());
   DCHECK(!in_paint_);
-  contents_.clear();
+  contents_.reset();
 }
 
 }  // namespace content
diff --git a/content/browser/compositor/software_output_device_win.h b/content/browser/compositor/software_output_device_win.h
index 1cc267d..5c80340 100644
--- a/content/browser/compositor/software_output_device_win.h
+++ b/content/browser/compositor/software_output_device_win.h
@@ -13,6 +13,8 @@
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 #include "cc/output/software_output_device.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkRefCnt.h"
 
 namespace base {
 class SharedMemory;
@@ -61,7 +63,7 @@
 
  private:
   HWND hwnd_;
-  skia::RefPtr<SkCanvas> contents_;
+  sk_sp<SkCanvas> contents_;
   bool is_hwnd_composited_;
   OutputDeviceBacking* backing_;
   bool in_paint_;
diff --git a/content/browser/frame_host/render_frame_host_manager_browsertest.cc b/content/browser/frame_host/render_frame_host_manager_browsertest.cc
index 13b9ef6..b70475dd 100644
--- a/content/browser/frame_host/render_frame_host_manager_browsertest.cc
+++ b/content/browser/frame_host/render_frame_host_manager_browsertest.cc
@@ -2360,8 +2360,17 @@
 
 // Ensure that we don't crash the renderer in CreateRenderView if a proxy goes
 // away between swapout and the next navigation.  See https://crbug.com/581912.
+// Dr.Memory reports a use-after-free in this test, thus it may be flaky on
+// Windows. See https://crbug.com/600957.
+#if defined(OS_WIN)
+#define MAYBE_CreateRenderViewAfterProcessKillAndClosedProxy \
+    DISABLED_CreateRenderViewAfterProcessKillAndClosedProxy
+#else
+#define MAYBE_CreateRenderViewAfterProcessKillAndClosedProxy \
+    CreateRenderViewAfterProcessKillAndClosedProxy
+#endif
 IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
-                       CreateRenderViewAfterProcessKillAndClosedProxy) {
+                       MAYBE_CreateRenderViewAfterProcessKillAndClosedProxy) {
   StartEmbeddedServer();
   FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents())
                             ->GetFrameTree()
diff --git a/content/browser/gpu/gpu_ipc_browsertests.cc b/content/browser/gpu/gpu_ipc_browsertests.cc
index 1d77399..c9ece28 100644
--- a/content/browser/gpu/gpu_ipc_browsertests.cc
+++ b/content/browser/gpu/gpu_ipc_browsertests.cc
@@ -237,16 +237,16 @@
   skia::RefPtr<GrContext> gr_context = skia::SharePtr(provider->GrContext());
 
   SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
-  skia::RefPtr<SkSurface> surface = skia::AdoptRef(SkSurface::NewRenderTarget(
-      gr_context.get(), SkBudgeted::kNo, info));
+  sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(
+      gr_context.get(), SkBudgeted::kNo, info);
   EXPECT_TRUE(surface);
 
   // Destroy the GL context after we made a surface.
   provider = nullptr;
 
   // New surfaces will fail to create now.
-  skia::RefPtr<SkSurface> surface2 = skia::AdoptRef(
-      SkSurface::NewRenderTarget(gr_context.get(), SkBudgeted::kNo, info));
+  sk_sp<SkSurface> surface2 =
+      SkSurface::MakeRenderTarget(gr_context.get(), SkBudgeted::kNo, info);
   EXPECT_FALSE(surface2);
 
   // Drop our reference to the gr_context also.
diff --git a/content/browser/renderer_host/DEPS b/content/browser/renderer_host/DEPS
index e20b5581..8c4fbe0 100644
--- a/content/browser/renderer_host/DEPS
+++ b/content/browser/renderer_host/DEPS
@@ -23,13 +23,6 @@
     "+content/public/browser/web_contents_view.h",
     "+media/renderers",
   ],
-  "sandbox_ipc_linux\.cc": [
-    "+third_party/WebKit/public/platform/linux/WebFontInfo.h",
-    "+third_party/WebKit/public/web/WebKit.h",
-  ],
-  "sandbox_ipc_linux\.h": [
-    "+content/child/blink_platform_impl.h",
-  ],
   "render_process_host_impl\.cc": [
     "+content/browser/frame_host/render_frame_message_filter.h",
   ],
diff --git a/content/browser/renderer_host/sandbox_ipc_linux.cc b/content/browser/renderer_host/sandbox_ipc_linux.cc
index 62feacc5..94a34b5 100644
--- a/content/browser/renderer_host/sandbox_ipc_linux.cc
+++ b/content/browser/renderer_host/sandbox_ipc_linux.cc
@@ -27,16 +27,11 @@
 #include "content/common/set_process_title.h"
 #include "content/public/common/content_switches.h"
 #include "ppapi/c/trusted/ppb_browser_font_trusted.h"
-#include "third_party/WebKit/public/platform/linux/WebFontInfo.h"
-#include "third_party/WebKit/public/web/WebKit.h"
 #include "third_party/skia/include/ports/SkFontConfigInterface.h"
 #include "ui/gfx/font.h"
+#include "ui/gfx/font_fallback_linux.h"
 #include "ui/gfx/font_render_params.h"
 
-using blink::WebFontInfo;
-using blink::WebUChar;
-using blink::WebUChar32;
-
 namespace content {
 
 namespace {
@@ -118,9 +113,6 @@
     }
   }
 
-  if (blink_platform_impl_)
-    blink::Platform::shutdown();
-
   VLOG(1) << "SandboxIPCHandler stopping.";
 }
 
@@ -250,8 +242,7 @@
   // The other side of this call is
   // content/common/child_process_sandbox_support_impl_linux.cc
 
-  EnsureWebKitInitialized();
-  WebUChar32 c;
+  UChar32 c;
   if (!iter.ReadInt(&c))
     return;
 
@@ -259,27 +250,17 @@
   if (!iter.ReadString(&preferred_locale))
     return;
 
-  blink::WebFallbackFont fallbackFont;
-  WebFontInfo::fallbackFontForChar(c, preferred_locale.c_str(), &fallbackFont);
-
-  int pathIndex = FindOrAddPath(SkString(fallbackFont.filename.data()));
-  fallbackFont.fontconfigInterfaceId = pathIndex;
+  auto fallback_font = gfx::GetFallbackFontForChar(c, preferred_locale);
+  int fontconfig_interface_id =
+      FindOrAddPath(SkString(fallback_font.filename.data()));
 
   base::Pickle reply;
-  if (fallbackFont.name.data()) {
-    reply.WriteString(fallbackFont.name.data());
-  } else {
-    reply.WriteString(std::string());
-  }
-  if (fallbackFont.filename.data()) {
-    reply.WriteString(fallbackFont.filename.data());
-  } else {
-    reply.WriteString(std::string());
-  }
-  reply.WriteInt(fallbackFont.fontconfigInterfaceId);
-  reply.WriteInt(fallbackFont.ttcIndex);
-  reply.WriteBool(fallbackFont.isBold);
-  reply.WriteBool(fallbackFont.isItalic);
+  reply.WriteString(fallback_font.name);
+  reply.WriteString(fallback_font.filename);
+  reply.WriteInt(fontconfig_interface_id);
+  reply.WriteInt(fallback_font.ttc_index);
+  reply.WriteBool(fallback_font.is_bold);
+  reply.WriteBool(fallback_font.is_italic);
   SendRendererReply(fds, reply, -1);
 }
 
@@ -298,8 +279,6 @@
     return;
   }
 
-  EnsureWebKitInitialized();
-
   gfx::FontRenderParamsQuery query;
   query.families.push_back(family);
   query.pixel_size = pixel_size;
@@ -441,11 +420,4 @@
     PLOG(ERROR) << "close";
 }
 
-void SandboxIPCHandler::EnsureWebKitInitialized() {
-  if (blink_platform_impl_)
-    return;
-  blink_platform_impl_.reset(new BlinkPlatformImpl);
-  blink::Platform::initialize(blink_platform_impl_.get());
-}
-
 }  // namespace content
diff --git a/content/browser/renderer_host/sandbox_ipc_linux.h b/content/browser/renderer_host/sandbox_ipc_linux.h
index 2a836e9..f1a6bd5 100644
--- a/content/browser/renderer_host/sandbox_ipc_linux.h
+++ b/content/browser/renderer_host/sandbox_ipc_linux.h
@@ -14,7 +14,6 @@
 #include "base/memory/scoped_ptr.h"
 #include "base/pickle.h"
 #include "base/threading/simple_thread.h"
-#include "content/child/blink_platform_impl.h"
 #include "skia/ext/skia_utils_base.h"
 
 namespace content {
@@ -30,8 +29,6 @@
   void Run() override;
 
  private:
-  void EnsureWebKitInitialized();
-
   int FindOrAddPath(const SkString& path);
 
   void HandleRequestFromRenderer(int fd);
@@ -70,7 +67,6 @@
 
   const int lifeline_fd_;
   const int browser_socket_;
-  scoped_ptr<BlinkPlatformImpl> blink_platform_impl_;
   std::vector<SkString> paths_;
 
   DISALLOW_COPY_AND_ASSIGN(SandboxIPCHandler);
diff --git a/content/browser/renderer_host/web_input_event_aura_unittest.cc b/content/browser/renderer_host/web_input_event_aura_unittest.cc
index f520258e..412c607 100644
--- a/content/browser/renderer_host/web_input_event_aura_unittest.cc
+++ b/content/browser/renderer_host/web_input_event_aura_unittest.cc
@@ -21,7 +21,7 @@
 #include <X11/keysym.h>
 #include <X11/Xlib.h>
 #include "ui/events/test/events_test_utils_x11.h"
-#include "ui/gfx/x/x11_types.h"
+#include "ui/gfx/x/x11_types.h" // nogncheck
 #endif
 
 namespace content {
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 384bdd307..ee82a54 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -745,6 +745,8 @@
   FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest, CrossSiteIframe);
   FRIEND_TEST_ALL_PREFIXES(SitePerProcessAccessibilityBrowserTest,
                            CrossSiteIframeAccessibility);
+  FRIEND_TEST_ALL_PREFIXES(WebContentsImplBrowserTest,
+                           JavaScriptDialogsInMainAndSubframes);
 
   // So InterstitialPageImpl can access SetIsLoading.
   friend class InterstitialPageImpl;
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc
index d52bfe5b..93ae205c 100644
--- a/content/browser/web_contents/web_contents_impl_browsertest.cc
+++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -11,6 +11,8 @@
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/browser/web_contents/web_contents_view.h"
 #include "content/common/frame_messages.h"
+#include "content/common/site_isolation_policy.h"
+#include "content/public/browser/javascript_dialog_manager.h"
 #include "content/public/browser/load_notification_details.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/notification_details.h"
@@ -861,4 +863,140 @@
   EXPECT_TRUE(shell()->web_contents()->IsLoading());
 }
 
+namespace {
+
+class TestJavaScriptDialogManager : public JavaScriptDialogManager,
+                                    public WebContentsDelegate {
+ public:
+  TestJavaScriptDialogManager() : message_loop_runner_(new MessageLoopRunner) {}
+  ~TestJavaScriptDialogManager() override {}
+
+  void Wait() {
+    message_loop_runner_->Run();
+    message_loop_runner_ = new MessageLoopRunner;
+  }
+
+  std::string last_message() { return last_message_; }
+
+  // WebContentsDelegate
+
+  JavaScriptDialogManager* GetJavaScriptDialogManager(
+      WebContents* source) override {
+    return this;
+  }
+
+  // JavaScriptDialogManager
+
+  void RunJavaScriptDialog(WebContents* web_contents,
+                           const GURL& origin_url,
+                           JavaScriptMessageType javascript_message_type,
+                           const base::string16& message_text,
+                           const base::string16& default_prompt_text,
+                           const DialogClosedCallback& callback,
+                           bool* did_suppress_message) override {
+    last_message_ = base::UTF16ToUTF8(message_text);
+    *did_suppress_message = true;
+
+    message_loop_runner_->Quit();
+  };
+
+  void RunBeforeUnloadDialog(WebContents* web_contents,
+                             bool is_reload,
+                             const DialogClosedCallback& callback) override {}
+
+  bool HandleJavaScriptDialog(WebContents* web_contents,
+                              bool accept,
+                              const base::string16* prompt_override) override {
+    return true;
+  }
+
+  void CancelActiveAndPendingDialogs(WebContents* web_contents) override {}
+
+  void ResetDialogState(WebContents* web_contents) override {}
+
+ private:
+  std::string last_message_;
+
+  // The MessageLoopRunner used to spin the message loop.
+  scoped_refptr<MessageLoopRunner> message_loop_runner_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestJavaScriptDialogManager);
+};
+
+}  // namespace
+
+IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
+                       JavaScriptDialogsInMainAndSubframes) {
+  WebContentsImpl* wc = static_cast<WebContentsImpl*>(shell()->web_contents());
+  TestJavaScriptDialogManager dialog_manager;
+  wc->SetDelegate(&dialog_manager);
+
+  host_resolver()->AddRule("*", "127.0.0.1");
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  NavigateToURL(shell(),
+                embedded_test_server()->GetURL("a.com", "/title1.html"));
+  EXPECT_TRUE(WaitForLoadStop(wc));
+
+  FrameTreeNode* root = wc->GetFrameTree()->root();
+  ASSERT_EQ(0U, root->child_count());
+
+  std::string script =
+      "var iframe = document.createElement('iframe');"
+      "document.body.appendChild(iframe);";
+  EXPECT_TRUE(content::ExecuteScript(root->current_frame_host(), script));
+  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+
+  ASSERT_EQ(1U, root->child_count());
+  FrameTreeNode* frame = root->child_at(0);
+  ASSERT_NE(nullptr, frame);
+
+  url::Replacements<char> clear_port;
+  clear_port.ClearPort();
+
+  // A dialog from the main frame.
+  std::string alert_location = "alert(document.location)";
+  EXPECT_TRUE(
+      content::ExecuteScript(root->current_frame_host(), alert_location));
+  dialog_manager.Wait();
+  EXPECT_EQ(GURL("http://a.com/title1.html"),
+            GURL(dialog_manager.last_message()).ReplaceComponents(clear_port));
+
+  // A dialog from the subframe.
+  EXPECT_TRUE(
+      content::ExecuteScript(frame->current_frame_host(), alert_location));
+  dialog_manager.Wait();
+  EXPECT_EQ("about:blank", dialog_manager.last_message());
+
+  // Dialogs do not work with out-of-process iframes yet.
+  // http://crbug.com/453893
+  if (SiteIsolationPolicy::UseSubframeNavigationEntries()) {
+    wc->SetDelegate(nullptr);
+    wc->SetJavaScriptDialogManagerForTesting(nullptr);
+    return;  // :(
+  }
+
+  // Navigate cross-domain.
+  NavigateFrameToURL(frame,
+                     embedded_test_server()->GetURL("b.com", "/title2.html"));
+  EXPECT_TRUE(WaitForLoadStop(wc));
+
+  // A dialog from the subframe.
+  EXPECT_TRUE(
+      content::ExecuteScript(frame->current_frame_host(), alert_location));
+  dialog_manager.Wait();
+  EXPECT_EQ(GURL("http://b.com/title2.html"),
+            GURL(dialog_manager.last_message()).ReplaceComponents(clear_port));
+
+  // A dialog from the main frame.
+  EXPECT_TRUE(
+      content::ExecuteScript(root->current_frame_host(), alert_location));
+  dialog_manager.Wait();
+  EXPECT_EQ(GURL("http://a.com/title1.html"),
+            GURL(dialog_manager.last_message()).ReplaceComponents(clear_port));
+
+  wc->SetDelegate(nullptr);
+  wc->SetJavaScriptDialogManagerForTesting(nullptr);
+}
+
 }  // namespace content
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc
index 327552c9..e62e7ad 100644
--- a/content/browser/web_contents/web_contents_impl_unittest.cc
+++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -3392,6 +3392,8 @@
   DeleteContents();
 }
 
+namespace {
+
 class TestJavaScriptDialogManager : public JavaScriptDialogManager {
  public:
   TestJavaScriptDialogManager() {}
@@ -3431,22 +3433,23 @@
   DISALLOW_COPY_AND_ASSIGN(TestJavaScriptDialogManager);
 };
 
+}  // namespace
+
 TEST_F(WebContentsImplTest, ResetJavaScriptDialogOnUserNavigate) {
-  scoped_ptr<TestJavaScriptDialogManager> delegate(
-      new TestJavaScriptDialogManager());
-  contents()->SetJavaScriptDialogManagerForTesting(delegate.get());
+  TestJavaScriptDialogManager dialog_manager;
+  contents()->SetJavaScriptDialogManagerForTesting(&dialog_manager);
 
   // A user-initiated navigation.
   contents()->TestDidNavigate(contents()->GetMainFrame(), 1, 0, true,
                               GURL("about:whatever"),
                               ui::PAGE_TRANSITION_TYPED);
-  EXPECT_EQ(1u, delegate->reset_count());
+  EXPECT_EQ(1u, dialog_manager.reset_count());
 
   // An automatic navigation.
   contents()->GetMainFrame()->SendNavigateWithModificationCallback(
       2, 0, true, GURL(url::kAboutBlankURL), base::Bind(SetAsNonUserGesture));
 
-  EXPECT_EQ(1u, delegate->reset_count());
+  EXPECT_EQ(1u, dialog_manager.reset_count());
 
   contents()->SetJavaScriptDialogManagerForTesting(nullptr);
 }
diff --git a/content/child/blob_storage/blob_transport_controller.cc b/content/child/blob_storage/blob_transport_controller.cc
index c2b639ad..87c22725 100644
--- a/content/child/blob_storage/blob_transport_controller.cc
+++ b/content/child/blob_storage/blob_transport_controller.cc
@@ -20,6 +20,7 @@
 #include "storage/common/blob_storage/blob_item_bytes_request.h"
 #include "storage/common/blob_storage/blob_item_bytes_response.h"
 #include "storage/common/data_element.h"
+#include "third_party/WebKit/public/platform/Platform.h"
 
 using base::SharedMemory;
 using base::SharedMemoryHandle;
@@ -27,6 +28,7 @@
 using storage::BlobItemBytesResponse;
 using storage::IPCBlobItemRequestStrategy;
 using storage::DataElement;
+using storage::kBlobStorageIPCThresholdBytes;
 
 namespace content {
 
@@ -36,16 +38,18 @@
 using ReadStatus = BlobConsolidation::ReadStatus;
 
 namespace {
-const size_t kLargeThresholdBytes = 250 * 1024;
-static base::LazyInstance<BlobTransportController> g_controller =
+static base::LazyInstance<BlobTransportController>::Leaky g_controller =
     LAZY_INSTANCE_INITIALIZER;
 
 // This keeps the process alive while blobs are being transferred.
+// These need to be called on the main thread.
 void IncChildProcessRefCount() {
+  blink::Platform::current()->suddenTerminationChanged(false);
   ChildProcess::current()->AddRefProcess();
 }
 
 void DecChildProcessRefCount() {
+  blink::Platform::current()->suddenTerminationChanged(true);
   ChildProcess::current()->ReleaseProcess();
 }
 }  // namespace
@@ -54,22 +58,35 @@
   return g_controller.Pointer();
 }
 
-BlobTransportController::~BlobTransportController() {}
-
+// static
 void BlobTransportController::InitiateBlobTransfer(
     const std::string& uuid,
+    const std::string& content_type,
     scoped_ptr<BlobConsolidation> consolidation,
-    IPC::Sender* sender,
+    scoped_refptr<ThreadSafeSender> sender,
+    base::SingleThreadTaskRunner* io_runner,
     scoped_refptr<base::SingleThreadTaskRunner> main_runner) {
-  BlobConsolidation* consolidation_ptr = consolidation.get();
-  if (blob_storage_.empty()) {
-    main_thread_runner_ = std::move(main_runner);
-    main_thread_runner_->PostTask(FROM_HERE,
-                                  base::Bind(&IncChildProcessRefCount));
+  if (main_runner->BelongsToCurrentThread()) {
+    IncChildProcessRefCount();
+  } else {
+    main_runner->PostTask(FROM_HERE, base::Bind(&IncChildProcessRefCount));
   }
-  blob_storage_[uuid] = std::move(consolidation);
+
   std::vector<storage::DataElement> descriptions;
-  GetDescriptions(consolidation_ptr, kLargeThresholdBytes, &descriptions);
+  std::set<std::string> referenced_blobs = consolidation->referenced_blobs();
+  BlobTransportController::GetDescriptions(
+      consolidation.get(), kBlobStorageIPCThresholdBytes, &descriptions);
+  // I post the task first to make sure that we store our consolidation before
+  // we get a request back from the browser.
+  io_runner->PostTask(
+      FROM_HERE,
+      base::Bind(&BlobTransportController::StoreBlobDataForRequests,
+                 base::Unretained(BlobTransportController::GetInstance()), uuid,
+                 base::Passed(std::move(consolidation)),
+                 base::Passed(std::move(main_runner))));
+  // TODO(dmurph): Merge register and start messages.
+  sender->Send(new BlobStorageMsg_RegisterBlobUUID(uuid, content_type, "",
+                                                   referenced_blobs));
   sender->Send(new BlobStorageMsg_StartBuildingBlob(uuid, descriptions));
 }
 
@@ -115,16 +132,7 @@
   ReleaseBlobConsolidation(uuid);
 }
 
-void BlobTransportController::ClearForTesting() {
-  if (!blob_storage_.empty() && main_thread_runner_) {
-    main_thread_runner_->PostTask(FROM_HERE,
-                                  base::Bind(&DecChildProcessRefCount));
-  }
-  blob_storage_.clear();
-}
-
-BlobTransportController::BlobTransportController() {}
-
+// static
 void BlobTransportController::GetDescriptions(
     BlobConsolidation* consolidation,
     size_t max_data_population,
@@ -178,6 +186,28 @@
   }
 }
 
+BlobTransportController::BlobTransportController() {}
+
+BlobTransportController::~BlobTransportController() {}
+
+void BlobTransportController::ClearForTesting() {
+  if (!blob_storage_.empty() && main_thread_runner_) {
+    main_thread_runner_->PostTask(FROM_HERE,
+                                  base::Bind(&DecChildProcessRefCount));
+  }
+  blob_storage_.clear();
+}
+
+void BlobTransportController::StoreBlobDataForRequests(
+    const std::string& uuid,
+    scoped_ptr<BlobConsolidation> consolidation,
+    scoped_refptr<base::SingleThreadTaskRunner> main_runner) {
+  if (!main_thread_runner_.get()) {
+    main_thread_runner_ = std::move(main_runner);
+  }
+  blob_storage_[uuid] = std::move(consolidation);
+}
+
 BlobTransportController::ResponsesStatus BlobTransportController::GetResponses(
     const std::string& uuid,
     const std::vector<BlobItemBytesRequest>& requests,
@@ -255,12 +285,9 @@
 
 void BlobTransportController::ReleaseBlobConsolidation(
     const std::string& uuid) {
-  // If we erased something and we're now empty, release the child process
-  // ref count and deref the main thread runner.
-  if (blob_storage_.erase(uuid) && blob_storage_.empty()) {
+  if (blob_storage_.erase(uuid)) {
     main_thread_runner_->PostTask(FROM_HERE,
                                   base::Bind(&DecChildProcessRefCount));
-    main_thread_runner_ = nullptr;
   }
 }
 
diff --git a/content/child/blob_storage/blob_transport_controller.h b/content/child/blob_storage/blob_transport_controller.h
index f2699abd..77a8bb91 100644
--- a/content/child/blob_storage/blob_transport_controller.h
+++ b/content/child/blob_storage/blob_transport_controller.h
@@ -39,6 +39,7 @@
 namespace content {
 
 class BlobConsolidation;
+class ThreadSafeSender;
 
 // This class is used to manage all the asynchronous transporation of blobs from
 // the Renderer to the Browser process, where it's handling the Renderer side.
@@ -55,14 +56,16 @@
   static BlobTransportController* GetInstance();
 
   // This kicks off a blob transfer to the browser thread, which involves
-  // sending an IPC message and storing the blob consolidation object.
-  // If we have no pending blobs, we also call ChildProcess::AddRefProcess to
-  // keep our process around while we transfer. This will be decremented when
-  // we finish our last pending transfer (when our map is empty).
-  void InitiateBlobTransfer(
+  // sending an IPC message and storing the blob consolidation object. Designed
+  // to be called by the main thread or a worker thread.
+  // This also calls ChildProcess::AddRefProcess to keep our process around
+  // while we transfer.
+  static void InitiateBlobTransfer(
       const std::string& uuid,
+      const std::string& content_type,
       scoped_ptr<BlobConsolidation> consolidation,
-      IPC::Sender* sender,
+      scoped_refptr<ThreadSafeSender> sender,
+      base::SingleThreadTaskRunner* io_runner,
       scoped_refptr<base::SingleThreadTaskRunner> main_runner);
 
   // This responds to the request using the sender.
@@ -78,13 +81,10 @@
 
   void OnDone(const std::string& uuid);
 
-
   bool IsTransporting(const std::string& uuid) {
     return blob_storage_.find(uuid) != blob_storage_.end();
   }
 
-  ~BlobTransportController();
-
  private:
   friend class BlobTransportControllerTest;
   FRIEND_TEST_ALL_PREFIXES(BlobTransportControllerTest, Descriptions);
@@ -92,6 +92,13 @@
   FRIEND_TEST_ALL_PREFIXES(BlobTransportControllerTest, SharedMemory);
   FRIEND_TEST_ALL_PREFIXES(BlobTransportControllerTest, ResponsesErrors);
 
+  static void GetDescriptions(BlobConsolidation* consolidation,
+                              size_t max_data_population,
+                              std::vector<storage::DataElement>* out);
+
+  BlobTransportController();
+  ~BlobTransportController();
+
   // Clears all internal state. If our map wasn't previously empty, then we call
   // ChildProcess::ReleaseProcess to release our previous reference.
   void ClearForTesting();
@@ -103,11 +110,10 @@
   };
   friend struct base::DefaultLazyInstanceTraits<BlobTransportController>;
 
-  BlobTransportController();
-
-  void GetDescriptions(BlobConsolidation* consolidation,
-                       size_t max_data_population,
-                       std::vector<storage::DataElement>* out);
+  void StoreBlobDataForRequests(
+      const std::string& uuid,
+      scoped_ptr<BlobConsolidation> consolidation,
+      scoped_refptr<base::SingleThreadTaskRunner> main_runner);
 
   ResponsesStatus GetResponses(
       const std::string& uuid,
diff --git a/content/child/blob_storage/blob_transport_controller_unittest.cc b/content/child/blob_storage/blob_transport_controller_unittest.cc
index d10d5a0..67dd7f9 100644
--- a/content/child/blob_storage/blob_transport_controller_unittest.cc
+++ b/content/child/blob_storage/blob_transport_controller_unittest.cc
@@ -11,8 +11,10 @@
 #include "base/test/test_simple_task_runner.h"
 #include "base/tuple.h"
 #include "content/child/blob_storage/blob_consolidation.h"
+#include "content/child/thread_safe_sender.h"
 #include "content/common/fileapi/webblob_messages.h"
 #include "ipc/ipc_sender.h"
+#include "ipc/ipc_sync_message_filter.h"
 #include "ipc/ipc_test_sink.h"
 #include "storage/common/blob_storage/blob_item_bytes_request.h"
 #include "storage/common/blob_storage/blob_item_bytes_response.h"
@@ -26,6 +28,29 @@
 namespace content {
 namespace {
 
+class OtherThreadTestSimpleTaskRunner : public base::TestSimpleTaskRunner {
+ public:
+  bool RunsTasksOnCurrentThread() const override { return false; }
+
+ protected:
+  ~OtherThreadTestSimpleTaskRunner() override {}
+};
+
+class BlobTransportControllerTestSender : public ThreadSafeSender {
+ public:
+  explicit BlobTransportControllerTestSender(IPC::TestSink* ipc_sink)
+      : ThreadSafeSender(nullptr, nullptr), ipc_sink_(ipc_sink) {}
+
+  bool Send(IPC::Message* message) override { return ipc_sink_->Send(message); }
+
+ private:
+  ~BlobTransportControllerTestSender() override {}
+
+  IPC::TestSink* ipc_sink_;
+
+  DISALLOW_COPY_AND_ASSIGN(BlobTransportControllerTestSender);
+};
+
 BlobItemBytesResponse ResponseWithData(size_t request_number,
                                        const std::string& str) {
   BlobItemBytesResponse response(request_number);
@@ -62,17 +87,45 @@
 class BlobTransportControllerTest : public testing::Test {
  public:
   BlobTransportControllerTest()
-      : main_thread_runner_(new base::TestSimpleTaskRunner()) {}
+      : io_thread_runner_(new base::TestSimpleTaskRunner()),
+        main_thread_runner_(new OtherThreadTestSimpleTaskRunner()) {}
 
   void SetUp() override {
+    sender_ = new BlobTransportControllerTestSender(&sink_);
     BlobTransportController::GetInstance()->ClearForTesting();
   }
 
+  void ExpectRegisterAndStartMessage(const std::string& expected_uuid,
+                                     const std::string& expected_content_type,
+                                     std::vector<DataElement>* descriptions) {
+    const IPC::Message* register_message =
+        sink_.GetUniqueMessageMatching(BlobStorageMsg_RegisterBlobUUID::ID);
+    const IPC::Message* start_message =
+        sink_.GetUniqueMessageMatching(BlobStorageMsg_StartBuildingBlob::ID);
+    ASSERT_TRUE(register_message);
+    ASSERT_TRUE(start_message);
+    base::Tuple<std::string, std::string, std::string, std::set<std::string>>
+        register_contents;
+    base::Tuple<std::string, std::vector<DataElement>> start_contents;
+    BlobStorageMsg_RegisterBlobUUID::Read(register_message, &register_contents);
+    BlobStorageMsg_StartBuildingBlob::Read(start_message, &start_contents);
+    EXPECT_EQ(expected_uuid, base::get<0>(register_contents));
+    EXPECT_EQ(expected_uuid, base::get<0>(start_contents));
+    EXPECT_EQ(expected_content_type, base::get<1>(register_contents));
+    if (descriptions)
+      *descriptions = base::get<1>(start_contents);
+    // We don't have dispositions from the renderer.
+    EXPECT_TRUE(base::get<2>(register_contents).empty());
+  }
+
   void TearDown() override {
     BlobTransportController::GetInstance()->ClearForTesting();
   }
 
-  scoped_refptr<base::TestSimpleTaskRunner> main_thread_runner_;
+  IPC::TestSink sink_;
+  scoped_refptr<BlobTransportControllerTestSender> sender_;
+  scoped_refptr<base::TestSimpleTaskRunner> io_thread_runner_;
+  scoped_refptr<OtherThreadTestSimpleTaskRunner> main_thread_runner_;
 };
 
 TEST_F(BlobTransportControllerTest, Descriptions) {
@@ -80,7 +133,6 @@
   const std::string KRefBlobUUID = "refuuid";
   const std::string kBadBlobUUID = "uuuidBad";
   const size_t kShortcutSize = 11;
-  BlobTransportController* holder = BlobTransportController::GetInstance();
 
   // The first two data elements should be combined and the data shortcut.
   scoped_ptr<BlobConsolidation> consolidation(new BlobConsolidation());
@@ -91,7 +143,8 @@
   consolidation->AddDataItem(CreateData("Hello3"));
 
   std::vector<DataElement> out;
-  holder->GetDescriptions(consolidation.get(), kShortcutSize, &out);
+  BlobTransportController::GetDescriptions(consolidation.get(), kShortcutSize,
+                                           &out);
 
   std::vector<DataElement> expected;
   expected.push_back(MakeBlobElement(KRefBlobUUID, 10, 10));
@@ -211,30 +264,33 @@
 
 TEST_F(BlobTransportControllerTest, TestPublicMethods) {
   const std::string kBlobUUID = "uuid";
+  const std::string kBlobContentType = "content_type";
   const std::string kBlob2UUID = "uuid2";
+  const std::string kBlob2ContentType = "content_type2";
   const std::string KRefBlobUUID = "refuuid";
+  std::vector<DataElement> message_descriptions;
   BlobTransportController* holder = BlobTransportController::GetInstance();
-  IPC::TestSink sink;
 
   BlobConsolidation* consolidation = new BlobConsolidation();
   consolidation->AddBlobItem(KRefBlobUUID, 10, 10);
-  holder->InitiateBlobTransfer(kBlobUUID, make_scoped_ptr(consolidation), &sink,
-                               main_thread_runner_);
+  BlobTransportController::InitiateBlobTransfer(
+      kBlobUUID, kBlobContentType, make_scoped_ptr(consolidation), sender_,
+      io_thread_runner_.get(), main_thread_runner_);
   // Check that we have the 'increase ref' pending task.
   EXPECT_TRUE(main_thread_runner_->HasPendingTask());
+  // Check that we have the 'store' pending task.
+  EXPECT_TRUE(io_thread_runner_->HasPendingTask());
+  // Check that we've sent the data.
+  ExpectRegisterAndStartMessage(kBlobUUID, kBlobContentType,
+                                &message_descriptions);
   main_thread_runner_->ClearPendingTasks();
 
   // Check that we got the correct start message.
-  const IPC::Message* message =
-      sink.GetUniqueMessageMatching(BlobStorageMsg_StartBuildingBlob::ID);
-  ASSERT_TRUE(message);
-  std::vector<DataElement> expected;
-  expected.push_back(MakeBlobElement(KRefBlobUUID, 10, 10));
+  EXPECT_FALSE(holder->IsTransporting(kBlobUUID));
+  io_thread_runner_->RunPendingTasks();
+  EXPECT_TRUE(holder->IsTransporting(kBlobUUID));
   base::Tuple<std::string, std::vector<DataElement>> message_contents;
-  BlobStorageMsg_StartBuildingBlob::Read(message, &message_contents);
-  EXPECT_EQ(kBlobUUID, base::get<0>(message_contents));
-  EXPECT_EQ(MakeBlobElement(KRefBlobUUID, 10, 10),
-            base::get<1>(message_contents)[0]);
+  EXPECT_EQ(MakeBlobElement(KRefBlobUUID, 10, 10), message_descriptions[0]);
 
   holder->OnCancel(kBlobUUID,
                    storage::IPCBlobCreationCancelCode::OUT_OF_MEMORY);
@@ -242,35 +298,22 @@
   // Check we have the 'decrease ref' task.
   EXPECT_TRUE(main_thread_runner_->HasPendingTask());
   main_thread_runner_->ClearPendingTasks();
-  message = nullptr;
-  sink.ClearMessages();
+  sink_.ClearMessages();
 
-  // Check that we can complete the blob, and check that we only update the
-  // child process ref on the first and last transfer.
-  consolidation = new BlobConsolidation();
-  consolidation->AddBlobItem(KRefBlobUUID, 10, 10);
-  holder->InitiateBlobTransfer(kBlobUUID, make_scoped_ptr(consolidation), &sink,
-                               main_thread_runner_);
-  EXPECT_TRUE(main_thread_runner_->HasPendingTask());
-  main_thread_runner_->ClearPendingTasks();
-  EXPECT_TRUE(
-      sink.GetUniqueMessageMatching(BlobStorageMsg_StartBuildingBlob::ID));
-  sink.ClearMessages();
-
-  // Add the second and check that we don't have a task.
+  // Add the second.
   BlobConsolidation* consolidation2 = new BlobConsolidation();
   consolidation2->AddBlobItem(KRefBlobUUID, 10, 10);
-  holder->InitiateBlobTransfer(kBlob2UUID, make_scoped_ptr(consolidation2),
-                               &sink, main_thread_runner_);
-  EXPECT_FALSE(main_thread_runner_->HasPendingTask());
-  sink.ClearMessages();
+  BlobTransportController::InitiateBlobTransfer(
+      kBlob2UUID, kBlob2ContentType, make_scoped_ptr(consolidation2), sender_,
+      io_thread_runner_.get(), main_thread_runner_);
+  EXPECT_TRUE(main_thread_runner_->HasPendingTask());
+  main_thread_runner_->ClearPendingTasks();
+  sink_.ClearMessages();
 
-  // Finish the first one.
-  holder->OnDone(kBlobUUID);
-  EXPECT_FALSE(holder->IsTransporting(kBlobUUID));
-  EXPECT_FALSE(main_thread_runner_->HasPendingTask());
+  io_thread_runner_->RunPendingTasks();
+  EXPECT_TRUE(holder->IsTransporting(kBlob2UUID));
 
-  // Finish the second one, and verify that we have the task.
+  // Finish the second one.
   holder->OnDone(kBlob2UUID);
   EXPECT_FALSE(holder->IsTransporting(kBlob2UUID));
   EXPECT_TRUE(main_thread_runner_->HasPendingTask());
diff --git a/content/child/notifications/pending_notifications_tracker_unittest.cc b/content/child/notifications/pending_notifications_tracker_unittest.cc
index 5aabbc5..d06ee972 100644
--- a/content/child/notifications/pending_notifications_tracker_unittest.cc
+++ b/content/child/notifications/pending_notifications_tracker_unittest.cc
@@ -25,8 +25,8 @@
 #include "third_party/WebKit/public/platform/WebString.h"
 #include "third_party/WebKit/public/platform/WebURL.h"
 #include "third_party/WebKit/public/platform/WebURLError.h"
+#include "third_party/WebKit/public/platform/WebURLLoaderMockFactory.h"
 #include "third_party/WebKit/public/platform/WebURLResponse.h"
-#include "third_party/WebKit/public/platform/WebUnitTestSupport.h"
 #include "third_party/WebKit/public/platform/modules/notifications/WebNotificationData.h"
 #include "third_party/WebKit/public/platform/modules/notifications/WebNotificationDelegate.h"
 #include "third_party/skia/include/core/SkBitmap.h"
@@ -60,7 +60,7 @@
             base::ThreadTaskRunnerHandle::Get())) {}
 
   ~PendingNotificationsTrackerTest() override {
-    UnitTestSupport()->unregisterAllMockedURLs();
+    GetURLLoaderMockFactory()->unregisterAllURLs();
   }
 
   void DidFetchResources(size_t index, const NotificationResources& resources) {
@@ -87,8 +87,8 @@
     return tracker_->delegate_to_pending_id_map_.size();
   }
 
-  blink::WebUnitTestSupport* UnitTestSupport() {
-    return blink::Platform::current()->unitTestSupport();
+  blink::WebURLLoaderMockFactory* GetURLLoaderMockFactory() {
+    return blink::Platform::current()->getURLLoaderMockFactory();
   }
 
   // Registers a mocked url. When fetched, |file_name| will be loaded from the
@@ -111,7 +111,7 @@
     blink::WebString string_file_path =
         blink::WebString::fromUTF8(file_path.MaybeAsASCII());
 
-    UnitTestSupport()->registerMockedURL(url, response, string_file_path);
+    GetURLLoaderMockFactory()->registerURL(url, response, string_file_path);
 
     return url;
   }
@@ -127,7 +127,7 @@
     blink::WebURLError error;
     error.reason = 404;
 
-    UnitTestSupport()->registerMockedErrorURL(url, response, error);
+    GetURLLoaderMockFactory()->registerErrorURL(url, response, error);
     return url;
   }
 
@@ -157,7 +157,7 @@
   ASSERT_EQ(0u, CountResources());
 
   base::RunLoop().RunUntilIdle();
-  UnitTestSupport()->serveAsynchronousMockedRequests();
+  GetURLLoaderMockFactory()->serveAsynchronousRequests();
 
   ASSERT_EQ(0u, CountPendingNotifications());
   ASSERT_EQ(1u, CountResources());
@@ -194,7 +194,7 @@
   ASSERT_EQ(0u, CountResources());
 
   base::RunLoop().RunUntilIdle();
-  UnitTestSupport()->serveAsynchronousMockedRequests();
+  GetURLLoaderMockFactory()->serveAsynchronousRequests();
 
   ASSERT_EQ(0u, CountPendingNotifications());
   ASSERT_EQ(1u, CountResources());
@@ -240,7 +240,7 @@
   ASSERT_EQ(0u, CountResources());
 
   base::RunLoop().RunUntilIdle();
-  UnitTestSupport()->serveAsynchronousMockedRequests();
+  GetURLLoaderMockFactory()->serveAsynchronousRequests();
 
   ASSERT_EQ(0u, CountPendingNotifications());
   ASSERT_EQ(2u, CountResources());
@@ -265,7 +265,7 @@
   ASSERT_EQ(0u, CountResources());
 
   base::RunLoop().RunUntilIdle();
-  UnitTestSupport()->serveAsynchronousMockedRequests();
+  GetURLLoaderMockFactory()->serveAsynchronousRequests();
 
   ASSERT_EQ(0u, CountPendingNotifications());
   ASSERT_EQ(1u, CountResources());
diff --git a/content/child/webblobregistry_impl.cc b/content/child/webblobregistry_impl.cc
index 3850ce5..afc7ae2 100644
--- a/content/child/webblobregistry_impl.cc
+++ b/content/child/webblobregistry_impl.cc
@@ -235,22 +235,9 @@
 }
 
 void WebBlobRegistryImpl::BuilderImpl::build() {
-  sender_->Send(new BlobStorageMsg_RegisterBlobUUID(
-      uuid_, content_type_, "", consolidation_->referenced_blobs()));
-  io_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&WebBlobRegistryImpl::StartBlobAsyncConstruction, uuid_,
-                 base::Passed(&consolidation_), sender_, main_runner_));
-}
-
-/* static */
-void WebBlobRegistryImpl::StartBlobAsyncConstruction(
-    const std::string& uuid,
-    std::unique_ptr<BlobConsolidation> consolidation,
-    scoped_refptr<ThreadSafeSender> sender,
-    scoped_refptr<base::SingleThreadTaskRunner> main_runner) {
-  BlobTransportController::GetInstance()->InitiateBlobTransfer(
-      uuid, std::move(consolidation), sender.get(), std::move(main_runner));
+  BlobTransportController::InitiateBlobTransfer(
+      uuid_, content_type_, std::move(consolidation_), sender_,
+      io_runner_.get(), main_runner_);
 }
 
 }  // namespace content
diff --git a/content/child/webblobregistry_impl.h b/content/child/webblobregistry_impl.h
index 3f590ad..ff41460 100644
--- a/content/child/webblobregistry_impl.h
+++ b/content/child/webblobregistry_impl.h
@@ -98,13 +98,6 @@
     scoped_refptr<base::SingleThreadTaskRunner> main_runner_;
   };
 
-  // Method called on the IO thread.
-  static void StartBlobAsyncConstruction(
-      const std::string& uuid,
-      std::unique_ptr<BlobConsolidation> consolidation,
-      scoped_refptr<ThreadSafeSender> sender,
-      scoped_refptr<base::SingleThreadTaskRunner> main_runner);
-
   scoped_refptr<base::SingleThreadTaskRunner> io_runner_;
   scoped_refptr<base::SingleThreadTaskRunner> main_runner_;
   scoped_refptr<ThreadSafeSender> sender_;
diff --git a/content/common/gpu/client/grcontext_for_gles2_interface.cc b/content/common/gpu/client/grcontext_for_gles2_interface.cc
index bfd11c8b..8805a4a 100644
--- a/content/common/gpu/client/grcontext_for_gles2_interface.cc
+++ b/content/common/gpu/client/grcontext_for_gles2_interface.cc
@@ -20,8 +20,8 @@
 
 GrContextForGLES2Interface::GrContextForGLES2Interface(
     gpu::gles2::GLES2Interface* gl) {
-  skia::RefPtr<GrGLInterface> interface =
-      skia_bindings::CreateGLES2InterfaceBindings(gl);
+  sk_sp<GrGLInterface> interface(
+      skia_bindings::CreateGLES2InterfaceBindings(gl));
   gr_context_ = skia::AdoptRef(
       GrContext::Create(kOpenGL_GrBackend,
                         // GrContext takes ownership of |interface|.
diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc
index 6c65f5c..606d5581 100644
--- a/content/gpu/gpu_main.cc
+++ b/content/gpu/gpu_main.cc
@@ -62,7 +62,7 @@
 
 #if defined(USE_X11)
 #include "ui/base/x/x11_util.h"
-#include "ui/gfx/x/x11_switches.h"
+#include "ui/gfx/x/x11_switches.h"  // nogncheck
 #endif
 
 #if defined(OS_LINUX)
diff --git a/content/gpu/gpu_watchdog_thread.h b/content/gpu/gpu_watchdog_thread.h
index 2f8cecd7..11d7b7dc 100644
--- a/content/gpu/gpu_watchdog_thread.h
+++ b/content/gpu/gpu_watchdog_thread.h
@@ -23,8 +23,7 @@
 }
 #include <sys/poll.h>
 #include "ui/base/x/x11_util.h"
-#include "ui/gfx/x/x11_types.h"
-
+#include "ui/gfx/x/x11_types.h"  // nogncheck
 #endif
 
 namespace content {
diff --git a/content/renderer/media/html_video_element_capturer_source.h b/content/renderer/media/html_video_element_capturer_source.h
index 16bf89e4..1f545d8 100644
--- a/content/renderer/media/html_video_element_capturer_source.h
+++ b/content/renderer/media/html_video_element_capturer_source.h
@@ -14,6 +14,7 @@
 #include "media/base/video_frame_pool.h"
 #include "media/base/video_types.h"
 #include "skia/ext/platform_canvas.h"
+#include "skia/ext/refptr.h"
 #include "third_party/WebKit/public/platform/WebSize.h"
 
 namespace blink {
diff --git a/content/test/test_blink_web_unit_test_support.cc b/content/test/test_blink_web_unit_test_support.cc
index 0d5d7cf..b05e447b 100644
--- a/content/test/test_blink_web_unit_test_support.cc
+++ b/content/test/test_blink_web_unit_test_support.cc
@@ -27,19 +27,12 @@
 #include "storage/browser/database/vfs_backend.h"
 #include "third_party/WebKit/public/platform/WebConnectionType.h"
 #include "third_party/WebKit/public/platform/WebData.h"
-#include "third_party/WebKit/public/platform/WebFileSystem.h"
 #include "third_party/WebKit/public/platform/WebPluginListBuilder.h"
-#include "third_party/WebKit/public/platform/WebStorageArea.h"
-#include "third_party/WebKit/public/platform/WebStorageNamespace.h"
 #include "third_party/WebKit/public/platform/WebString.h"
 #include "third_party/WebKit/public/platform/WebURL.h"
-#include "third_party/WebKit/public/web/WebCache.h"
-#include "third_party/WebKit/public/web/WebDatabase.h"
 #include "third_party/WebKit/public/web/WebKit.h"
 #include "third_party/WebKit/public/web/WebNetworkStateNotifier.h"
 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
-#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
-#include "third_party/WebKit/public/web/WebStorageEventDispatcher.h"
 #include "v8/include/v8.h"
 
 #if defined(OS_MACOSX)
@@ -300,41 +293,9 @@
   return new WebGestureCurveMock(velocity, cumulative_scroll);
 }
 
-blink::WebUnitTestSupport* TestBlinkWebUnitTestSupport::unitTestSupport() {
-  return this;
-}
-
-void TestBlinkWebUnitTestSupport::registerMockedURL(
-    const blink::WebURL& url,
-    const blink::WebURLResponse& response,
-    const blink::WebString& file_path) {
-  url_loader_factory_->registerURL(url, response, file_path);
-}
-
-void TestBlinkWebUnitTestSupport::registerMockedErrorURL(
-    const blink::WebURL& url,
-    const blink::WebURLResponse& response,
-    const blink::WebURLError& error) {
-  url_loader_factory_->registerErrorURL(url, response, error);
-}
-
-void TestBlinkWebUnitTestSupport::unregisterMockedURL(
-    const blink::WebURL& url) {
-  url_loader_factory_->unregisterURL(url);
-}
-
-void TestBlinkWebUnitTestSupport::unregisterAllMockedURLs() {
-  url_loader_factory_->unregisterAllURLs();
-  blink::WebCache::clear();
-}
-
-void TestBlinkWebUnitTestSupport::serveAsynchronousMockedRequests() {
-  url_loader_factory_->serveAsynchronousRequests();
-}
-
-void TestBlinkWebUnitTestSupport::setLoaderDelegate(
-    blink::WebURLLoaderTestDelegate* delegate) {
-  url_loader_factory_->setLoaderDelegate(delegate);
+blink::WebURLLoaderMockFactory*
+TestBlinkWebUnitTestSupport::getURLLoaderMockFactory() {
+  return url_loader_factory_.get();
 }
 
 blink::WebThread* TestBlinkWebUnitTestSupport::currentThread() {
diff --git a/content/test/test_blink_web_unit_test_support.h b/content/test/test_blink_web_unit_test_support.h
index c192b15..5139de8 100644
--- a/content/test/test_blink_web_unit_test_support.h
+++ b/content/test/test_blink_web_unit_test_support.h
@@ -16,7 +16,6 @@
 #include "content/test/mock_webblob_registry_impl.h"
 #include "content/test/mock_webclipboard_impl.h"
 #include "third_party/WebKit/public/platform/WebURLLoaderMockFactory.h"
-#include "third_party/WebKit/public/platform/WebUnitTestSupport.h"
 
 namespace base {
 class StatsTable;
@@ -32,10 +31,8 @@
 
 namespace content {
 
-// An implementation of blink::WebUnitTestSupport and BlinkPlatformImpl for
-// tests.
-class TestBlinkWebUnitTestSupport : public blink::WebUnitTestSupport,
-                                    public BlinkPlatformImpl {
+// An implementation of BlinkPlatformImpl for tests.
+class TestBlinkWebUnitTestSupport : public BlinkPlatformImpl {
  public:
   TestBlinkWebUnitTestSupport();
   ~TestBlinkWebUnitTestSupport() override;
@@ -71,20 +68,8 @@
       const blink::WebFloatPoint& velocity,
       const blink::WebSize& cumulative_scroll) override;
 
-  blink::WebUnitTestSupport* unitTestSupport() override;
+  blink::WebURLLoaderMockFactory* getURLLoaderMockFactory() override;
 
-  // WebUnitTestSupport implementation
-  // TODO(kinuko): Remove these methods.
-  void registerMockedURL(const blink::WebURL& url,
-                         const blink::WebURLResponse& response,
-                         const blink::WebString& filePath) override;
-  void registerMockedErrorURL(const blink::WebURL& url,
-                              const blink::WebURLResponse& response,
-                              const blink::WebURLError& error) override;
-  void unregisterMockedURL(const blink::WebURL& url) override;
-  void unregisterAllMockedURLs() override;
-  void serveAsynchronousMockedRequests() override;
-  void setLoaderDelegate(blink::WebURLLoaderTestDelegate* delegate) override;
   blink::WebThread* currentThread() override;
 
   void getPluginList(bool refresh,
diff --git a/gpu/config/gpu_driver_bug_list_json.cc b/gpu/config/gpu_driver_bug_list_json.cc
index d8cec4e..be31cd3 100644
--- a/gpu/config/gpu_driver_bug_list_json.cc
+++ b/gpu/config/gpu_driver_bug_list_json.cc
@@ -19,7 +19,7 @@
 {
   "name": "gpu driver bug list",
   // Please update the version number whenever you change this file.
-  "version": "8.58",
+  "version": "8.59",
   "entries": [
     {
       "id": 1,
@@ -1879,6 +1879,25 @@
       "features": [
         "avda_dont_copy_pictures"
       ]
+    },
+    {
+      "id": 157,
+      "description": "Testing fences was broken on Mali ES2 drivers for specific phone models",
+      "cr_bugs": [589814],
+      "os": {
+        "type": "android"
+      },
+      "machine_model_name": ["SM-G361H", "SM-G531H"],
+      "gl_vendor": "ARM.*",
+      "gl_renderer": "Mali.*",
+      "gl_type": "gles",
+      "gl_version": {
+        "op": "<",
+        "value": "3.0"
+      },
+      "disabled_extensions": [
+        "EGL_KHR_fence_sync"
+      ]
     }
   ]
 }
diff --git a/gpu/skia_bindings/DEPS b/gpu/skia_bindings/DEPS
index 6b85449..3e2b989 100644
--- a/gpu/skia_bindings/DEPS
+++ b/gpu/skia_bindings/DEPS
@@ -1,5 +1,4 @@
 include_rules = [
-  "+skia/ext/refptr.h",
   "+third_party/khronos",
   "+third_party/skia",
 ]
diff --git a/gpu/skia_bindings/gl_bindings_skia_cmd_buffer.cc b/gpu/skia_bindings/gl_bindings_skia_cmd_buffer.cc
index b2a3fa8..e9ca986 100644
--- a/gpu/skia_bindings/gl_bindings_skia_cmd_buffer.cc
+++ b/gpu/skia_bindings/gl_bindings_skia_cmd_buffer.cc
@@ -21,8 +21,8 @@
 
 namespace skia_bindings {
 
-skia::RefPtr<GrGLInterface> CreateGLES2InterfaceBindings(GLES2Interface* impl) {
-  skia::RefPtr<GrGLInterface> interface = skia::AdoptRef(new GrGLInterface);
+sk_sp<GrGLInterface> CreateGLES2InterfaceBindings(GLES2Interface* impl) {
+  sk_sp<GrGLInterface> interface(new GrGLInterface);
   interface->fStandard = kGLES_GrGLStandard;
   interface->fExtensions.init(
       kGLES_GrGLStandard, gles_bind(&GLES2Interface::GetString, impl), nullptr,
diff --git a/gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h b/gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h
index dc69248ce..16df66cc 100644
--- a/gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h
+++ b/gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h
@@ -5,7 +5,7 @@
 #ifndef GPU_SKIA_BINDINGS_GL_BINDINGS_SKIA_CMD_BUFFER_H_
 #define GPU_SKIA_BINDINGS_GL_BINDINGS_SKIA_CMD_BUFFER_H_
 
-#include "skia/ext/refptr.h"
+#include "third_party/skia/include/core/SkRefCnt.h"
 #include "third_party/skia/include/core/SkTypes.h"
 
 struct GrGLInterface;
@@ -20,8 +20,7 @@
 
 // The GPU back-end for skia requires pointers to GL functions. This function
 // initializes bindings for skia-gpu to a GLES2Interface object.
-skia::RefPtr<GrGLInterface> CreateGLES2InterfaceBindings(
-    gpu::gles2::GLES2Interface*);
+sk_sp<GrGLInterface> CreateGLES2InterfaceBindings(gpu::gles2::GLES2Interface*);
 
 }  // namespace skia_bindings
 
diff --git a/headless/app/headless_shell.cc b/headless/app/headless_shell.cc
index e2d6348..1031dbd 100644
--- a/headless/app/headless_shell.cc
+++ b/headless/app/headless_shell.cc
@@ -37,8 +37,6 @@
 
   void OnStart(HeadlessBrowser* browser) {
     browser_ = browser;
-    web_contents_ = browser->CreateWebContents(gfx::Size(800, 600));
-    web_contents_->AddObserver(this);
 
     base::CommandLine::StringVector args =
         base::CommandLine::ForCurrentProcess()->GetArgs();
@@ -50,11 +48,13 @@
     } else {
       url = GURL(args[0]);
     }
-    if (!web_contents_->OpenURL(url)) {
+    web_contents_ = browser->CreateWebContents(url, gfx::Size(800, 600));
+    if (!web_contents_) {
       LOG(ERROR) << "Navigation failed";
-      web_contents_ = nullptr;
       browser_->Shutdown();
+      return;
     }
+    web_contents_->AddObserver(this);
   }
 
   void ShutdownIfNeeded() {
@@ -71,8 +71,6 @@
     ShutdownIfNeeded();
   }
 
-  void DidFinishNavigation(bool success) override {}
-
  private:
   HeadlessBrowser* browser_;  // Not owned.
   std::unique_ptr<HeadlessWebContents> web_contents_;
diff --git a/headless/lib/browser/headless_browser_impl.cc b/headless/lib/browser/headless_browser_impl.cc
index 77f463d..57564d7 100644
--- a/headless/lib/browser/headless_browser_impl.cc
+++ b/headless/lib/browser/headless_browser_impl.cc
@@ -31,10 +31,18 @@
 HeadlessBrowserImpl::~HeadlessBrowserImpl() {}
 
 std::unique_ptr<HeadlessWebContents> HeadlessBrowserImpl::CreateWebContents(
+    const GURL& initial_url,
     const gfx::Size& size) {
   DCHECK(BrowserMainThread()->BelongsToCurrentThread());
-  return base::WrapUnique(new HeadlessWebContentsImpl(
-      browser_context(), window_tree_host_->window(), size));
+  std::unique_ptr<HeadlessWebContentsImpl> web_contents =
+      base::WrapUnique(new HeadlessWebContentsImpl(
+          browser_context(), window_tree_host_->window(), size));
+  // We require the user to pass in an initial URL to ensure that the renderer
+  // gets initialized and eventually becomes ready to be inspected. See
+  // HeadlessWebContents::Observer::WebContentsReady.
+  if (!web_contents->OpenURL(initial_url))
+    return nullptr;
+  return std::move(web_contents);
 }
 
 scoped_refptr<base::SingleThreadTaskRunner>
diff --git a/headless/lib/browser/headless_browser_impl.h b/headless/lib/browser/headless_browser_impl.h
index 3a4abd32..eadeb56b 100644
--- a/headless/lib/browser/headless_browser_impl.h
+++ b/headless/lib/browser/headless_browser_impl.h
@@ -30,6 +30,7 @@
 
   // HeadlessBrowser implementation:
   std::unique_ptr<HeadlessWebContents> CreateWebContents(
+      const GURL& initial_url,
       const gfx::Size& size) override;
   scoped_refptr<base::SingleThreadTaskRunner> BrowserMainThread()
       const override;
diff --git a/headless/lib/browser/headless_web_contents_impl.cc b/headless/lib/browser/headless_web_contents_impl.cc
index 04c00e54..f58dfe0 100644
--- a/headless/lib/browser/headless_web_contents_impl.cc
+++ b/headless/lib/browser/headless_web_contents_impl.cc
@@ -31,6 +31,8 @@
 
   ~WebContentsObserverAdapter() override {}
 
+  void RenderViewReady() override { observer_->WebContentsReady(); }
+
   void DocumentOnLoadCompletedInMainFrame() override {
     observer_->DocumentOnLoadCompletedInMainFrame();
   }
diff --git a/headless/lib/browser/headless_web_contents_impl.h b/headless/lib/browser/headless_web_contents_impl.h
index 2bbaeff..e1cdc2d1 100644
--- a/headless/lib/browser/headless_web_contents_impl.h
+++ b/headless/lib/browser/headless_web_contents_impl.h
@@ -28,22 +28,19 @@
 
 class HeadlessWebContentsImpl : public HeadlessWebContents {
  public:
+  HeadlessWebContentsImpl(content::BrowserContext* context,
+                          aura::Window* parent_window,
+                          const gfx::Size& initial_size);
   ~HeadlessWebContentsImpl() override;
 
   // HeadlessWebContents implementation:
-  bool OpenURL(const GURL& url) override;
   void AddObserver(Observer* observer) override;
   void RemoveObserver(Observer* observer) override;
 
   content::WebContents* web_contents() const;
+  bool OpenURL(const GURL& url);
 
  private:
-  friend class HeadlessBrowserImpl;
-
-  HeadlessWebContentsImpl(content::BrowserContext* context,
-                          aura::Window* parent_window,
-                          const gfx::Size& initial_size);
-
   class Delegate;
   std::unique_ptr<Delegate> web_contents_delegate_;
   std::unique_ptr<content::WebContents> web_contents_;
diff --git a/headless/lib/headless_browser_browsertest.cc b/headless/lib/headless_browser_browsertest.cc
index be3dffa..9cc5940 100644
--- a/headless/lib/headless_browser_browsertest.cc
+++ b/headless/lib/headless_browser_browsertest.cc
@@ -16,12 +16,19 @@
 
 IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, CreateAndDestroyWebContents) {
   std::unique_ptr<HeadlessWebContents> web_contents =
-      browser()->CreateWebContents(gfx::Size(800, 600));
+      browser()->CreateWebContents(GURL("about:blank"), gfx::Size(800, 600));
   EXPECT_TRUE(web_contents);
   // TODO(skyostil): Verify viewport dimensions once we can.
   web_contents.reset();
 }
 
+IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, CreateWithBadURL) {
+  GURL bad_url("not_valid");
+  std::unique_ptr<HeadlessWebContents> web_contents =
+      browser()->CreateWebContents(bad_url, gfx::Size(800, 600));
+  EXPECT_FALSE(web_contents);
+}
+
 class HeadlessBrowserTestWithProxy : public HeadlessBrowserTest {
  public:
   HeadlessBrowserTestWithProxy()
@@ -51,13 +58,13 @@
   builder.SetProxyServer(proxy_server()->host_port_pair());
   SetBrowserOptions(builder.Build());
 
-  std::unique_ptr<HeadlessWebContents> web_contents =
-      browser()->CreateWebContents(gfx::Size(800, 600));
-
   // Load a page which doesn't actually exist, but for which the our proxy
   // returns valid content anyway.
-  EXPECT_TRUE(NavigateAndWaitForLoad(
-      web_contents.get(), GURL("http://not-an-actual-domain.tld/hello.html")));
+  std::unique_ptr<HeadlessWebContents> web_contents =
+      browser()->CreateWebContents(
+          GURL("http://not-an-actual-domain.tld/hello.html"),
+          gfx::Size(800, 600));
+  EXPECT_TRUE(WaitForLoad(web_contents.get()));
 }
 
 }  // namespace headless
diff --git a/headless/lib/headless_web_contents_browsertest.cc b/headless/lib/headless_web_contents_browsertest.cc
index 863bcdc..aaa549188 100644
--- a/headless/lib/headless_web_contents_browsertest.cc
+++ b/headless/lib/headless_web_contents_browsertest.cc
@@ -16,19 +16,39 @@
 
 class HeadlessWebContentsTest : public HeadlessBrowserTest {};
 
+class NavigationObserver : public HeadlessWebContents::Observer {
+ public:
+  NavigationObserver(HeadlessWebContentsTest* browser_test)
+      : browser_test_(browser_test), navigation_succeeded_(false) {}
+  ~NavigationObserver() override {}
+
+  void DocumentOnLoadCompletedInMainFrame() override {
+    browser_test_->FinishAsynchronousTest();
+  }
+
+  void DidFinishNavigation(bool success) override {
+    navigation_succeeded_ = success;
+  }
+
+  bool navigation_succeeded() const { return navigation_succeeded_; }
+
+ private:
+  HeadlessWebContentsTest* browser_test_;  // Not owned.
+  bool navigation_succeeded_;
+};
+
 IN_PROC_BROWSER_TEST_F(HeadlessWebContentsTest, Navigation) {
   EXPECT_TRUE(embedded_test_server()->Start());
   std::unique_ptr<HeadlessWebContents> web_contents =
-      browser()->CreateWebContents(gfx::Size(800, 600));
-  EXPECT_TRUE(NavigateAndWaitForLoad(
-      web_contents.get(), embedded_test_server()->GetURL("/hello.html")));
-}
+      browser()->CreateWebContents(
+          embedded_test_server()->GetURL("/hello.html"), gfx::Size(800, 600));
+  NavigationObserver observer(this);
+  web_contents->AddObserver(&observer);
 
-IN_PROC_BROWSER_TEST_F(HeadlessWebContentsTest, NavigationWithBadURL) {
-  std::unique_ptr<HeadlessWebContents> web_contents =
-      browser()->CreateWebContents(gfx::Size(800, 600));
-  GURL bad_url("not_valid");
-  EXPECT_FALSE(web_contents->OpenURL(bad_url));
+  RunAsynchronousTest();
+
+  EXPECT_TRUE(observer.navigation_succeeded());
+  web_contents->RemoveObserver(&observer);
 }
 
 }  // namespace headless
diff --git a/headless/public/headless_browser.h b/headless/public/headless_browser.h
index 7539407..367a838 100644
--- a/headless/public/headless_browser.h
+++ b/headless/public/headless_browser.h
@@ -35,8 +35,10 @@
  public:
   struct Options;
 
-  // Create a new browser tab. |size| is in physical pixels.
+  // Create a new browser tab which navigates to |initial_url|. |size| is in
+  // physical pixels.
   virtual std::unique_ptr<HeadlessWebContents> CreateWebContents(
+      const GURL& initial_url,
       const gfx::Size& size) = 0;
 
   // Returns a task runner for submitting work to the browser main thread.
diff --git a/headless/public/headless_web_contents.h b/headless/public/headless_web_contents.h
index e3cfbfb..04ac95300 100644
--- a/headless/public/headless_web_contents.h
+++ b/headless/public/headless_web_contents.h
@@ -22,9 +22,13 @@
   // TODO(skyostil): Replace this with an equivalent client API.
   class Observer {
    public:
-    // Will be called on browser thread.
-    virtual void DocumentOnLoadCompletedInMainFrame() = 0;
-    virtual void DidFinishNavigation(bool success) = 0;
+    // All the following notifications will be called on browser main thread.
+    virtual void DocumentOnLoadCompletedInMainFrame(){};
+    virtual void DidFinishNavigation(bool success){};
+
+    // After this event, this HeadlessWebContents instance is ready to be
+    // controlled using a DevTools client.
+    virtual void WebContentsReady(){};
 
    protected:
     Observer() {}
@@ -34,9 +38,6 @@
     DISALLOW_COPY_AND_ASSIGN(Observer);
   };
 
-  // TODO(skyostil): Replace this with an equivalent client API.
-  virtual bool OpenURL(const GURL& url) = 0;
-
   // Add or remove an observer to receive events from this WebContents.
   // |observer| must outlive this class or be removed prior to being destroyed.
   virtual void AddObserver(Observer* observer) = 0;
diff --git a/headless/test/headless_browser_test.cc b/headless/test/headless_browser_test.cc
index 61d4551..0525782 100644
--- a/headless/test/headless_browser_test.cc
+++ b/headless/test/headless_browser_test.cc
@@ -5,6 +5,7 @@
 #include "headless/test/headless_browser_test.h"
 
 #include "base/files/file_path.h"
+#include "base/memory/ptr_util.h"
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "content/public/browser/browser_thread.h"
@@ -18,9 +19,9 @@
 
 class WaitForNavigationObserver : public HeadlessWebContents::Observer {
  public:
-  WaitForNavigationObserver(base::RunLoop* run_loop,
+  WaitForNavigationObserver(HeadlessBrowserTest* browser_test,
                             HeadlessWebContents* web_contents)
-      : run_loop_(run_loop),
+      : browser_test_(browser_test),
         web_contents_(web_contents),
         navigation_succeeded_(false) {
     web_contents_->AddObserver(this);
@@ -28,7 +29,9 @@
 
   ~WaitForNavigationObserver() override { web_contents_->RemoveObserver(this); }
 
-  void DocumentOnLoadCompletedInMainFrame() override { run_loop_->Quit(); }
+  void DocumentOnLoadCompletedInMainFrame() override {
+    browser_test_->FinishAsynchronousTest();
+  }
   void DidFinishNavigation(bool success) override {
     navigation_succeeded_ = success;
   }
@@ -36,7 +39,7 @@
   bool navigation_succeeded() const { return navigation_succeeded_; }
 
  private:
-  base::RunLoop* run_loop_;            // Not owned.
+  HeadlessBrowserTest* browser_test_;  // Not owned.
   HeadlessWebContents* web_contents_;  // Not owned.
 
   bool navigation_succeeded_;
@@ -86,18 +89,22 @@
   return HeadlessContentMainDelegate::GetInstance()->browser();
 }
 
-bool HeadlessBrowserTest::NavigateAndWaitForLoad(
-    HeadlessWebContents* web_contents,
-    const GURL& url) {
-  base::RunLoop run_loop;
+bool HeadlessBrowserTest::WaitForLoad(HeadlessWebContents* web_contents) {
+  WaitForNavigationObserver observer(this, web_contents);
+  RunAsynchronousTest();
+  return observer.navigation_succeeded();
+}
+
+void HeadlessBrowserTest::RunAsynchronousTest() {
   base::MessageLoop::ScopedNestableTaskAllower nestable_allower(
       base::MessageLoop::current());
-  WaitForNavigationObserver observer(&run_loop, web_contents);
+  run_loop_ = base::WrapUnique(new base::RunLoop());
+  run_loop_->Run();
+  run_loop_ = nullptr;
+}
 
-  if (!web_contents->OpenURL(url))
-    return false;
-  run_loop.Run();
-  return observer.navigation_succeeded();
+void HeadlessBrowserTest::FinishAsynchronousTest() {
+  run_loop_->Quit();
 }
 
 }  // namespace headless
diff --git a/headless/test/headless_browser_test.h b/headless/test/headless_browser_test.h
index f46fb90b..f4875a2 100644
--- a/headless/test/headless_browser_test.h
+++ b/headless/test/headless_browser_test.h
@@ -5,14 +5,24 @@
 #ifndef HEADLESS_TEST_HEADLESS_BROWSER_TEST_H_
 #define HEADLESS_TEST_HEADLESS_BROWSER_TEST_H_
 
+#include <memory>
 #include "content/public/test/browser_test_base.h"
 #include "headless/public/headless_browser.h"
 
+namespace base {
+class RunLoop;
+}
+
 namespace headless {
 class HeadlessWebContents;
 
 // Base class for tests which require a full instance of the headless browser.
 class HeadlessBrowserTest : public content::BrowserTestBase {
+ public:
+  // Notify that an asynchronous test is now complete and the test runner should
+  // exit.
+  void FinishAsynchronousTest();
+
  protected:
   HeadlessBrowserTest();
   ~HeadlessBrowserTest() override;
@@ -27,15 +37,20 @@
   // pumps) cannot be set via this method.
   void SetBrowserOptions(const HeadlessBrowser::Options& options);
 
-  // Navigate to |url| and wait for the document load to complete.
-  bool NavigateAndWaitForLoad(HeadlessWebContents* web_contents,
-                              const GURL& url);
+  // Run an asynchronous test in a nested run loop. The caller should call
+  // FinishAsynchronousTest() to notify that the test should finish.
+  void RunAsynchronousTest();
+
+  // Synchronously waits for a tab to finish loading.
+  bool WaitForLoad(HeadlessWebContents* web_contents);
 
  protected:
   // Returns the browser for the test.
   HeadlessBrowser* browser() const;
 
  private:
+  std::unique_ptr<base::RunLoop> run_loop_;
+
   DISALLOW_COPY_AND_ASSIGN(HeadlessBrowserTest);
 };
 
diff --git a/ios/chrome/browser/chrome_url_constants.cc b/ios/chrome/browser/chrome_url_constants.cc
index 799efe4..a04c3de5 100644
--- a/ios/chrome/browser/chrome_url_constants.cc
+++ b/ios/chrome/browser/chrome_url_constants.cc
@@ -73,6 +73,12 @@
 const char kClearBrowsingDataLearnMoreURL[] =
     "https://support.google.com/chrome/answer/2392709";
 
+const char kClearBrowsingDataMyActivityUrlInFooterURL[] =
+    "https://history.google.com/history/?utm_source=chrome_cbd";
+
+const char kClearBrowsingDataMyActivityUrlInDialogURL[] =
+    "https://history.google.com/history/?utm_source=chrome_n";
+
 const char kGoogleHistoryURL[] = "https://history.google.com";
 
 const char kGoogleMyAccountURL[] =
diff --git a/ios/chrome/browser/chrome_url_constants.h b/ios/chrome/browser/chrome_url_constants.h
index 7b2496b0..e262de2 100644
--- a/ios/chrome/browser/chrome_url_constants.h
+++ b/ios/chrome/browser/chrome_url_constants.h
@@ -78,7 +78,16 @@
 // "Learn more" URL for the Clear Browsing Data under Privacy Options.
 extern const char kClearBrowsingDataLearnMoreURL[];
 
+// Google history URL for the footer in the Clear Browsing Data under Privacy
+// Options.
+extern const char kClearBrowsingDataMyActivityUrlInFooterURL[];
+
+// Google history URL for the dialog that informs the user that the history data
+// in the Clear Browsing Data under Privacy Options.
+extern const char kClearBrowsingDataMyActivityUrlInDialogURL[];
+
 // Google history URL for the Clear Browsing Data under Privacy Options.
+// Obsolete: This is no longer used and will removed.
 extern const char kGoogleHistoryURL[];
 
 // Google my account URL for the sign-in confirmation screen.
diff --git a/ios/chrome/browser/ntp_snippets/ios_chrome_ntp_snippets_service_factory.cc b/ios/chrome/browser/ntp_snippets/ios_chrome_ntp_snippets_service_factory.cc
index 1533af63..e142273 100644
--- a/ios/chrome/browser/ntp_snippets/ios_chrome_ntp_snippets_service_factory.cc
+++ b/ios/chrome/browser/ntp_snippets/ios_chrome_ntp_snippets_service_factory.cc
@@ -11,13 +11,11 @@
 #include "components/keyed_service/ios/browser_state_dependency_manager.h"
 #include "components/ntp_snippets/ntp_snippets_fetcher.h"
 #include "components/ntp_snippets/ntp_snippets_service.h"
-#include "components/signin/core/browser/profile_oauth2_token_service.h"
-#include "google_apis/gaia/oauth2_token_service.h"
+#include "components/version_info/version_info.h"
 #include "ios/chrome/browser/application_context.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
-#include "ios/chrome/browser/signin/oauth2_token_service_factory.h"
-#include "ios/chrome/browser/signin/signin_manager_factory.h"
 #include "ios/chrome/browser/suggestions/suggestions_service_factory.h"
+#include "ios/chrome/common/channel_info.h"
 #include "ios/web/public/browser_state.h"
 #include "ios/web/public/web_thread.h"
 #include "net/url_request/url_request_context_getter.h"
@@ -63,8 +61,6 @@
     : BrowserStateKeyedServiceFactory(
           "NTPSnippetsService",
           BrowserStateDependencyManager::GetInstance()) {
-  DependsOn(OAuth2TokenServiceFactory::GetInstance());
-  DependsOn(ios::SigninManagerFactory::GetInstance());
   DependsOn(SuggestionsServiceFactory::GetInstance());
 }
 
@@ -76,10 +72,6 @@
   ios::ChromeBrowserState* chrome_browser_state =
       ios::ChromeBrowserState::FromBrowserState(browser_state);
   DCHECK(!browser_state->IsOffTheRecord());
-  SigninManager* signin_manager =
-      ios::SigninManagerFactory::GetForBrowserState(chrome_browser_state);
-  OAuth2TokenService* token_service =
-      OAuth2TokenServiceFactory::GetForBrowserState(chrome_browser_state);
   scoped_refptr<net::URLRequestContextGetter> request_context =
       browser_state->GetRequestContext();
   SuggestionsService* suggestions_service =
@@ -96,7 +88,7 @@
       chrome_browser_state->GetPrefs(), suggestions_service, task_runner,
       GetApplicationContext()->GetApplicationLocale(), scheduler,
       make_scoped_ptr(new ntp_snippets::NTPSnippetsFetcher(
-          task_runner, (SigninManagerBase*)signin_manager, token_service,
-          request_context)),
+          task_runner, request_context,
+          GetChannel() == version_info::Channel::STABLE)),
       base::Bind(&ParseJson)));
 }
diff --git a/ios/chrome/browser/pref_names.cc b/ios/chrome/browser/pref_names.cc
index e350b42..b5ad233 100644
--- a/ios/chrome/browser/pref_names.cc
+++ b/ios/chrome/browser/pref_names.cc
@@ -33,6 +33,9 @@
 const char kBrowsingDataMigrationHasBeenPossible[] =
     "ios.browsing_data_migration_controller.migration_has_been_possible";
 
+const char kClearBrowsingDataHistoryNoticeShownTimes[] =
+    "browser.clear_data.history_notice_shown_times";
+
 // String indicating the Contextual Search enabled state.
 // "false" - opt-out (disabled)
 // "" (empty string) - undecided
diff --git a/ios/chrome/browser/pref_names.h b/ios/chrome/browser/pref_names.h
index 0bf4c4f..4986f0b 100644
--- a/ios/chrome/browser/pref_names.h
+++ b/ios/chrome/browser/pref_names.h
@@ -14,6 +14,7 @@
 extern const char kBrowserStatesLastActive[];
 extern const char kBrowserStatesNumCreated[];
 extern const char kBrowsingDataMigrationHasBeenPossible[];
+extern const char kClearBrowsingDataHistoryNoticeShownTimes[];
 extern const char kContextualSearchEnabled[];
 extern const char kDataSaverEnabled[];
 extern const char kDefaultCharset[];
diff --git a/ios/chrome/browser/prefs/browser_prefs.mm b/ios/chrome/browser/prefs/browser_prefs.mm
index 300c0ec..93c4f48 100644
--- a/ios/chrome/browser/prefs/browser_prefs.mm
+++ b/ios/chrome/browser/prefs/browser_prefs.mm
@@ -131,6 +131,10 @@
                              user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
   registry->RegisterListPref(kURLsToRestoreOnStartupOld);
 
+  // Register prefs used by Clear Browsing Data UI.
+  registry->RegisterIntegerPref(
+      prefs::kClearBrowsingDataHistoryNoticeShownTimes, 0);
+
   ios::GetChromeBrowserProvider()->RegisterProfilePrefs(registry);
 }
 
diff --git a/ipc/ipc_message_macros.h b/ipc/ipc_message_macros.h
index ea28d0c..38f428e 100644
--- a/ipc/ipc_message_macros.h
+++ b/ipc/ipc_message_macros.h
@@ -249,7 +249,7 @@
 #define IPC_SYNC_MESSAGE_ROUTED(msg_class, in, out) \
   IPC_MESSAGE_DECL(msg_class, ROUTED, IPC_TUPLE in, IPC_TUPLE out)
 
-#define IPC_TUPLE(...) std::tuple<__VA_ARGS__>
+#define IPC_TUPLE(...) IPC::CheckedTuple<__VA_ARGS__>::Tuple
 
 #define IPC_MESSAGE_DECL(msg_name, kind, in_tuple, out_tuple)       \
   struct IPC_MESSAGE_EXPORT msg_name##_Meta {                       \
diff --git a/ipc/ipc_message_utils.h b/ipc/ipc_message_utils.h
index efd669c..cf4fa8f 100644
--- a/ipc/ipc_message_utils.h
+++ b/ipc/ipc_message_utils.h
@@ -77,12 +77,26 @@
 struct NoParams {
 };
 
+// Specializations are checked by 'IPC checker' part of find-bad-constructs
+// Clang plugin (see WriteParam() below for the details).
+template <typename... Ts>
+struct CheckedTuple {
+  typedef std::tuple<Ts...> Tuple;
+};
+
 template <class P>
 static inline void GetParamSize(base::PickleSizer* sizer, const P& p) {
   typedef typename SimilarTypeTraits<P>::Type Type;
   ParamTraits<Type>::GetSize(sizer, static_cast<const Type&>(p));
 }
 
+// This function is checked by 'IPC checker' part of find-bad-constructs
+// Clang plugin to make it's not called on the following types:
+// 1. long / unsigned long (but not typedefs to)
+// 2. intmax_t, uintmax_t, intptr_t, uintptr_t, wint_t,
+//    size_t, rsize_t, ssize_t, ptrdiff_t, dev_t, off_t, clock_t,
+//    time_t, suseconds_t (including typedefs to)
+// 3. Any template referencing types above (e.g. std::vector<size_t>)
 template <class P>
 static inline void WriteParam(base::Pickle* m, const P& p) {
   typedef typename SimilarTypeTraits<P>::Type Type;
diff --git a/mojo/shell/runner/host/linux_sandbox.h b/mojo/shell/runner/host/linux_sandbox.h
index 9cf5e7d..df81cf4 100644
--- a/mojo/shell/runner/host/linux_sandbox.h
+++ b/mojo/shell/runner/host/linux_sandbox.h
@@ -5,6 +5,8 @@
 #ifndef MOJO_SHELL_RUNNER_HOST_LINUX_SANDBOX_H_
 #define MOJO_SHELL_RUNNER_HOST_LINUX_SANDBOX_H_
 
+#include <memory>
+
 #include "base/files/scoped_file.h"
 #include "base/macros.h"
 #include "sandbox/linux/bpf_dsl/bpf_dsl.h"
@@ -39,8 +41,8 @@
  private:
   bool warmed_up_;
   base::ScopedFD proc_fd_;
-  scoped_ptr<sandbox::syscall_broker::BrokerProcess> broker_;
-  scoped_ptr<sandbox::bpf_dsl::Policy> policy_;
+  std::unique_ptr<sandbox::syscall_broker::BrokerProcess> broker_;
+  std::unique_ptr<sandbox::bpf_dsl::Policy> policy_;
 
   DISALLOW_COPY_AND_ASSIGN(LinuxSandbox);
 };
diff --git a/net/http/bidirectional_stream_unittest.cc b/net/http/bidirectional_stream_unittest.cc
index 1fa6155..4d6445f 100644
--- a/net/http/bidirectional_stream_unittest.cc
+++ b/net/http/bidirectional_stream_unittest.cc
@@ -356,10 +356,10 @@
 // Simulates user calling ReadData after END_STREAM has been received in
 // BidirectionalStreamSpdyImpl.
 TEST_F(BidirectionalStreamTest, TestReadDataAfterClose) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
   // Empty DATA frame with an END_STREAM flag.
-  scoped_ptr<SpdyFrame> end_stream(
+  scoped_ptr<SpdySerializedFrame> end_stream(
       spdy_util_.ConstructSpdyBodyFrame(1, nullptr, 0, true));
   MockWrite writes[] = {
       CreateMockWrite(*req.get(), 0),
@@ -367,12 +367,13 @@
 
   const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(kExtraResponseHeaders, 1, 1));
 
-  scoped_ptr<SpdyFrame> body_frame(spdy_util_.ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdySerializedFrame> body_frame(
+      spdy_util_.ConstructSpdyBodyFrame(1, false));
   // Last body frame has END_STREAM flag set.
-  scoped_ptr<SpdyFrame> last_body_frame(
+  scoped_ptr<SpdySerializedFrame> last_body_frame(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
 
   MockRead reads[] = {
@@ -446,24 +447,24 @@
 TEST_F(BidirectionalStreamTest, TestInterleaveReadDataAndSendData) {
   BufferedSpdyFramer framer(spdy_util_.spdy_version());
 
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
       "https://www.example.org", 1, kBodyDataSize * 3, LOWEST, nullptr, 0));
-  scoped_ptr<SpdyFrame> data_frame1(
+  scoped_ptr<SpdySerializedFrame> data_frame1(
       framer.CreateDataFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_NONE));
-  scoped_ptr<SpdyFrame> data_frame2(
+  scoped_ptr<SpdySerializedFrame> data_frame2(
       framer.CreateDataFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_NONE));
-  scoped_ptr<SpdyFrame> data_frame3(
+  scoped_ptr<SpdySerializedFrame> data_frame3(
       framer.CreateDataFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_FIN));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*data_frame1, 3),
       CreateMockWrite(*data_frame2, 6), CreateMockWrite(*data_frame3, 9),
   };
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> response_body_frame1(
+  scoped_ptr<SpdySerializedFrame> response_body_frame1(
       spdy_util_.ConstructSpdyBodyFrame(1, false));
-  scoped_ptr<SpdyFrame> response_body_frame2(
+  scoped_ptr<SpdySerializedFrame> response_body_frame2(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
 
   MockRead reads[] = {
@@ -553,18 +554,18 @@
 // Tests that BidirectionalStreamSpdyImpl::OnClose will complete any remaining
 // read even if the read queue is empty.
 TEST_F(BidirectionalStreamTest, TestCompleteAsyncRead) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
   // Empty DATA frame with an END_STREAM flag.
-  scoped_ptr<SpdyFrame> end_stream(
+  scoped_ptr<SpdySerializedFrame> end_stream(
       spdy_util_.ConstructSpdyBodyFrame(1, nullptr, 0, true));
 
   MockWrite writes[] = {CreateMockWrite(*req.get(), 0)};
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
 
-  scoped_ptr<SpdyFrame> response_body_frame(
+  scoped_ptr<SpdySerializedFrame> response_body_frame(
       spdy_util_.ConstructSpdyBodyFrame(1, nullptr, 0, true));
 
   MockRead reads[] = {
@@ -615,22 +616,23 @@
 }
 
 TEST_F(BidirectionalStreamTest, TestBuffering) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
   // Empty DATA frame with an END_STREAM flag.
-  scoped_ptr<SpdyFrame> end_stream(
+  scoped_ptr<SpdySerializedFrame> end_stream(
       spdy_util_.ConstructSpdyBodyFrame(1, nullptr, 0, true));
 
   MockWrite writes[] = {CreateMockWrite(*req.get(), 0)};
 
   const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(kExtraResponseHeaders, 1, 1));
 
-  scoped_ptr<SpdyFrame> body_frame(spdy_util_.ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdySerializedFrame> body_frame(
+      spdy_util_.ConstructSpdyBodyFrame(1, false));
   // Last body frame has END_STREAM flag set.
-  scoped_ptr<SpdyFrame> last_body_frame(
+  scoped_ptr<SpdySerializedFrame> last_body_frame(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
 
   MockRead reads[] = {
@@ -696,10 +698,10 @@
 }
 
 TEST_F(BidirectionalStreamTest, TestBufferingWithTrailers) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
   // Empty DATA frame with an END_STREAM flag.
-  scoped_ptr<SpdyFrame> end_stream(
+  scoped_ptr<SpdySerializedFrame> end_stream(
       spdy_util_.ConstructSpdyBodyFrame(1, nullptr, 0, true));
 
   MockWrite writes[] = {
@@ -708,14 +710,15 @@
 
   const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(kExtraResponseHeaders, 1, 1));
 
-  scoped_ptr<SpdyFrame> body_frame(spdy_util_.ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdySerializedFrame> body_frame(
+      spdy_util_.ConstructSpdyBodyFrame(1, false));
 
   SpdyHeaderBlock late_headers;
   late_headers["foo"] = "bar";
-  scoped_ptr<SpdyFrame> trailers(
+  scoped_ptr<SpdySerializedFrame> trailers(
       spdy_util_.ConstructSpdyResponseHeaders(1, late_headers, true));
 
   MockRead reads[] = {
@@ -775,11 +778,11 @@
 TEST_F(BidirectionalStreamTest, CancelStreamAfterSendData) {
   BufferedSpdyFramer framer(spdy_util_.spdy_version());
 
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
       "https://www.example.org", 1, kBodyDataSize * 3, LOWEST, nullptr, 0));
-  scoped_ptr<SpdyFrame> data_frame(
+  scoped_ptr<SpdySerializedFrame> data_frame(
       framer.CreateDataFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_NONE));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
 
   MockWrite writes[] = {
@@ -787,9 +790,9 @@
       CreateMockWrite(*rst, 5),
   };
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> response_body_frame(
+  scoped_ptr<SpdySerializedFrame> response_body_frame(
       spdy_util_.ConstructSpdyBodyFrame(1, false));
 
   MockRead reads[] = {
@@ -845,20 +848,20 @@
 TEST_F(BidirectionalStreamTest, CancelStreamDuringReadData) {
   BufferedSpdyFramer framer(spdy_util_.spdy_version());
 
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
       "https://www.example.org", 1, kBodyDataSize * 3, LOWEST, nullptr, 0));
-  scoped_ptr<SpdyFrame> data_frame(
+  scoped_ptr<SpdySerializedFrame> data_frame(
       framer.CreateDataFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_NONE));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
 
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4),
   };
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> response_body_frame(
+  scoped_ptr<SpdySerializedFrame> response_body_frame(
       spdy_util_.ConstructSpdyBodyFrame(1, false));
 
   MockRead reads[] = {
@@ -908,9 +911,9 @@
 // Receiving a header with uppercase ASCII will result in a protocol error,
 // which should be propagated via Delegate::OnFailed.
 TEST_F(BidirectionalStreamTest, PropagateProtocolError) {
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
       "https://www.example.org", 1, kBodyDataSize * 3, LOW, nullptr, 0));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
 
   MockWrite writes[] = {
@@ -918,7 +921,7 @@
   };
 
   const char* const kExtraHeaders[] = {"X-UpperCase", "yes"};
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(kExtraHeaders, 1, 1));
 
   MockRead reads[] = {
@@ -962,10 +965,10 @@
                         ::testing::Values(true, false));
 
 TEST_P(BidirectionalStreamTest, CancelOrDeleteStreamDuringOnHeadersReceived) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
 
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*rst, 2),
@@ -973,7 +976,7 @@
 
   const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(kExtraResponseHeaders, 1, 1));
 
   MockRead reads[] = {
@@ -1018,10 +1021,10 @@
 }
 
 TEST_P(BidirectionalStreamTest, CancelOrDeleteStreamDuringOnDataRead) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
 
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*rst, 3),
@@ -1029,10 +1032,10 @@
 
   const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(kExtraResponseHeaders, 1, 1));
 
-  scoped_ptr<SpdyFrame> response_body_frame(
+  scoped_ptr<SpdySerializedFrame> response_body_frame(
       spdy_util_.ConstructSpdyBodyFrame(1, false));
 
   MockRead reads[] = {
@@ -1077,10 +1080,10 @@
 }
 
 TEST_P(BidirectionalStreamTest, CancelOrDeleteStreamDuringOnTrailersReceived) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
 
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4),
@@ -1088,15 +1091,15 @@
 
   const char* const kExtraResponseHeaders[] = {"header-name", "header-value"};
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(kExtraResponseHeaders, 1, 1));
 
-  scoped_ptr<SpdyFrame> response_body_frame(
+  scoped_ptr<SpdySerializedFrame> response_body_frame(
       spdy_util_.ConstructSpdyBodyFrame(1, false));
 
   SpdyHeaderBlock late_headers;
   late_headers["foo"] = "bar";
-  scoped_ptr<SpdyFrame> trailers(
+  scoped_ptr<SpdySerializedFrame> trailers(
       spdy_util_.ConstructSpdyResponseHeaders(1, late_headers, true));
 
   MockRead reads[] = {
@@ -1143,10 +1146,10 @@
 }
 
 TEST_P(BidirectionalStreamTest, CancelOrDeleteStreamDuringOnFailed) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
 
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
 
   MockWrite writes[] = {
@@ -1154,7 +1157,7 @@
   };
 
   const char* const kExtraHeaders[] = {"X-UpperCase", "yes"};
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(kExtraHeaders, 1, 1));
 
   MockRead reads[] = {
@@ -1197,10 +1200,10 @@
 }
 
 TEST_F(BidirectionalStreamTest, TestHonorAlternativeServiceHeader) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
   // Empty DATA frame with an END_STREAM flag.
-  scoped_ptr<SpdyFrame> end_stream(
+  scoped_ptr<SpdySerializedFrame> end_stream(
       spdy_util_.ConstructSpdyBodyFrame(1, nullptr, 0, true));
 
   MockWrite writes[] = {CreateMockWrite(*req.get(), 0)};
@@ -1210,9 +1213,10 @@
   const char* const kExtraResponseHeaders[] = {"alt-svc",
                                                alt_svc_header_value.c_str()};
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(kExtraResponseHeaders, 1, 1));
-  scoped_ptr<SpdyFrame> body_frame(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> body_frame(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
 
   MockRead reads[] = {
       CreateMockRead(*resp, 1), CreateMockRead(*body_frame, 2),
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 3ebe1cb4..6be19d7e 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -1437,11 +1437,11 @@
   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
 
   // SPDY versions of the request and response.
-  scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
+  scoped_ptr<SpdySerializedFrame> spdy_request(spdy_util_.ConstructSpdyGet(
       request.url.spec().c_str(), 1, DEFAULT_PRIORITY));
-  scoped_ptr<SpdyFrame> spdy_response(
+  scoped_ptr<SpdySerializedFrame> spdy_response(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> spdy_data(
+  scoped_ptr<SpdySerializedFrame> spdy_data(
       spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
 
   // HTTP/1.1 versions of the request and response.
@@ -4215,12 +4215,14 @@
   scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
 
   // fetch http://www.example.org/ via SPDY
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
   MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
+  scoped_ptr<SpdySerializedFrame> data(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead spdy_reads[] = {
       CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
   };
@@ -4275,12 +4277,14 @@
   scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
 
   // Fetch http://www.example.org/ through the SPDY proxy.
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
   MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> data(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead spdy_reads[] = {
       CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
   };
@@ -4345,18 +4349,16 @@
 
   // The first request will be a bare GET, the second request will be a
   // GET with a Proxy-Authorization header.
-  scoped_ptr<SpdyFrame> req_get(
+  scoped_ptr<SpdySerializedFrame> req_get(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
   spdy_util_.UpdateWithStreamDestruction(1);
   const char* const kExtraAuthorizationHeaders[] = {
     "proxy-authorization", "Basic Zm9vOmJhcg=="
   };
-  scoped_ptr<SpdyFrame> req_get_authorization(
+  scoped_ptr<SpdySerializedFrame> req_get_authorization(
       spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
-                                  arraysize(kExtraAuthorizationHeaders) / 2,
-                                  3,
-                                  LOWEST,
-                                  false));
+                                  arraysize(kExtraAuthorizationHeaders) / 2, 3,
+                                  LOWEST, false));
   MockWrite spdy_writes[] = {
       CreateMockWrite(*req_get, 0), CreateMockWrite(*req_get_authorization, 3),
   };
@@ -4367,16 +4369,16 @@
   const char* const kExtraAuthenticationHeaders[] = {
     "proxy-authenticate", "Basic realm=\"MyRealm1\""
   };
-  scoped_ptr<SpdyFrame> resp_authentication(
+  scoped_ptr<SpdySerializedFrame> resp_authentication(
       spdy_util_.ConstructSpdySynReplyError(
-          "407 Proxy Authentication Required",
-          kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
-          1));
-  scoped_ptr<SpdyFrame> body_authentication(
+          "407 Proxy Authentication Required", kExtraAuthenticationHeaders,
+          arraysize(kExtraAuthenticationHeaders) / 2, 1));
+  scoped_ptr<SpdySerializedFrame> body_authentication(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
-  scoped_ptr<SpdyFrame> resp_data(
+  scoped_ptr<SpdySerializedFrame> resp_data(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
-  scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
+  scoped_ptr<SpdySerializedFrame> body_data(
+      spdy_util_.ConstructSpdyBodyFrame(3, true));
   MockRead spdy_reads[] = {
       CreateMockRead(*resp_authentication, 1),
       CreateMockRead(*body_authentication, 2),
@@ -4447,7 +4449,7 @@
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
   // CONNECT to www.example.org:443 via SPDY
-  scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
+  scoped_ptr<SpdySerializedFrame> connect(spdy_util_.ConstructSpdyConnect(
       NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
   // fetch https://www.example.org/ via HTTP
 
@@ -4455,17 +4457,17 @@
       "GET / HTTP/1.1\r\n"
       "Host: www.example.org\r\n"
       "Connection: keep-alive\r\n\r\n";
-  scoped_ptr<SpdyFrame> wrapped_get(
+  scoped_ptr<SpdySerializedFrame> wrapped_get(
       spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
-  scoped_ptr<SpdyFrame> conn_resp(
+  scoped_ptr<SpdySerializedFrame> conn_resp(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   const char resp[] = "HTTP/1.1 200 OK\r\n"
       "Content-Length: 10\r\n\r\n";
-  scoped_ptr<SpdyFrame> wrapped_get_resp(
+  scoped_ptr<SpdySerializedFrame> wrapped_get_resp(
       spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
-  scoped_ptr<SpdyFrame> wrapped_body(
+  scoped_ptr<SpdySerializedFrame> wrapped_body(
       spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
-  scoped_ptr<SpdyFrame> window_update(
+  scoped_ptr<SpdySerializedFrame> window_update(
       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
 
   MockWrite spdy_writes[] = {
@@ -4533,26 +4535,27 @@
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
   // CONNECT to www.example.org:443 via SPDY
-  scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
+  scoped_ptr<SpdySerializedFrame> connect(spdy_util_.ConstructSpdyConnect(
       NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
   // fetch https://www.example.org/ via SPDY
   const char kMyUrl[] = "https://www.example.org/";
-  scoped_ptr<SpdyFrame> get(
+  scoped_ptr<SpdySerializedFrame> get(
       spdy_util_wrapped.ConstructSpdyGet(kMyUrl, 1, LOWEST));
-  scoped_ptr<SpdyFrame> wrapped_get(
+  scoped_ptr<SpdySerializedFrame> wrapped_get(
       spdy_util_.ConstructWrappedSpdyFrame(get, 1));
-  scoped_ptr<SpdyFrame> conn_resp(
+  scoped_ptr<SpdySerializedFrame> conn_resp(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> get_resp(
+  scoped_ptr<SpdySerializedFrame> get_resp(
       spdy_util_wrapped.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> wrapped_get_resp(
+  scoped_ptr<SpdySerializedFrame> wrapped_get_resp(
       spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
-  scoped_ptr<SpdyFrame> body(spdy_util_wrapped.ConstructSpdyBodyFrame(1, true));
-  scoped_ptr<SpdyFrame> wrapped_body(
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_wrapped.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> wrapped_body(
       spdy_util_.ConstructWrappedSpdyFrame(body, 1));
-  scoped_ptr<SpdyFrame> window_update_get_resp(
+  scoped_ptr<SpdySerializedFrame> window_update_get_resp(
       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
-  scoped_ptr<SpdyFrame> window_update_body(
+  scoped_ptr<SpdySerializedFrame> window_update_body(
       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
 
   MockWrite spdy_writes[] = {
@@ -4624,17 +4627,19 @@
       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
 
   // CONNECT to www.example.org:443 via SPDY
-  scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(
+  scoped_ptr<SpdySerializedFrame> connect(spdy_util_.ConstructSpdyConnect(
       NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
-  scoped_ptr<SpdyFrame> get(
+  scoped_ptr<SpdySerializedFrame> get(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
 
   MockWrite spdy_writes[] = {
       CreateMockWrite(*connect, 0), CreateMockWrite(*get, 2),
   };
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
-  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdySynReplyError(1));
+  scoped_ptr<SpdySerializedFrame> data(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead spdy_reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, 0, 3),
   };
@@ -4683,9 +4688,9 @@
   request2.load_flags = 0;
 
   // CONNECT to www.example.org:443 via SPDY.
-  scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
+  scoped_ptr<SpdySerializedFrame> connect1(spdy_util_.ConstructSpdyConnect(
       NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
-  scoped_ptr<SpdyFrame> conn_resp1(
+  scoped_ptr<SpdySerializedFrame> conn_resp1(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
 
   // Fetch https://www.example.org/ via HTTP.
@@ -4693,15 +4698,15 @@
       "GET / HTTP/1.1\r\n"
       "Host: www.example.org\r\n"
       "Connection: keep-alive\r\n\r\n";
-  scoped_ptr<SpdyFrame> wrapped_get1(
+  scoped_ptr<SpdySerializedFrame> wrapped_get1(
       spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
   const char resp1[] = "HTTP/1.1 200 OK\r\n"
       "Content-Length: 1\r\n\r\n";
-  scoped_ptr<SpdyFrame> wrapped_get_resp1(
+  scoped_ptr<SpdySerializedFrame> wrapped_get_resp1(
       spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
-  scoped_ptr<SpdyFrame> wrapped_body1(
+  scoped_ptr<SpdySerializedFrame> wrapped_body1(
       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
-  scoped_ptr<SpdyFrame> window_update(
+  scoped_ptr<SpdySerializedFrame> window_update(
       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
 
   // CONNECT to mail.example.org:443 via SPDY.
@@ -4714,10 +4719,10 @@
     connect2_block[spdy_util_.GetHostKey()] = "mail.example.org";
     connect2_block[spdy_util_.GetPathKey()] = "mail.example.org:443";
   }
-  scoped_ptr<SpdyFrame> connect2(
+  scoped_ptr<SpdySerializedFrame> connect2(
       spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false));
 
-  scoped_ptr<SpdyFrame> conn_resp2(
+  scoped_ptr<SpdySerializedFrame> conn_resp2(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
 
   // Fetch https://mail.example.org/ via HTTP.
@@ -4725,13 +4730,13 @@
       "GET / HTTP/1.1\r\n"
       "Host: mail.example.org\r\n"
       "Connection: keep-alive\r\n\r\n";
-  scoped_ptr<SpdyFrame> wrapped_get2(
+  scoped_ptr<SpdySerializedFrame> wrapped_get2(
       spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
   const char resp2[] = "HTTP/1.1 200 OK\r\n"
       "Content-Length: 2\r\n\r\n";
-  scoped_ptr<SpdyFrame> wrapped_get_resp2(
+  scoped_ptr<SpdySerializedFrame> wrapped_get_resp2(
       spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
-  scoped_ptr<SpdyFrame> wrapped_body2(
+  scoped_ptr<SpdySerializedFrame> wrapped_body2(
       spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
 
   MockWrite spdy_writes[] = {
@@ -4825,9 +4830,9 @@
   request2.load_flags = 0;
 
   // CONNECT to www.example.org:443 via SPDY.
-  scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(
+  scoped_ptr<SpdySerializedFrame> connect1(spdy_util_.ConstructSpdyConnect(
       NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
-  scoped_ptr<SpdyFrame> conn_resp1(
+  scoped_ptr<SpdySerializedFrame> conn_resp1(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
 
   // Fetch https://www.example.org/ via HTTP.
@@ -4835,15 +4840,15 @@
       "GET / HTTP/1.1\r\n"
       "Host: www.example.org\r\n"
       "Connection: keep-alive\r\n\r\n";
-  scoped_ptr<SpdyFrame> wrapped_get1(
+  scoped_ptr<SpdySerializedFrame> wrapped_get1(
       spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
   const char resp1[] = "HTTP/1.1 200 OK\r\n"
       "Content-Length: 1\r\n\r\n";
-  scoped_ptr<SpdyFrame> wrapped_get_resp1(
+  scoped_ptr<SpdySerializedFrame> wrapped_get_resp1(
       spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
-  scoped_ptr<SpdyFrame> wrapped_body1(
+  scoped_ptr<SpdySerializedFrame> wrapped_body1(
       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
-  scoped_ptr<SpdyFrame> window_update(
+  scoped_ptr<SpdySerializedFrame> window_update(
       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
 
   // Fetch https://www.example.org/2 via HTTP.
@@ -4851,13 +4856,13 @@
       "GET /2 HTTP/1.1\r\n"
       "Host: www.example.org\r\n"
       "Connection: keep-alive\r\n\r\n";
-  scoped_ptr<SpdyFrame> wrapped_get2(
+  scoped_ptr<SpdySerializedFrame> wrapped_get2(
       spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
   const char resp2[] = "HTTP/1.1 200 OK\r\n"
       "Content-Length: 2\r\n\r\n";
-  scoped_ptr<SpdyFrame> wrapped_get_resp2(
+  scoped_ptr<SpdySerializedFrame> wrapped_get_resp2(
       spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
-  scoped_ptr<SpdyFrame> wrapped_body2(
+  scoped_ptr<SpdySerializedFrame> wrapped_body2(
       spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
 
   MockWrite spdy_writes[] = {
@@ -4950,22 +4955,22 @@
   // http://www.example.org/
   scoped_ptr<SpdyHeaderBlock> headers(
       spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
-  scoped_ptr<SpdyFrame> get1(
+  scoped_ptr<SpdySerializedFrame> get1(
       spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, true));
-  scoped_ptr<SpdyFrame> get_resp1(
+  scoped_ptr<SpdySerializedFrame> get_resp1(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body1(
+  scoped_ptr<SpdySerializedFrame> body1(
       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
   spdy_util_.UpdateWithStreamDestruction(1);
 
   // http://mail.example.org/
   scoped_ptr<SpdyHeaderBlock> headers2(
       spdy_util_.ConstructGetHeaderBlockForProxy("http://mail.example.org/"));
-  scoped_ptr<SpdyFrame> get2(
+  scoped_ptr<SpdySerializedFrame> get2(
       spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, true));
-  scoped_ptr<SpdyFrame> get_resp2(
+  scoped_ptr<SpdySerializedFrame> get_resp2(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
-  scoped_ptr<SpdyFrame> body2(
+  scoped_ptr<SpdySerializedFrame> body2(
       spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
 
   MockWrite spdy_writes[] = {
@@ -7396,9 +7401,9 @@
   request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
-  scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
+  scoped_ptr<SpdySerializedFrame> conn(spdy_util_.ConstructSpdyConnect(
       NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
-  scoped_ptr<SpdyFrame> goaway(
+  scoped_ptr<SpdySerializedFrame> goaway(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   MockWrite data_writes[] = {
       CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
@@ -7409,9 +7414,8 @@
     "location",
     "http://login.example.com/",
   };
-  scoped_ptr<SpdyFrame> resp(
-      spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
-                                 arraysize(kExtraHeaders)/2, 1));
+  scoped_ptr<SpdySerializedFrame> resp(spdy_util_.ConstructSpdySynReplyError(
+      "302 Redirect", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
   MockRead data_reads[] = {
       CreateMockRead(*resp.get(), 1), MockRead(ASYNC, 0, 3),  // EOF
   };
@@ -7500,9 +7504,9 @@
   request.url = GURL("https://www.example.org/");
   request.load_flags = 0;
 
-  scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(
+  scoped_ptr<SpdySerializedFrame> conn(spdy_util_.ConstructSpdyConnect(
       NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   MockWrite data_writes[] = {
       CreateMockWrite(*conn.get(), 0), CreateMockWrite(*rst.get(), 3),
@@ -7512,12 +7516,10 @@
     "location",
     "http://login.example.com/",
   };
-  scoped_ptr<SpdyFrame> resp(
-      spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
-                                 arraysize(kExtraHeaders)/2, 1));
-  scoped_ptr<SpdyFrame> body(
-      spdy_util_.ConstructSpdyBodyFrame(
-          1, "The host does not exist", 23, true));
+  scoped_ptr<SpdySerializedFrame> resp(spdy_util_.ConstructSpdySynReplyError(
+      "404 Not Found", kExtraHeaders, arraysize(kExtraHeaders) / 2, 1));
+  scoped_ptr<SpdySerializedFrame> body(spdy_util_.ConstructSpdyBodyFrame(
+      1, "The host does not exist", 23, true));
   MockRead data_reads[] = {
       CreateMockRead(*resp.get(), 1),
       CreateMockRead(*body.get(), 2),
@@ -7564,9 +7566,9 @@
   scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
 
   // Since we have proxy, should try to establish tunnel.
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyConnect(
       NULL, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   spdy_util_.UpdateWithStreamDestruction(1);
 
@@ -7575,7 +7577,7 @@
   const char* const kAuthCredentials[] = {
       "proxy-authorization", "Basic Zm9vOmJhcg==",
   };
-  scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
+  scoped_ptr<SpdySerializedFrame> connect2(spdy_util_.ConstructSpdyConnect(
       kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST,
       HostPortPair("www.example.org", 443)));
   // fetch https://www.example.org/ via HTTP
@@ -7583,7 +7585,7 @@
       "GET / HTTP/1.1\r\n"
       "Host: www.example.org\r\n"
       "Connection: keep-alive\r\n\r\n";
-  scoped_ptr<SpdyFrame> wrapped_get(
+  scoped_ptr<SpdySerializedFrame> wrapped_get(
       spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
 
   MockWrite spdy_writes[] = {
@@ -7599,17 +7601,18 @@
   const char* const kAuthChallenge[] = {
     "proxy-authenticate", "Basic realm=\"MyRealm1\"",
   };
-  scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
-      kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
+  scoped_ptr<SpdySerializedFrame> conn_auth_resp(
+      spdy_util_.ConstructSpdySynReplyError(kAuthStatus, kAuthChallenge,
+                                            arraysize(kAuthChallenge) / 2, 1));
 
-  scoped_ptr<SpdyFrame> conn_resp(
+  scoped_ptr<SpdySerializedFrame> conn_resp(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   const char resp[] = "HTTP/1.1 200 OK\r\n"
       "Content-Length: 5\r\n\r\n";
 
-  scoped_ptr<SpdyFrame> wrapped_get_resp(
+  scoped_ptr<SpdySerializedFrame> wrapped_get_resp(
       spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
-  scoped_ptr<SpdyFrame> wrapped_body(
+  scoped_ptr<SpdySerializedFrame> wrapped_body(
       spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
   MockRead spdy_reads[] = {
       CreateMockRead(*conn_auth_resp, 1, ASYNC),
@@ -7712,29 +7715,25 @@
 
   scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
 
-  scoped_ptr<SpdyFrame> stream1_syn(
+  scoped_ptr<SpdySerializedFrame> stream1_syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
 
   MockWrite spdy_writes[] = {
       CreateMockWrite(*stream1_syn, 0, ASYNC),
   };
 
-  scoped_ptr<SpdyFrame>
-      stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> stream1_reply(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
 
-  scoped_ptr<SpdyFrame>
-      stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> stream1_body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
 
-  scoped_ptr<SpdyFrame>
-      stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
-                                    0,
-                                    2,
-                                    1,
-                                    "http://www.another-origin.com/foo.dat"));
+  scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
+      NULL, 0, 2, 1, "http://www.another-origin.com/foo.dat"));
   const char kPushedData[] = "pushed";
-  scoped_ptr<SpdyFrame> stream2_body(
-      spdy_util_.ConstructSpdyBodyFrame(
-          2, kPushedData, strlen(kPushedData), true));
+  scoped_ptr<SpdySerializedFrame> stream2_body(
+      spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData),
+                                        true));
 
   MockRead spdy_reads[] = {
       CreateMockRead(*stream1_reply, 1, ASYNC),
@@ -7829,28 +7828,24 @@
 
   scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
 
-  scoped_ptr<SpdyFrame> stream1_syn(
+  scoped_ptr<SpdySerializedFrame> stream1_syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
 
-  scoped_ptr<SpdyFrame> push_rst(
+  scoped_ptr<SpdySerializedFrame> push_rst(
       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
 
   MockWrite spdy_writes[] = {
       CreateMockWrite(*stream1_syn, 0, ASYNC), CreateMockWrite(*push_rst, 3),
   };
 
-  scoped_ptr<SpdyFrame>
-      stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> stream1_reply(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
 
-  scoped_ptr<SpdyFrame>
-      stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> stream1_body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
 
-  scoped_ptr<SpdyFrame>
-      stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
-                                    0,
-                                    2,
-                                    1,
-                                    "https://www.another-origin.com/foo.dat"));
+  scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
+      NULL, 0, 2, 1, "https://www.another-origin.com/foo.dat"));
 
   MockRead spdy_reads[] = {
       CreateMockRead(*stream1_reply, 1, ASYNC),
@@ -7915,26 +7910,26 @@
 
   scoped_ptr<HttpNetworkSession> session(CreateSession(&session_deps_));
 
-  scoped_ptr<SpdyFrame> stream1_syn(
+  scoped_ptr<SpdySerializedFrame> stream1_syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, false));
 
   MockWrite spdy_writes[] = {
       CreateMockWrite(*stream1_syn, 0, ASYNC),
   };
 
-  scoped_ptr<SpdyFrame> stream1_reply(
+  scoped_ptr<SpdySerializedFrame> stream1_reply(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
 
-  scoped_ptr<SpdyFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
       nullptr, 0, 2, 1, "https://myproxy:70/foo.dat"));
 
-  scoped_ptr<SpdyFrame> stream1_body(
+  scoped_ptr<SpdySerializedFrame> stream1_body(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
 
-  scoped_ptr<SpdyFrame> stream2_reply(
+  scoped_ptr<SpdySerializedFrame> stream2_reply(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
 
-  scoped_ptr<SpdyFrame> stream2_body(
+  scoped_ptr<SpdySerializedFrame> stream2_body(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
 
   MockRead spdy_reads[] = {
@@ -10686,12 +10681,14 @@
   ASSERT_TRUE(ssl.cert.get());
   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> data(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead spdy_reads[] = {
       CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
   };
@@ -10787,17 +10784,21 @@
   ASSERT_TRUE(ssl.cert.get());
   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
 
-  scoped_ptr<SpdyFrame> req1(
+  scoped_ptr<SpdySerializedFrame> req1(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true));
   MockWrite spdy_writes[] = {
       CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
   };
-  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
-  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
-  scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
+  scoped_ptr<SpdySerializedFrame> resp1(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> data1(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp2(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdySerializedFrame> data2(
+      spdy_util_.ConstructSpdyBodyFrame(3, true));
   MockRead spdy_reads[] = {
       CreateMockRead(*resp1, 2),
       CreateMockRead(*data1, 3),
@@ -11038,7 +11039,7 @@
   ASSERT_TRUE(ssl.cert.get());
   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite spdy_writes[] = {
       MockWrite(ASYNC, 0,
@@ -11050,8 +11051,10 @@
 
   const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> data(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead spdy_reads[] = {
       MockRead(ASYNC, 1, kCONNECTResponse), CreateMockRead(*resp.get(), 3),
       CreateMockRead(*data.get(), 4), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 5),
@@ -11148,12 +11151,14 @@
   ASSERT_TRUE(ssl.cert.get());
   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> data(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead spdy_reads[] = {
       CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
   };
@@ -11896,7 +11901,7 @@
   ssl.SetNextProto(GetProtocol());
   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite spdy_writes[] = {CreateMockWrite(*req, 1)};
 
@@ -12005,10 +12010,12 @@
   // retry-http-when-alternate-protocol fails logic kicks in, which was more
   // complicated to set up expectations for than the SPDY session.
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> data(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
 
   MockWrite data_writes_2[] = {
       // First connection attempt without Proxy-Authorization.
@@ -12464,12 +12471,14 @@
 
 // Test for crbug.com/55424.
 TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
   MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> data(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead spdy_reads[] = {
       CreateMockRead(*resp, 1), CreateMockRead(*data, 2), MockRead(ASYNC, 0, 3),
   };
@@ -12887,21 +12896,21 @@
   ssl.SetNextProto(GetProtocol());
   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
 
-  scoped_ptr<SpdyFrame> host1_req(
+  scoped_ptr<SpdySerializedFrame> host1_req(
       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
   spdy_util_.UpdateWithStreamDestruction(1);
-  scoped_ptr<SpdyFrame> host2_req(
+  scoped_ptr<SpdySerializedFrame> host2_req(
       spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
   MockWrite spdy_writes[] = {
       CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
   };
-  scoped_ptr<SpdyFrame> host1_resp(
+  scoped_ptr<SpdySerializedFrame> host1_resp(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> host1_resp_body(
+  scoped_ptr<SpdySerializedFrame> host1_resp_body(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
-  scoped_ptr<SpdyFrame> host2_resp(
+  scoped_ptr<SpdySerializedFrame> host2_resp(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
-  scoped_ptr<SpdyFrame> host2_resp_body(
+  scoped_ptr<SpdySerializedFrame> host2_resp_body(
       spdy_util_.ConstructSpdyBodyFrame(3, true));
   MockRead spdy_reads[] = {
       CreateMockRead(*host1_resp, 1),
@@ -12985,21 +12994,21 @@
   ssl.SetNextProto(GetProtocol());
   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
 
-  scoped_ptr<SpdyFrame> host1_req(
+  scoped_ptr<SpdySerializedFrame> host1_req(
       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
   spdy_util_.UpdateWithStreamDestruction(1);
-  scoped_ptr<SpdyFrame> host2_req(
+  scoped_ptr<SpdySerializedFrame> host2_req(
       spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
   MockWrite spdy_writes[] = {
       CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
   };
-  scoped_ptr<SpdyFrame> host1_resp(
+  scoped_ptr<SpdySerializedFrame> host1_resp(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> host1_resp_body(
+  scoped_ptr<SpdySerializedFrame> host1_resp_body(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
-  scoped_ptr<SpdyFrame> host2_resp(
+  scoped_ptr<SpdySerializedFrame> host2_resp(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
-  scoped_ptr<SpdyFrame> host2_resp_body(
+  scoped_ptr<SpdySerializedFrame> host2_resp_body(
       spdy_util_.ConstructSpdyBodyFrame(3, true));
   MockRead spdy_reads[] = {
       CreateMockRead(*host1_resp, 1),
@@ -13114,21 +13123,21 @@
   ssl.SetNextProto(GetProtocol());
   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
 
-  scoped_ptr<SpdyFrame> host1_req(
+  scoped_ptr<SpdySerializedFrame> host1_req(
       spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST));
   spdy_util_.UpdateWithStreamDestruction(1);
-  scoped_ptr<SpdyFrame> host2_req(
+  scoped_ptr<SpdySerializedFrame> host2_req(
       spdy_util_.ConstructSpdyGet("https://www.gmail.com", 3, LOWEST));
   MockWrite spdy_writes[] = {
       CreateMockWrite(*host1_req, 0), CreateMockWrite(*host2_req, 3),
   };
-  scoped_ptr<SpdyFrame> host1_resp(
+  scoped_ptr<SpdySerializedFrame> host1_resp(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> host1_resp_body(
+  scoped_ptr<SpdySerializedFrame> host1_resp_body(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
-  scoped_ptr<SpdyFrame> host2_resp(
+  scoped_ptr<SpdySerializedFrame> host2_resp(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
-  scoped_ptr<SpdyFrame> host2_resp_body(
+  scoped_ptr<SpdySerializedFrame> host2_resp_body(
       spdy_util_.ConstructSpdyBodyFrame(3, true));
   MockRead spdy_reads[] = {
       CreateMockRead(*host1_resp, 1),
@@ -13202,15 +13211,17 @@
   const std::string http_url = "http://www.example.org:8080/";
 
   // SPDY GET for HTTPS URL
-  scoped_ptr<SpdyFrame> req1(
+  scoped_ptr<SpdySerializedFrame> req1(
       spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
 
   MockWrite writes1[] = {
     CreateMockWrite(*req1, 0),
   };
 
-  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp1(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body1(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads1[] = {CreateMockRead(*resp1, 1), CreateMockRead(*body1, 2),
                        MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)};
 
@@ -13303,12 +13314,12 @@
     url1.append(origin.host());
     url1.append(":443");
 
-    scoped_ptr<SpdyFrame> req0;
-    scoped_ptr<SpdyFrame> req1;
-    scoped_ptr<SpdyFrame> resp0;
-    scoped_ptr<SpdyFrame> body0;
-    scoped_ptr<SpdyFrame> resp1;
-    scoped_ptr<SpdyFrame> body1;
+    scoped_ptr<SpdySerializedFrame> req0;
+    scoped_ptr<SpdySerializedFrame> req1;
+    scoped_ptr<SpdySerializedFrame> resp0;
+    scoped_ptr<SpdySerializedFrame> body0;
+    scoped_ptr<SpdySerializedFrame> resp1;
+    scoped_ptr<SpdySerializedFrame> body1;
     std::vector<MockWrite> writes;
     std::vector<MockRead> reads;
 
@@ -13723,11 +13734,11 @@
 
   // SPDY GET for HTTPS URL (through CONNECT tunnel)
   const HostPortPair host_port_pair("www.example.org", 8080);
-  scoped_ptr<SpdyFrame> connect(
+  scoped_ptr<SpdySerializedFrame> connect(
       spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
-  scoped_ptr<SpdyFrame> req1(
+  scoped_ptr<SpdySerializedFrame> req1(
       spdy_util_wrapped.ConstructSpdyGet(https_url.c_str(), 1, LOWEST));
-  scoped_ptr<SpdyFrame> wrapped_req1(
+  scoped_ptr<SpdySerializedFrame> wrapped_req1(
       spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
 
   // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
@@ -13737,7 +13748,7 @@
   req2_block[spdy_util_.GetHostKey()] = "www.example.org:8080";
   req2_block[spdy_util_.GetSchemeKey()] = "http";
   req2_block[spdy_util_.GetPathKey()] = "/";
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, true));
 
   MockWrite writes1[] = {
@@ -13745,18 +13756,20 @@
       CreateMockWrite(*req2, 6),
   };
 
-  scoped_ptr<SpdyFrame> conn_resp(
+  scoped_ptr<SpdySerializedFrame> conn_resp(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> resp1(
+  scoped_ptr<SpdySerializedFrame> resp1(
       spdy_util_wrapped.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> body1(
+  scoped_ptr<SpdySerializedFrame> body1(
       spdy_util_wrapped.ConstructSpdyBodyFrame(1, true));
-  scoped_ptr<SpdyFrame> wrapped_resp1(
+  scoped_ptr<SpdySerializedFrame> wrapped_resp1(
       spdy_util_wrapped.ConstructWrappedSpdyFrame(resp1, 1));
-  scoped_ptr<SpdyFrame> wrapped_body1(
+  scoped_ptr<SpdySerializedFrame> wrapped_body1(
       spdy_util_wrapped.ConstructWrappedSpdyFrame(body1, 1));
-  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
-  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
+  scoped_ptr<SpdySerializedFrame> resp2(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdySerializedFrame> body2(
+      spdy_util_.ConstructSpdyBodyFrame(3, true));
   MockRead reads1[] = {
       CreateMockRead(*conn_resp, 1),
       MockRead(ASYNC, ERR_IO_PENDING, 3),
@@ -13849,15 +13862,17 @@
   // SPDY GET for HTTP URL (through SPDY proxy)
   scoped_ptr<SpdyHeaderBlock> headers(
       spdy_util_.ConstructGetHeaderBlockForProxy("http://www.example.org/"));
-  scoped_ptr<SpdyFrame> req1(
+  scoped_ptr<SpdySerializedFrame> req1(
       spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, true));
 
   MockWrite writes1[] = {
     CreateMockWrite(*req1, 0),
   };
 
-  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp1(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body1(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads1[] = {
       MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(*resp1, 2),
       CreateMockRead(*body1, 3), MockRead(ASYNC, OK, 4),  // EOF
@@ -13872,16 +13887,17 @@
   data1.set_connect_data(connect_data1);
 
   // SPDY GET for HTTPS URL (direct)
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_secure.ConstructSpdyGet(url2.c_str(), 1, MEDIUM));
 
   MockWrite writes2[] = {
     CreateMockWrite(*req2, 0),
   };
 
-  scoped_ptr<SpdyFrame> resp2(
+  scoped_ptr<SpdySerializedFrame> resp2(
       spdy_util_secure.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body2(spdy_util_secure.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> body2(
+      spdy_util_secure.ConstructSpdyBodyFrame(1, true));
   MockRead reads2[] = {CreateMockRead(*resp2, 1), CreateMockRead(*body2, 2),
                        MockRead(ASYNC, OK, 3)};
 
@@ -13966,14 +13982,16 @@
 
   SequencedSocketData data1(reads1, arraysize(reads1), NULL, 0);
 
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_.ConstructSpdyGet(https_url.c_str(), 1, MEDIUM));
   MockWrite writes2[] = {
     CreateMockWrite(*req2, 0),
   };
 
-  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp2(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body2(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads2[] = {
     CreateMockRead(*resp2, 1),
     CreateMockRead(*body2, 2),
@@ -14040,14 +14058,14 @@
   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
 
-  scoped_ptr<SpdyFrame> host1_req(
+  scoped_ptr<SpdySerializedFrame> host1_req(
       spdy_util_.ConstructSpdyGet("https://www.a.com", 1, DEFAULT_PRIORITY));
   MockWrite spdy1_writes[] = {
       CreateMockWrite(*host1_req, 0),
   };
-  scoped_ptr<SpdyFrame> host1_resp(
+  scoped_ptr<SpdySerializedFrame> host1_resp(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> host1_resp_body(
+  scoped_ptr<SpdySerializedFrame> host1_resp_body(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead spdy1_reads[] = {
       CreateMockRead(*host1_resp, 1), CreateMockRead(*host1_resp_body, 2),
@@ -14062,14 +14080,14 @@
                               arraysize(spdy1_writes)));
   session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
 
-  scoped_ptr<SpdyFrame> host2_req(
+  scoped_ptr<SpdySerializedFrame> host2_req(
       spdy_util_2.ConstructSpdyGet("https://www.b.com", 1, DEFAULT_PRIORITY));
   MockWrite spdy2_writes[] = {
       CreateMockWrite(*host2_req, 0),
   };
-  scoped_ptr<SpdyFrame> host2_resp(
+  scoped_ptr<SpdySerializedFrame> host2_resp(
       spdy_util_2.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> host2_resp_body(
+  scoped_ptr<SpdySerializedFrame> host2_resp_body(
       spdy_util_2.ConstructSpdyBodyFrame(1, true));
   MockRead spdy2_reads[] = {
       CreateMockRead(*host2_resp, 1), CreateMockRead(*host2_resp_body, 2),
@@ -15934,9 +15952,10 @@
   ssl.SetNextProto(GetProtocol());
   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {CreateMockRead(*resp), CreateMockRead(*body),
                       MockRead(ASYNC, ERR_IO_PENDING)};
   StaticSocketDataProvider data(reads, arraysize(reads), nullptr, 0);
diff --git a/net/http/http_proxy_client_socket_pool_unittest.cc b/net/http/http_proxy_client_socket_pool_unittest.cc
index 7fea5f1f..1daca24 100644
--- a/net/http/http_proxy_client_socket_pool_unittest.cc
+++ b/net/http/http_proxy_client_socket_pool_unittest.cc
@@ -288,9 +288,9 @@
     MockRead(ASYNC, 3, "Content-Length: 10\r\n\r\n"),
     MockRead(ASYNC, 4, "0123456789"),
   };
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyConnect(
       NULL, 0, 1, LOW, HostPortPair("www.google.com", 443)));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   MockWrite spdy_writes[] = {
     CreateMockWrite(*req, 0, ASYNC),
@@ -301,7 +301,8 @@
   resp_block["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
   spdy_util_.MaybeAddVersionHeader(&resp_block);
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyReply(1, resp_block));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyReply(1, resp_block));
   MockRead spdy_reads[] = {
     CreateMockRead(*resp, 1, ASYNC),
     MockRead(ASYNC, 0, 3)
@@ -396,13 +397,14 @@
     MockRead(ASYNC, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
   };
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyConnect(kAuthHeaders, kAuthHeadersSize, 1, LOW,
                                       HostPortPair("www.google.com", 443)));
   MockWrite spdy_writes[] = {
     CreateMockWrite(*req, 0, ASYNC)
   };
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   MockRead spdy_reads[] = {
       CreateMockRead(*resp, 1, ASYNC),
       // Connection stays open.
@@ -438,13 +440,14 @@
   if (GetParam().proxy_type != SPDY)
     return;
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyConnect(kAuthHeaders, kAuthHeadersSize, 1, MEDIUM,
                                       HostPortPair("www.google.com", 443)));
   MockWrite spdy_writes[] = {
     CreateMockWrite(*req, 0, ASYNC)
   };
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   MockRead spdy_reads[] = {
     CreateMockRead(*resp, 1, ASYNC),
     MockRead(ASYNC, 0, 2)
@@ -548,7 +551,7 @@
     MockRead(ASYNC, 1, "HTTP/1.1 200 Conn"),
     MockRead(ASYNC, ERR_CONNECTION_CLOSED, 2),
   };
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyConnect(kAuthHeaders, kAuthHeadersSize, 1, LOW,
                                       HostPortPair("www.google.com", 443)));
   MockWrite spdy_writes[] = {
@@ -623,16 +626,17 @@
   MockRead reads[] = {
     MockRead(ASYNC, 1, "HTTP/1.1 304 Not Modified\r\n\r\n"),
   };
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyConnect(kAuthHeaders, kAuthHeadersSize, 1, LOW,
                                       HostPortPair("www.google.com", 443)));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   MockWrite spdy_writes[] = {
     CreateMockWrite(*req, 0, ASYNC),
     CreateMockWrite(*rst, 2, ASYNC),
   };
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdySynReplyError(1));
   MockRead spdy_reads[] = {
     CreateMockRead(*resp, 1, ASYNC),
     MockRead(ASYNC, 0, 3),
@@ -674,10 +678,10 @@
   MockRead reads[] = {
     MockRead(ASYNC, 1, responseText.c_str()),
   };
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyConnect(kAuthHeaders, kAuthHeadersSize, 1, LOW,
                                       HostPortPair("www.google.com", 443)));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
 
   MockWrite spdy_writes[] = {
@@ -690,11 +694,8 @@
     "set-cookie", "foo=bar",
   };
   const int responseHeadersSize = arraysize(responseHeaders) / 2;
-  scoped_ptr<SpdyFrame> resp(
-      spdy_util_.ConstructSpdySynReplyError(
-          "302 Found",
-          responseHeaders, responseHeadersSize,
-          1));
+  scoped_ptr<SpdySerializedFrame> resp(spdy_util_.ConstructSpdySynReplyError(
+      "302 Found", responseHeaders, responseHeadersSize, 1));
   MockRead spdy_reads[] = {
     CreateMockRead(*resp, 1, ASYNC),
     MockRead(ASYNC, 0, 2),
diff --git a/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_openssl.cc b/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_openssl.cc
index 2c85aa2..9a1aa4c 100644
--- a/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_openssl.cc
+++ b/net/quic/crypto/chacha20_poly1305_rfc7539_decrypter_openssl.cc
@@ -17,7 +17,7 @@
 }  // namespace
 
 ChaCha20Poly1305Rfc7539Decrypter::ChaCha20Poly1305Rfc7539Decrypter()
-    : AeadBaseDecrypter(EVP_aead_chacha20_poly1305_rfc7539(),
+    : AeadBaseDecrypter(EVP_aead_chacha20_poly1305(),
                         kKeySize,
                         kAuthTagSize,
                         kNoncePrefixSize) {
diff --git a/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter_openssl.cc b/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter_openssl.cc
index 6912f925..a2219ae 100644
--- a/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter_openssl.cc
+++ b/net/quic/crypto/chacha20_poly1305_rfc7539_encrypter_openssl.cc
@@ -16,7 +16,7 @@
 }  // namespace
 
 ChaCha20Poly1305Rfc7539Encrypter::ChaCha20Poly1305Rfc7539Encrypter()
-    : AeadBaseEncrypter(EVP_aead_chacha20_poly1305_rfc7539(),
+    : AeadBaseEncrypter(EVP_aead_chacha20_poly1305(),
                         kKeySize,
                         kAuthTagSize,
                         kNoncePrefixSize) {
diff --git a/net/quic/crypto/crypto_protocol.h b/net/quic/crypto/crypto_protocol.h
index f1bbd47f..532f8035 100644
--- a/net/quic/crypto/crypto_protocol.h
+++ b/net/quic/crypto/crypto_protocol.h
@@ -92,6 +92,8 @@
                                                  // out of order packets.
 const QuicTag kSSLR = TAG('S', 'S', 'L', 'R');   // Slow Start Large Reduction.
 const QuicTag k5RTO = TAG('5', 'R', 'T', 'O');   // Close connection on 5 RTOs
+const QuicTag kCTIM = TAG('C', 'T', 'I', 'M');   // Client timestamp in seconds
+                                                 // since UNIX epoch.
 
 // Optional support of truncated Connection IDs.  If sent by a peer, the value
 // is the minimum number of bytes allowed for the connection ID sent to the
diff --git a/net/quic/crypto/crypto_server_test.cc b/net/quic/crypto/crypto_server_test.cc
index 430aa7cf..d2fd4c5 100644
--- a/net/quic/crypto/crypto_server_test.cc
+++ b/net/quic/crypto/crypto_server_test.cc
@@ -1136,7 +1136,7 @@
         reinterpret_cast<const uint8_t*>(kOrbit.c_str()),
         StrikeRegister::NO_STARTUP_PERIOD_NEEDED);
     config_.SetStrikeRegisterClient(strike_register_client_);
-    CryptoServerTest::SetUp();
+    ASSERT_NO_FATAL_FAILURE(CryptoServerTest::SetUp());
     strike_register_client_->StartDelayingVerification();
   }
 
diff --git a/net/quic/quic_alarm.cc b/net/quic/quic_alarm.cc
index ca407b52..30edcaa 100644
--- a/net/quic/quic_alarm.cc
+++ b/net/quic/quic_alarm.cc
@@ -22,7 +22,7 @@
 }
 
 void QuicAlarm::Cancel() {
-  if (FLAGS_quic_only_cancel_set_alarms && !IsSet()) {
+  if (!IsSet()) {
     // Don't try to cancel an alarm that hasn't been set.
     return;
   }
diff --git a/net/quic/quic_bandwidth.cc b/net/quic/quic_bandwidth.cc
index c1f9c48..734858d5 100644
--- a/net/quic/quic_bandwidth.cc
+++ b/net/quic/quic_bandwidth.cc
@@ -7,6 +7,7 @@
 #include <stdint.h>
 
 #include "base/logging.h"
+#include "net/quic/quic_bug_tracker.h"
 #include "net/quic/quic_time.h"
 #include "net/quic/quic_types.h"
 
@@ -55,7 +56,12 @@
 
 QuicBandwidth::QuicBandwidth(int64_t bits_per_second)
     : bits_per_second_(bits_per_second) {
-  DCHECK_GE(bits_per_second, 0);
+  if (bits_per_second < 0) {
+    QUIC_BUG << "Can't set negative bandwidth " << bits_per_second;
+    bits_per_second_ = 0;
+    return;
+  }
+  bits_per_second_ = bits_per_second;
 }
 
 int64_t QuicBandwidth::ToBitsPerSecond() const {
diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc
index a6ec3ac..d5a28d0 100644
--- a/net/quic/quic_connection.cc
+++ b/net/quic/quic_connection.cc
@@ -862,13 +862,11 @@
   if (debug_visitor_ != nullptr) {
     debug_visitor_->OnConnectionCloseFrame(frame);
   }
-  const string error_details =
-      StringPrintf("CONNECTION_CLOSE_FRAME received for connection: %" PRIu64
-                   " with error: %s %s",
-                   connection_id(), QuicUtils::ErrorToString(frame.error_code),
-                   frame.error_details.c_str());
-  DVLOG(1) << ENDPOINT << error_details;
-  TearDownLocalConnectionState(frame.error_code, error_details,
+  DVLOG(1) << ENDPOINT
+           << "Received ConnectionClose for connection: " << connection_id()
+           << ", with error: " << QuicUtils::ErrorToString(frame.error_code)
+           << " (" << frame.error_details << ")";
+  TearDownLocalConnectionState(frame.error_code, frame.error_details,
                                ConnectionCloseSource::FROM_PEER);
   return connected_;
 }
@@ -1054,11 +1052,6 @@
   }
 }
 
-void QuicConnection::PopulateAckFrame(QuicAckFrame* ack) {
-  received_packet_manager_.UpdateReceivedPacketInfo(ack,
-                                                    clock_->ApproximateNow());
-}
-
 const QuicFrame QuicConnection::GetUpdatedAckFrame() {
   return received_packet_manager_.GetUpdatedAckFrame(clock_->ApproximateNow());
 }
diff --git a/net/quic/quic_connection.h b/net/quic/quic_connection.h
index 64f1ed2..5baff2e 100644
--- a/net/quic/quic_connection.h
+++ b/net/quic/quic_connection.h
@@ -455,7 +455,6 @@
   // QuicPacketGenerator::DelegateInterface
   bool ShouldGeneratePacket(HasRetransmittableData retransmittable,
                             IsHandshake handshake) override;
-  void PopulateAckFrame(QuicAckFrame* ack) override;
   const QuicFrame GetUpdatedAckFrame() override;
   void PopulateStopWaitingFrame(QuicStopWaitingFrame* stop_waiting) override;
 
diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc
index b1c33cf..ee2ab97d 100644
--- a/net/quic/quic_connection_test.cc
+++ b/net/quic/quic_connection_test.cc
@@ -699,13 +699,8 @@
   QuicVersion version() { return GetParam().version; }
 
   QuicAckFrame* outgoing_ack() {
-    if (FLAGS_quic_dont_copy_acks) {
-      QuicFrame ack_frame =
-          QuicConnectionPeer::GetUpdatedAckFrame(&connection_);
-      ack_ = *ack_frame.ack_frame;
-    } else {
-      QuicConnectionPeer::PopulateAckFrame(&connection_, &ack_);
-    }
+    QuicFrame ack_frame = QuicConnectionPeer::GetUpdatedAckFrame(&connection_);
+    ack_ = *ack_frame.ack_frame;
     return &ack_;
   }
 
diff --git a/net/quic/quic_crypto_client_stream.cc b/net/quic/quic_crypto_client_stream.cc
index 88e0d68f..f91d894 100644
--- a/net/quic/quic_crypto_client_stream.cc
+++ b/net/quic/quic_crypto_client_stream.cc
@@ -312,6 +312,10 @@
   // This call and function should be removed after removing QUIC_VERSION_25.
   AppendFixed(&out);
 
+  // Send a local timestamp to the server.
+  out.SetValue(kCTIM,
+               session()->connection()->clock()->WallNow().ToUNIXSeconds());
+
   if (!cached->IsComplete(session()->connection()->clock()->WallNow())) {
     crypto_config_->FillInchoateClientHello(
         server_id_, session()->connection()->supported_versions().front(),
diff --git a/net/quic/quic_flags.cc b/net/quic/quic_flags.cc
index 370d613f..94dcb1da 100644
--- a/net/quic/quic_flags.cc
+++ b/net/quic/quic_flags.cc
@@ -71,17 +71,10 @@
 // If true, headers stream will support receiving PUSH_PROMISE frames.
 bool FLAGS_quic_supports_push_promise = true;
 
-// When turn on, log packet loss into transport connection stats LossEvent.
-bool FLAGS_quic_log_loss_event = true;
-
 // If true, make sure new incoming streams correctly cede to higher
 // priority (or batch) streams when doing QUIC writes.
 bool FLAGS_quic_cede_correctly = true;
 
-// If on, max number of incoming and outgoing streams will be different.
-// Incoming will be a little higher than outgoing to tolerate race condition.
-bool FLAGS_quic_different_max_num_open_streams = true;
-
 // If true, QUIC should correctly report if it supports ChaCha20. Otherwise,
 // QUIC will lie and claim that it does not support ChaCha20. The primary use
 // case for this is places where ChaCha20 is prohibitively expensive compared to
@@ -105,13 +98,6 @@
 // If true, QUIC connections will defer responding to ACKs to their send alarms.
 bool FLAGS_quic_connection_defer_ack_response = true;
 
-// If true, calls to QuicAlarm::Cancel don't do anything  if the alarm is not
-// set.
-bool FLAGS_quic_only_cancel_set_alarms = true;
-
-// Simplify QUIC's write path for inplace encryption now that FEC is gone.
-bool FLAGS_quic_inplace_encryption2 = true;
-
 // If true, SpdyFramer will call OnStreamEnd from SpdyFramerVisitorInterface
 // instead of empty-data sentinel calls when the stream is to be ended.
 bool FLAGS_spdy_on_stream_end = true;
@@ -124,10 +110,6 @@
 // consecutive RTOs are sent.
 bool FLAGS_quic_enable_rto_timeout = true;
 
-// Don't copy QuicAckFrame or QuicStopWaitingFrame into the
-// QuicPacketGenerator.
-bool FLAGS_quic_dont_copy_acks = true;
-
 // Use a byte conservation approach instead of packet conservation in the
 // Slow Start Large Reduction experiment.
 bool FLAGS_quic_sslr_byte_conservation = true;
diff --git a/net/quic/quic_flags.h b/net/quic/quic_flags.h
index ac73bcd3..e5c635e 100644
--- a/net/quic/quic_flags.h
+++ b/net/quic/quic_flags.h
@@ -28,21 +28,16 @@
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_stateless_version_negotiation;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_supports_push_promise;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_supports_push_promise;
-NET_EXPORT_PRIVATE extern bool FLAGS_quic_log_loss_event;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_cede_correctly;
-NET_EXPORT_PRIVATE extern bool FLAGS_quic_different_max_num_open_streams;
 NET_EXPORT_PRIVATE extern bool
     FLAGS_quic_crypto_server_config_default_has_chacha20;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_log_received_parameters;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_new_tcp_sender;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_ack_decimation2;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_connection_defer_ack_response;
-NET_EXPORT_PRIVATE extern bool FLAGS_quic_only_cancel_set_alarms;
-NET_EXPORT_PRIVATE extern bool FLAGS_quic_inplace_encryption2;
 NET_EXPORT_PRIVATE extern bool FLAGS_spdy_on_stream_end;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_cached_compressed_certs;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_enable_rto_timeout;
-NET_EXPORT_PRIVATE extern bool FLAGS_quic_dont_copy_acks;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_sslr_byte_conservation;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_socket_timestamp;
 NET_EXPORT_PRIVATE extern bool FLAGS_quic_consolidate_onstreamframe_errors;
diff --git a/net/quic/quic_headers_stream.cc b/net/quic/quic_headers_stream.cc
index 88a6186c..9f43927 100644
--- a/net/quic/quic_headers_stream.cc
+++ b/net/quic/quic_headers_stream.cc
@@ -223,11 +223,10 @@
     headers_frame.set_has_priority(true);
     headers_frame.set_priority(priority);
   }
-  scoped_ptr<SpdySerializedFrame> frame(
-      spdy_framer_.SerializeFrame(headers_frame));
-  WriteOrBufferData(StringPiece(frame->data(), frame->size()), false,
+  SpdySerializedFrame frame(spdy_framer_.SerializeFrame(headers_frame));
+  WriteOrBufferData(StringPiece(frame.data(), frame.size()), false,
                     ack_listener);
-  return frame->size();
+  return frame.size();
 }
 
 size_t QuicHeadersStream::WritePushPromise(
@@ -246,11 +245,10 @@
   // response headers.
   push_promise.set_fin(false);
 
-  scoped_ptr<SpdySerializedFrame> frame(
-      spdy_framer_.SerializeFrame(push_promise));
-  WriteOrBufferData(StringPiece(frame->data(), frame->size()), false,
+  SpdySerializedFrame frame(spdy_framer_.SerializeFrame(push_promise));
+  WriteOrBufferData(StringPiece(frame.data(), frame.size()), false,
                     ack_listener);
-  return frame->size();
+  return frame.size();
 }
 
 void QuicHeadersStream::OnDataAvailable() {
diff --git a/net/quic/quic_headers_stream_test.cc b/net/quic/quic_headers_stream_test.cc
index 93d63577..e02f530 100644
--- a/net/quic/quic_headers_stream_test.cc
+++ b/net/quic/quic_headers_stream_test.cc
@@ -322,29 +322,29 @@
     for (bool fin : {false, true}) {
       for (SpdyPriority priority = 0; priority < 7; ++priority) {
         // Replace with "WriteHeadersAndSaveData"
-        scoped_ptr<SpdySerializedFrame> frame;
+        SpdySerializedFrame frame;
         if (perspective() == Perspective::IS_SERVER) {
           SpdyHeadersIR headers_frame(stream_id);
           headers_frame.set_header_block(headers_);
           headers_frame.set_fin(fin);
           headers_frame.set_has_priority(true);
-          frame.reset(framer_->SerializeFrame(headers_frame));
+          frame = framer_->SerializeFrame(headers_frame);
           EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0));
         } else {
           SpdyHeadersIR headers_frame(stream_id);
           headers_frame.set_header_block(headers_);
           headers_frame.set_fin(fin);
-          frame.reset(framer_->SerializeFrame(headers_frame));
+          frame = framer_->SerializeFrame(headers_frame);
         }
         EXPECT_CALL(session_, OnStreamHeaders(stream_id, _))
             .WillRepeatedly(WithArgs<1>(Invoke(
                 this, &QuicHeadersStreamTest::SaveHeaderDataStringPiece)));
         EXPECT_CALL(session_,
-                    OnStreamHeadersComplete(stream_id, fin, frame->size()));
-        stream_frame_.frame_buffer = frame->data();
-        stream_frame_.frame_length = frame->size();
+                    OnStreamHeadersComplete(stream_id, fin, frame.size()));
+        stream_frame_.frame_buffer = frame.data();
+        stream_frame_.frame_length = frame.size();
         headers_stream_->OnStreamFrame(stream_frame_);
-        stream_frame_.offset += frame->size();
+        stream_frame_.offset += frame.size();
         CheckHeaders();
       }
     }
@@ -357,10 +357,9 @@
   for (QuicStreamId stream_id = kClientDataStreamId1;
        stream_id < kClientDataStreamId3; stream_id += 2) {
     QuicStreamId promised_stream_id = NextPromisedStreamId();
-    scoped_ptr<SpdySerializedFrame> frame;
     SpdyPushPromiseIR push_promise(stream_id, promised_stream_id);
     push_promise.set_header_block(headers_);
-    frame.reset(framer_->SerializeFrame(push_promise));
+    SpdySerializedFrame frame(framer_->SerializeFrame(push_promise));
     if (perspective() == Perspective::IS_SERVER) {
       EXPECT_CALL(*connection_,
                   CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
@@ -372,13 +371,13 @@
           .WillRepeatedly(WithArgs<1>(
               Invoke(this, &QuicHeadersStreamTest::SaveHeaderDataStringPiece)));
       EXPECT_CALL(session_, OnPromiseHeadersComplete(
-                                stream_id, promised_stream_id, frame->size()));
+                                stream_id, promised_stream_id, frame.size()));
     }
-    stream_frame_.frame_buffer = frame->data();
-    stream_frame_.frame_length = frame->size();
+    stream_frame_.frame_buffer = frame.data();
+    stream_frame_.frame_length = frame.size();
     headers_stream_->OnStreamFrame(stream_frame_);
     if (perspective() == Perspective::IS_CLIENT) {
-      stream_frame_.offset += frame->size();
+      stream_frame_.offset += frame.size();
       CheckHeaders();
     }
   }
@@ -391,28 +390,28 @@
   for (int stream_num = 0; stream_num < 10; stream_num++) {
     QuicStreamId stream_id = QuicClientDataStreamId(stream_num);
     // Replace with "WriteHeadersAndSaveData"
-    scoped_ptr<SpdySerializedFrame> frame;
+    SpdySerializedFrame frame;
     if (perspective() == Perspective::IS_SERVER) {
       SpdyHeadersIR headers_frame(stream_id);
       headers_frame.set_header_block(headers_);
       headers_frame.set_fin(fin);
       headers_frame.set_has_priority(true);
-      frame.reset(framer_->SerializeFrame(headers_frame));
+      frame = framer_->SerializeFrame(headers_frame);
       EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0));
     } else {
       SpdyHeadersIR headers_frame(stream_id);
       headers_frame.set_header_block(headers_);
       headers_frame.set_fin(fin);
-      frame.reset(framer_->SerializeFrame(headers_frame));
+      frame = framer_->SerializeFrame(headers_frame);
     }
     EXPECT_CALL(session_, OnStreamHeaders(stream_id, _));
     EXPECT_CALL(session_,
-                OnStreamHeadersComplete(stream_id, fin, frame->size()));
-    stream_frame_.frame_buffer = frame->data();
-    stream_frame_.frame_length = frame->size();
+                OnStreamHeadersComplete(stream_id, fin, frame.size()));
+    stream_frame_.frame_buffer = frame.data();
+    stream_frame_.frame_length = frame.size();
     headers_stream_->OnStreamFrame(stream_frame_);
     connection_->AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
-    stream_frame_.offset += frame->size();
+    stream_frame_.offset += frame.size();
   }
 }
 
@@ -420,7 +419,7 @@
   QuicStreamId stream_id;
   bool fin = true;
   QuicStreamFrame stream_frames[10];
-  scoped_ptr<SpdySerializedFrame> frames[10];
+  SpdySerializedFrame frames[10];
   // First create all the frames in order
   {
     InSequence seq;
@@ -431,21 +430,21 @@
         headers_frame.set_header_block(headers_);
         headers_frame.set_fin(fin);
         headers_frame.set_has_priority(true);
-        frames[stream_num].reset(framer_->SerializeFrame(headers_frame));
+        frames[stream_num] = framer_->SerializeFrame(headers_frame);
         EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0)).Times(1);
       } else {
         SpdyHeadersIR headers_frame(stream_id);
         headers_frame.set_header_block(headers_);
         headers_frame.set_fin(fin);
-        frames[stream_num].reset(framer_->SerializeFrame(headers_frame));
+        frames[stream_num] = framer_->SerializeFrame(headers_frame);
       }
       stream_frames[stream_num].stream_id = stream_frame_.stream_id;
       stream_frames[stream_num].offset = stream_frame_.offset;
-      stream_frames[stream_num].frame_buffer = frames[stream_num]->data();
-      stream_frames[stream_num].frame_length = frames[stream_num]->size();
+      stream_frames[stream_num].frame_buffer = frames[stream_num].data();
+      stream_frames[stream_num].frame_length = frames[stream_num].size();
       DVLOG(1) << "make frame for stream " << stream_num << " offset "
                << stream_frames[stream_num].offset;
-      stream_frame_.offset += frames[stream_num]->size();
+      stream_frame_.offset += frames[stream_num].size();
       EXPECT_CALL(session_, OnStreamHeaders(stream_id, _)).Times(1);
       EXPECT_CALL(session_, OnStreamHeadersComplete(stream_id, fin, _))
           .Times(1);
@@ -475,29 +474,29 @@
     for (bool fin : {false, true}) {
       for (SpdyPriority priority = 0; priority < 7; ++priority) {
         // Replace with "WriteHeadersAndSaveData"
-        scoped_ptr<SpdySerializedFrame> frame;
+        SpdySerializedFrame frame;
         if (perspective() == Perspective::IS_SERVER) {
           SpdyHeadersIR headers_frame(stream_id);
           headers_frame.set_header_block(headers_);
           headers_frame.set_fin(fin);
           headers_frame.set_has_priority(true);
-          frame.reset(framer_->SerializeFrame(headers_frame));
+          frame = framer_->SerializeFrame(headers_frame);
           EXPECT_CALL(session_, OnStreamHeadersPriority(stream_id, 0));
         } else {
           SpdyHeadersIR headers_frame(stream_id);
           headers_frame.set_header_block(headers_);
           headers_frame.set_fin(fin);
-          frame.reset(framer_->SerializeFrame(headers_frame));
+          frame = framer_->SerializeFrame(headers_frame);
         }
         EXPECT_CALL(session_, OnStreamHeaders(stream_id, _))
             .WillRepeatedly(WithArgs<1>(Invoke(
                 this, &QuicHeadersStreamTest::SaveHeaderDataStringPiece)));
         EXPECT_CALL(session_,
-                    OnStreamHeadersComplete(stream_id, fin, frame->size()));
-        stream_frame_.frame_buffer = frame->data();
-        stream_frame_.frame_length = frame->size();
+                    OnStreamHeadersComplete(stream_id, fin, frame.size()));
+        stream_frame_.frame_buffer = frame.data();
+        stream_frame_.frame_length = frame.size();
         headers_stream_->OnStreamFrame(stream_frame_);
-        stream_frame_.offset += frame->size();
+        stream_frame_.offset += frame.size();
         CheckHeaders();
       }
     }
@@ -516,76 +515,76 @@
 
 TEST_P(QuicHeadersStreamTest, ProcessSpdyDataFrame) {
   SpdyDataIR data(2, "");
-  scoped_ptr<SpdySerializedFrame> frame(framer_->SerializeFrame(data));
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
   EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
                                             "SPDY DATA frame received.", _))
       .WillOnce(InvokeWithoutArgs(
           this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
-  stream_frame_.frame_buffer = frame->data();
-  stream_frame_.frame_length = frame->size();
+  stream_frame_.frame_buffer = frame.data();
+  stream_frame_.frame_length = frame.size();
   headers_stream_->OnStreamFrame(stream_frame_);
 }
 
 TEST_P(QuicHeadersStreamTest, ProcessSpdyRstStreamFrame) {
   SpdyRstStreamIR data(2, RST_STREAM_PROTOCOL_ERROR);
-  scoped_ptr<SpdySerializedFrame> frame(framer_->SerializeFrame(data));
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
   EXPECT_CALL(*connection_,
               CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
                               "SPDY RST_STREAM frame received.", _))
       .WillOnce(InvokeWithoutArgs(
           this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
-  stream_frame_.frame_buffer = frame->data();
-  stream_frame_.frame_length = frame->size();
+  stream_frame_.frame_buffer = frame.data();
+  stream_frame_.frame_length = frame.size();
   headers_stream_->OnStreamFrame(stream_frame_);
 }
 
 TEST_P(QuicHeadersStreamTest, ProcessSpdySettingsFrame) {
   SpdySettingsIR data;
   data.AddSetting(SETTINGS_HEADER_TABLE_SIZE, true, true, 0);
-  scoped_ptr<SpdySerializedFrame> frame(framer_->SerializeFrame(data));
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
   EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
                                             "SPDY SETTINGS frame received.", _))
       .WillOnce(InvokeWithoutArgs(
           this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
-  stream_frame_.frame_buffer = frame->data();
-  stream_frame_.frame_length = frame->size();
+  stream_frame_.frame_buffer = frame.data();
+  stream_frame_.frame_length = frame.size();
   headers_stream_->OnStreamFrame(stream_frame_);
 }
 
 TEST_P(QuicHeadersStreamTest, ProcessSpdyPingFrame) {
   SpdyPingIR data(1);
-  scoped_ptr<SpdySerializedFrame> frame(framer_->SerializeFrame(data));
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
   EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
                                             "SPDY PING frame received.", _))
       .WillOnce(InvokeWithoutArgs(
           this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
-  stream_frame_.frame_buffer = frame->data();
-  stream_frame_.frame_length = frame->size();
+  stream_frame_.frame_buffer = frame.data();
+  stream_frame_.frame_length = frame.size();
   headers_stream_->OnStreamFrame(stream_frame_);
 }
 
 TEST_P(QuicHeadersStreamTest, ProcessSpdyGoAwayFrame) {
   SpdyGoAwayIR data(1, GOAWAY_PROTOCOL_ERROR, "go away");
-  scoped_ptr<SpdySerializedFrame> frame(framer_->SerializeFrame(data));
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
   EXPECT_CALL(*connection_, CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
                                             "SPDY GOAWAY frame received.", _))
       .WillOnce(InvokeWithoutArgs(
           this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
-  stream_frame_.frame_buffer = frame->data();
-  stream_frame_.frame_length = frame->size();
+  stream_frame_.frame_buffer = frame.data();
+  stream_frame_.frame_length = frame.size();
   headers_stream_->OnStreamFrame(stream_frame_);
 }
 
 TEST_P(QuicHeadersStreamTest, ProcessSpdyWindowUpdateFrame) {
   SpdyWindowUpdateIR data(1, 1);
-  scoped_ptr<SpdySerializedFrame> frame(framer_->SerializeFrame(data));
+  SpdySerializedFrame frame(framer_->SerializeFrame(data));
   EXPECT_CALL(*connection_,
               CloseConnection(QUIC_INVALID_HEADERS_STREAM_DATA,
                               "SPDY WINDOW_UPDATE frame received.", _))
       .WillOnce(InvokeWithoutArgs(
           this, &QuicHeadersStreamTest::TearDownLocalConnectionState));
-  stream_frame_.frame_buffer = frame->data();
-  stream_frame_.frame_length = frame->size();
+  stream_frame_.frame_buffer = frame.data();
+  stream_frame_.frame_length = frame.size();
   headers_stream_->OnStreamFrame(stream_frame_);
 }
 
diff --git a/net/quic/quic_multipath_received_packet_manager.cc b/net/quic/quic_multipath_received_packet_manager.cc
index 26d7fa0..fd2898f 100644
--- a/net/quic/quic_multipath_received_packet_manager.cc
+++ b/net/quic/quic_multipath_received_packet_manager.cc
@@ -81,23 +81,6 @@
   return manager->IsAwaitingPacket(packet_number);
 }
 
-void QuicMultipathReceivedPacketManager::UpdateReceivedPacketInfo(
-    std::vector<QuicAckFrame>* ack_frames,
-    QuicTime approximate_now,
-    bool force_all_paths) {
-  QuicAckFrame ack_frame;
-  for (std::pair<QuicPathId, QuicReceivedPacketManager*>
-           per_path_received_packet_manager : path_managers_) {
-    if (!force_all_paths &&
-        !per_path_received_packet_manager.second->ack_frame_updated()) {
-      continue;
-    }
-    per_path_received_packet_manager.second->UpdateReceivedPacketInfo(
-        &ack_frame, approximate_now);
-    ack_frames->push_back(ack_frame);
-  }
-}
-
 void QuicMultipathReceivedPacketManager::UpdatePacketInformationSentByPeer(
     const std::vector<QuicStopWaitingFrame>& stop_waitings) {
   for (QuicStopWaitingFrame stop_waiting : stop_waitings) {
diff --git a/net/quic/quic_multipath_received_packet_manager_test.cc b/net/quic/quic_multipath_received_packet_manager_test.cc
index 4d6e4f9f..e03a28a 100644
--- a/net/quic/quic_multipath_received_packet_manager_test.cc
+++ b/net/quic/quic_multipath_received_packet_manager_test.cc
@@ -127,26 +127,6 @@
       "Check whether a packet is awaited on a non-existent path");
 }
 
-TEST_F(QuicMultipathReceivedPacketManagerTest, UpdateReceivedPacketInfo) {
-  FLAGS_quic_dont_copy_acks = false;
-  std::vector<QuicAckFrame> ack_frames;
-  EXPECT_EQ(static_cast<size_t>(0), ack_frames.size());
-  EXPECT_CALL(*manager_0_, ack_frame_updated()).WillOnce(Return(false));
-  EXPECT_CALL(*manager_1_, ack_frame_updated()).WillRepeatedly(Return(false));
-  multipath_manager_.UpdateReceivedPacketInfo(&ack_frames, QuicTime::Zero(),
-                                              /*force_all_paths=*/false);
-  EXPECT_EQ(static_cast<size_t>(0), ack_frames.size());
-  EXPECT_CALL(*manager_0_, ack_frame_updated()).WillOnce(Return(true));
-  multipath_manager_.UpdateReceivedPacketInfo(&ack_frames, QuicTime::Zero(),
-                                              /*force_all_paths=*/false);
-  EXPECT_EQ(static_cast<size_t>(1), ack_frames.size());
-
-  std::vector<QuicAckFrame> ack_frames_all;
-  multipath_manager_.UpdateReceivedPacketInfo(&ack_frames_all, QuicTime::Zero(),
-                                              /*force_all_paths=*/true);
-  EXPECT_EQ(static_cast<size_t>(2), ack_frames_all.size());
-}
-
 TEST_F(QuicMultipathReceivedPacketManagerTest,
        UpdatePacketInformationSentByPeer) {
   std::vector<QuicStopWaitingFrame> stop_waitings;
diff --git a/net/quic/quic_packet_creator.cc b/net/quic/quic_packet_creator.cc
index 1381547..5147b09 100644
--- a/net/quic/quic_packet_creator.cc
+++ b/net/quic/quic_packet_creator.cc
@@ -444,24 +444,10 @@
   if (!possibly_truncated_by_length) {
     DCHECK_EQ(packet_size_, length);
   }
-  size_t encrypted_length = 0;
-  if (FLAGS_quic_inplace_encryption2) {
-    const size_t ad_len = GetStartOfEncryptedData(header);
-    encrypted_length = framer_->EncryptInPlace(
-        packet_.encryption_level, packet_.path_id, packet_.packet_number,
-        ad_len, length, encrypted_buffer_len, encrypted_buffer);
-  } else {
-    QuicPacket packet(
-        encrypted_buffer, length,
-        /* owns_buffer */ false, header.public_header.connection_id_length,
-        header.public_header.version_flag, header.public_header.multipath_flag,
-        header.public_header.packet_number_length);
-    // Immediately encrypt the packet, to ensure we don't encrypt the same
-    // packet number multiple times.
-    encrypted_length = framer_->EncryptPayload(
-        packet_.encryption_level, packet_.path_id, packet_.packet_number,
-        packet, encrypted_buffer, encrypted_buffer_len);
-  }
+  const size_t encrypted_length = framer_->EncryptInPlace(
+      packet_.encryption_level, packet_.path_id, packet_.packet_number,
+      GetStartOfEncryptedData(header), length, encrypted_buffer_len,
+      encrypted_buffer);
   if (encrypted_length == 0) {
     QUIC_BUG << "Failed to encrypt packet number " << packet_.packet_number;
     return;
diff --git a/net/quic/quic_packet_generator.cc b/net/quic/quic_packet_generator.cc
index 25da2be..f83dfb6 100644
--- a/net/quic/quic_packet_generator.cc
+++ b/net/quic/quic_packet_generator.cc
@@ -209,16 +209,8 @@
 
 bool QuicPacketGenerator::AddNextPendingFrame() {
   if (should_send_ack_) {
-    if (FLAGS_quic_dont_copy_acks) {
-      should_send_ack_ =
-          !packet_creator_.AddSavedFrame(delegate_->GetUpdatedAckFrame());
-    } else {
-      delegate_->PopulateAckFrame(&pending_ack_frame_);
-      // If we can't this add the frame now, then we still need to do so later.
-      should_send_ack_ =
-          !packet_creator_.AddSavedFrame(QuicFrame(&pending_ack_frame_));
-      // Return success if we have added the frame.
-    }
+    should_send_ack_ =
+        !packet_creator_.AddSavedFrame(delegate_->GetUpdatedAckFrame());
     return !should_send_ack_;
   }
 
diff --git a/net/quic/quic_packet_generator.h b/net/quic/quic_packet_generator.h
index 2ba8969b..cb366c90 100644
--- a/net/quic/quic_packet_generator.h
+++ b/net/quic/quic_packet_generator.h
@@ -65,7 +65,6 @@
     // Consults delegate whether a packet should be generated.
     virtual bool ShouldGeneratePacket(HasRetransmittableData retransmittable,
                                       IsHandshake handshake) = 0;
-    virtual void PopulateAckFrame(QuicAckFrame* ack) = 0;
     virtual const QuicFrame GetUpdatedAckFrame() = 0;
     virtual void PopulateStopWaitingFrame(
         QuicStopWaitingFrame* stop_waiting) = 0;
diff --git a/net/quic/quic_packet_generator_test.cc b/net/quic/quic_packet_generator_test.cc
index d7912e5..0adbfe9 100644
--- a/net/quic/quic_packet_generator_test.cc
+++ b/net/quic/quic_packet_generator_test.cc
@@ -42,7 +42,6 @@
   MOCK_METHOD2(ShouldGeneratePacket,
                bool(HasRetransmittableData retransmittable,
                     IsHandshake handshake));
-  MOCK_METHOD1(PopulateAckFrame, void(QuicAckFrame*));
   MOCK_METHOD0(GetUpdatedAckFrame, const QuicFrame());
   MOCK_METHOD1(PopulateStopWaitingFrame, void(QuicStopWaitingFrame*));
   MOCK_METHOD1(OnSerializedPacket, void(SerializedPacket* packet));
@@ -240,12 +239,8 @@
   delegate_.SetCanWriteOnlyNonRetransmittable();
   generator_.StartBatchOperations();
 
-  if (FLAGS_quic_dont_copy_acks) {
-    EXPECT_CALL(delegate_, GetUpdatedAckFrame())
-        .WillOnce(Return(QuicFrame(&ack_frame_)));
-  } else {
-    EXPECT_CALL(delegate_, PopulateAckFrame(_));
-  }
+  EXPECT_CALL(delegate_, GetUpdatedAckFrame())
+      .WillOnce(Return(QuicFrame(&ack_frame_)));
   EXPECT_CALL(debug_delegate, OnFrameAddedToPacket(_)).Times(1);
 
   generator_.SetShouldSendAck(false);
@@ -255,12 +250,8 @@
 TEST_F(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldFlush) {
   delegate_.SetCanWriteOnlyNonRetransmittable();
 
-  if (FLAGS_quic_dont_copy_acks) {
-    EXPECT_CALL(delegate_, GetUpdatedAckFrame())
-        .WillOnce(Return(QuicFrame(&ack_frame_)));
-  } else {
-    EXPECT_CALL(delegate_, PopulateAckFrame(_));
-  }
+  EXPECT_CALL(delegate_, GetUpdatedAckFrame())
+      .WillOnce(Return(QuicFrame(&ack_frame_)));
   EXPECT_CALL(delegate_, OnSerializedPacket(_))
       .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
 
@@ -280,12 +271,8 @@
   delegate_.SetCanWriteAnything();
 
   // Only one AckFrame should be created.
-  if (FLAGS_quic_dont_copy_acks) {
-    EXPECT_CALL(delegate_, GetUpdatedAckFrame())
-        .WillOnce(Return(QuicFrame(&ack_frame_)));
-  } else {
-    EXPECT_CALL(delegate_, PopulateAckFrame(_)).Times(1);
-  }
+  EXPECT_CALL(delegate_, GetUpdatedAckFrame())
+      .WillOnce(Return(QuicFrame(&ack_frame_)));
   EXPECT_CALL(delegate_, OnSerializedPacket(_))
       .Times(1)
       .WillOnce(Invoke(this, &QuicPacketGeneratorTest::SavePacket));
@@ -513,12 +500,8 @@
   generator_.StartBatchOperations();
 
   // When the first write operation is invoked, the ack frame will be returned.
-  if (FLAGS_quic_dont_copy_acks) {
-    EXPECT_CALL(delegate_, GetUpdatedAckFrame())
-        .WillOnce(Return(QuicFrame(&ack_frame_)));
-  } else {
-    EXPECT_CALL(delegate_, PopulateAckFrame(_));
-  }
+  EXPECT_CALL(delegate_, GetUpdatedAckFrame())
+      .WillOnce(Return(QuicFrame(&ack_frame_)));
 
   // Send some data and a control frame
   generator_.ConsumeData(3, MakeIOVector("quux"), 7, false, nullptr);
@@ -550,12 +533,8 @@
   generator_.StartBatchOperations();
 
   // When the first write operation is invoked, the ack frame will be returned.
-  if (FLAGS_quic_dont_copy_acks) {
-    EXPECT_CALL(delegate_, GetUpdatedAckFrame())
-        .WillOnce(Return(QuicFrame(&ack_frame_)));
-  } else {
-    EXPECT_CALL(delegate_, PopulateAckFrame(_));
-  }
+  EXPECT_CALL(delegate_, GetUpdatedAckFrame())
+      .WillOnce(Return(QuicFrame(&ack_frame_)));
 
   {
     InSequence dummy;
@@ -844,12 +823,8 @@
   generator_.StartBatchOperations();
 
   // Set up frames to write into the creator when control frames are written.
-  if (FLAGS_quic_dont_copy_acks) {
-    EXPECT_CALL(delegate_, GetUpdatedAckFrame())
-        .WillOnce(Return(QuicFrame(&ack_frame_)));
-  } else {
-    EXPECT_CALL(delegate_, PopulateAckFrame(_));
-  }
+  EXPECT_CALL(delegate_, GetUpdatedAckFrame())
+      .WillOnce(Return(QuicFrame(&ack_frame_)));
   EXPECT_CALL(delegate_, PopulateStopWaitingFrame(_));
   // Generator should have queued control frames, and creator should be empty.
   EXPECT_TRUE(generator_.HasQueuedFrames());
diff --git a/net/quic/quic_received_packet_manager.cc b/net/quic/quic_received_packet_manager.cc
index a5cf1ff2..9e7a9e5 100644
--- a/net/quic/quic_received_packet_manager.cc
+++ b/net/quic/quic_received_packet_manager.cc
@@ -147,7 +147,7 @@
     QuicTime receipt_time) {
   QuicPacketNumber packet_number = header.packet_number;
   DCHECK(IsAwaitingPacket(packet_number));
-  if (FLAGS_quic_dont_copy_acks && !ack_frame_updated_) {
+  if (!ack_frame_updated_) {
     ack_frame_.received_packet_times.clear();
   }
   ack_frame_updated_ = true;
@@ -205,42 +205,6 @@
 };
 }  // namespace
 
-void QuicReceivedPacketManager::UpdateReceivedPacketInfo(
-    QuicAckFrame* ack_frame,
-    QuicTime approximate_now) {
-  DCHECK(!FLAGS_quic_dont_copy_acks);
-  ack_frame_updated_ = false;
-  *ack_frame = ack_frame_;
-  ack_frame->entropy_hash = EntropyHash(ack_frame_.largest_observed);
-
-  if (time_largest_observed_ == QuicTime::Zero()) {
-    // We have received no packets.
-    ack_frame->ack_delay_time = QuicTime::Delta::Infinite();
-    return;
-  }
-
-  // Ensure the delta is zero if approximate now is "in the past".
-  ack_frame->ack_delay_time =
-      approximate_now < time_largest_observed_
-          ? QuicTime::Delta::Zero()
-          : approximate_now.Subtract(time_largest_observed_);
-
-  // Clear all packet times if any are too far from largest observed.
-  // It's expected this is extremely rare.
-  for (PacketTimeVector::iterator it = ack_frame_.received_packet_times.begin();
-       it != ack_frame_.received_packet_times.end();) {
-    if (ack_frame_.largest_observed - it->first >=
-        numeric_limits<uint8_t>::max()) {
-      it = ack_frame_.received_packet_times.erase(it);
-    } else {
-      ++it;
-    }
-  }
-
-  ack_frame->received_packet_times.clear();
-  ack_frame->received_packet_times.swap(ack_frame_.received_packet_times);
-}
-
 const QuicFrame QuicReceivedPacketManager::GetUpdatedAckFrame(
     QuicTime approximate_now) {
   ack_frame_updated_ = false;
diff --git a/net/quic/quic_received_packet_manager.h b/net/quic/quic_received_packet_manager.h
index 7985e108..99f0a5c 100644
--- a/net/quic/quic_received_packet_manager.h
+++ b/net/quic/quic_received_packet_manager.h
@@ -115,12 +115,6 @@
   // Checks if we're still waiting for the packet with |packet_number|.
   virtual bool IsAwaitingPacket(QuicPacketNumber packet_number);
 
-  // Update the |ack_frame| for an outgoing ack.
-  // TODO(ianswett): Deprecate with
-  // gfe2_reloadable_flag_quic_dont_copy_ack_frames.
-  void UpdateReceivedPacketInfo(QuicAckFrame* ack_frame,
-                                QuicTime approximate_now);
-
   // Retrieves a frame containing a QuicAckFrame.  The ack frame may not be
   // changed outside QuicReceivedPacketManager and must be serialized before
   // another packet is received, or it will change.
diff --git a/net/quic/quic_received_packet_manager_test.cc b/net/quic/quic_received_packet_manager_test.cc
index 18d8794b..8016fbd3 100644
--- a/net/quic/quic_received_packet_manager_test.cc
+++ b/net/quic/quic_received_packet_manager_test.cc
@@ -300,47 +300,7 @@
   EXPECT_TRUE(received_manager_.IsAwaitingPacket(6u));
 }
 
-TEST_F(QuicReceivedPacketManagerTest, UpdateReceivedPacketInfo) {
-  FLAGS_quic_dont_copy_acks = false;
-  QuicPacketHeader header;
-  header.packet_number = 2u;
-  QuicTime two_ms = QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(2));
-  EXPECT_FALSE(received_manager_.ack_frame_updated());
-  received_manager_.RecordPacketReceived(0u, header, two_ms);
-  EXPECT_TRUE(received_manager_.ack_frame_updated());
-
-  QuicAckFrame ack;
-  received_manager_.UpdateReceivedPacketInfo(&ack, QuicTime::Zero());
-  EXPECT_FALSE(received_manager_.ack_frame_updated());
-  // When UpdateReceivedPacketInfo with a time earlier than the time of the
-  // largest observed packet, make sure that the delta is 0, not negative.
-  EXPECT_EQ(QuicTime::Delta::Zero(), ack.ack_delay_time);
-  EXPECT_EQ(1u, ack.received_packet_times.size());
-
-  QuicTime four_ms = QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(4));
-  received_manager_.UpdateReceivedPacketInfo(&ack, four_ms);
-  EXPECT_FALSE(received_manager_.ack_frame_updated());
-  // When UpdateReceivedPacketInfo after not having received a new packet,
-  // the delta should still be accurate.
-  EXPECT_EQ(QuicTime::Delta::FromMilliseconds(2), ack.ack_delay_time);
-  EXPECT_EQ(0u, ack.received_packet_times.size());
-
-  header.packet_number = 999u;
-  received_manager_.RecordPacketReceived(0u, header, two_ms);
-  header.packet_number = 4u;
-  received_manager_.RecordPacketReceived(0u, header, two_ms);
-  header.packet_number = 1000u;
-  received_manager_.RecordPacketReceived(0u, header, two_ms);
-  EXPECT_TRUE(received_manager_.ack_frame_updated());
-  received_manager_.UpdateReceivedPacketInfo(&ack, two_ms);
-  EXPECT_FALSE(received_manager_.ack_frame_updated());
-  // UpdateReceivedPacketInfo should discard any times which can't be
-  // expressed on the wire.
-  EXPECT_EQ(2ul, ack.received_packet_times.size());
-}
-
 TEST_F(QuicReceivedPacketManagerTest, GetUpdatedAckFrame) {
-  FLAGS_quic_dont_copy_acks = true;
   QuicPacketHeader header;
   header.packet_number = 2u;
   QuicTime two_ms = QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(2));
diff --git a/net/quic/quic_sent_packet_manager.cc b/net/quic/quic_sent_packet_manager.cc
index 1a0337b8..bed16fe 100644
--- a/net/quic/quic_sent_packet_manager.cc
+++ b/net/quic/quic_sent_packet_manager.cc
@@ -668,7 +668,7 @@
       // Retransmittable data is marked as lost during loss detection, and will
       // be logged later.
       unacked_packets_.RemoveFromInFlight(packet_number);
-      if (FLAGS_quic_log_loss_event && debug_delegate_ != nullptr) {
+      if (debug_delegate_ != nullptr) {
         debug_delegate_->OnPacketLoss(packet_number, RTO_RETRANSMISSION,
                                       clock_->Now());
       }
@@ -704,7 +704,7 @@
                                 &packets_lost_);
   for (const pair<QuicPacketNumber, QuicByteCount>& pair : packets_lost_) {
     ++stats_->packets_lost;
-    if (FLAGS_quic_log_loss_event && debug_delegate_ != nullptr) {
+    if (debug_delegate_ != nullptr) {
       debug_delegate_->OnPacketLoss(pair.first, LOSS_RETRANSMISSION, time);
     }
 
diff --git a/net/quic/quic_sent_packet_manager_test.cc b/net/quic/quic_sent_packet_manager_test.cc
index 00b57ab..5098261 100644
--- a/net/quic/quic_sent_packet_manager_test.cc
+++ b/net/quic/quic_sent_packet_manager_test.cc
@@ -968,10 +968,8 @@
   EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
   // RTO's use loss detection instead of immediately declaring retransmitted
   // packets lost.
-  if (FLAGS_quic_log_loss_event) {
-    for (int i = 1; i <= 99; ++i) {
-      EXPECT_CALL(debug_delegate, OnPacketLoss(i, LOSS_RETRANSMISSION, _));
-    }
+  for (int i = 1; i <= 99; ++i) {
+    EXPECT_CALL(debug_delegate, OnPacketLoss(i, LOSS_RETRANSMISSION, _));
   }
   manager_.OnIncomingAck(ack_frame, clock_.Now());
 }
diff --git a/net/quic/quic_session.cc b/net/quic/quic_session.cc
index eb6376b..2967c76c 100644
--- a/net/quic/quic_session.cc
+++ b/net/quic/quic_session.cc
@@ -378,12 +378,6 @@
 
   uint32_t max_streams = config_.MaxStreamsPerConnection();
   if (perspective() == Perspective::IS_SERVER) {
-    if (!FLAGS_quic_different_max_num_open_streams) {
-      max_streams =
-          max(max_streams + kMaxStreamsMinimumIncrement,
-              static_cast<uint32_t>(max_streams * kMaxStreamsMultiplier));
-    }
-
     if (config_.HasReceivedConnectionOptions()) {
       if (ContainsQuicTag(config_.ReceivedConnectionOptions(), kAFCW)) {
         // The following variations change the initial receive flow control
@@ -404,17 +398,14 @@
 
   set_max_open_outgoing_streams(max_streams);
 
-  uint32_t max_incoming_streams = max_streams;
-  if (FLAGS_quic_different_max_num_open_streams) {
-    // A small number of additional incoming streams beyond the limit should be
-    // allowed. This helps avoid early connection termination when FIN/RSTs for
-    // old streams are lost or arrive out of order.
-    // Use a minimum number of additional streams, or a percentage increase,
-    // whichever is larger.
-    max_incoming_streams =
-        max(max_streams + kMaxStreamsMinimumIncrement,
-            static_cast<uint32_t>(max_streams * kMaxStreamsMultiplier));
-  }
+  // A small number of additional incoming streams beyond the limit should be
+  // allowed. This helps avoid early connection termination when FIN/RSTs for
+  // old streams are lost or arrive out of order.
+  // Use a minimum number of additional streams, or a percentage increase,
+  // whichever is larger.
+  uint32_t max_incoming_streams =
+      max(max_streams + kMaxStreamsMinimumIncrement,
+          static_cast<uint32_t>(max_streams * kMaxStreamsMultiplier));
   set_max_open_incoming_streams(max_incoming_streams);
 
   if (config_.HasReceivedInitialStreamFlowControlWindowBytes()) {
diff --git a/net/quic/quic_session_test.cc b/net/quic/quic_session_test.cc
index d74a4ae..4d4004b3 100644
--- a/net/quic/quic_session_test.cc
+++ b/net/quic/quic_session_test.cc
@@ -1107,24 +1107,15 @@
 TEST_P(QuicSessionTestServer, TestMaxIncomingAndOutgoingStreamsAllowed) {
   // Tests that on server side, the value of max_open_incoming/outgoing streams
   // are setup correctly during negotiation.
-  // When FLAGS_quic_different_max_num_open_streams is off, both of them are a
-  // little larger than negotiated values. When flag is true, the value for
-  // outgoing stream is limited to negotiated value and for incoming stream it
-  // is set to be larger than that.
+  // The value for outgoing stream is limited to negotiated value and for
+  // incoming stream it is set to be larger than that.
   session_.OnConfigNegotiated();
-  if (FLAGS_quic_different_max_num_open_streams) {
-    // The max number of open outgoing streams is less than that of incoming
-    // streams, and it should be same as negotiated value.
-    EXPECT_LT(session_.max_open_outgoing_streams(),
-              session_.max_open_incoming_streams());
-    EXPECT_EQ(session_.max_open_outgoing_streams(),
-              kDefaultMaxStreamsPerConnection);
-  } else {
-    // The max number of outgoing/incoming streams are the same.
-    EXPECT_EQ(session_.max_open_outgoing_streams(),
-              session_.max_open_incoming_streams());
-  }
-
+  // The max number of open outgoing streams is less than that of incoming
+  // streams, and it should be same as negotiated value.
+  EXPECT_LT(session_.max_open_outgoing_streams(),
+            session_.max_open_incoming_streams());
+  EXPECT_EQ(session_.max_open_outgoing_streams(),
+            kDefaultMaxStreamsPerConnection);
   EXPECT_GT(session_.max_open_incoming_streams(),
             kDefaultMaxStreamsPerConnection);
 }
@@ -1185,19 +1176,11 @@
 TEST_P(QuicSessionTestClient, TestMaxIncomingAndOutgoingStreamsAllowed) {
   // Tests that on client side, the value of max_open_incoming/outgoing streams
   // are setup correctly during negotiation.
-  // When FLAGS_quic_different_max_num_open_streams is off, both of them are
-  // same as negotiated value. When flag is true, the value for outgoing stream
-  // is limited to negotiated value and for incoming stream it is set to be
-  // larger than that.
+  // When flag is true, the value for outgoing stream is limited to negotiated
+  // value and for incoming stream it is set to be larger than that.
   session_.OnConfigNegotiated();
-  if (FLAGS_quic_different_max_num_open_streams) {
-    EXPECT_LT(session_.max_open_outgoing_streams(),
-              session_.max_open_incoming_streams());
-  } else {
-    EXPECT_EQ(session_.max_open_outgoing_streams(),
-              session_.max_open_incoming_streams());
-  }
-
+  EXPECT_LT(session_.max_open_outgoing_streams(),
+            session_.max_open_incoming_streams());
   EXPECT_EQ(session_.max_open_outgoing_streams(),
             kDefaultMaxStreamsPerConnection);
 }
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc
index 20335a57..3a4d135 100644
--- a/net/quic/quic_stream_factory.cc
+++ b/net/quic/quic_stream_factory.cc
@@ -65,6 +65,7 @@
 #endif
 
 using std::min;
+using std::vector;
 using NetworkHandle = net::NetworkChangeNotifier::NetworkHandle;
 
 namespace net {
@@ -1712,12 +1713,18 @@
   if (http_server_properties_->max_server_configs_stored_in_properties() == 0)
     return;
   // Create a temporary QuicServerInfo object to deserialize and to populate the
-  // in-memory crypto server config cache.
+  // in-memory crypto server config cache in the MRU order.
   scoped_ptr<QuicServerInfo> server_info;
   CompletionCallback callback;
-  for (const auto& key_value :
-       http_server_properties_->quic_server_info_map()) {
-    const QuicServerId& server_id = key_value.first;
+  // Get the list of servers to be deserialized first because WaitForDataReady
+  // touches quic_server_info_map.
+  const QuicServerInfoMap& quic_server_info_map =
+      http_server_properties_->quic_server_info_map();
+  vector<QuicServerId> server_list(quic_server_info_map.size());
+  for (const auto& key_value : quic_server_info_map)
+    server_list.push_back(key_value.first);
+  for (auto it = server_list.rbegin(); it != server_list.rend(); ++it) {
+    const QuicServerId& server_id = *it;
     server_info.reset(quic_server_info_factory_->GetForServer(server_id));
     if (server_info->WaitForDataReady(callback) == OK) {
       DVLOG(1) << "Initialized server config for: " << server_id.ToString();
diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc
index 3651bf6..e6fffab 100644
--- a/net/quic/quic_stream_factory_test.cc
+++ b/net/quic/quic_stream_factory_test.cc
@@ -3801,6 +3801,16 @@
 
   http_server_properties_.SetAlternativeServices(
       host_port_pair_, alternative_service_info_vector);
+
+  HostPortPair host_port_pair2(kServer2HostName, kDefaultServerPort);
+  const AlternativeService alternative_service2(QUIC, host_port_pair2.host(),
+                                                host_port_pair2.port());
+  AlternativeServiceInfoVector alternative_service_info_vector2;
+  alternative_service_info_vector2.push_back(
+      AlternativeServiceInfo(alternative_service2, expiration));
+  http_server_properties_.SetAlternativeServices(
+      host_port_pair2, alternative_service_info_vector2);
+
   http_server_properties_.SetMaxServerConfigsStoredInProperties(
       kMaxQuicServersToPersist);
 
@@ -3848,8 +3858,58 @@
 
   quic_server_info->Persist();
 
+  QuicServerId quic_server_id2(kServer2HostName, 80, PRIVACY_MODE_DISABLED);
+  scoped_ptr<QuicServerInfo> quic_server_info2(
+      quic_server_info_factory->GetForServer(quic_server_id2));
+
+  // Update quic_server_info2's server_config and persist it.
+  QuicServerInfo::State* state2 = quic_server_info2->mutable_state();
+
+  // Minimum SCFG that passes config validation checks.
+  const char scfg2[] = {// SCFG
+                        0x53, 0x43, 0x46, 0x47,
+                        // num entries
+                        0x01, 0x00,
+                        // padding
+                        0x00, 0x00,
+                        // EXPY
+                        0x45, 0x58, 0x50, 0x59,
+                        // EXPY end offset
+                        0x08, 0x00, 0x00, 0x00,
+                        // Value
+                        '8', '7', '3', '4', '5', '6', '2', '1'};
+
+  // Create temporary strings becasue Persist() clears string data in |state2|.
+  string server_config2(reinterpret_cast<const char*>(&scfg2), sizeof(scfg2));
+  string source_address_token2("test_source_address_token2");
+  string cert_sct2("test_cert_sct2");
+  string chlo_hash2("test_chlo_hash2");
+  string signature2("test_signature2");
+  string test_cert2("test_cert2");
+  vector<string> certs2;
+  certs2.push_back(test_cert2);
+  state2->server_config = server_config2;
+  state2->source_address_token = source_address_token2;
+  state2->cert_sct = cert_sct2;
+  state2->chlo_hash = chlo_hash2;
+  state2->server_config_sig = signature2;
+  state2->certs = certs2;
+
+  quic_server_info2->Persist();
+
   QuicStreamFactoryPeer::MaybeInitialize(factory_.get());
   EXPECT_TRUE(QuicStreamFactoryPeer::HasInitializedData(factory_.get()));
+
+  // Verify the MRU order is maintained.
+  const QuicServerInfoMap& quic_server_info_map =
+      http_server_properties_.quic_server_info_map();
+  EXPECT_EQ(2u, quic_server_info_map.size());
+  QuicServerInfoMap::const_iterator quic_server_info_map_it =
+      quic_server_info_map.begin();
+  EXPECT_EQ(quic_server_info_map_it->first, quic_server_id2);
+  ++quic_server_info_map_it;
+  EXPECT_EQ(quic_server_info_map_it->first, quic_server_id);
+
   EXPECT_TRUE(QuicStreamFactoryPeer::SupportsQuicAtStartUp(factory_.get(),
                                                            host_port_pair_));
   EXPECT_FALSE(QuicStreamFactoryPeer::CryptoConfigCacheIsEmpty(factory_.get(),
@@ -3867,6 +3927,22 @@
   EXPECT_EQ(signature, cached->signature());
   ASSERT_EQ(1U, cached->certs().size());
   EXPECT_EQ(test_cert, cached->certs()[0]);
+
+  EXPECT_TRUE(QuicStreamFactoryPeer::SupportsQuicAtStartUp(factory_.get(),
+                                                           host_port_pair2));
+  EXPECT_FALSE(QuicStreamFactoryPeer::CryptoConfigCacheIsEmpty(
+      factory_.get(), quic_server_id2));
+  QuicCryptoClientConfig::CachedState* cached2 =
+      crypto_config->LookupOrCreate(quic_server_id2);
+  EXPECT_FALSE(cached2->server_config().empty());
+  EXPECT_TRUE(cached2->GetServerConfig());
+  EXPECT_EQ(server_config2, cached2->server_config());
+  EXPECT_EQ(source_address_token2, cached2->source_address_token());
+  EXPECT_EQ(cert_sct2, cached2->cert_sct());
+  EXPECT_EQ(chlo_hash2, cached2->chlo_hash());
+  EXPECT_EQ(signature2, cached2->signature());
+  ASSERT_EQ(1U, cached->certs().size());
+  EXPECT_EQ(test_cert2, cached2->certs()[0]);
 }
 
 TEST_P(QuicStreamFactoryTest, QuicDoingZeroRTT) {
diff --git a/net/quic/quic_stream_sequencer_buffer.cc b/net/quic/quic_stream_sequencer_buffer.cc
index 5f940851..dabb2ce 100644
--- a/net/quic/quic_stream_sequencer_buffer.cc
+++ b/net/quic/quic_stream_sequencer_buffer.cc
@@ -5,12 +5,23 @@
 #include "net/quic/quic_stream_sequencer_buffer.h"
 
 #include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
 #include "net/quic/quic_bug_tracker.h"
 
 using std::min;
+using std::string;
 
 namespace net {
 
+namespace {
+
+string RangeDebugString(QuicStreamOffset start, QuicStreamOffset end) {
+  return string("[") + base::IntToString(start) + ", " +
+         base::IntToString(end) + ") ";
+}
+
+}  // namespace
+
 QuicStreamSequencerBuffer::Gap::Gap(QuicStreamOffset begin_offset,
                                     QuicStreamOffset end_offset)
     : begin_offset(begin_offset), end_offset(end_offset) {}
@@ -92,12 +103,29 @@
   if (offset < current_gap->begin_offset &&
       offset + size > current_gap->begin_offset) {
     // Beginning of new data overlaps data before current gap.
-    *error_details = "Beginning of received data overlaps with buffered data.";
+    *error_details =
+        string("Beginning of received data overlaps with buffered data.\n") +
+        "New frame range " + RangeDebugString(offset, offset + size) +
+        "\n"
+        "Currently received frames: " +
+        ReceivedFramesDebugString() +
+        "\n"
+        "Current gaps: " +
+        GapsDebugString() + "\n";
     return QUIC_OVERLAPPING_STREAM_DATA;
   }
   if (offset + size > current_gap->end_offset) {
     // End of new data overlaps with data after current gap.
-    *error_details = "End of received data overlaps with buffered data.";
+    *error_details =
+        "End of received data overlaps with buffered data.\n"
+        "New frame range " +
+        RangeDebugString(offset, offset + size) +
+        "\n"
+        "Currently received frames: " +
+        ReceivedFramesDebugString() +
+        "\n"
+        "Current gaps: " +
+        GapsDebugString() + "\n";
     return QUIC_OVERLAPPING_STREAM_DATA;
   }
 
@@ -457,4 +485,26 @@
   }
 }
 
+string QuicStreamSequencerBuffer::GapsDebugString() {
+  string current_gaps_string;
+  for (const Gap& gap : gaps_) {
+    QuicStreamOffset current_gap_begin = gap.begin_offset;
+    QuicStreamOffset current_gap_end = gap.end_offset;
+    current_gaps_string += RangeDebugString(current_gap_begin, current_gap_end);
+  }
+  return current_gaps_string;
+}
+
+string QuicStreamSequencerBuffer::ReceivedFramesDebugString() {
+  string current_frames_string;
+  for (auto it : frame_arrival_time_map_) {
+    QuicStreamOffset current_frame_begin_offset = it.first;
+    QuicStreamOffset current_frame_end_offset =
+        it.second.length + current_frame_begin_offset;
+    current_frames_string +=
+        RangeDebugString(current_frame_begin_offset, current_frame_end_offset);
+  }
+  return current_frames_string;
+}
+
 }  //  namespace net
diff --git a/net/quic/quic_stream_sequencer_buffer.h b/net/quic/quic_stream_sequencer_buffer.h
index 2a59041..7b854aee 100644
--- a/net/quic/quic_stream_sequencer_buffer.h
+++ b/net/quic/quic_stream_sequencer_buffer.h
@@ -210,6 +210,14 @@
   // should be removed from the map.
   void UpdateFrameArrivalMap(QuicStreamOffset offset);
 
+  // Return |gaps_| as a std::string: [1024, 1500) [1800, 2048)... for
+  // debugging.
+  std::string GapsDebugString();
+
+  // Return all received frames as a std::string in same format as
+  // GapsDebugString();
+  std::string ReceivedFramesDebugString();
+
   // The maximum total capacity of this buffer in byte, as constructed.
   const size_t max_buffer_capacity_bytes_;
 
diff --git a/net/quic/spdy_utils.cc b/net/quic/spdy_utils.cc
index 3f87bff..468c982 100644
--- a/net/quic/spdy_utils.cc
+++ b/net/quic/spdy_utils.cc
@@ -28,8 +28,8 @@
   SpdyFrameBuilder builder(length, spdy_version);
   SpdyFramer framer(spdy_version);
   framer.SerializeHeaderBlockWithoutCompression(&builder, headers);
-  scoped_ptr<SpdyFrame> block(builder.take());
-  return string(block->data(), length);
+  SpdySerializedFrame block(builder.take());
+  return string(block.data(), length);
 }
 
 // static
diff --git a/net/quic/test_tools/quic_connection_peer.cc b/net/quic/test_tools/quic_connection_peer.cc
index 9a1235b..8b2407c 100644
--- a/net/quic/test_tools/quic_connection_peer.cc
+++ b/net/quic/test_tools/quic_connection_peer.cc
@@ -28,12 +28,6 @@
 }
 
 // static
-void QuicConnectionPeer::PopulateAckFrame(QuicConnection* connection,
-                                          QuicAckFrame* ack) {
-  connection->PopulateAckFrame(ack);
-}
-
-// static
 const QuicFrame QuicConnectionPeer::GetUpdatedAckFrame(
     QuicConnection* connection) {
   return connection->GetUpdatedAckFrame();
diff --git a/net/quic/test_tools/quic_connection_peer.h b/net/quic/test_tools/quic_connection_peer.h
index af154496..d6130e9 100644
--- a/net/quic/test_tools/quic_connection_peer.h
+++ b/net/quic/test_tools/quic_connection_peer.h
@@ -38,8 +38,6 @@
   static void SetSendAlgorithm(QuicConnection* connection,
                                SendAlgorithmInterface* send_algorithm);
 
-  static void PopulateAckFrame(QuicConnection* connection, QuicAckFrame* ack);
-
   static const QuicFrame GetUpdatedAckFrame(QuicConnection* connection);
 
   static void PopulateStopWaitingFrame(QuicConnection* connection,
diff --git a/net/quic/test_tools/quic_test_packet_maker.cc b/net/quic/test_tools/quic_test_packet_maker.cc
index 58e06c9..67e0ffa 100644
--- a/net/quic/test_tools/quic_test_packet_maker.cc
+++ b/net/quic/test_tools/quic_test_packet_maker.cc
@@ -341,34 +341,34 @@
     size_t* spdy_headers_frame_length,
     QuicStreamOffset* offset) {
   InitializeHeader(packet_number, should_include_version);
-  scoped_ptr<SpdySerializedFrame> spdy_frame;
+  SpdySerializedFrame spdy_frame;
   if (spdy_request_framer_.protocol_version() == SPDY3) {
     SpdySynStreamIR syn_stream(stream_id);
     syn_stream.set_header_block(headers);
     syn_stream.set_fin(fin);
     syn_stream.set_priority(priority);
-    spdy_frame.reset(spdy_request_framer_.SerializeSynStream(syn_stream));
+    spdy_frame = spdy_request_framer_.SerializeSynStream(syn_stream);
   } else {
     SpdyHeadersIR headers_frame(stream_id);
     headers_frame.set_header_block(headers);
     headers_frame.set_fin(fin);
     headers_frame.set_priority(priority);
     headers_frame.set_has_priority(true);
-    spdy_frame.reset(spdy_request_framer_.SerializeFrame(headers_frame));
+    spdy_frame = spdy_request_framer_.SerializeFrame(headers_frame);
   }
   if (spdy_headers_frame_length) {
-    *spdy_headers_frame_length = spdy_frame->size();
+    *spdy_headers_frame_length = spdy_frame.size();
   }
   if (offset != nullptr) {
     QuicStreamFrame frame(
         kHeadersStreamId, false, *offset,
-        base::StringPiece(spdy_frame->data(), spdy_frame->size()));
-    *offset += spdy_frame->size();
+        base::StringPiece(spdy_frame.data(), spdy_frame.size()));
+    *offset += spdy_frame.size();
     return MakePacket(header_, QuicFrame(&frame));
   } else {
     QuicStreamFrame frame(
         kHeadersStreamId, false, 0,
-        base::StringPiece(spdy_frame->data(), spdy_frame->size()));
+        base::StringPiece(spdy_frame.data(), spdy_frame.size()));
 
     return MakePacket(header_, QuicFrame(&frame));
   }
@@ -401,31 +401,31 @@
     size_t* spdy_headers_frame_length,
     QuicStreamOffset* offset) {
   InitializeHeader(packet_number, should_include_version);
-  scoped_ptr<SpdySerializedFrame> spdy_frame;
+  SpdySerializedFrame spdy_frame;
   if (spdy_response_framer_.protocol_version() == SPDY3) {
     SpdySynReplyIR syn_reply(stream_id);
     syn_reply.set_header_block(headers);
     syn_reply.set_fin(fin);
-    spdy_frame.reset(spdy_response_framer_.SerializeSynReply(syn_reply));
+    spdy_frame = spdy_response_framer_.SerializeSynReply(syn_reply);
   } else {
     SpdyHeadersIR headers_frame(stream_id);
     headers_frame.set_header_block(headers);
     headers_frame.set_fin(fin);
-    spdy_frame.reset(spdy_response_framer_.SerializeFrame(headers_frame));
+    spdy_frame = spdy_response_framer_.SerializeFrame(headers_frame);
   }
   if (spdy_headers_frame_length) {
-    *spdy_headers_frame_length = spdy_frame->size();
+    *spdy_headers_frame_length = spdy_frame.size();
   }
   if (offset != nullptr) {
     QuicStreamFrame frame(
         kHeadersStreamId, false, *offset,
-        base::StringPiece(spdy_frame->data(), spdy_frame->size()));
-    *offset += spdy_frame->size();
+        base::StringPiece(spdy_frame.data(), spdy_frame.size()));
+    *offset += spdy_frame.size();
     return MakePacket(header_, QuicFrame(&frame));
   } else {
     QuicStreamFrame frame(
         kHeadersStreamId, false, 0,
-        base::StringPiece(spdy_frame->data(), spdy_frame->size()));
+        base::StringPiece(spdy_frame.data(), spdy_frame.size()));
     return MakePacket(header_, QuicFrame(&frame));
   }
 }
diff --git a/net/spdy/buffered_spdy_framer.cc b/net/spdy/buffered_spdy_framer.cc
index e7e3d3d..ba0f4583 100644
--- a/net/spdy/buffered_spdy_framer.cc
+++ b/net/spdy/buffered_spdy_framer.cc
@@ -326,7 +326,7 @@
 
 // TODO(jgraettinger): Eliminate uses of this method (prefer
 // SpdySynStreamIR).
-SpdyFrame* BufferedSpdyFramer::CreateSynStream(
+SpdySerializedFrame* BufferedSpdyFramer::CreateSynStream(
     SpdyStreamId stream_id,
     SpdyStreamId associated_stream_id,
     SpdyPriority priority,
@@ -339,12 +339,12 @@
   syn_stream.set_unidirectional((flags & CONTROL_FLAG_UNIDIRECTIONAL) != 0);
   // TODO(hkhalil): Avoid copy here.
   syn_stream.set_header_block(*headers);
-  return spdy_framer_.SerializeSynStream(syn_stream);
+  return new SpdySerializedFrame(spdy_framer_.SerializeSynStream(syn_stream));
 }
 
 // TODO(jgraettinger): Eliminate uses of this method (prefer
 // SpdySynReplyIR).
-SpdyFrame* BufferedSpdyFramer::CreateSynReply(
+SpdySerializedFrame* BufferedSpdyFramer::CreateSynReply(
     SpdyStreamId stream_id,
     SpdyControlFlags flags,
     const SpdyHeaderBlock* headers) {
@@ -352,21 +352,21 @@
   syn_reply.set_fin(flags & CONTROL_FLAG_FIN);
   // TODO(hkhalil): Avoid copy here.
   syn_reply.set_header_block(*headers);
-  return spdy_framer_.SerializeSynReply(syn_reply);
+  return new SpdySerializedFrame(spdy_framer_.SerializeSynReply(syn_reply));
 }
 
 // TODO(jgraettinger): Eliminate uses of this method (prefer
 // SpdyRstStreamIR).
-SpdyFrame* BufferedSpdyFramer::CreateRstStream(
+SpdySerializedFrame* BufferedSpdyFramer::CreateRstStream(
     SpdyStreamId stream_id,
     SpdyRstStreamStatus status) const {
   SpdyRstStreamIR rst_ir(stream_id, status);
-  return spdy_framer_.SerializeRstStream(rst_ir);
+  return new SpdySerializedFrame(spdy_framer_.SerializeRstStream(rst_ir));
 }
 
 // TODO(jgraettinger): Eliminate uses of this method (prefer
 // SpdySettingsIR).
-SpdyFrame* BufferedSpdyFramer::CreateSettings(
+SpdySerializedFrame* BufferedSpdyFramer::CreateSettings(
     const SettingsMap& values) const {
   SpdySettingsIR settings_ir;
   for (SettingsMap::const_iterator it = values.begin();
@@ -378,28 +378,28 @@
         (it->second.first & SETTINGS_FLAG_PERSISTED) != 0,
         it->second.second);
   }
-  return spdy_framer_.SerializeSettings(settings_ir);
+  return new SpdySerializedFrame(spdy_framer_.SerializeSettings(settings_ir));
 }
 
 // TODO(jgraettinger): Eliminate uses of this method (prefer SpdyPingIR).
-SpdyFrame* BufferedSpdyFramer::CreatePingFrame(SpdyPingId unique_id,
-                                               bool is_ack) const {
+SpdySerializedFrame* BufferedSpdyFramer::CreatePingFrame(SpdyPingId unique_id,
+                                                         bool is_ack) const {
   SpdyPingIR ping_ir(unique_id);
   ping_ir.set_is_ack(is_ack);
-  return spdy_framer_.SerializePing(ping_ir);
+  return new SpdySerializedFrame(spdy_framer_.SerializePing(ping_ir));
 }
 
 // TODO(jgraettinger): Eliminate uses of this method (prefer SpdyGoAwayIR).
-SpdyFrame* BufferedSpdyFramer::CreateGoAway(
+SpdySerializedFrame* BufferedSpdyFramer::CreateGoAway(
     SpdyStreamId last_accepted_stream_id,
     SpdyGoAwayStatus status,
     base::StringPiece debug_data) const {
   SpdyGoAwayIR go_ir(last_accepted_stream_id, status, debug_data);
-  return spdy_framer_.SerializeGoAway(go_ir);
+  return new SpdySerializedFrame(spdy_framer_.SerializeGoAway(go_ir));
 }
 
 // TODO(jgraettinger): Eliminate uses of this method (prefer SpdyHeadersIR).
-SpdyFrame* BufferedSpdyFramer::CreateHeaders(
+SpdySerializedFrame* BufferedSpdyFramer::CreateHeaders(
     SpdyStreamId stream_id,
     SpdyControlFlags flags,
     SpdyPriority priority,
@@ -411,37 +411,38 @@
     headers_ir.set_priority(priority);
   }
   headers_ir.set_header_block(*headers);
-  return spdy_framer_.SerializeHeaders(headers_ir);
+  return new SpdySerializedFrame(spdy_framer_.SerializeHeaders(headers_ir));
 }
 
 // TODO(jgraettinger): Eliminate uses of this method (prefer
 // SpdyWindowUpdateIR).
-SpdyFrame* BufferedSpdyFramer::CreateWindowUpdate(
+SpdySerializedFrame* BufferedSpdyFramer::CreateWindowUpdate(
     SpdyStreamId stream_id,
     uint32_t delta_window_size) const {
   SpdyWindowUpdateIR update_ir(stream_id, delta_window_size);
-  return spdy_framer_.SerializeWindowUpdate(update_ir);
+  return new SpdySerializedFrame(spdy_framer_.SerializeWindowUpdate(update_ir));
 }
 
 // TODO(jgraettinger): Eliminate uses of this method (prefer SpdyDataIR).
-SpdyFrame* BufferedSpdyFramer::CreateDataFrame(SpdyStreamId stream_id,
-                                               const char* data,
-                                               uint32_t len,
-                                               SpdyDataFlags flags) {
+SpdySerializedFrame* BufferedSpdyFramer::CreateDataFrame(SpdyStreamId stream_id,
+                                                         const char* data,
+                                                         uint32_t len,
+                                                         SpdyDataFlags flags) {
   SpdyDataIR data_ir(stream_id,
                      base::StringPiece(data, len));
   data_ir.set_fin((flags & DATA_FLAG_FIN) != 0);
-  return spdy_framer_.SerializeData(data_ir);
+  return new SpdySerializedFrame(spdy_framer_.SerializeData(data_ir));
 }
 
 // TODO(jgraettinger): Eliminate uses of this method (prefer SpdyPushPromiseIR).
-SpdyFrame* BufferedSpdyFramer::CreatePushPromise(
+SpdySerializedFrame* BufferedSpdyFramer::CreatePushPromise(
     SpdyStreamId stream_id,
     SpdyStreamId promised_stream_id,
     const SpdyHeaderBlock* headers) {
   SpdyPushPromiseIR push_promise_ir(stream_id, promised_stream_id);
   push_promise_ir.set_header_block(*headers);
-  return spdy_framer_.SerializePushPromise(push_promise_ir);
+  return new SpdySerializedFrame(
+      spdy_framer_.SerializePushPromise(push_promise_ir));
 }
 
 SpdyPriority BufferedSpdyFramer::GetHighestPriority() const {
diff --git a/net/spdy/buffered_spdy_framer.h b/net/spdy/buffered_spdy_framer.h
index 65460bb..8ad0def 100644
--- a/net/spdy/buffered_spdy_framer.h
+++ b/net/spdy/buffered_spdy_framer.h
@@ -29,7 +29,7 @@
  public:
   BufferedSpdyFramerVisitorInterface() {}
 
-  // Called if an error is detected in the SpdyFrame protocol.
+  // Called if an error is detected in the SpdySerializedFrame protocol.
   virtual void OnError(SpdyFramer::SpdyError error_code) = 0;
 
   // Called if an error is detected in a SPDY stream.
@@ -213,37 +213,37 @@
   SpdyFramer::SpdyState state() const;
   bool MessageFullyRead();
   bool HasError();
-  SpdyFrame* CreateSynStream(SpdyStreamId stream_id,
-                             SpdyStreamId associated_stream_id,
-                             SpdyPriority priority,
-                             SpdyControlFlags flags,
-                             const SpdyHeaderBlock* headers);
-  SpdyFrame* CreateSynReply(SpdyStreamId stream_id,
-                            SpdyControlFlags flags,
-                            const SpdyHeaderBlock* headers);
-  SpdyFrame* CreateRstStream(SpdyStreamId stream_id,
-                             SpdyRstStreamStatus status) const;
-  SpdyFrame* CreateSettings(const SettingsMap& values) const;
-  SpdyFrame* CreatePingFrame(SpdyPingId unique_id, bool is_ack) const;
-  SpdyFrame* CreateGoAway(SpdyStreamId last_accepted_stream_id,
-                          SpdyGoAwayStatus status,
-                          base::StringPiece debug_data) const;
-  SpdyFrame* CreateHeaders(SpdyStreamId stream_id,
-                           SpdyControlFlags flags,
-                           SpdyPriority priority,
-                           const SpdyHeaderBlock* headers);
-  SpdyFrame* CreateWindowUpdate(SpdyStreamId stream_id,
-                                uint32_t delta_window_size) const;
-  SpdyFrame* CreateDataFrame(SpdyStreamId stream_id,
-                             const char* data,
-                             uint32_t len,
-                             SpdyDataFlags flags);
-  SpdyFrame* CreatePushPromise(SpdyStreamId stream_id,
-                               SpdyStreamId promised_stream_id,
-                               const SpdyHeaderBlock* headers);
+  SpdySerializedFrame* CreateSynStream(SpdyStreamId stream_id,
+                                       SpdyStreamId associated_stream_id,
+                                       SpdyPriority priority,
+                                       SpdyControlFlags flags,
+                                       const SpdyHeaderBlock* headers);
+  SpdySerializedFrame* CreateSynReply(SpdyStreamId stream_id,
+                                      SpdyControlFlags flags,
+                                      const SpdyHeaderBlock* headers);
+  SpdySerializedFrame* CreateRstStream(SpdyStreamId stream_id,
+                                       SpdyRstStreamStatus status) const;
+  SpdySerializedFrame* CreateSettings(const SettingsMap& values) const;
+  SpdySerializedFrame* CreatePingFrame(SpdyPingId unique_id, bool is_ack) const;
+  SpdySerializedFrame* CreateGoAway(SpdyStreamId last_accepted_stream_id,
+                                    SpdyGoAwayStatus status,
+                                    base::StringPiece debug_data) const;
+  SpdySerializedFrame* CreateHeaders(SpdyStreamId stream_id,
+                                     SpdyControlFlags flags,
+                                     SpdyPriority priority,
+                                     const SpdyHeaderBlock* headers);
+  SpdySerializedFrame* CreateWindowUpdate(SpdyStreamId stream_id,
+                                          uint32_t delta_window_size) const;
+  SpdySerializedFrame* CreateDataFrame(SpdyStreamId stream_id,
+                                       const char* data,
+                                       uint32_t len,
+                                       SpdyDataFlags flags);
+  SpdySerializedFrame* CreatePushPromise(SpdyStreamId stream_id,
+                                         SpdyStreamId promised_stream_id,
+                                         const SpdyHeaderBlock* headers);
 
   // Serialize a frame of unknown type.
-  SpdySerializedFrame* SerializeFrame(const SpdyFrameIR& frame) {
+  SpdySerializedFrame SerializeFrame(const SpdyFrameIR& frame) {
     return spdy_framer_.SerializeFrame(frame);
   }
 
diff --git a/net/spdy/buffered_spdy_framer_unittest.cc b/net/spdy/buffered_spdy_framer_unittest.cc
index 645be7b..be2d66e 100644
--- a/net/spdy/buffered_spdy_framer_unittest.cc
+++ b/net/spdy/buffered_spdy_framer_unittest.cc
@@ -118,13 +118,13 @@
     goaway_debug_data_.assign(debug_data.data(), debug_data.size());
   }
 
-  void OnDataFrameHeader(const SpdyFrame* frame) {
+  void OnDataFrameHeader(const SpdySerializedFrame* frame) {
     LOG(FATAL) << "Unexpected OnDataFrameHeader call.";
   }
 
-  void OnRstStream(const SpdyFrame& frame) {}
-  void OnGoAway(const SpdyFrame& frame) {}
-  void OnPing(const SpdyFrame& frame) {}
+  void OnRstStream(const SpdySerializedFrame& frame) {}
+  void OnGoAway(const SpdySerializedFrame& frame) {}
+  void OnPing(const SpdySerializedFrame& frame) {}
   void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override {}
 
   void OnPushPromise(SpdyStreamId stream_id,
@@ -208,12 +208,12 @@
   SpdySettingsIR settings_ir;
   settings_ir.AddSetting(SETTINGS_INITIAL_WINDOW_SIZE, false, false, 2);
   settings_ir.AddSetting(SETTINGS_MAX_CONCURRENT_STREAMS, false, false, 3);
-  scoped_ptr<SpdyFrame> control_frame(framer.SerializeSettings(settings_ir));
+  SpdySerializedFrame control_frame(framer.SerializeSettings(settings_ir));
   TestBufferedSpdyVisitor visitor(spdy_version());
 
   visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame->data()),
-      control_frame->size());
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
   EXPECT_EQ(0, visitor.error_count_);
   EXPECT_EQ(2, visitor.setting_count_);
 }
@@ -227,12 +227,11 @@
   headers["aa"] = "vv";
   headers["bb"] = "ww";
   BufferedSpdyFramer framer(spdy_version());
-  scoped_ptr<SpdyFrame> control_frame(
-      framer.CreateSynStream(1,                        // stream_id
-                             0,                        // associated_stream_id
-                             1,                        // priority
-                             CONTROL_FLAG_NONE,
-                             &headers));
+  scoped_ptr<SpdySerializedFrame> control_frame(
+      framer.CreateSynStream(1,  // stream_id
+                             0,  // associated_stream_id
+                             1,  // priority
+                             CONTROL_FLAG_NONE, &headers));
   EXPECT_TRUE(control_frame.get() != NULL);
 
   TestBufferedSpdyVisitor visitor(spdy_version());
@@ -256,10 +255,9 @@
   headers["alpha"] = "beta";
   headers["gamma"] = "delta";
   BufferedSpdyFramer framer(spdy_version());
-  scoped_ptr<SpdyFrame> control_frame(
-      framer.CreateSynReply(1,                        // stream_id
-                            CONTROL_FLAG_NONE,
-                            &headers));
+  scoped_ptr<SpdySerializedFrame> control_frame(
+      framer.CreateSynReply(1,  // stream_id
+                            CONTROL_FLAG_NONE, &headers));
   EXPECT_TRUE(control_frame.get() != NULL);
 
   TestBufferedSpdyVisitor visitor(spdy_version());
@@ -284,10 +282,10 @@
   headers["alpha"] = "beta";
   headers["gamma"] = "delta";
   BufferedSpdyFramer framer(spdy_version());
-  scoped_ptr<SpdyFrame> control_frame(
-      framer.CreateHeaders(1,                        // stream_id
+  scoped_ptr<SpdySerializedFrame> control_frame(
+      framer.CreateHeaders(1,  // stream_id
                            CONTROL_FLAG_NONE,
-                           0,                        // priority
+                           0,  // priority
                            &headers));
   EXPECT_TRUE(control_frame.get() != NULL);
 
@@ -310,7 +308,7 @@
   headers["alpha"] = "beta";
   headers["gamma"] = "delta";
   BufferedSpdyFramer framer(spdy_version());
-  scoped_ptr<SpdyFrame> control_frame(
+  scoped_ptr<SpdySerializedFrame> control_frame(
       framer.CreatePushPromise(1, 2, &headers));
   EXPECT_TRUE(control_frame.get() != NULL);
 
@@ -332,7 +330,7 @@
   if (spdy_version() < HTTP2)
     return;
   BufferedSpdyFramer framer(spdy_version());
-  scoped_ptr<SpdyFrame> goaway_frame(
+  scoped_ptr<SpdySerializedFrame> goaway_frame(
       framer.CreateGoAway(2u, GOAWAY_FRAME_SIZE_ERROR, "foo"));
 
   TestBufferedSpdyVisitor visitor(spdy_version());
diff --git a/net/spdy/spdy_buffer.cc b/net/spdy/spdy_buffer.cc
index fad3305..be783fc 100644
--- a/net/spdy/spdy_buffer.cc
+++ b/net/spdy/spdy_buffer.cc
@@ -20,16 +20,17 @@
 // Bound on largest frame any SPDY version has allowed.
 const size_t kMaxSpdyFrameSize = 0x00ffffff;
 
-// Makes a SpdyFrame with |size| bytes of data copied from
-// |data|. |data| must be non-NULL and |size| must be positive.
-scoped_ptr<SpdyFrame> MakeSpdyFrame(const char* data, size_t size) {
+// Makes a SpdySerializedFrame with |size| bytes of data copied from |data|.
+// |data| must be non-NULL and |size| must be positive.
+scoped_ptr<SpdySerializedFrame> MakeSpdySerializedFrame(const char* data,
+                                                        size_t size) {
   DCHECK(data);
   CHECK_GT(size, 0u);
   CHECK_LE(size, kMaxSpdyFrameSize);
   scoped_ptr<char[]> frame_data(new char[size]);
   std::memcpy(frame_data.get(), data, size);
-  scoped_ptr<SpdyFrame> frame(
-      new SpdyFrame(frame_data.release(), size, true /* owns_buffer */));
+  scoped_ptr<SpdySerializedFrame> frame(new SpdySerializedFrame(
+      frame_data.release(), size, true /* owns_buffer */));
   return frame;
 }
 
@@ -56,9 +57,8 @@
   DISALLOW_COPY_AND_ASSIGN(SharedFrameIOBuffer);
 };
 
-SpdyBuffer::SpdyBuffer(scoped_ptr<SpdyFrame> frame)
-    : shared_frame_(new SharedFrame()),
-      offset_(0) {
+SpdyBuffer::SpdyBuffer(scoped_ptr<SpdySerializedFrame> frame)
+    : shared_frame_(new SharedFrame()), offset_(0) {
   shared_frame_->data = std::move(frame);
 }
 
@@ -69,7 +69,7 @@
     offset_(0) {
   CHECK_GT(size, 0u);
   CHECK_LE(size, kMaxSpdyFrameSize);
-  shared_frame_->data = MakeSpdyFrame(data, size);
+  shared_frame_->data = MakeSpdySerializedFrame(data, size);
 }
 
 SpdyBuffer::~SpdyBuffer() {
diff --git a/net/spdy/spdy_buffer.h b/net/spdy/spdy_buffer.h
index 94ee97f..d12c89f 100644
--- a/net/spdy/spdy_buffer.h
+++ b/net/spdy/spdy_buffer.h
@@ -17,7 +17,7 @@
 namespace net {
 
 class IOBuffer;
-class SpdyFrame;
+class SpdySerializedFrame;
 
 // SpdyBuffer is a class to hold data read from or to be written to a
 // SPDY connection. It is similar to a DrainableIOBuffer but is not
@@ -47,7 +47,7 @@
 
   // Construct with the data in the given frame. Assumes that data is
   // owned by |frame| or outlives it.
-  explicit SpdyBuffer(scoped_ptr<SpdyFrame> frame);
+  explicit SpdyBuffer(scoped_ptr<SpdySerializedFrame> frame);
 
   // Construct with a copy of the given raw data. |data| must be
   // non-NULL and |size| must be non-zero.
@@ -86,9 +86,9 @@
  private:
   void ConsumeHelper(size_t consume_size, ConsumeSource consume_source);
 
-  // Ref-count the passed-in SpdyFrame to support the semantics of
+  // Ref-count the passed-in SpdySerializedFrame to support the semantics of
   // |GetIOBufferForRemainingData()|.
-  typedef base::RefCountedData<scoped_ptr<SpdyFrame> > SharedFrame;
+  typedef base::RefCountedData<scoped_ptr<SpdySerializedFrame>> SharedFrame;
 
   class SharedFrameIOBuffer;
 
diff --git a/net/spdy/spdy_buffer_unittest.cc b/net/spdy/spdy_buffer_unittest.cc
index 4200916..46a5c2b 100644
--- a/net/spdy/spdy_buffer_unittest.cc
+++ b/net/spdy/spdy_buffer_unittest.cc
@@ -29,13 +29,11 @@
   return std::string(buffer.GetRemainingData(), buffer.GetRemainingSize());
 }
 
-// Construct a SpdyBuffer from a SpdyFrame and make sure its data
+// Construct a SpdyBuffer from a SpdySerializedFrame and make sure its data
 // points to the frame's underlying data.
 TEST_F(SpdyBufferTest, FrameConstructor) {
-  SpdyBuffer buffer(
-      scoped_ptr<SpdyFrame>(
-          new SpdyFrame(const_cast<char*>(kData), kDataSize,
-                        false /* owns_buffer */)));
+  SpdyBuffer buffer(scoped_ptr<SpdySerializedFrame>(new SpdySerializedFrame(
+      const_cast<char*>(kData), kDataSize, false /* owns_buffer */)));
 
   EXPECT_EQ(kData, buffer.GetRemainingData());
   EXPECT_EQ(kDataSize, buffer.GetRemainingSize());
diff --git a/net/spdy/spdy_frame_builder.h b/net/spdy/spdy_frame_builder.h
index 29cb5546..d1f9535 100644
--- a/net/spdy/spdy_frame_builder.h
+++ b/net/spdy/spdy_frame_builder.h
@@ -74,13 +74,13 @@
                      SpdyStreamId stream_id);
 
   // Takes the buffer from the SpdyFrameBuilder.
-  SpdyFrame* take() {
+  SpdySerializedFrame take() {
     if (version_ == HTTP2) {
       DLOG_IF(DFATAL, SpdyConstants::GetFrameMaximumSize(version_) < length_)
           << "Frame length " << length_
           << " is longer than the maximum allowed length.";
     }
-    SpdyFrame* rv = new SpdyFrame(buffer_.release(), length(), true);
+    SpdySerializedFrame rv(buffer_.release(), length(), true);
     capacity_ = 0;
     length_ = 0;
     offset_ = 0;
diff --git a/net/spdy/spdy_frame_builder_test.cc b/net/spdy/spdy_frame_builder_test.cc
index 3fa82dc..b27abf9 100644
--- a/net/spdy/spdy_frame_builder_test.cc
+++ b/net/spdy/spdy_frame_builder_test.cc
@@ -29,11 +29,11 @@
   char* writable_buffer = builder.GetWritableBuffer(builder_size);
   memset(writable_buffer, ~1, builder_size);
   EXPECT_TRUE(builder.Seek(builder_size));
-  scoped_ptr<SpdyFrame> frame(builder.take());
+  SpdySerializedFrame frame(builder.take());
   char expected[builder_size];
   memset(expected, ~1, builder_size);
   EXPECT_EQ(base::StringPiece(expected, builder_size),
-            base::StringPiece(frame->data(), builder_size));
+            base::StringPiece(frame.data(), builder_size));
 }
 
 TEST_P(SpdyFrameBuilderTest, RewriteLength) {
@@ -42,8 +42,8 @@
   // then is corrected via RewriteLength().
   SpdyFramer framer(spdy_version_);
   SpdySettingsIR settings_ir;
-  scoped_ptr<SpdyFrame> expected(framer.SerializeSettings(settings_ir));
-  SpdyFrameBuilder builder(expected->size() + 1, spdy_version_);
+  SpdySerializedFrame expected(framer.SerializeSettings(settings_ir));
+  SpdyFrameBuilder builder(expected.size() + 1, spdy_version_);
   if (spdy_version_ == SPDY3) {
     builder.WriteControlFrameHeader(framer, SETTINGS, 0);
     builder.WriteUInt32(0);  // Write the number of settings.
@@ -52,9 +52,9 @@
   }
   EXPECT_TRUE(builder.GetWritableBuffer(1) != NULL);
   builder.RewriteLength(framer);
-  scoped_ptr<SpdyFrame> built(builder.take());
-  EXPECT_EQ(base::StringPiece(expected->data(), expected->size()),
-            base::StringPiece(built->data(), expected->size()));
+  SpdySerializedFrame built(builder.take());
+  EXPECT_EQ(base::StringPiece(expected.data(), expected.size()),
+            base::StringPiece(built.data(), expected.size()));
 }
 
 TEST_P(SpdyFrameBuilderTest, OverwriteFlags) {
@@ -65,13 +65,13 @@
     return;
   }
   SpdyHeadersIR headers_ir(1);
-  scoped_ptr<SpdyFrame> expected(framer.SerializeHeaders(headers_ir));
-  SpdyFrameBuilder builder(expected->size(), spdy_version_);
+  SpdySerializedFrame expected(framer.SerializeHeaders(headers_ir));
+  SpdyFrameBuilder builder(expected.size(), spdy_version_);
   builder.BeginNewFrame(framer, HEADERS, 0, 1);
   builder.OverwriteFlags(framer, HEADERS_FLAG_END_HEADERS);
-  scoped_ptr<SpdyFrame> built(builder.take());
-  EXPECT_EQ(base::StringPiece(expected->data(), expected->size()),
-            base::StringPiece(built->data(), built->size()));
+  SpdySerializedFrame built(builder.take());
+  EXPECT_EQ(base::StringPiece(expected.data(), expected.size()),
+            base::StringPiece(built.data(), built.size()));
 }
 
 }  // namespace net
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc
index 5c8d011..2994ae6d 100644
--- a/net/spdy/spdy_framer.cc
+++ b/net/spdy/spdy_framer.cc
@@ -1719,13 +1719,13 @@
   SpdyFrameBuilder builder(payload_len, SPDY3);
 
   SerializeHeaderBlockWithoutCompression(&builder, block);
-  scoped_ptr<SpdyFrame> frame(builder.take());
+  SpdySerializedFrame frame = builder.take();
 
   // Preserve padding length, and reset it after the re-entrant call.
   size_t remaining_padding = remaining_padding_payload_length_;
 
   remaining_padding_payload_length_ = 0;
-  remaining_data_length_ = frame->size();
+  remaining_data_length_ = frame.size();
 
   if (payload_len != 0) {
     int compression_pct = 100 - (100 * compressed_len) / payload_len;
@@ -1734,7 +1734,7 @@
                              compression_pct);
   }
 
-  ProcessControlFrameHeaderBlock(frame->data(), frame->size(), false);
+  ProcessControlFrameHeaderBlock(frame.data(), frame.size(), false);
 
   remaining_padding_payload_length_ = remaining_padding;
   remaining_data_length_ = remaining_padding;
@@ -2206,8 +2206,7 @@
   return true;
 }
 
-SpdySerializedFrame* SpdyFramer::SerializeData(
-    const SpdyDataIR& data_ir) const {
+SpdySerializedFrame SpdyFramer::SerializeData(const SpdyDataIR& data_ir) const {
   uint8_t flags = DATA_FLAG_NONE;
   if (data_ir.fin()) {
     flags = DATA_FLAG_FIN;
@@ -2245,7 +2244,7 @@
   }
 }
 
-SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField(
+SpdySerializedFrame SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField(
     const SpdyDataIR& data_ir) const {
   uint8_t flags = DATA_FLAG_NONE;
   if (data_ir.fin()) {
@@ -2277,7 +2276,7 @@
   return builder.take();
 }
 
-SpdySerializedFrame* SpdyFramer::SerializeSynStream(
+SpdySerializedFrame SpdyFramer::SerializeSynStream(
     const SpdySynStreamIR& syn_stream) {
   DCHECK_EQ(SPDY3, protocol_version_);
   uint8_t flags = 0;
@@ -2320,7 +2319,7 @@
   return builder.take();
 }
 
-SpdySerializedFrame* SpdyFramer::SerializeSynReply(
+SpdySerializedFrame SpdyFramer::SerializeSynReply(
     const SpdySynReplyIR& syn_reply) {
   DCHECK_EQ(SPDY3, protocol_version_);
   uint8_t flags = 0;
@@ -2350,7 +2349,7 @@
   return builder.take();
 }
 
-SpdySerializedFrame* SpdyFramer::SerializeRstStream(
+SpdySerializedFrame SpdyFramer::SerializeRstStream(
     const SpdyRstStreamIR& rst_stream) const {
   // TODO(jgraettinger): For now, Chromium will support parsing RST_STREAM
   // payloads, but will not emit them. SPDY4 is used for draft HTTP/2,
@@ -2375,7 +2374,7 @@
   return builder.take();
 }
 
-SpdySerializedFrame* SpdyFramer::SerializeSettings(
+SpdySerializedFrame SpdyFramer::SerializeSettings(
     const SpdySettingsIR& settings) const {
   uint8_t flags = 0;
 
@@ -2437,7 +2436,7 @@
   return builder.take();
 }
 
-SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const {
+SpdySerializedFrame SpdyFramer::SerializePing(const SpdyPingIR& ping) const {
   SpdyFrameBuilder builder(GetPingSize(), protocol_version_);
   if (protocol_version_ == SPDY3) {
     builder.WriteControlFrameHeader(*this, PING, kNoFlags);
@@ -2454,9 +2453,8 @@
   return builder.take();
 }
 
-SpdySerializedFrame* SpdyFramer::SerializeGoAway(
+SpdySerializedFrame SpdyFramer::SerializeGoAway(
     const SpdyGoAwayIR& goaway) const {
-
   // Compute the output buffer size, take opaque data into account.
   size_t expected_length = GetGoAwayMinimumSize();
   if (protocol_version_ == HTTP2) {
@@ -2488,8 +2486,7 @@
   return builder.take();
 }
 
-SpdySerializedFrame* SpdyFramer::SerializeHeaders(
-    const SpdyHeadersIR& headers) {
+SpdySerializedFrame SpdyFramer::SerializeHeaders(const SpdyHeadersIR& headers) {
   uint8_t flags = 0;
   if (headers.fin()) {
     flags |= CONTROL_FLAG_FIN;
@@ -2589,7 +2586,7 @@
   return builder.take();
 }
 
-SpdySerializedFrame* SpdyFramer::SerializeWindowUpdate(
+SpdySerializedFrame SpdyFramer::SerializeWindowUpdate(
     const SpdyWindowUpdateIR& window_update) const {
   SpdyFrameBuilder builder(GetWindowUpdateSize(), protocol_version_);
   if (protocol_version_ == SPDY3) {
@@ -2606,14 +2603,15 @@
   return builder.take();
 }
 
-SpdyFrame* SpdyFramer::SerializeBlocked(const SpdyBlockedIR& blocked) const {
+SpdySerializedFrame SpdyFramer::SerializeBlocked(
+    const SpdyBlockedIR& blocked) const {
   DCHECK_EQ(HTTP2, protocol_version_);
   SpdyFrameBuilder builder(GetBlockedSize(), protocol_version_);
   builder.BeginNewFrame(*this, BLOCKED, kNoFlags, blocked.stream_id());
   return builder.take();
 }
 
-SpdyFrame* SpdyFramer::SerializePushPromise(
+SpdySerializedFrame SpdyFramer::SerializePushPromise(
     const SpdyPushPromiseIR& push_promise) {
   DCHECK_EQ(HTTP2, protocol_version_);
   uint8_t flags = 0;
@@ -2685,7 +2683,7 @@
 // TODO(jgraettinger): This implementation is incorrect. The continuation
 // frame continues a previously-begun HPACK encoding; it doesn't begin a
 // new one. Figure out whether it makes sense to keep SerializeContinuation().
-SpdyFrame* SpdyFramer::SerializeContinuation(
+SpdySerializedFrame SpdyFramer::SerializeContinuation(
     const SpdyContinuationIR& continuation) {
   CHECK_EQ(HTTP2, protocol_version_);
   uint8_t flags = 0;
@@ -2714,7 +2712,7 @@
   return builder.take();
 }
 
-SpdyFrame* SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc_ir) {
+SpdySerializedFrame SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc_ir) {
   DCHECK_EQ(HTTP2, protocol_version_);
 
   size_t size = GetAltSvcMinimumSize();
@@ -2733,7 +2731,8 @@
   return builder.take();
 }
 
-SpdyFrame* SpdyFramer::SerializePriority(const SpdyPriorityIR& priority) const {
+SpdySerializedFrame SpdyFramer::SerializePriority(
+    const SpdyPriorityIR& priority) const {
   DCHECK_EQ(HTTP2, protocol_version_);
   size_t size = GetPrioritySize();
 
@@ -2751,62 +2750,63 @@
 
 class FrameSerializationVisitor : public SpdyFrameVisitor {
  public:
-  explicit FrameSerializationVisitor(SpdyFramer* framer) : framer_(framer) {}
+  explicit FrameSerializationVisitor(SpdyFramer* framer)
+      : framer_(framer), frame_() {}
   ~FrameSerializationVisitor() override {}
 
-  SpdySerializedFrame* ReleaseSerializedFrame() { return frame_.release(); }
+  SpdySerializedFrame ReleaseSerializedFrame() { return std::move(frame_); }
 
   void VisitData(const SpdyDataIR& data) override {
-    frame_.reset(framer_->SerializeData(data));
+    frame_ = framer_->SerializeData(data);
   }
   void VisitSynStream(const SpdySynStreamIR& syn_stream) override {
-    frame_.reset(framer_->SerializeSynStream(syn_stream));
+    frame_ = framer_->SerializeSynStream(syn_stream);
   }
   void VisitSynReply(const SpdySynReplyIR& syn_reply) override {
-    frame_.reset(framer_->SerializeSynReply(syn_reply));
+    frame_ = framer_->SerializeSynReply(syn_reply);
   }
   void VisitRstStream(const SpdyRstStreamIR& rst_stream) override {
-    frame_.reset(framer_->SerializeRstStream(rst_stream));
+    frame_ = framer_->SerializeRstStream(rst_stream);
   }
   void VisitSettings(const SpdySettingsIR& settings) override {
-    frame_.reset(framer_->SerializeSettings(settings));
+    frame_ = framer_->SerializeSettings(settings);
   }
   void VisitPing(const SpdyPingIR& ping) override {
-    frame_.reset(framer_->SerializePing(ping));
+    frame_ = framer_->SerializePing(ping);
   }
   void VisitGoAway(const SpdyGoAwayIR& goaway) override {
-    frame_.reset(framer_->SerializeGoAway(goaway));
+    frame_ = framer_->SerializeGoAway(goaway);
   }
   void VisitHeaders(const SpdyHeadersIR& headers) override {
-    frame_.reset(framer_->SerializeHeaders(headers));
+    frame_ = framer_->SerializeHeaders(headers);
   }
   void VisitWindowUpdate(const SpdyWindowUpdateIR& window_update) override {
-    frame_.reset(framer_->SerializeWindowUpdate(window_update));
+    frame_ = framer_->SerializeWindowUpdate(window_update);
   }
   void VisitBlocked(const SpdyBlockedIR& blocked) override {
-    frame_.reset(framer_->SerializeBlocked(blocked));
+    frame_ = framer_->SerializeBlocked(blocked);
   }
   void VisitPushPromise(const SpdyPushPromiseIR& push_promise) override {
-    frame_.reset(framer_->SerializePushPromise(push_promise));
+    frame_ = framer_->SerializePushPromise(push_promise);
   }
   void VisitContinuation(const SpdyContinuationIR& continuation) override {
-    frame_.reset(framer_->SerializeContinuation(continuation));
+    frame_ = framer_->SerializeContinuation(continuation);
   }
   void VisitAltSvc(const SpdyAltSvcIR& altsvc) override {
-    frame_.reset(framer_->SerializeAltSvc(altsvc));
+    frame_ = framer_->SerializeAltSvc(altsvc);
   }
   void VisitPriority(const SpdyPriorityIR& priority) override {
-    frame_.reset(framer_->SerializePriority(priority));
+    frame_ = framer_->SerializePriority(priority);
   }
 
  private:
   SpdyFramer* framer_;
-  scoped_ptr<SpdySerializedFrame> frame_;
+  SpdySerializedFrame frame_;
 };
 
 }  // namespace
 
-SpdySerializedFrame* SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) {
+SpdySerializedFrame SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) {
   FrameSerializationVisitor visitor(this);
   frame.Visit(&visitor);
   return visitor.ReleaseSerializedFrame();
@@ -3097,7 +3097,7 @@
   SpdyFrameBuilder uncompressed_builder(uncompressed_len, protocol_version_);
   SerializeHeaderBlockWithoutCompression(&uncompressed_builder,
                                          frame.header_block());
-  scoped_ptr<SpdyFrame> uncompressed_payload(uncompressed_builder.take());
+  SpdySerializedFrame uncompressed_payload(uncompressed_builder.take());
 
   z_stream* compressor = GetHeaderCompressor();
   if (!compressor) {
@@ -3116,7 +3116,7 @@
   // TODO(phajdan.jr): Clean up after we no longer need
   // to workaround http://crbug.com/139744.
 #if defined(USE_SYSTEM_ZLIB)
-  compressor->next_in = reinterpret_cast<Bytef*>(uncompressed_payload->data());
+  compressor->next_in = reinterpret_cast<Bytef*>(uncompressed_payload.data());
   compressor->avail_in = uncompressed_len;
 #endif  // defined(USE_SYSTEM_ZLIB)
   compressor->next_out = reinterpret_cast<Bytef*>(
diff --git a/net/spdy/spdy_framer.h b/net/spdy/spdy_framer.h
index 6261777..27384ce8 100644
--- a/net/spdy/spdy_framer.h
+++ b/net/spdy/spdy_framer.h
@@ -98,7 +98,7 @@
  public:
   virtual ~SpdyFramerVisitorInterface() {}
 
-  // Called if an error is detected in the SpdyFrame protocol.
+  // Called if an error is detected in the SpdySerializedFrame protocol.
   virtual void OnError(SpdyFramer* framer) = 0;
 
   // Called when a data frame header is received. The frame's data
@@ -413,55 +413,55 @@
                                 SpdyHeaderBlock* block) const;
 
   // Serialize a data frame.
-  SpdySerializedFrame* SerializeData(const SpdyDataIR& data) const;
+  SpdySerializedFrame SerializeData(const SpdyDataIR& data) const;
   // Serializes the data frame header and optionally padding length fields,
   // excluding actual data payload and padding.
-  SpdySerializedFrame* SerializeDataFrameHeaderWithPaddingLengthField(
+  SpdySerializedFrame SerializeDataFrameHeaderWithPaddingLengthField(
       const SpdyDataIR& data) const;
 
   // Serializes a SYN_STREAM frame.
-  SpdySerializedFrame* SerializeSynStream(const SpdySynStreamIR& syn_stream);
+  SpdySerializedFrame SerializeSynStream(const SpdySynStreamIR& syn_stream);
 
-  // Serialize a SYN_REPLY SpdyFrame.
-  SpdySerializedFrame* SerializeSynReply(const SpdySynReplyIR& syn_reply);
+  // Serialize a SYN_REPLY frame.
+  SpdySerializedFrame SerializeSynReply(const SpdySynReplyIR& syn_reply);
 
-  SpdySerializedFrame* SerializeRstStream(
+  SpdySerializedFrame SerializeRstStream(
       const SpdyRstStreamIR& rst_stream) const;
 
   // Serializes a SETTINGS frame. The SETTINGS frame is
   // used to communicate name/value pairs relevant to the communication channel.
-  SpdySerializedFrame* SerializeSettings(const SpdySettingsIR& settings) const;
+  SpdySerializedFrame SerializeSettings(const SpdySettingsIR& settings) const;
 
   // Serializes a PING frame. The unique_id is used to
   // identify the ping request/response.
-  SpdySerializedFrame* SerializePing(const SpdyPingIR& ping) const;
+  SpdySerializedFrame SerializePing(const SpdyPingIR& ping) const;
 
   // Serializes a GOAWAY frame. The GOAWAY frame is used
   // prior to the shutting down of the TCP connection, and includes the
   // stream_id of the last stream the sender of the frame is willing to process
   // to completion.
-  SpdySerializedFrame* SerializeGoAway(const SpdyGoAwayIR& goaway) const;
+  SpdySerializedFrame SerializeGoAway(const SpdyGoAwayIR& goaway) const;
 
   // Serializes a HEADERS frame. The HEADERS frame is used
   // for sending additional headers outside of a SYN_STREAM/SYN_REPLY.
-  SpdySerializedFrame* SerializeHeaders(const SpdyHeadersIR& headers);
+  SpdySerializedFrame SerializeHeaders(const SpdyHeadersIR& headers);
 
   // Serializes a WINDOW_UPDATE frame. The WINDOW_UPDATE
   // frame is used to implement per stream flow control in SPDY.
-  SpdySerializedFrame* SerializeWindowUpdate(
+  SpdySerializedFrame SerializeWindowUpdate(
       const SpdyWindowUpdateIR& window_update) const;
 
   // Serializes a BLOCKED frame. The BLOCKED frame is used to
   // indicate to the remote endpoint that this endpoint believes itself to be
   // flow-control blocked but otherwise ready to send data. The BLOCKED frame
   // is purely advisory and optional.
-  SpdySerializedFrame* SerializeBlocked(const SpdyBlockedIR& blocked) const;
+  SpdySerializedFrame SerializeBlocked(const SpdyBlockedIR& blocked) const;
 
   // Serializes a PUSH_PROMISE frame. The PUSH_PROMISE frame is used
   // to inform the client that it will be receiving an additional stream
   // in response to the original request. The frame includes synthesized
   // headers to explain the upcoming data.
-  SpdySerializedFrame* SerializePushPromise(
+  SpdySerializedFrame SerializePushPromise(
       const SpdyPushPromiseIR& push_promise);
 
   // Serializes a CONTINUATION frame. The CONTINUATION frame is used
@@ -469,19 +469,19 @@
   // TODO(jgraettinger): This implementation is incorrect. The continuation
   // frame continues a previously-begun HPACK encoding; it doesn't begin a
   // new one. Figure out whether it makes sense to keep SerializeContinuation().
-  SpdySerializedFrame* SerializeContinuation(
+  SpdySerializedFrame SerializeContinuation(
       const SpdyContinuationIR& continuation);
 
   // Serializes an ALTSVC frame. The ALTSVC frame advertises the
   // availability of an alternative service to the client.
-  SpdySerializedFrame* SerializeAltSvc(const SpdyAltSvcIR& altsvc);
+  SpdySerializedFrame SerializeAltSvc(const SpdyAltSvcIR& altsvc);
 
   // Serializes a PRIORITY frame. The PRIORITY frame advises a change in
   // the relative priority of the given stream.
-  SpdySerializedFrame* SerializePriority(const SpdyPriorityIR& priority) const;
+  SpdySerializedFrame SerializePriority(const SpdyPriorityIR& priority) const;
 
   // Serialize a frame of unknown type.
-  SpdySerializedFrame* SerializeFrame(const SpdyFrameIR& frame);
+  SpdySerializedFrame SerializeFrame(const SpdyFrameIR& frame);
 
   // NOTES about frame compression.
   // We want spdy to compress headers across the entire session.  As long as
@@ -494,13 +494,6 @@
   // not build its state in a serial (stream based) manner....  For now, we're
   // using zlib anyway.
 
-  // Compresses a SpdyFrame.
-  // On success, returns a new SpdyFrame with the payload compressed.
-  // Compression state is maintained as part of the SpdyFramer.
-  // Returned frame must be freed with "delete".
-  // On failure, returns NULL.
-  SpdyFrame* CompressFrame(const SpdyFrame& frame);
-
   // For ease of testing and experimentation we can tweak compression on/off.
   void set_enable_compression(bool value) {
     enable_compression_ = value;
diff --git a/net/spdy/spdy_framer_test.cc b/net/spdy/spdy_framer_test.cc
index 5e413272..386f2b94 100644
--- a/net/spdy/spdy_framer_test.cc
+++ b/net/spdy/spdy_framer_test.cc
@@ -55,9 +55,10 @@
   // and will CHECK fail if the input is anything other than a single,
   // well-formed compressed frame.
   //
-  // Returns a new decompressed SpdyFrame.
-  template<class SpdyFrameType> static SpdyFrame* DecompressFrame(
-      SpdyFramer* framer, const SpdyFrameType& frame) {
+  // Returns a new decompressed SpdySerializedFrame.
+  template <class SpdyFrameType>
+  static SpdySerializedFrame DecompressFrame(SpdyFramer* framer,
+                                             const SpdyFrameType& frame) {
     DecompressionVisitor visitor(framer->protocol_version());
     framer->set_visitor(&visitor);
     CHECK_EQ(frame.size(), framer->ProcessInput(frame.data(), frame.size()));
@@ -66,8 +67,8 @@
 
     char* buffer = visitor.ReleaseBuffer();
     CHECK(buffer != NULL);
-    SpdyFrame* decompressed_frame = new SpdyFrame(buffer, visitor.size(), true);
-    SetFrameLength(decompressed_frame,
+    SpdySerializedFrame decompressed_frame(buffer, visitor.size(), true);
+    SetFrameLength(&decompressed_frame,
                    visitor.size() - framer->GetControlFrameHeaderSize(),
                    framer->protocol_version());
     return decompressed_frame;
@@ -142,9 +143,9 @@
       syn_stream.set_priority(priority);
       syn_stream.set_fin(fin);
       syn_stream.set_unidirectional(unidirectional);
-      scoped_ptr<SpdyFrame> frame(framer.SerializeSynStream(syn_stream));
+      SpdySerializedFrame frame(framer.SerializeSynStream(syn_stream));
       ResetBuffer();
-      memcpy(buffer_.get(), frame->data(), framer.GetSynStreamMinimumSize());
+      memcpy(buffer_.get(), frame.data(), framer.GetSynStreamMinimumSize());
       size_ += framer.GetSynStreamMinimumSize();
     }
 
@@ -153,9 +154,9 @@
       framer.set_enable_compression(false);
       SpdyHeadersIR headers(stream_id);
       headers.set_fin(fin);
-      scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers));
+      SpdySerializedFrame frame(framer.SerializeHeaders(headers));
       ResetBuffer();
-      memcpy(buffer_.get(), frame->data(), framer.GetHeadersMinimumSize());
+      memcpy(buffer_.get(), frame.data(), framer.GetHeadersMinimumSize());
       size_ += framer.GetSynStreamMinimumSize();
     }
 
@@ -188,9 +189,9 @@
       headers.set_parent_stream_id(parent_stream_id);
       headers.set_exclusive(exclusive);
       headers.set_fin(fin);
-      scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers));
+      SpdySerializedFrame frame(framer.SerializeHeaders(headers));
       ResetBuffer();
-      memcpy(buffer_.get(), frame->data(), framer.GetHeadersMinimumSize());
+      memcpy(buffer_.get(), frame.data(), framer.GetHeadersMinimumSize());
       size_ += framer.GetHeadersMinimumSize();
     }
 
@@ -205,9 +206,9 @@
       SpdyFramer framer(version_);
       framer.set_enable_compression(false);
       SpdyPushPromiseIR push_promise(stream_id, promised_stream_id);
-      scoped_ptr<SpdyFrame> frame(framer.SerializePushPromise(push_promise));
+      SpdySerializedFrame frame(framer.SerializePushPromise(push_promise));
       ResetBuffer();
-      memcpy(buffer_.get(), frame->data(), framer.GetPushPromiseMinimumSize());
+      memcpy(buffer_.get(), frame.data(), framer.GetPushPromiseMinimumSize());
       size_ += framer.GetPushPromiseMinimumSize();
     }
 
@@ -625,9 +626,9 @@
 };
 
 // Retrieves serialized headers from a HEADERS or SYN_STREAM frame.
-StringPiece GetSerializedHeaders(const SpdyFrame* frame,
+StringPiece GetSerializedHeaders(const SpdySerializedFrame& frame,
                                  const SpdyFramer& framer) {
-  SpdyFrameReader reader(frame->data(), frame->size());
+  SpdyFrameReader reader(frame.data(), frame.size());
   if (framer.protocol_version() == SPDY3) {
     reader.Seek(2);  // Seek past the frame length.
   } else {
@@ -654,11 +655,11 @@
   }
 
   if (frame_type == SYN_STREAM) {
-    return StringPiece(frame->data() + framer.GetSynStreamMinimumSize(),
-                       frame->size() - framer.GetSynStreamMinimumSize());
+    return StringPiece(frame.data() + framer.GetSynStreamMinimumSize(),
+                       frame.size() - framer.GetSynStreamMinimumSize());
   } else {
-    return StringPiece(frame->data() + framer.GetHeadersMinimumSize(),
-                       frame->size() - framer.GetHeadersMinimumSize());
+    return StringPiece(frame.data() + framer.GetHeadersMinimumSize(),
+                       frame.size() - framer.GetHeadersMinimumSize());
   }
 }
 
@@ -669,7 +670,7 @@
   }
 
   void CompareFrame(const string& description,
-                    const SpdyFrame& actual_frame,
+                    const SpdySerializedFrame& actual_frame,
                     const unsigned char* expected,
                     const int expected_len) {
     const unsigned char* actual =
@@ -679,8 +680,8 @@
   }
 
   void CompareFrames(const string& description,
-                     const SpdyFrame& expected_frame,
-                     const SpdyFrame& actual_frame) {
+                     const SpdySerializedFrame& expected_frame,
+                     const SpdySerializedFrame& actual_frame) {
     CompareCharArraysWithHexError(
         description,
         reinterpret_cast<const unsigned char*>(expected_frame.data()),
@@ -714,14 +715,12 @@
   headers.set_priority(1);
   headers.SetHeader("cookie",
                     "=; key=value; ;  = ; foo; bar=;  ;  =   ; k2=v2 ; =");
-  scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers));
-  EXPECT_TRUE(frame.get() != NULL);
+  SpdySerializedFrame frame(framer.SerializeHeaders(headers));
 
   TestSpdyVisitor visitor(spdy_version_);
   visitor.use_compression_ = true;
-  visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(frame->data()),
-      frame->size());
+  visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()),
+                           frame.size());
 
   EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
   EXPECT_NE(headers.header_block(), visitor.headers_);
@@ -740,14 +739,12 @@
   headers.SetHeader("alpha", "beta");
   headers.SetHeader("gamma", "charlie");
   headers.SetHeader("cookie", "key1=value1; key2=value2");
-  scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers));
-  EXPECT_TRUE(frame.get() != NULL);
+  SpdySerializedFrame frame(framer.SerializeHeaders(headers));
 
   TestSpdyVisitor visitor(spdy_version_);
   visitor.use_compression_ = false;
-  visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(frame->data()),
-      frame->size());
+  visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()),
+                           frame.size());
 
   EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_);
   EXPECT_EQ(headers.header_block(), visitor.headers_);
@@ -763,14 +760,12 @@
   headers.set_priority(1);
   headers.SetHeader("alpha", "beta");
   headers.SetHeader("gamma", "charlie");
-  scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers));
-  EXPECT_TRUE(frame.get() != NULL);
+  SpdySerializedFrame frame(framer.SerializeHeaders(headers));
 
   TestSpdyVisitor visitor(spdy_version_);
   visitor.use_compression_ = false;
-  visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(frame->data()),
-      frame->size() - 2);
+  visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()),
+                           frame.size() - 2);
 
   EXPECT_EQ(0, visitor.zero_length_control_frame_header_data_count_);
   EXPECT_EQ(0u, visitor.headers_.size());
@@ -794,13 +789,12 @@
       headers.set_has_priority(true);
       headers.set_parent_stream_id(parent_stream_id);
       headers.set_exclusive(exclusive);
-      scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers));
-      EXPECT_TRUE(frame.get() != NULL);
+      SpdySerializedFrame frame(framer.SerializeHeaders(headers));
 
       TestSpdyVisitor visitor(spdy_version_);
       visitor.use_compression_ = false;
-      visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame->data()),
-                               frame->size());
+      visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()),
+                               frame.size());
 
       EXPECT_TRUE(visitor.header_has_priority_);
       EXPECT_EQ(parent_stream_id, visitor.header_parent_stream_id_);
@@ -822,12 +816,11 @@
 
   SpdySynReplyIR syn_reply(0);
   syn_reply.SetHeader("alpha", "beta");
-  scoped_ptr<SpdySerializedFrame> frame(framer.SerializeSynReply(syn_reply));
-  ASSERT_TRUE(frame.get() != NULL);
+  SpdySerializedFrame frame(framer.SerializeSynReply(syn_reply));
 
   // We shouldn't have to read the whole frame before we signal an error.
   EXPECT_CALL(visitor, OnError(testing::Eq(&framer)));
-  EXPECT_GT(frame->size(), framer.ProcessInput(frame->data(), frame->size()));
+  EXPECT_GT(frame.size(), framer.ProcessInput(frame.data(), frame.size()));
   EXPECT_TRUE(framer.HasError());
   EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME, framer.error_code())
       << SpdyFramer::ErrorCodeToString(framer.error_code());
@@ -842,12 +835,11 @@
 
   SpdyHeadersIR headers_ir(0);
   headers_ir.SetHeader("alpha", "beta");
-  scoped_ptr<SpdySerializedFrame> frame(framer.SerializeHeaders(headers_ir));
-  ASSERT_TRUE(frame.get() != NULL);
+  SpdySerializedFrame frame(framer.SerializeHeaders(headers_ir));
 
   // We shouldn't have to read the whole frame before we signal an error.
   EXPECT_CALL(visitor, OnError(testing::Eq(&framer)));
-  EXPECT_GT(frame->size(), framer.ProcessInput(frame->data(), frame->size()));
+  EXPECT_GT(frame.size(), framer.ProcessInput(frame.data(), frame.size()));
   EXPECT_TRUE(framer.HasError());
   EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME, framer.error_code())
       << SpdyFramer::ErrorCodeToString(framer.error_code());
@@ -866,13 +858,11 @@
 
   SpdyPushPromiseIR push_promise(0, 4);
   push_promise.SetHeader("alpha", "beta");
-  scoped_ptr<SpdySerializedFrame> frame(
-      framer.SerializePushPromise(push_promise));
-  ASSERT_TRUE(frame.get() != NULL);
+  SpdySerializedFrame frame(framer.SerializePushPromise(push_promise));
 
   // We shouldn't have to read the whole frame before we signal an error.
   EXPECT_CALL(visitor, OnError(testing::Eq(&framer)));
-  EXPECT_GT(frame->size(), framer.ProcessInput(frame->data(), frame->size()));
+  EXPECT_GT(frame.size(), framer.ProcessInput(frame.data(), frame.size()));
   EXPECT_TRUE(framer.HasError());
   EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME, framer.error_code())
       << SpdyFramer::ErrorCodeToString(framer.error_code());
@@ -891,13 +881,11 @@
 
   SpdyPushPromiseIR push_promise(3, 0);
   push_promise.SetHeader("alpha", "beta");
-  scoped_ptr<SpdySerializedFrame> frame(
-    framer.SerializePushPromise(push_promise));
-  ASSERT_TRUE(frame.get() != NULL);
+  SpdySerializedFrame frame(framer.SerializePushPromise(push_promise));
 
   // We shouldn't have to read the whole frame before we signal an error.
   EXPECT_CALL(visitor, OnError(testing::Eq(&framer)));
-  EXPECT_GT(frame->size(), framer.ProcessInput(frame->data(), frame->size()));
+  EXPECT_GT(frame.size(), framer.ProcessInput(frame.data(), frame.size()));
   EXPECT_TRUE(framer.HasError());
   EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME, framer.error_code())
       << SpdyFramer::ErrorCodeToString(framer.error_code());
@@ -933,9 +921,8 @@
 
   SpdyHeaderBlock new_headers;
   framer.set_enable_compression(false);
-  scoped_ptr<SpdyFrame> control_frame(frame.take());
-  StringPiece serialized_headers =
-      GetSerializedHeaders(control_frame.get(), framer);
+  SpdySerializedFrame control_frame(frame.take());
+  StringPiece serialized_headers = GetSerializedHeaders(control_frame, framer);
   // This should fail because duplicate headers are verboten by the spec.
   EXPECT_FALSE(framer.ParseHeaderBlockInBuffer(serialized_headers.data(),
                                                serialized_headers.size(),
@@ -978,13 +965,13 @@
   frame.RewriteLength(framer);
 
   framer.set_enable_compression(false);
-  scoped_ptr<SpdyFrame> control_frame(frame.take());
+  SpdySerializedFrame control_frame(frame.take());
 
   TestSpdyVisitor visitor(spdy_version_);
   visitor.use_compression_ = false;
   visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame->data()),
-      control_frame->size());
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
 
   EXPECT_THAT(visitor.headers_,
               testing::ElementsAre(testing::Pair("name", StringPiece(value))));
@@ -1007,7 +994,7 @@
   syn_stream.SetHeader("version", "HTTP/1.1");
   syn_stream.SetHeader("content-type", "text/html");
   syn_stream.SetHeader("content-length", "12");
-  scoped_ptr<SpdyFrame> frame1(framer.SerializeSynStream(syn_stream));
+  SpdySerializedFrame frame1(framer.SerializeSynStream(syn_stream));
   size_t uncompressed_size1 = visitor->last_payload_len_;
   size_t compressed_size1 =
       visitor->last_frame_len_ - framer.GetSynStreamMinimumSize();
@@ -1017,25 +1004,24 @@
 #else  // !defined(USE_SYSTEM_ZLIB)
   EXPECT_EQ(117u, compressed_size1);
 #endif  // !defined(USE_SYSTEM_ZLIB)
-  scoped_ptr<SpdyFrame> frame2(framer.SerializeSynStream(syn_stream));
+  SpdySerializedFrame frame2(framer.SerializeSynStream(syn_stream));
   size_t uncompressed_size2 = visitor->last_payload_len_;
   size_t compressed_size2 =
       visitor->last_frame_len_ - framer.GetSynStreamMinimumSize();
 
   // Expect the second frame to be more compact than the first.
-  EXPECT_LE(frame2->size(), frame1->size());
+  EXPECT_LE(frame2.size(), frame1.size());
 
   // Decompress the first frame
-  scoped_ptr<SpdyFrame> frame3(
-      SpdyFramerTestUtil::DecompressFrame(&framer, *frame1));
+  SpdySerializedFrame frame3(
+      SpdyFramerTestUtil::DecompressFrame(&framer, frame1));
 
   // Decompress the second frame
   visitor.reset(new TestSpdyVisitor(spdy_version_));
   framer.set_debug_visitor(visitor.get());
-  scoped_ptr<SpdyFrame> frame4(
-      SpdyFramerTestUtil::DecompressFrame(&framer, *frame2));
-  size_t uncompressed_size4 =
-      frame4->size() - framer.GetSynStreamMinimumSize();
+  SpdySerializedFrame frame4(
+      SpdyFramerTestUtil::DecompressFrame(&framer, frame2));
+  size_t uncompressed_size4 = frame4.size() - framer.GetSynStreamMinimumSize();
   size_t compressed_size4 =
       visitor->last_frame_len_ - framer.GetSynStreamMinimumSize();
   EXPECT_EQ(165u, uncompressed_size4);
@@ -1050,14 +1036,13 @@
   EXPECT_EQ(compressed_size2, compressed_size4);
 
   // Expect frames 3 & 4 to be the same.
-  CompareFrames("Uncompressed SYN_STREAM", *frame3, *frame4);
+  CompareFrames("Uncompressed SYN_STREAM", frame3, frame4);
 
   // Expect frames 3 to be the same as a uncompressed frame created
   // from scratch.
   framer.set_enable_compression(false);
-  scoped_ptr<SpdyFrame> uncompressed_frame(
-      framer.SerializeSynStream(syn_stream));
-  CompareFrames("Uncompressed SYN_STREAM", *frame3, *uncompressed_frame);
+  SpdySerializedFrame uncompressed_frame(framer.SerializeSynStream(syn_stream));
+  CompareFrames("Uncompressed SYN_STREAM", frame3, uncompressed_frame);
 }
 
 TEST_P(SpdyFramerTest, CompressEmptyHeaders) {
@@ -1073,7 +1058,7 @@
 
   SpdyFramer framer(spdy_version_);
   framer.set_enable_compression(true);
-  scoped_ptr<SpdyFrame> frame1(framer.SerializeHeaders(headers));
+  SpdySerializedFrame frame1(framer.SerializeHeaders(headers));
 }
 
 TEST_P(SpdyFramerTest, Basic) {
@@ -1382,27 +1367,20 @@
   block[kHeader2] = kValue2;
   SpdySynStreamIR syn_ir_1(1);
   syn_ir_1.set_header_block(block);
-  scoped_ptr<SpdyFrame> syn_frame_1(send_framer.SerializeFrame(syn_ir_1));
-  EXPECT_TRUE(syn_frame_1.get() != NULL);
+  SpdySerializedFrame syn_frame_1(send_framer.SerializeFrame(syn_ir_1));
 
   // SYN_STREAM #2
   block[kHeader3] = kValue3;
   SpdySynStreamIR syn_stream(3);
   syn_stream.set_header_block(block);
-  scoped_ptr<SpdyFrame> syn_frame_2(send_framer.SerializeSynStream(syn_stream));
-  EXPECT_TRUE(syn_frame_2.get() != NULL);
-
-  // Now start decompressing
-  scoped_ptr<SpdyFrame> decompressed;
-  scoped_ptr<SpdyFrame> uncompressed;
-  StringPiece serialized_headers;
-  SpdyHeaderBlock decompressed_headers;
+  SpdySerializedFrame syn_frame_2(send_framer.SerializeSynStream(syn_stream));
 
   // Decompress SYN_STREAM #1
-  decompressed.reset(
-      SpdyFramerTestUtil::DecompressFrame(&recv_framer, *syn_frame_1));
-  EXPECT_TRUE(decompressed.get() != NULL);
-  serialized_headers = GetSerializedHeaders(decompressed.get(), send_framer);
+  SpdySerializedFrame decompressed(
+      SpdyFramerTestUtil::DecompressFrame(&recv_framer, syn_frame_1));
+  StringPiece serialized_headers =
+      GetSerializedHeaders(decompressed, send_framer);
+  SpdyHeaderBlock decompressed_headers;
   EXPECT_TRUE(recv_framer.ParseHeaderBlockInBuffer(serialized_headers.data(),
                                                    serialized_headers.size(),
                                                    &decompressed_headers));
@@ -1411,10 +1389,8 @@
   EXPECT_EQ(kValue2, decompressed_headers[kHeader2]);
 
   // Decompress SYN_STREAM #2
-  decompressed.reset(
-      SpdyFramerTestUtil::DecompressFrame(&recv_framer, *syn_frame_2));
-  EXPECT_TRUE(decompressed.get() != NULL);
-  serialized_headers = GetSerializedHeaders(decompressed.get(), send_framer);
+  decompressed = SpdyFramerTestUtil::DecompressFrame(&recv_framer, syn_frame_2);
+  serialized_headers = GetSerializedHeaders(decompressed, send_framer);
   decompressed_headers.clear();
   EXPECT_TRUE(recv_framer.ParseHeaderBlockInBuffer(serialized_headers.data(),
                                                    serialized_headers.size(),
@@ -1440,26 +1416,24 @@
   SpdyHeadersIR headers(1);
   headers.SetHeader(kHeader1, kValue1);
   headers.SetHeader(kHeader2, kValue2);
-  scoped_ptr<SpdyFrame> headers_frame(send_framer.SerializeHeaders(headers));
-  EXPECT_TRUE(headers_frame.get() != NULL);
+  SpdySerializedFrame headers_frame(send_framer.SerializeHeaders(headers));
 
   const char bytes[] = "this is a test test test test test!";
   SpdyDataIR data_ir(1, StringPiece(bytes, arraysize(bytes)));
   data_ir.set_fin(true);
-  scoped_ptr<SpdyFrame> send_frame(send_framer.SerializeData(data_ir));
-  EXPECT_TRUE(send_frame.get() != NULL);
+  SpdySerializedFrame send_frame(send_framer.SerializeData(data_ir));
 
   // Run the inputs through the framer.
   TestSpdyVisitor visitor(spdy_version_);
   visitor.use_compression_ = true;
   const unsigned char* data;
-  data = reinterpret_cast<const unsigned char*>(headers_frame->data());
-  for (size_t idx = 0; idx < headers_frame->size(); ++idx) {
+  data = reinterpret_cast<const unsigned char*>(headers_frame.data());
+  for (size_t idx = 0; idx < headers_frame.size(); ++idx) {
     visitor.SimulateInFramer(data + idx, 1);
     ASSERT_EQ(0, visitor.error_count_);
   }
-  data = reinterpret_cast<const unsigned char*>(send_frame->data());
-  for (size_t idx = 0; idx < send_frame->size(); ++idx) {
+  data = reinterpret_cast<const unsigned char*>(send_frame.data());
+  for (size_t idx = 0; idx < send_frame.size(); ++idx) {
     visitor.SimulateInFramer(data + idx, 1);
     ASSERT_EQ(0, visitor.error_count_);
   }
@@ -1477,8 +1451,8 @@
 
 TEST_P(SpdyFramerTest, WindowUpdateFrame) {
   SpdyFramer framer(spdy_version_);
-  scoped_ptr<SpdyFrame> frame(framer.SerializeWindowUpdate(
-      SpdyWindowUpdateIR(1, 0x12345678)));
+  SpdySerializedFrame frame(
+      framer.SerializeWindowUpdate(SpdyWindowUpdateIR(1, 0x12345678)));
 
   const char kDescription[] = "WINDOW_UPDATE frame, stream 1, delta 0x12345678";
   const unsigned char kV3FrameData[] = {
@@ -1495,9 +1469,9 @@
   };
 
   if (IsSpdy3()) {
-    CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+    CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
   } else {
-    CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+    CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
   }
 }
 
@@ -1529,19 +1503,19 @@
     const char bytes[] = "hello";
 
     SpdyDataIR data_ir(1, bytes);
-    scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
+    SpdySerializedFrame frame(framer.SerializeData(data_ir));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
 
     SpdyDataIR data_header_ir(1);
     data_header_ir.SetDataShallow(bytes);
-    frame.reset(framer.SerializeDataFrameHeaderWithPaddingLengthField(
-        data_header_ir));
+    frame =
+        framer.SerializeDataFrameHeaderWithPaddingLengthField(data_header_ir);
     CompareCharArraysWithHexError(
-        kDescription, reinterpret_cast<const unsigned char*>(frame->data()),
+        kDescription, reinterpret_cast<const unsigned char*>(frame.data()),
         framer.GetDataFrameMinimumSize(),
         IsSpdy3() ? kV3FrameData : kH2FrameData,
         framer.GetDataFrameMinimumSize());
@@ -1591,16 +1565,16 @@
     // 247 zeros and the pad length field make the overall padding to be 248
     // bytes.
     data_ir.set_padding_len(248);
-    scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
+    SpdySerializedFrame frame(framer.SerializeData(data_ir));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
 
-    frame.reset(framer.SerializeDataFrameHeaderWithPaddingLengthField(data_ir));
+    frame = framer.SerializeDataFrameHeaderWithPaddingLengthField(data_ir);
     CompareCharArraysWithHexError(
-        kDescription, reinterpret_cast<const unsigned char*>(frame->data()),
+        kDescription, reinterpret_cast<const unsigned char*>(frame.data()),
         framer.GetDataFrameMinimumSize(),
         IsSpdy3() ? kV3FrameData : kH2FrameData,
         framer.GetDataFrameMinimumSize());
@@ -1629,11 +1603,11 @@
     SpdyDataIR data_ir(1, bytes);
     // 7 zeros and the pad length field make the overall padding to be 8 bytes.
     data_ir.set_padding_len(8);
-    scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
+    SpdySerializedFrame frame(framer.SerializeData(data_ir));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
   }
 
@@ -1660,16 +1634,16 @@
     // The pad length field itself is used for the 1-byte padding and no padding
     // payload is needed.
     data_ir.set_padding_len(1);
-    scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
+    SpdySerializedFrame frame(framer.SerializeData(data_ir));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
 
-    frame.reset(framer.SerializeDataFrameHeaderWithPaddingLengthField(data_ir));
+    frame = framer.SerializeDataFrameHeaderWithPaddingLengthField(data_ir);
     CompareCharArraysWithHexError(
-        kDescription, reinterpret_cast<const unsigned char*>(frame->data()),
+        kDescription, reinterpret_cast<const unsigned char*>(frame.data()),
         framer.GetDataFrameMinimumSize(),
         IsSpdy3() ? kV3FrameData : kH2FrameData,
         framer.GetDataFrameMinimumSize());
@@ -1685,11 +1659,11 @@
     const unsigned char kH2FrameData[] = {
         0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff};
     SpdyDataIR data_ir(1, "\xff");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
+    SpdySerializedFrame frame(framer.SerializeData(data_ir));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
   }
 
@@ -1709,11 +1683,11 @@
     };
     SpdyDataIR data_ir(1, "hello");
     data_ir.set_fin(true);
-    scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
+    SpdySerializedFrame frame(framer.SerializeData(data_ir));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
   }
 
@@ -1728,16 +1702,16 @@
       0x01,
     };
     SpdyDataIR data_ir(1, "");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
+    SpdySerializedFrame frame(framer.SerializeData(data_ir));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
 
-    frame.reset(framer.SerializeDataFrameHeaderWithPaddingLengthField(data_ir));
+    frame = framer.SerializeDataFrameHeaderWithPaddingLengthField(data_ir);
     CompareCharArraysWithHexError(
-        kDescription, reinterpret_cast<const unsigned char*>(frame->data()),
+        kDescription, reinterpret_cast<const unsigned char*>(frame.data()),
         framer.GetDataFrameMinimumSize(),
         IsSpdy3() ? kV3FrameData : kH2FrameData,
         framer.GetDataFrameMinimumSize());
@@ -1759,11 +1733,11 @@
     };
     SpdyDataIR data_ir(0x7fffffff, "hello");
     data_ir.set_fin(true);
-    scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
+    SpdySerializedFrame frame(framer.SerializeData(data_ir));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
   }
 
@@ -1786,8 +1760,8 @@
 
     SpdyDataIR data_ir(1, kData);
     data_ir.set_fin(true);
-    scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
-    CompareFrame(kDescription, *frame, expected_frame_data.get(), kFrameSize);
+    SpdySerializedFrame frame(framer.SerializeData(data_ir));
+    CompareFrame(kDescription, frame, expected_frame_data.get(), kFrameSize);
   }
 }
 
@@ -1821,9 +1795,9 @@
     syn_stream.set_priority(framer.GetLowestPriority());
     syn_stream.SetHeader("bar", "foo");
     syn_stream.SetHeader("foo", "bar");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeSynStream(syn_stream));
+    SpdySerializedFrame frame(framer.SerializeSynStream(syn_stream));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
       LOG(FATAL) << "Unsupported version in test.";
     }
@@ -1854,9 +1828,9 @@
     syn_stream.set_fin(true);
     syn_stream.SetHeader("", "foo");
     syn_stream.SetHeader("foo", "bar");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeSynStream(syn_stream));
+    SpdySerializedFrame frame(framer.SerializeSynStream(syn_stream));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
       LOG(FATAL) << "Unsupported version in test.";
     }
@@ -1887,9 +1861,9 @@
     syn_stream.set_fin(true);
     syn_stream.SetHeader("bar", "foo");
     syn_stream.SetHeader("foo", "");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeSynStream(syn_stream));
+    SpdySerializedFrame frame(framer.SerializeSynStream(syn_stream));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
       LOG(FATAL) << "Unsupported version in test.";
     }
@@ -1951,18 +1925,14 @@
     syn_stream.set_priority(4);
     syn_stream.SetHeader("bar", "foo");
     syn_stream.SetHeader("foo", "bar");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeSynStream(syn_stream));
+    SpdySerializedFrame frame(framer.SerializeSynStream(syn_stream));
     const unsigned char* frame_data =
-        reinterpret_cast<const unsigned char*>(frame->data());
+        reinterpret_cast<const unsigned char*>(frame.data());
     if (IsSpdy3()) {
-      if (memcmp(frame_data,
-                 kV3SIMDFrameData,
-                 std::min(arraysize(kV3SIMDFrameData), frame->size())) != 0) {
-        CompareCharArraysWithHexError(kDescription,
-                                      frame_data,
-                                      frame->size(),
-                                      kV3FrameData,
-                                      arraysize(kV3FrameData));
+      if (memcmp(frame_data, kV3SIMDFrameData,
+                 std::min(arraysize(kV3SIMDFrameData), frame.size())) != 0) {
+        CompareCharArraysWithHexError(kDescription, frame_data, frame.size(),
+                                      kV3FrameData, arraysize(kV3FrameData));
       }
     } else {
       LOG(FATAL) << "Unsupported version in test.";
@@ -1998,9 +1968,9 @@
     SpdySynReplyIR syn_reply(1);
     syn_reply.SetHeader("bar", "foo");
     syn_reply.SetHeader("foo", "bar");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeSynReply(syn_reply));
+    SpdySerializedFrame frame(framer.SerializeSynReply(syn_reply));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
       LOG(FATAL) << "Unsupported version in test.";
     }
@@ -2027,9 +1997,9 @@
     syn_reply.set_fin(true);
     syn_reply.SetHeader("", "foo");
     syn_reply.SetHeader("foo", "bar");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeSynReply(syn_reply));
+    SpdySerializedFrame frame(framer.SerializeSynReply(syn_reply));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
       LOG(FATAL) << "Unsupported version in test.";
     }
@@ -2056,9 +2026,9 @@
     syn_reply.set_fin(true);
     syn_reply.SetHeader("bar", "foo");
     syn_reply.SetHeader("foo", "");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeSynReply(syn_reply));
+    SpdySerializedFrame frame(framer.SerializeSynReply(syn_reply));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
       LOG(FATAL) << "Unsupported version in test.";
     }
@@ -2115,18 +2085,14 @@
     SpdySynReplyIR syn_reply(1);
     syn_reply.SetHeader("bar", "foo");
     syn_reply.SetHeader("foo", "bar");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeSynReply(syn_reply));
+    SpdySerializedFrame frame(framer.SerializeSynReply(syn_reply));
     const unsigned char* frame_data =
-        reinterpret_cast<const unsigned char*>(frame->data());
+        reinterpret_cast<const unsigned char*>(frame.data());
     if (IsSpdy3()) {
-      if (memcmp(frame_data,
-                 kV3SIMDFrameData,
-                 std::min(arraysize(kV3SIMDFrameData), frame->size())) != 0) {
-        CompareCharArraysWithHexError(kDescription,
-                                      frame_data,
-                                      frame->size(),
-                                      kV3FrameData,
-                                      arraysize(kV3FrameData));
+      if (memcmp(frame_data, kV3SIMDFrameData,
+                 std::min(arraysize(kV3SIMDFrameData), frame.size())) != 0) {
+        CompareCharArraysWithHexError(kDescription, frame_data, frame.size(),
+                                      kV3FrameData, arraysize(kV3FrameData));
       }
     } else {
       LOG(FATAL) << "Unsupported version in test.";
@@ -2151,11 +2117,11 @@
         0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
     };
     SpdyRstStreamIR rst_stream(1, RST_STREAM_PROTOCOL_ERROR);
-    scoped_ptr<SpdyFrame> frame(framer.SerializeRstStream(rst_stream));
+    SpdySerializedFrame frame(framer.SerializeRstStream(rst_stream));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
   }
 
@@ -2174,11 +2140,11 @@
       0x01,
     };
     SpdyRstStreamIR rst_stream(0x7FFFFFFF, RST_STREAM_PROTOCOL_ERROR);
-    scoped_ptr<SpdyFrame> frame(framer.SerializeRstStream(rst_stream));
+    SpdySerializedFrame frame(framer.SerializeRstStream(rst_stream));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
   }
 
@@ -2197,11 +2163,11 @@
       0x02,
     };
     SpdyRstStreamIR rst_stream(0x7FFFFFFF, RST_STREAM_INTERNAL_ERROR);
-    scoped_ptr<SpdyFrame> frame(framer.SerializeRstStream(rst_stream));
+    SpdySerializedFrame frame(framer.SerializeRstStream(rst_stream));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
   }
 }
@@ -2236,11 +2202,11 @@
                            kFlags & SETTINGS_FLAG_PERSISTED,
                            kValue);
 
-    scoped_ptr<SpdyFrame> frame(framer.SerializeSettings(settings_ir));
+    SpdySerializedFrame frame(framer.SerializeSettings(settings_ir));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
   }
 
@@ -2293,12 +2259,12 @@
                            false,  // persist
                            false,  // persisted
                            8);
-    scoped_ptr<SpdyFrame> frame(framer.SerializeSettings(settings_ir));
+    SpdySerializedFrame frame(framer.SerializeSettings(settings_ir));
 
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
   }
 
@@ -2316,11 +2282,11 @@
       0x00,
     };
     SpdySettingsIR settings_ir;
-    scoped_ptr<SpdyFrame> frame(framer.SerializeSettings(settings_ir));
+    SpdySerializedFrame frame(framer.SerializeSettings(settings_ir));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
   }
 }
@@ -2349,24 +2315,23 @@
       0x78, 0x9a, 0xbc, 0xde,
       0xff,
     };
-    scoped_ptr<SpdyFrame> frame;
+    SpdySerializedFrame frame;
     if (IsSpdy3()) {
-      frame.reset(framer.SerializePing(SpdyPingIR(0x12345678ull)));
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      frame = framer.SerializePing(SpdyPingIR(0x12345678ull));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
       const SpdyPingId kPingId = 0x123456789abcdeffULL;
       SpdyPingIR ping_ir(kPingId);
       // Tests SpdyPingIR when the ping is not an ack.
       ASSERT_FALSE(ping_ir.is_ack());
-      frame.reset(framer.SerializePing(ping_ir));
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      frame = framer.SerializePing(ping_ir);
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
 
       // Tests SpdyPingIR when the ping is an ack.
       ping_ir.set_is_ack(true);
-      frame.reset(framer.SerializePing(ping_ir));
-      CompareFrame(kDescription, *frame, kH2FrameDataWithAck,
+      frame = framer.SerializePing(ping_ir);
+      CompareFrame(kDescription, frame, kH2FrameDataWithAck,
                    arraysize(kH2FrameDataWithAck));
-
     }
   }
 }
@@ -2390,11 +2355,11 @@
       0x00, 0x47, 0x41,        // Opaque Description
     };
     SpdyGoAwayIR goaway_ir(0, GOAWAY_OK, "GA");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeGoAway(goaway_ir));
+    SpdySerializedFrame frame(framer.SerializeGoAway(goaway_ir));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
   }
 
@@ -2414,11 +2379,11 @@
       0x02, 0x47, 0x41,        // Opaque Description
     };
     SpdyGoAwayIR goaway_ir(0x7FFFFFFF, GOAWAY_INTERNAL_ERROR, "GA");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeGoAway(goaway_ir));
+    SpdySerializedFrame frame(framer.SerializeGoAway(goaway_ir));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
   }
 }
@@ -2455,11 +2420,11 @@
     SpdyHeadersIR headers_ir(1);
     headers_ir.SetHeader("bar", "foo");
     headers_ir.SetHeader("foo", "bar");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers_ir));
+    SpdySerializedFrame frame(framer.SerializeHeaders(headers_ir));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
   }
 
@@ -2492,11 +2457,11 @@
     headers_ir.set_fin(true);
     headers_ir.SetHeader("", "foo");
     headers_ir.SetHeader("foo", "bar");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers_ir));
+    SpdySerializedFrame frame(framer.SerializeHeaders(headers_ir));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
   }
 
@@ -2529,11 +2494,11 @@
     headers_ir.set_fin(true);
      headers_ir.SetHeader("bar", "foo");
     headers_ir.SetHeader("foo", "");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers_ir));
+    SpdySerializedFrame frame(framer.SerializeHeaders(headers_ir));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
   }
 
@@ -2557,11 +2522,11 @@
     headers_ir.set_has_priority(true);
     headers_ir.SetHeader("bar", "foo");
     headers_ir.SetHeader("foo", "");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers_ir));
+    SpdySerializedFrame frame(framer.SerializeHeaders(headers_ir));
     if (IsSpdy3()) {
       // HEADERS with priority not supported.
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
   }
 
@@ -2588,11 +2553,11 @@
     headers_ir.set_parent_stream_id(0);
     headers_ir.SetHeader("bar", "foo");
     headers_ir.SetHeader("foo", "");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers_ir));
+    SpdySerializedFrame frame(framer.SerializeHeaders(headers_ir));
     if (IsSpdy3()) {
       // HEADERS with priority not supported.
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
   }
 
@@ -2619,11 +2584,11 @@
     headers_ir.set_parent_stream_id(0x7fffffff);
     headers_ir.SetHeader("bar", "foo");
     headers_ir.SetHeader("foo", "");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers_ir));
+    SpdySerializedFrame frame(framer.SerializeHeaders(headers_ir));
     if (IsSpdy3()) {
       // HEADERS with priority not supported.
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
   }
 
@@ -2648,11 +2613,11 @@
     headers_ir.SetHeader("", "foo");
     headers_ir.SetHeader("foo", "bar");
     headers_ir.set_padding_len(6);
-    scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers_ir));
+    SpdySerializedFrame frame(framer.SerializeHeaders(headers_ir));
     if (IsSpdy3()) {
       // Padding is not supported.
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
   }
 }
@@ -2703,18 +2668,14 @@
     SpdyHeadersIR headers_ir(1);
     headers_ir.SetHeader("bar", "foo");
     headers_ir.SetHeader("foo", "bar");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers_ir));
+    SpdySerializedFrame frame(framer.SerializeHeaders(headers_ir));
     const unsigned char* frame_data =
-        reinterpret_cast<const unsigned char*>(frame->data());
+        reinterpret_cast<const unsigned char*>(frame.data());
     if (IsSpdy3()) {
-      if (memcmp(frame_data,
-                 kV3SIMDFrameData,
-                 std::min(arraysize(kV3SIMDFrameData), frame->size())) != 0) {
-        CompareCharArraysWithHexError(kDescription,
-                                      frame_data,
-                                      frame->size(),
-                                      kV3FrameData,
-                                      arraysize(kV3FrameData));
+      if (memcmp(frame_data, kV3SIMDFrameData,
+                 std::min(arraysize(kV3SIMDFrameData), frame.size())) != 0) {
+        CompareCharArraysWithHexError(kDescription, frame_data, frame.size(),
+                                      kV3FrameData, arraysize(kV3FrameData));
       }
     } else {
       // Deflate compression doesn't apply to HPACK.
@@ -2740,12 +2701,12 @@
       0x01, 0x00, 0x00, 0x00,
       0x01,
     };
-    scoped_ptr<SpdyFrame> frame(
+    SpdySerializedFrame frame(
         framer.SerializeWindowUpdate(SpdyWindowUpdateIR(1, 1)));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
   }
 
@@ -2763,12 +2724,12 @@
       0xff, 0x00, 0x00, 0x00,
       0x01,
     };
-    scoped_ptr<SpdyFrame> frame(framer.SerializeWindowUpdate(
-        SpdyWindowUpdateIR(0x7FFFFFFF, 1)));
+    SpdySerializedFrame frame(
+        framer.SerializeWindowUpdate(SpdyWindowUpdateIR(0x7FFFFFFF, 1)));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
   }
 
@@ -2786,12 +2747,12 @@
       0x01, 0x7f, 0xff, 0xff,
       0xff,
     };
-    scoped_ptr<SpdyFrame> frame(framer.SerializeWindowUpdate(
-        SpdyWindowUpdateIR(1, 0x7FFFFFFF)));
+    SpdySerializedFrame frame(
+        framer.SerializeWindowUpdate(SpdyWindowUpdateIR(1, 0x7FFFFFFF)));
     if (IsSpdy3()) {
-      CompareFrame(kDescription, *frame, kV3FrameData, arraysize(kV3FrameData));
+      CompareFrame(kDescription, frame, kV3FrameData, arraysize(kV3FrameData));
     } else {
-      CompareFrame(kDescription, *frame, kH2FrameData, arraysize(kH2FrameData));
+      CompareFrame(kDescription, frame, kH2FrameData, arraysize(kH2FrameData));
     }
   }
 }
@@ -2811,8 +2772,8 @@
     0x00, 0x00, 0x00,  0x00,
   };
   SpdyBlockedIR blocked_ir(0);
-  scoped_ptr<SpdySerializedFrame> frame(framer.SerializeFrame(blocked_ir));
-  CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+  SpdySerializedFrame frame(framer.SerializeFrame(blocked_ir));
+  CompareFrame(kDescription, frame, kFrameData, arraysize(kFrameData));
 }
 
 TEST_P(SpdyFramerTest, CreateBlocked) {
@@ -2825,13 +2786,12 @@
   const char kDescription[] = "BLOCKED frame";
   const SpdyStreamId kStreamId = 3;
 
-  scoped_ptr<SpdySerializedFrame> frame_serialized(
+  SpdySerializedFrame frame_serialized(
       framer.SerializeBlocked(SpdyBlockedIR(kStreamId)));
   SpdyBlockedIR blocked_ir(kStreamId);
-  scoped_ptr<SpdySerializedFrame> frame_created(
-      framer.SerializeFrame(blocked_ir));
+  SpdySerializedFrame frame_created(framer.SerializeFrame(blocked_ir));
 
-  CompareFrames(kDescription, *frame_serialized, *frame_created);
+  CompareFrames(kDescription, frame_serialized, frame_created);
 }
 
 TEST_P(SpdyFramerTest, CreatePushPromiseUncompressed) {
@@ -2859,9 +2819,8 @@
     SpdyPushPromiseIR push_promise(42, 57);
     push_promise.SetHeader("bar", "foo");
     push_promise.SetHeader("foo", "bar");
-    scoped_ptr<SpdySerializedFrame> frame(
-        framer.SerializePushPromise(push_promise));
-    CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+    SpdySerializedFrame frame(framer.SerializePushPromise(push_promise));
+    CompareFrame(kDescription, frame, kFrameData, arraysize(kFrameData));
   }
 
   {
@@ -2885,9 +2844,8 @@
     push_promise.set_padding_len(1);
     push_promise.SetHeader("bar", "foo");
     push_promise.SetHeader("foo", "bar");
-    scoped_ptr<SpdySerializedFrame> frame(
-        framer.SerializePushPromise(push_promise));
-    CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+    SpdySerializedFrame frame(framer.SerializePushPromise(push_promise));
+    CompareFrame(kDescription, frame, kFrameData, arraysize(kFrameData));
   }
 
   {
@@ -2927,9 +2885,8 @@
     push_promise.set_padding_len(177);
     push_promise.SetHeader("bar", "foo");
     push_promise.SetHeader("foo", "bar");
-    scoped_ptr<SpdySerializedFrame> frame(
-        framer.SerializePushPromise(push_promise));
-    CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+    SpdySerializedFrame frame(framer.SerializePushPromise(push_promise));
+    CompareFrame(kDescription, frame, kFrameData, arraysize(kFrameData));
   }
 }
 
@@ -2973,9 +2930,8 @@
   continuation.SetHeader("bar", "foo");
   continuation.SetHeader("foo", "bar");
   continuation.set_end_headers(true);
-  scoped_ptr<SpdySerializedFrame> frame(
-    framer.SerializeContinuation(continuation));
-  CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+  SpdySerializedFrame frame(framer.SerializeContinuation(continuation));
+  CompareFrame(kDescription, frame, kFrameData, arraysize(kFrameData));
 }
 
 TEST_P(SpdyFramerTest, CreatePushPromiseThenContinuationUncompressed) {
@@ -3037,8 +2993,7 @@
     push_promise.set_padding_len(1);
     string big_value(TestSpdyVisitor::sent_control_frame_max_size(), 'x');
     push_promise.SetHeader("xxx", big_value);
-    scoped_ptr<SpdySerializedFrame> frame(
-        framer.SerializePushPromise(push_promise));
+    SpdySerializedFrame frame(framer.SerializePushPromise(push_promise));
 
     // The entire frame should look like below:
     // Name                     Length in Byte
@@ -3059,11 +3014,11 @@
     int len_non_data_payload = 31;
     EXPECT_EQ(
         TestSpdyVisitor::sent_control_frame_max_size() + len_non_data_payload,
-        frame->size());
+        frame.size());
 
     // Partially compare the PUSH_PROMISE frame against the template.
     const unsigned char* frame_data =
-        reinterpret_cast<const unsigned char*>(frame->data());
+        reinterpret_cast<const unsigned char*>(frame.data());
     CompareCharArraysWithHexError(kDescription,
                                   frame_data,
                                   arraysize(kPartialPushPromiseFrameData),
@@ -3106,8 +3061,8 @@
   altsvc_ir.add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
       "p\"=i:d", "h_\\o\"st", 123, 42, 0.2,
       SpdyAltSvcWireFormat::VersionVector{24}));
-  scoped_ptr<SpdySerializedFrame> frame(framer.SerializeFrame(altsvc_ir));
-  CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+  SpdySerializedFrame frame(framer.SerializeFrame(altsvc_ir));
+  CompareFrame(kDescription, frame, kFrameData, arraysize(kFrameData));
 }
 
 TEST_P(SpdyFramerTest, CreatePriority) {
@@ -3127,14 +3082,14 @@
       0x10,                    // Weight = 16
   };
   SpdyPriorityIR priority_ir(2, 1, 16, true);
-  scoped_ptr<SpdySerializedFrame> frame(framer.SerializeFrame(priority_ir));
-  CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+  SpdySerializedFrame frame(framer.SerializeFrame(priority_ir));
+  CompareFrame(kDescription, frame, kFrameData, arraysize(kFrameData));
   SpdyPriorityIR priority2(2);
   priority2.set_parent_stream_id(1);
   priority2.set_weight(16);
   priority2.set_exclusive(true);
-  frame.reset(framer.SerializeFrame(priority2));
-  CompareFrame(kDescription, *frame, kFrameData, arraysize(kFrameData));
+  frame = framer.SerializeFrame(priority2);
+  CompareFrame(kDescription, frame, kFrameData, arraysize(kFrameData));
 }
 
 TEST_P(SpdyFramerTest, ReadCompressedSynStreamHeaderBlock) {
@@ -3148,13 +3103,12 @@
   syn_stream.SetHeader("aa", "vv");
   syn_stream.SetHeader("bb", "ww");
   SpdyHeaderBlock headers = syn_stream.header_block();
-  scoped_ptr<SpdyFrame> control_frame(framer.SerializeSynStream(syn_stream));
-  EXPECT_TRUE(control_frame.get() != NULL);
+  SpdySerializedFrame control_frame(framer.SerializeSynStream(syn_stream));
   TestSpdyVisitor visitor(spdy_version_);
   visitor.use_compression_ = true;
   visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame->data()),
-      control_frame->size());
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
   EXPECT_EQ(1, visitor.syn_frame_count_);
   EXPECT_EQ(headers, visitor.headers_);
 }
@@ -3169,13 +3123,12 @@
   syn_reply.SetHeader("alpha", "beta");
   syn_reply.SetHeader("gamma", "delta");
   SpdyHeaderBlock headers = syn_reply.header_block();
-  scoped_ptr<SpdyFrame> control_frame(framer.SerializeSynReply(syn_reply));
-  EXPECT_TRUE(control_frame.get() != NULL);
+  SpdySerializedFrame control_frame(framer.SerializeSynReply(syn_reply));
   TestSpdyVisitor visitor(spdy_version_);
   visitor.use_compression_ = true;
   visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame->data()),
-      control_frame->size());
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
   EXPECT_EQ(1, visitor.syn_reply_frame_count_);
   EXPECT_EQ(0, visitor.headers_frame_count_);
   EXPECT_EQ(headers, visitor.headers_);
@@ -3187,13 +3140,12 @@
   headers_ir.SetHeader("alpha", "beta");
   headers_ir.SetHeader("gamma", "delta");
   SpdyHeaderBlock headers = headers_ir.header_block();
-  scoped_ptr<SpdyFrame> control_frame(framer.SerializeHeaders(headers_ir));
-  EXPECT_TRUE(control_frame.get() != NULL);
+  SpdySerializedFrame control_frame(framer.SerializeHeaders(headers_ir));
   TestSpdyVisitor visitor(spdy_version_);
   visitor.use_compression_ = true;
   visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame->data()),
-      control_frame->size());
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
   EXPECT_EQ(1, visitor.headers_frame_count_);
   // control_frame_header_data_count_ depends on the random sequence
   // produced by rand(), so adding, removing or running single tests
@@ -3212,13 +3164,12 @@
   headers_ir.SetHeader("alpha", "beta");
   headers_ir.SetHeader("gamma", "delta");
   SpdyHeaderBlock headers = headers_ir.header_block();
-  scoped_ptr<SpdyFrame> control_frame(framer.SerializeHeaders(headers_ir));
-  EXPECT_TRUE(control_frame.get() != NULL);
+  SpdySerializedFrame control_frame(framer.SerializeHeaders(headers_ir));
   TestSpdyVisitor visitor(spdy_version_);
   visitor.use_compression_ = true;
   visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame->data()),
-      control_frame->size());
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
   EXPECT_EQ(1, visitor.headers_frame_count_);
   // control_frame_header_data_count_ depends on the random sequence
   // produced by rand(), so adding, removing or running single tests
@@ -3243,22 +3194,21 @@
   SpdySynStreamIR syn_stream(1);
   syn_stream.set_priority(1);
   syn_stream.SetHeader("aa", "");
-  scoped_ptr<SpdyFrame> control_frame(framer.SerializeSynStream(syn_stream));
+  SpdySerializedFrame control_frame(framer.SerializeSynStream(syn_stream));
   const size_t kBigValueSize =
-      TestSpdyVisitor::sent_control_frame_max_size() - control_frame->size();
+      TestSpdyVisitor::sent_control_frame_max_size() - control_frame.size();
 
   // Create a frame at exactly that size.
   string big_value(kBigValueSize, 'x');
   syn_stream.SetHeader("aa", big_value);
-  control_frame.reset(framer.SerializeSynStream(syn_stream));
-  EXPECT_TRUE(control_frame.get() != NULL);
+  control_frame = framer.SerializeSynStream(syn_stream);
   EXPECT_EQ(TestSpdyVisitor::sent_control_frame_max_size(),
-            control_frame->size());
+            control_frame.size());
 
   TestSpdyVisitor visitor(spdy_version_);
   visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame->data()),
-      control_frame->size());
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
   EXPECT_TRUE(visitor.header_buffer_valid_);
   EXPECT_EQ(0, visitor.error_count_);
   EXPECT_EQ(1, visitor.syn_frame_count_);
@@ -3280,9 +3230,9 @@
   SpdySynStreamIR syn_stream(1);
   syn_stream.SetHeader("aa", "");
   syn_stream.set_priority(1);
-  scoped_ptr<SpdyFrame> control_frame(framer.SerializeSynStream(syn_stream));
+  SpdySerializedFrame control_frame(framer.SerializeSynStream(syn_stream));
   const size_t kBigValueSize =
-      SpdyConstants::GetFrameMaximumSize(spdy_version_) - control_frame->size();
+      SpdyConstants::GetFrameMaximumSize(spdy_version_) - control_frame.size();
 
   // Create a frame at exatly that size.
   string big_value(kBigValueSize, 'x');
@@ -3290,16 +3240,15 @@
   // Upstream branches here and wraps HTTP/2 with EXPECT_DEBUG_DFATAL. We
   // neither support that in Chromium, nor do we use the same DFATAL (see
   // SpdyFrameBuilder::WriteFramePrefix()).
-  control_frame.reset(framer.SerializeSynStream(syn_stream));
+  control_frame = framer.SerializeSynStream(syn_stream);
 
-  EXPECT_TRUE(control_frame.get() != NULL);
   EXPECT_EQ(SpdyConstants::GetFrameMaximumSize(spdy_version_),
-            control_frame->size());
+            control_frame.size());
 
   TestSpdyVisitor visitor(spdy_version_);
   visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame->data()),
-      control_frame->size());
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
   EXPECT_TRUE(visitor.header_buffer_valid_);
   EXPECT_EQ(0, visitor.error_count_);
   EXPECT_EQ(1, visitor.syn_frame_count_);
@@ -3320,15 +3269,14 @@
   const size_t kBigValueSize = TestSpdyVisitor::sent_control_frame_max_size();
   string big_value(kBigValueSize, 'x');
   headers.SetHeader("aa", big_value);
-  scoped_ptr<SpdyFrame> control_frame(framer.SerializeHeaders(headers));
-  EXPECT_TRUE(control_frame.get() != NULL);
-  EXPECT_GT(control_frame->size(),
+  SpdySerializedFrame control_frame(framer.SerializeHeaders(headers));
+  EXPECT_GT(control_frame.size(),
             TestSpdyVisitor::sent_control_frame_max_size());
 
   TestSpdyVisitor visitor(spdy_version_);
   visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame->data()),
-      control_frame->size());
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
   EXPECT_TRUE(visitor.header_buffer_valid_);
   EXPECT_EQ(0, visitor.error_count_);
   EXPECT_EQ(1, visitor.headers_frame_count_);
@@ -3351,16 +3299,14 @@
   const size_t kBigValueSize = TestSpdyVisitor::sent_control_frame_max_size();
   string big_value(kBigValueSize, 'x');
   push_promise.SetHeader("aa", big_value);
-  scoped_ptr<SpdyFrame> control_frame(
-      framer.SerializePushPromise(push_promise));
-  EXPECT_TRUE(control_frame.get() != NULL);
-  EXPECT_GT(control_frame->size(),
+  SpdySerializedFrame control_frame(framer.SerializePushPromise(push_promise));
+  EXPECT_GT(control_frame.size(),
             TestSpdyVisitor::sent_control_frame_max_size());
 
   TestSpdyVisitor visitor(spdy_version_);
   visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame->data()),
-      control_frame->size());
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
   EXPECT_TRUE(visitor.header_buffer_valid_);
   EXPECT_EQ(0, visitor.error_count_);
   EXPECT_EQ(1, visitor.push_promise_frame_count_);
@@ -3382,14 +3328,13 @@
   headers.set_priority(1);
   headers.set_fin(true);
   headers.SetHeader("aa", big_value);
-  scoped_ptr<SpdyFrame> control_frame(framer.SerializeHeaders(headers));
-  EXPECT_TRUE(control_frame.get() != NULL);
+  SpdySerializedFrame control_frame(framer.SerializeHeaders(headers));
   TestSpdyVisitor visitor(spdy_version_);
   visitor.set_header_buffer_size(kHeaderBufferSize);
   visitor.use_compression_ = true;
   visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame->data()),
-      control_frame->size());
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
   EXPECT_FALSE(visitor.header_buffer_valid_);
   EXPECT_EQ(1, visitor.error_count_);
   EXPECT_EQ(SpdyFramer::SPDY_CONTROL_PAYLOAD_TOO_LARGE,
@@ -3425,12 +3370,12 @@
   SpdySynStreamIR syn_stream(1);
   syn_stream.set_priority(1);
   syn_stream.SetHeader("aa", "alpha beta gamma delta");
-  scoped_ptr<SpdyFrame> control_frame(framer.SerializeSynStream(syn_stream));
+  SpdySerializedFrame control_frame(framer.SerializeSynStream(syn_stream));
   TestSpdyVisitor visitor(spdy_version_);
   visitor.use_compression_ = true;
   visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame->data()),
-      control_frame->size());
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
   EXPECT_EQ(1, visitor.error_count_);
   EXPECT_EQ(SpdyFramer::SPDY_DECOMPRESS_FAILURE, visitor.framer_.error_code())
       << SpdyFramer::ErrorCodeToString(framer.error_code());
@@ -3488,12 +3433,12 @@
 TEST_P(SpdyFramerTest, ReadZeroLenSettingsFrame) {
   SpdyFramer framer(spdy_version_);
   SpdySettingsIR settings_ir;
-  scoped_ptr<SpdyFrame> control_frame(framer.SerializeSettings(settings_ir));
-  SetFrameLength(control_frame.get(), 0, spdy_version_);
+  SpdySerializedFrame control_frame(framer.SerializeSettings(settings_ir));
+  SetFrameLength(&control_frame, 0, spdy_version_);
   TestSpdyVisitor visitor(spdy_version_);
   visitor.use_compression_ = false;
   visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame->data()),
+      reinterpret_cast<unsigned char*>(control_frame.data()),
       framer.GetControlFrameHeaderSize());
   if (IsSpdy3()) {
     // Should generate an error, since zero-len settings frames are unsupported.
@@ -3515,13 +3460,13 @@
                          false,
                          false,
                          0x00000002);
-  scoped_ptr<SpdyFrame> control_frame(framer.SerializeSettings(settings_ir));
+  SpdySerializedFrame control_frame(framer.SerializeSettings(settings_ir));
   const size_t kNewLength = 14;
-  SetFrameLength(control_frame.get(), kNewLength, spdy_version_);
+  SetFrameLength(&control_frame, kNewLength, spdy_version_);
   TestSpdyVisitor visitor(spdy_version_);
   visitor.use_compression_ = false;
   visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame->data()),
+      reinterpret_cast<unsigned char*>(control_frame.data()),
       framer.GetControlFrameHeaderSize() + kNewLength);
   // Should generate an error, since its not possible to have a
   // settings frame of length kNewLength.
@@ -3545,15 +3490,15 @@
                          false,  // persisted
                          7);
 
-  scoped_ptr<SpdyFrame> control_frame(framer.SerializeSettings(settings_ir));
-  EXPECT_LT(SpdyFramerPeer::ControlFrameBufferSize(), control_frame->size());
+  SpdySerializedFrame control_frame(framer.SerializeSettings(settings_ir));
+  EXPECT_LT(SpdyFramerPeer::ControlFrameBufferSize(), control_frame.size());
   TestSpdyVisitor visitor(spdy_version_);
   visitor.use_compression_ = false;
 
   // Read all at once.
   visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame->data()),
-      control_frame->size());
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
   EXPECT_EQ(0, visitor.error_count_);
   EXPECT_EQ(3, visitor.setting_count_);
   if (IsHttp2()) {
@@ -3562,12 +3507,12 @@
 
   // Read data in small chunks.
   size_t framed_data = 0;
-  size_t unframed_data = control_frame->size();
+  size_t unframed_data = control_frame.size();
   size_t kReadChunkSize = 5;  // Read five bytes at a time.
   while (unframed_data > 0) {
     size_t to_read = std::min(kReadChunkSize, unframed_data);
     visitor.SimulateInFramer(
-        reinterpret_cast<unsigned char*>(control_frame->data() + framed_data),
+        reinterpret_cast<unsigned char*>(control_frame.data() + framed_data),
         to_read);
     unframed_data -= to_read;
     framed_data += to_read;
@@ -3740,8 +3685,7 @@
 
   SpdyDataIR data_ir(1, data_payload);
   data_ir.set_padding_len(kPaddingLen);
-  scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
-  ASSERT_TRUE(frame.get() != NULL);
+  SpdySerializedFrame frame(framer.SerializeData(data_ir));
 
   int bytes_consumed = 0;
 
@@ -3750,55 +3694,54 @@
                                          kPaddingLen + strlen(data_payload),
                                          false));
   CHECK_EQ(framer.GetDataFrameMinimumSize(),
-           framer.ProcessInput(frame->data(),
-                               framer.GetDataFrameMinimumSize()));
+           framer.ProcessInput(frame.data(), framer.GetDataFrameMinimumSize()));
   CHECK_EQ(framer.state(), SpdyFramer::SPDY_READ_DATA_FRAME_PADDING_LENGTH);
   CHECK_EQ(framer.error_code(), SpdyFramer::SPDY_NO_ERROR);
   bytes_consumed += framer.GetDataFrameMinimumSize();
 
   // Send the padding length field.
   EXPECT_CALL(visitor, OnStreamPadding(1, 1));
-  CHECK_EQ(1u, framer.ProcessInput(frame->data() + bytes_consumed, 1));
+  CHECK_EQ(1u, framer.ProcessInput(frame.data() + bytes_consumed, 1));
   CHECK_EQ(framer.state(), SpdyFramer::SPDY_FORWARD_STREAM_FRAME);
   CHECK_EQ(framer.error_code(), SpdyFramer::SPDY_NO_ERROR);
   bytes_consumed += 1;
 
   // Send the first two bytes of the data payload, i.e., "he".
   EXPECT_CALL(visitor, OnStreamFrameData(1, _, 2, false));
-  CHECK_EQ(2u, framer.ProcessInput(frame->data() + bytes_consumed, 2));
+  CHECK_EQ(2u, framer.ProcessInput(frame.data() + bytes_consumed, 2));
   CHECK_EQ(framer.state(), SpdyFramer::SPDY_FORWARD_STREAM_FRAME);
   CHECK_EQ(framer.error_code(), SpdyFramer::SPDY_NO_ERROR);
   bytes_consumed += 2;
 
   // Send the rest three bytes of the data payload, i.e., "llo".
   EXPECT_CALL(visitor, OnStreamFrameData(1, _, 3, false));
-  CHECK_EQ(3u, framer.ProcessInput(frame->data() + bytes_consumed, 3));
+  CHECK_EQ(3u, framer.ProcessInput(frame.data() + bytes_consumed, 3));
   CHECK_EQ(framer.state(), SpdyFramer::SPDY_CONSUME_PADDING);
   CHECK_EQ(framer.error_code(), SpdyFramer::SPDY_NO_ERROR);
   bytes_consumed += 3;
 
   // Send the first 100 bytes of the padding payload.
   EXPECT_CALL(visitor, OnStreamPadding(1, 100));
-  CHECK_EQ(100u, framer.ProcessInput(frame->data() + bytes_consumed, 100));
+  CHECK_EQ(100u, framer.ProcessInput(frame.data() + bytes_consumed, 100));
   CHECK_EQ(framer.state(), SpdyFramer::SPDY_CONSUME_PADDING);
   CHECK_EQ(framer.error_code(), SpdyFramer::SPDY_NO_ERROR);
   bytes_consumed += 100;
 
   // Send rest of the padding payload.
   EXPECT_CALL(visitor, OnStreamPadding(1, 18));
-  CHECK_EQ(18u, framer.ProcessInput(frame->data() + bytes_consumed, 18));
+  CHECK_EQ(18u, framer.ProcessInput(frame.data() + bytes_consumed, 18));
   CHECK_EQ(framer.state(), SpdyFramer::SPDY_READY_FOR_FRAME);
   CHECK_EQ(framer.error_code(), SpdyFramer::SPDY_NO_ERROR);
 }
 
 TEST_P(SpdyFramerTest, ReadWindowUpdate) {
   SpdyFramer framer(spdy_version_);
-  scoped_ptr<SpdyFrame> control_frame(
+  SpdySerializedFrame control_frame(
       framer.SerializeWindowUpdate(SpdyWindowUpdateIR(1, 2)));
   TestSpdyVisitor visitor(spdy_version_);
   visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame->data()),
-      control_frame->size());
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
   EXPECT_EQ(1u, visitor.last_window_update_stream_);
   EXPECT_EQ(2, visitor.last_window_update_delta_);
 }
@@ -3813,14 +3756,11 @@
   push_promise.SetHeader("foo", "bar");
   push_promise.SetHeader("bar", "foofoo");
   SpdyHeaderBlock headers = push_promise.header_block();
-  scoped_ptr<SpdySerializedFrame> frame(
-    framer.SerializePushPromise(push_promise));
-  EXPECT_TRUE(frame.get() != NULL);
+  SpdySerializedFrame frame(framer.SerializePushPromise(push_promise));
   TestSpdyVisitor visitor(spdy_version_);
   visitor.use_compression_ = true;
-  visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(frame->data()),
-      frame->size());
+  visitor.SimulateInFramer(reinterpret_cast<unsigned char*>(frame.data()),
+                           frame.size());
   EXPECT_EQ(42u, visitor.last_push_promise_stream_);
   EXPECT_EQ(57u, visitor.last_push_promise_promised_stream_);
   EXPECT_EQ(headers, visitor.headers_);
@@ -4144,10 +4084,10 @@
                          false,  // persist
                          false,  // persisted
                          10);
-  scoped_ptr<SpdyFrame> control_frame(framer.SerializeSettings(settings_ir));
+  SpdySerializedFrame control_frame(framer.SerializeSettings(settings_ir));
   visitor.SimulateInFramer(
-      reinterpret_cast<unsigned char*>(control_frame->data()),
-      control_frame->size());
+      reinterpret_cast<unsigned char*>(control_frame.data()),
+      control_frame.size());
   EXPECT_EQ(0, visitor.error_count_);
   EXPECT_EQ(1u, static_cast<unsigned>(visitor.setting_count_));
   EXPECT_EQ(1u, static_cast<unsigned>(visitor.settings_ack_sent_));
@@ -4404,8 +4344,8 @@
     framer.set_visitor(&visitor);
 
     SpdyDataIR data_ir(1, "hello");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
-    SetFrameFlags(frame.get(), flags, spdy_version_);
+    SpdySerializedFrame frame(framer.SerializeData(data_ir));
+    SetFrameFlags(&frame, flags, spdy_version_);
 
     if (flags & ~DATA_FLAG_FIN) {
       EXPECT_CALL(visitor, OnError(_));
@@ -4417,7 +4357,7 @@
       }
     }
 
-    framer.ProcessInput(frame->data(), frame->size());
+    framer.ProcessInput(frame.data(), frame.size());
     if (flags & ~DATA_FLAG_FIN) {
       EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
       EXPECT_EQ(SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS, framer.error_code())
@@ -4446,8 +4386,8 @@
     framer.set_visitor(&visitor);
 
     SpdyDataIR data_ir(1, "hello");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
-    SetFrameFlags(frame.get(), flags, spdy_version_);
+    SpdySerializedFrame frame(framer.SerializeData(data_ir));
+    SetFrameFlags(&frame, flags, spdy_version_);
 
     if (flags & ~DATA_FLAG_FIN) {
       EXPECT_CALL(visitor, OnError(_));
@@ -4459,7 +4399,7 @@
       }
     }
 
-    framer.ProcessInput(frame->data(), frame->size());
+    framer.ProcessInput(frame.data(), frame.size());
     if (flags & ~DATA_FLAG_FIN) {
       EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
       EXPECT_EQ(SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS,
@@ -4492,8 +4432,8 @@
     framer.set_visitor(&visitor);
 
     SpdyDataIR data_ir(1, "hello");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
-    SetFrameFlags(frame.get(), flags, spdy_version_);
+    SpdySerializedFrame frame(framer.SerializeData(data_ir));
+    SetFrameFlags(&frame, flags, spdy_version_);
 
     if (flags & ~valid_data_flags) {
       EXPECT_CALL(visitor, OnError(_));
@@ -4512,7 +4452,7 @@
       }
     }
 
-    framer.ProcessInput(frame->data(), frame->size());
+    framer.ProcessInput(frame.data(), frame.size());
     if ((flags & ~valid_data_flags) || (flags & DATA_FLAG_PADDED)) {
       EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
       EXPECT_EQ(SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS, framer.error_code())
@@ -4544,8 +4484,8 @@
     framer.set_visitor(&visitor);
 
     SpdyDataIR data_ir(1, "hello");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeData(data_ir));
-    SetFrameFlags(frame.get(), flags, spdy_version_);
+    SpdySerializedFrame frame(framer.SerializeData(data_ir));
+    SetFrameFlags(&frame, flags, spdy_version_);
 
     if (flags & ~valid_data_flags) {
       EXPECT_CALL(visitor, OnError(_));
@@ -4564,7 +4504,7 @@
       }
     }
 
-    framer.ProcessInput(frame->data(), frame->size());
+    framer.ProcessInput(frame.data(), frame.size());
     if ((flags & ~valid_data_flags) || (flags & DATA_FLAG_PADDED)) {
       EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
       EXPECT_EQ(SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS, framer.error_code())
@@ -4600,8 +4540,8 @@
     syn_stream.set_associated_to_stream_id(3);
     syn_stream.set_priority(1);
     syn_stream.SetHeader("foo", "bar");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeSynStream(syn_stream));
-    SetFrameFlags(frame.get(), flags, spdy_version_);
+    SpdySerializedFrame frame(framer.SerializeSynStream(syn_stream));
+    SetFrameFlags(&frame, flags, spdy_version_);
 
     if (flags & ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) {
       EXPECT_CALL(visitor, OnError(_));
@@ -4619,7 +4559,7 @@
       }
     }
 
-    framer.ProcessInput(frame->data(), frame->size());
+    framer.ProcessInput(frame.data(), frame.size());
     if (flags & ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) {
       EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
       EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
@@ -4656,8 +4596,8 @@
     syn_stream.set_associated_to_stream_id(3);
     syn_stream.set_priority(1);
     syn_stream.SetHeader("foo", "bar");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeSynStream(syn_stream));
-    SetFrameFlags(frame.get(), flags, spdy_version_);
+    SpdySerializedFrame frame(framer.SerializeSynStream(syn_stream));
+    SetFrameFlags(&frame, flags, spdy_version_);
 
     if (flags & ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) {
       EXPECT_CALL(visitor, OnError(_));
@@ -4675,7 +4615,7 @@
       }
     }
 
-    framer.ProcessInput(frame->data(), frame->size());
+    framer.ProcessInput(frame.data(), frame.size());
     if (flags & ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) {
       EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
       EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
@@ -4706,8 +4646,8 @@
 
     SpdySynReplyIR syn_reply(37);
     syn_reply.SetHeader("foo", "bar");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeSynReply(syn_reply));
-    SetFrameFlags(frame.get(), flags, spdy_version_);
+    SpdySerializedFrame frame(framer.SerializeSynReply(syn_reply));
+    SetFrameFlags(&frame, flags, spdy_version_);
 
     if (flags & ~CONTROL_FLAG_FIN) {
       EXPECT_CALL(visitor, OnError(_));
@@ -4720,7 +4660,7 @@
       }
     }
 
-    framer.ProcessInput(frame->data(), frame->size());
+    framer.ProcessInput(frame.data(), frame.size());
     if (flags & ~CONTROL_FLAG_FIN) {
       EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
       EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
@@ -4751,8 +4691,8 @@
 
     SpdySynReplyIR syn_reply(37);
     syn_reply.SetHeader("foo", "bar");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeSynReply(syn_reply));
-    SetFrameFlags(frame.get(), flags, spdy_version_);
+    SpdySerializedFrame frame(framer.SerializeSynReply(syn_reply));
+    SetFrameFlags(&frame, flags, spdy_version_);
 
     if (flags & ~CONTROL_FLAG_FIN) {
       EXPECT_CALL(visitor, OnError(_));
@@ -4765,7 +4705,7 @@
       }
     }
 
-    framer.ProcessInput(frame->data(), frame->size());
+    framer.ProcessInput(frame.data(), frame.size());
     if (flags & ~CONTROL_FLAG_FIN) {
       EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
       EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
@@ -4789,8 +4729,8 @@
     framer.set_visitor(&visitor);
 
     SpdyRstStreamIR rst_stream(13, RST_STREAM_CANCEL);
-    scoped_ptr<SpdyFrame> frame(framer.SerializeRstStream(rst_stream));
-    SetFrameFlags(frame.get(), flags, spdy_version_);
+    SpdySerializedFrame frame(framer.SerializeRstStream(rst_stream));
+    SetFrameFlags(&frame, flags, spdy_version_);
 
     if (flags != 0) {
       EXPECT_CALL(visitor, OnError(_));
@@ -4798,7 +4738,7 @@
       EXPECT_CALL(visitor, OnRstStream(13, RST_STREAM_CANCEL));
     }
 
-    framer.ProcessInput(frame->data(), frame->size());
+    framer.ProcessInput(frame.data(), frame.size());
     if (flags != 0) {
       EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
       EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
@@ -4830,8 +4770,8 @@
                            false,
                            false,
                            54321);
-    scoped_ptr<SpdyFrame> frame(framer.SerializeSettings(settings_ir));
-    SetFrameFlags(frame.get(), flags, spdy_version_);
+    SpdySerializedFrame frame(framer.SerializeSettings(settings_ir));
+    SetFrameFlags(&frame, flags, spdy_version_);
 
     if (flags & ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) {
       EXPECT_CALL(visitor, OnError(_));
@@ -4843,7 +4783,7 @@
       EXPECT_CALL(visitor, OnSettingsEnd());
     }
 
-    framer.ProcessInput(frame->data(), frame->size());
+    framer.ProcessInput(frame.data(), frame.size());
     if (flags & ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) {
       EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
       EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
@@ -4872,8 +4812,8 @@
 
     SpdySettingsIR settings_ir;
     settings_ir.AddSetting(SETTINGS_INITIAL_WINDOW_SIZE, 0, 0, 16);
-    scoped_ptr<SpdyFrame> frame(framer.SerializeSettings(settings_ir));
-    SetFrameFlags(frame.get(), flags, spdy_version_);
+    SpdySerializedFrame frame(framer.SerializeSettings(settings_ir));
+    SetFrameFlags(&frame, flags, spdy_version_);
 
     if (flags != 0) {
       EXPECT_CALL(visitor, OnError(_));
@@ -4883,7 +4823,7 @@
       EXPECT_CALL(visitor, OnSettingsEnd());
     }
 
-    framer.ProcessInput(frame->data(), frame->size());
+    framer.ProcessInput(frame.data(), frame.size());
     if (flags & ~SETTINGS_FLAG_ACK) {
       EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
       EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
@@ -4913,8 +4853,8 @@
     framer.set_visitor(&visitor);
 
     SpdyGoAwayIR goaway_ir(97, GOAWAY_OK, "test");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeGoAway(goaway_ir));
-    SetFrameFlags(frame.get(), flags, spdy_version_);
+    SpdySerializedFrame frame(framer.SerializeGoAway(goaway_ir));
+    SetFrameFlags(&frame, flags, spdy_version_);
 
     if (flags != 0) {
       EXPECT_CALL(visitor, OnError(_));
@@ -4922,7 +4862,7 @@
       EXPECT_CALL(visitor, OnGoAway(97, GOAWAY_OK));
     }
 
-    framer.ProcessInput(frame->data(), frame->size());
+    framer.ProcessInput(frame.data(), frame.size());
     if (flags != 0) {
       EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
       EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
@@ -4955,14 +4895,14 @@
       headers_ir.set_exclusive(true);
     }
     headers_ir.SetHeader("foo", "bar");
-    std::unique_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers_ir));
+    SpdySerializedFrame frame(framer.SerializeHeaders(headers_ir));
     uint8_t set_flags = flags;
     if (IsHttp2()) {
       // TODO(jgraettinger): Add padding to SpdyHeadersIR,
       // and implement framing.
       set_flags &= ~HEADERS_FLAG_PADDED;
     }
-    SetFrameFlags(frame.get(), set_flags, spdy_version_);
+    SetFrameFlags(&frame, set_flags, spdy_version_);
 
     if (!IsHttp2() && flags & ~CONTROL_FLAG_FIN) {
       EXPECT_CALL(visitor, OnError(_));
@@ -5000,7 +4940,7 @@
       }
     }
 
-    framer.ProcessInput(frame->data(), frame->size());
+    framer.ProcessInput(frame.data(), frame.size());
     if (IsSpdy3() && flags & ~CONTROL_FLAG_FIN) {
       EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
       EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
@@ -5046,14 +4986,14 @@
       headers_ir.set_exclusive(true);
     }
     headers_ir.SetHeader("foo", "bar");
-    scoped_ptr<SpdyFrame> frame(framer.SerializeHeaders(headers_ir));
+    SpdySerializedFrame frame(framer.SerializeHeaders(headers_ir));
     uint8_t set_flags = flags;
     if (IsHttp2()) {
       // TODO(jgraettinger): Add padding to SpdyHeadersIR,
       // and implement framing.
       set_flags &= ~HEADERS_FLAG_PADDED;
     }
-    SetFrameFlags(frame.get(), set_flags, spdy_version_);
+    SetFrameFlags(&frame, set_flags, spdy_version_);
 
     if (!IsHttp2() && flags & ~CONTROL_FLAG_FIN) {
       EXPECT_CALL(visitor, OnError(_));
@@ -5091,7 +5031,7 @@
       }
     }
 
-    framer.ProcessInput(frame->data(), frame->size());
+    framer.ProcessInput(frame.data(), frame.size());
     if (IsSpdy3() && flags & ~CONTROL_FLAG_FIN) {
       EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
       EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
@@ -5127,8 +5067,8 @@
     SpdyFramer framer(spdy_version_);
     framer.set_visitor(&visitor);
 
-    scoped_ptr<SpdyFrame> frame(framer.SerializePing(SpdyPingIR(42)));
-    SetFrameFlags(frame.get(), flags, spdy_version_);
+    SpdySerializedFrame frame(framer.SerializePing(SpdyPingIR(42)));
+    SetFrameFlags(&frame, flags, spdy_version_);
 
     if (IsHttp2() && flags == PING_FLAG_ACK) {
       EXPECT_CALL(visitor, OnPing(42, true));
@@ -5138,7 +5078,7 @@
       EXPECT_CALL(visitor, OnError(_));
     }
 
-    framer.ProcessInput(frame->data(), frame->size());
+    framer.ProcessInput(frame.data(), frame.size());
     if ((IsHttp2() && flags == PING_FLAG_ACK) || flags == 0) {
       EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state());
       EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
@@ -5161,9 +5101,9 @@
     SpdyFramer framer(spdy_version_);
     framer.set_visitor(&visitor);
 
-    scoped_ptr<SpdyFrame> frame(framer.SerializeWindowUpdate(
-        SpdyWindowUpdateIR(4, 1024)));
-    SetFrameFlags(frame.get(), flags, spdy_version_);
+    SpdySerializedFrame frame(
+        framer.SerializeWindowUpdate(SpdyWindowUpdateIR(4, 1024)));
+    SetFrameFlags(&frame, flags, spdy_version_);
 
     if (flags != 0) {
       EXPECT_CALL(visitor, OnError(_));
@@ -5171,7 +5111,7 @@
       EXPECT_CALL(visitor, OnWindowUpdate(4, 1024));
     }
 
-    framer.ProcessInput(frame->data(), frame->size());
+    framer.ProcessInput(frame.data(), frame.size());
     if (flags != 0) {
       EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
       EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
@@ -5204,11 +5144,10 @@
 
     SpdyPushPromiseIR push_promise(42, 57);
     push_promise.SetHeader("foo", "bar");
-    scoped_ptr<SpdySerializedFrame> frame(
-    framer.SerializePushPromise(push_promise));
+    SpdySerializedFrame frame(framer.SerializePushPromise(push_promise));
     // TODO(jgraettinger): Add padding to SpdyPushPromiseIR,
     // and implement framing.
-    SetFrameFlags(frame.get(), flags & ~HEADERS_FLAG_PADDED, spdy_version_);
+    SetFrameFlags(&frame, flags & ~HEADERS_FLAG_PADDED, spdy_version_);
 
     if (flags & ~(PUSH_PROMISE_FLAG_END_PUSH_PROMISE | HEADERS_FLAG_PADDED)) {
       EXPECT_CALL(visitor, OnError(_));
@@ -5220,7 +5159,7 @@
           .WillRepeatedly(testing::Return(true));
     }
 
-    framer.ProcessInput(frame->data(), frame->size());
+    framer.ProcessInput(frame.data(), frame.size());
     if (flags & ~(PUSH_PROMISE_FLAG_END_PUSH_PROMISE | HEADERS_FLAG_PADDED)) {
       EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
       EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
@@ -5257,14 +5196,13 @@
 
     SpdyHeadersIR headers_ir(42);
     headers_ir.SetHeader("foo", "bar");
-    scoped_ptr<SpdyFrame> frame0(framer.SerializeHeaders(headers_ir));
-    SetFrameFlags(frame0.get(), 0, spdy_version_);
+    SpdySerializedFrame frame0(framer.SerializeHeaders(headers_ir));
+    SetFrameFlags(&frame0, 0, spdy_version_);
 
     SpdyContinuationIR continuation(42);
     continuation.SetHeader("foo", "bar");
-    scoped_ptr<SpdySerializedFrame> frame(
-    framer.SerializeContinuation(continuation));
-    SetFrameFlags(frame.get(), flags, spdy_version_);
+    SpdySerializedFrame frame(framer.SerializeContinuation(continuation));
+    SetFrameFlags(&frame, flags, spdy_version_);
 
     if (flags & ~(HEADERS_FLAG_END_HEADERS)) {
       EXPECT_CALL(visitor, OnError(_));
@@ -5276,8 +5214,8 @@
           .WillRepeatedly(testing::Return(true));
     }
 
-    framer.ProcessInput(frame0->data(), frame0->size());
-    framer.ProcessInput(frame->data(), frame->size());
+    framer.ProcessInput(frame0.data(), frame0.size());
+    framer.ProcessInput(frame.data(), frame.size());
     if (flags & ~(HEADERS_FLAG_END_HEADERS)) {
       EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
       EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS,
@@ -5310,18 +5248,17 @@
 
   SpdySynStreamIR syn_stream(1);
   syn_stream.set_priority(1);
-  scoped_ptr<SpdyFrame> frame(framer.SerializeSynStream(syn_stream));
+  SpdySerializedFrame frame(framer.SerializeSynStream(syn_stream));
   // Adjust size to remove the header block.
-  SetFrameLength(
-      frame.get(),
-      framer.GetSynStreamMinimumSize() - framer.GetControlFrameHeaderSize(),
-      spdy_version_);
+  SetFrameLength(&frame, framer.GetSynStreamMinimumSize() -
+                             framer.GetControlFrameHeaderSize(),
+                 spdy_version_);
 
   EXPECT_CALL(debug_visitor, OnReceiveCompressedFrame(1, SYN_STREAM, _));
   EXPECT_CALL(visitor, OnSynStream(1, 0, 1, false, false));
   EXPECT_CALL(visitor, OnControlFrameHeaderData(1, NULL, 0));
 
-  framer.ProcessInput(frame->data(), framer.GetSynStreamMinimumSize());
+  framer.ProcessInput(frame.data(), framer.GetSynStreamMinimumSize());
   EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state());
   EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
       << SpdyFramer::ErrorCodeToString(framer.error_code());
@@ -5486,8 +5423,8 @@
   EXPECT_CALL(visitor, OnBlocked(kStreamId));
 
   SpdyBlockedIR blocked_ir(0);
-  scoped_ptr<SpdySerializedFrame> frame(framer.SerializeFrame(blocked_ir));
-  framer.ProcessInput(frame->data(), framer.GetBlockedSize());
+  SpdySerializedFrame frame(framer.SerializeFrame(blocked_ir));
+  framer.ProcessInput(frame.data(), framer.GetBlockedSize());
 
   EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state());
   EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
@@ -5520,8 +5457,8 @@
   altsvc_ir.set_origin("o_r|g!n");
   altsvc_ir.add_altsvc(altsvc1);
   altsvc_ir.add_altsvc(altsvc2);
-  scoped_ptr<SpdySerializedFrame> frame(framer.SerializeFrame(altsvc_ir));
-  framer.ProcessInput(frame->data(), frame->size());
+  SpdySerializedFrame frame(framer.SerializeFrame(altsvc_ir));
+  framer.ProcessInput(frame.data(), frame.size());
 
   EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state());
   EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
@@ -5552,8 +5489,8 @@
   SpdyAltSvcIR altsvc_ir(1);
   altsvc_ir.add_altsvc(altsvc1);
   altsvc_ir.add_altsvc(altsvc2);
-  scoped_ptr<SpdySerializedFrame> frame(framer.SerializeFrame(altsvc_ir));
-  framer.ProcessInput(frame->data(), frame->size());
+  SpdySerializedFrame frame(framer.SerializeFrame(altsvc_ir));
+  framer.ProcessInput(frame.data(), frame.size());
 
   EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state());
   EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
@@ -5577,8 +5514,8 @@
       "pid1", "host", 443, 5, 1.0, SpdyAltSvcWireFormat::VersionVector()));
   altsvc_ir.add_altsvc(SpdyAltSvcWireFormat::AlternativeService(
       "", "h1", 443, 10, 1.0, SpdyAltSvcWireFormat::VersionVector()));
-  scoped_ptr<SpdySerializedFrame> frame(framer.SerializeFrame(altsvc_ir));
-  framer.ProcessInput(frame->data(), frame->size());
+  SpdySerializedFrame frame(framer.SerializeFrame(altsvc_ir));
+  framer.ProcessInput(frame.data(), frame.size());
 
   EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state());
   EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME, framer.error_code())
@@ -5605,8 +5542,8 @@
   SpdyAltSvcIR altsvc_ir(1);
   altsvc_ir.set_origin("o1");
   altsvc_ir.add_altsvc(altsvc);
-  scoped_ptr<SpdySerializedFrame> frame(framer.SerializeFrame(altsvc_ir));
-  framer.ProcessInput(frame->data(), frame->size());
+  SpdySerializedFrame frame(framer.SerializeFrame(altsvc_ir));
+  framer.ProcessInput(frame.data(), frame.size());
 
   EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state());
   EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
@@ -5629,18 +5566,18 @@
   altsvc_ir.add_altsvc(altsvc1);
   altsvc_ir.add_altsvc(altsvc2);
 
-  scoped_ptr<SpdyFrame> control_frame(framer.SerializeAltSvc(altsvc_ir));
+  SpdySerializedFrame control_frame(framer.SerializeAltSvc(altsvc_ir));
   TestSpdyVisitor visitor(spdy_version_);
   visitor.use_compression_ = false;
 
   // Read data in small chunks.
   size_t framed_data = 0;
-  size_t unframed_data = control_frame->size();
+  size_t unframed_data = control_frame.size();
   size_t kReadChunkSize = 5;  // Read five bytes at a time.
   while (unframed_data > 0) {
     size_t to_read = std::min(kReadChunkSize, unframed_data);
     visitor.SimulateInFramer(
-        reinterpret_cast<unsigned char*>(control_frame->data() + framed_data),
+        reinterpret_cast<unsigned char*>(control_frame.data() + framed_data),
         to_read);
     unframed_data -= to_read;
     framed_data += to_read;
@@ -5660,11 +5597,11 @@
 
   SpdyFramer framer(spdy_version_);
   SpdyPriorityIR priority(3, 1, 255, false);
-  scoped_ptr<SpdySerializedFrame> frame(framer.SerializePriority(priority));
+  SpdySerializedFrame frame(framer.SerializePriority(priority));
   testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
   framer.set_visitor(&visitor);
   EXPECT_CALL(visitor, OnPriority(3, 1, 255, false));
-  framer.ProcessInput(frame->data(), frame->size());
+  framer.ProcessInput(frame.data(), frame.size());
 
   EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state());
   EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code())
@@ -5741,26 +5678,26 @@
   headers.SetHeader("alpha", "beta");
   headers.SetHeader("gamma", "charlie");
   headers.SetHeader("cookie", "key1=value1; key2=value2");
-  scoped_ptr<SpdyFrame> headers_frame(framer.SerializeHeaders(headers));
+  SpdySerializedFrame headers_frame(framer.SerializeHeaders(headers));
 
   const char four_score[] = "Four score and seven years ago";
   SpdyDataIR four_score_ir(1, four_score);
-  scoped_ptr<SpdyFrame> four_score_frame(framer.SerializeData(four_score_ir));
+  SpdySerializedFrame four_score_frame(framer.SerializeData(four_score_ir));
 
   // Put them in a single buffer (new variables here to make it easy to
   // change the order and type of frames).
-  SpdyFrame* frame1 = headers_frame.get();
-  SpdyFrame* frame2 = four_score_frame.get();
+  SpdySerializedFrame frame1 = std::move(headers_frame);
+  SpdySerializedFrame frame2 = std::move(four_score_frame);
 
-  const size_t frame1_size = frame1->size();
-  const size_t frame2_size = frame2->size();
+  const size_t frame1_size = frame1.size();
+  const size_t frame2_size = frame2.size();
 
   LOG(INFO) << "frame1_size = " << frame1_size;
   LOG(INFO) << "frame2_size = " << frame2_size;
 
   string input_buffer;
-  input_buffer.append(frame1->data(), frame1_size);
-  input_buffer.append(frame2->data(), frame2_size);
+  input_buffer.append(frame1.data(), frame1_size);
+  input_buffer.append(frame2.data(), frame2_size);
 
   const char* buf = input_buffer.data();
   const size_t buf_size = input_buffer.size();
@@ -5787,28 +5724,28 @@
   // Create two input frames.
   const char four_score[] = "Four score and ...";
   SpdyDataIR four_score_ir(1, four_score);
-  scoped_ptr<SpdyFrame> four_score_frame(framer.SerializeData(four_score_ir));
+  SpdySerializedFrame four_score_frame(framer.SerializeData(four_score_ir));
 
   SpdyHeadersIR headers(2);
   headers.SetHeader("alpha", "beta");
   headers.SetHeader("gamma", "charlie");
   headers.SetHeader("cookie", "key1=value1; key2=value2");
-  scoped_ptr<SpdyFrame> headers_frame(framer.SerializeHeaders(headers));
+  SpdySerializedFrame headers_frame(framer.SerializeHeaders(headers));
 
   // Put them in a single buffer (new variables here to make it easy to
   // change the order and type of frames).
-  SpdyFrame* frame1 = four_score_frame.get();
-  SpdyFrame* frame2 = headers_frame.get();
+  SpdySerializedFrame frame1 = std::move(four_score_frame);
+  SpdySerializedFrame frame2 = std::move(headers_frame);
 
-  const size_t frame1_size = frame1->size();
-  const size_t frame2_size = frame2->size();
+  const size_t frame1_size = frame1.size();
+  const size_t frame2_size = frame2.size();
 
   LOG(INFO) << "frame1_size = " << frame1_size;
   LOG(INFO) << "frame2_size = " << frame2_size;
 
   string input_buffer;
-  input_buffer.append(frame1->data(), frame1_size);
-  input_buffer.append(frame2->data(), frame2_size);
+  input_buffer.append(frame1.data(), frame1_size);
+  input_buffer.append(frame2.data(), frame2_size);
 
   const char* buf = input_buffer.data();
   const size_t buf_size = input_buffer.size();
diff --git a/net/spdy/spdy_http_stream_unittest.cc b/net/spdy/spdy_http_stream_unittest.cc
index 9bd5a703..9ef70cede 100644
--- a/net/spdy/spdy_http_stream_unittest.cc
+++ b/net/spdy/spdy_http_stream_unittest.cc
@@ -162,12 +162,13 @@
 }
 
 TEST_P(SpdyHttpStreamTest, SendRequest) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite writes[] = {
       CreateMockWrite(*req.get(), 0),
   };
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   MockRead reads[] = {
       CreateMockRead(*resp, 1), MockRead(SYNCHRONOUS, 0, 2)  // EOF
   };
@@ -222,21 +223,21 @@
 }
 
 TEST_P(SpdyHttpStreamTest, LoadTimingTwoRequests) {
-  scoped_ptr<SpdyFrame> req1(
+  scoped_ptr<SpdySerializedFrame> req1(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true));
   MockWrite writes[] = {
     CreateMockWrite(*req1, 0),
     CreateMockWrite(*req2, 1),
   };
-  scoped_ptr<SpdyFrame> resp1(
+  scoped_ptr<SpdySerializedFrame> resp1(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body1(
+  scoped_ptr<SpdySerializedFrame> body1(
       spdy_util_.ConstructSpdyBodyFrame(1, "", 0, true));
-  scoped_ptr<SpdyFrame> resp2(
+  scoped_ptr<SpdySerializedFrame> resp2(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
-  scoped_ptr<SpdyFrame> body2(
+  scoped_ptr<SpdySerializedFrame> body2(
       spdy_util_.ConstructSpdyBodyFrame(3, "", 0, true));
   MockRead reads[] = {
     CreateMockRead(*resp1, 2),
@@ -324,16 +325,17 @@
 TEST_P(SpdyHttpStreamTest, SendChunkedPost) {
   BufferedSpdyFramer framer(spdy_util_.spdy_version());
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
-  scoped_ptr<SpdyFrame> body(
+  scoped_ptr<SpdySerializedFrame> body(
       framer.CreateDataFrame(1, kUploadData, kUploadDataSize, DATA_FLAG_FIN));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0),  // request
       CreateMockWrite(*body, 1)  // POST upload frame
   };
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
   MockRead reads[] = {
       CreateMockRead(*resp, 2),
       CreateMockRead(*body, 3),
@@ -388,15 +390,17 @@
 TEST_P(SpdyHttpStreamTest, ConnectionClosedDuringChunkedPost) {
   BufferedSpdyFramer framer(spdy_util_.spdy_version());
 
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
-  scoped_ptr<SpdyFrame> body(
+  scoped_ptr<SpdySerializedFrame> req(
+      spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> body(
       framer.CreateDataFrame(1, kUploadData, kUploadDataSize, DATA_FLAG_NONE));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0),  // Request
       CreateMockWrite(*body, 1)  // First POST upload frame
   };
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
   MockRead reads[] = {
       MockRead(ASYNC, ERR_CONNECTION_CLOSED, 2)  // Server hangs up early.
   };
@@ -457,19 +461,22 @@
 TEST_P(SpdyHttpStreamTest, DelayedSendChunkedPost) {
   const char kUploadData1[] = "12345678";
   const int kUploadData1Size = arraysize(kUploadData1)-1;
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
-  scoped_ptr<SpdyFrame> chunk1(spdy_util_.ConstructSpdyBodyFrame(1, false));
-  scoped_ptr<SpdyFrame> chunk2(
-      spdy_util_.ConstructSpdyBodyFrame(
-          1, kUploadData1, kUploadData1Size, false));
-  scoped_ptr<SpdyFrame> chunk3(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> req(
+      spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> chunk1(
+      spdy_util_.ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdySerializedFrame> chunk2(spdy_util_.ConstructSpdyBodyFrame(
+      1, kUploadData1, kUploadData1Size, false));
+  scoped_ptr<SpdySerializedFrame> chunk3(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockWrite writes[] = {
     CreateMockWrite(*req.get(), 0),
     CreateMockWrite(*chunk1, 1),  // POST upload frames
     CreateMockWrite(*chunk2, 2),
     CreateMockWrite(*chunk3, 3),
   };
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
   MockRead reads[] = {
     CreateMockRead(*resp, 4),
     CreateMockRead(*chunk1, 5),
@@ -557,16 +564,19 @@
 // Test that the SpdyStream state machine can handle sending a final empty data
 // frame when uploading a chunked data stream.
 TEST_P(SpdyHttpStreamTest, DelayedSendChunkedPostWithEmptyFinalDataFrame) {
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
-  scoped_ptr<SpdyFrame> chunk1(spdy_util_.ConstructSpdyBodyFrame(1, false));
-  scoped_ptr<SpdyFrame> chunk2(
+  scoped_ptr<SpdySerializedFrame> req(
+      spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> chunk1(
+      spdy_util_.ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdySerializedFrame> chunk2(
       spdy_util_.ConstructSpdyBodyFrame(1, "", 0, true));
   MockWrite writes[] = {
     CreateMockWrite(*req.get(), 0),
     CreateMockWrite(*chunk1, 1),  // POST upload frames
     CreateMockWrite(*chunk2, 2),
   };
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
   MockRead reads[] = {
     CreateMockRead(*resp, 3),
     CreateMockRead(*chunk1, 4),
@@ -646,14 +656,16 @@
 // Test that the SpdyStream state machine handles a chunked upload with no
 // payload. Unclear if this is a case worth supporting.
 TEST_P(SpdyHttpStreamTest, ChunkedPostWithEmptyPayload) {
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
-  scoped_ptr<SpdyFrame> chunk(
+  scoped_ptr<SpdySerializedFrame> req(
+      spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> chunk(
       spdy_util_.ConstructSpdyBodyFrame(1, "", 0, true));
   MockWrite writes[] = {
     CreateMockWrite(*req.get(), 0),
     CreateMockWrite(*chunk, 1),
   };
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
   MockRead reads[] = {
     CreateMockRead(*resp, 2),
     CreateMockRead(*chunk, 3),
@@ -716,11 +728,13 @@
 TEST_P(SpdyHttpStreamTest, SpdyURLTest) {
   const char* const full_url = "http://www.example.org/foo?query=what#anchor";
   const char* const base_url = "http://www.example.org/foo?query=what";
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyGet(base_url, 1, LOWEST));
+  scoped_ptr<SpdySerializedFrame> req(
+      spdy_util_.ConstructSpdyGet(base_url, 1, LOWEST));
   MockWrite writes[] = {
       CreateMockWrite(*req.get(), 0),
   };
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   MockRead reads[] = {
       CreateMockRead(*resp, 1), MockRead(SYNCHRONOUS, 0, 2)  // EOF
   };
@@ -762,14 +776,17 @@
 // Test the receipt of a WINDOW_UPDATE frame while waiting for a chunk to be
 // made available is handled correctly.
 TEST_P(SpdyHttpStreamTest, DelayedSendChunkedPostWithWindowUpdate) {
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
-  scoped_ptr<SpdyFrame> chunk1(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> req(
+      spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> chunk1(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockWrite writes[] = {
     CreateMockWrite(*req.get(), 0),
     CreateMockWrite(*chunk1, 1),
   };
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
-  scoped_ptr<SpdyFrame> window_update(
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> window_update(
       spdy_util_.ConstructSpdyWindowUpdate(1, kUploadDataSize));
   MockRead reads[] = {
       CreateMockRead(*window_update, 2),
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc
index cecfe7c..e87ba46 100644
--- a/net/spdy/spdy_network_transaction_unittest.cc
+++ b/net/spdy/spdy_network_transaction_unittest.cc
@@ -712,12 +712,14 @@
 
 TEST_P(SpdyNetworkTransactionTest, Get) {
   // Construct the request.
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite writes[] = {CreateMockWrite(*req, 0)};
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       CreateMockRead(*resp, 1),
       CreateMockRead(*body, 2),
@@ -742,7 +744,7 @@
     spdy_test_util.set_default_url(GURL(GetDefaultUrl()));
 
     // Construct the request.
-    scoped_ptr<SpdyFrame> req(
+    scoped_ptr<SpdySerializedFrame> req(
         spdy_test_util.ConstructSpdyGet(nullptr, 0, 1, p, true));
     MockWrite writes[] = {CreateMockWrite(*req, 0)};
 
@@ -772,9 +774,10 @@
         FAIL();
     }
 
-    scoped_ptr<SpdyFrame> resp(
+    scoped_ptr<SpdySerializedFrame> resp(
         spdy_test_util.ConstructSpdyGetSynReply(nullptr, 0, 1));
-    scoped_ptr<SpdyFrame> body(spdy_test_util.ConstructSpdyBodyFrame(1, true));
+    scoped_ptr<SpdySerializedFrame> body(
+        spdy_test_util.ConstructSpdyBodyFrame(1, true));
     MockRead reads[] = {
         CreateMockRead(*resp, 1),
         CreateMockRead(*body, 2),
@@ -806,23 +809,32 @@
 // can allow multiple streams in flight.
 
 TEST_P(SpdyNetworkTransactionTest, ThreeGets) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
-  scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdySerializedFrame> fbody(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
 
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true));
-  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
-  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false));
-  scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true));
+  scoped_ptr<SpdySerializedFrame> resp2(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdySerializedFrame> body2(
+      spdy_util_.ConstructSpdyBodyFrame(3, false));
+  scoped_ptr<SpdySerializedFrame> fbody2(
+      spdy_util_.ConstructSpdyBodyFrame(3, true));
 
-  scoped_ptr<SpdyFrame> req3(
+  scoped_ptr<SpdySerializedFrame> req3(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 5, LOWEST, true));
-  scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5));
-  scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(5, false));
-  scoped_ptr<SpdyFrame> fbody3(spdy_util_.ConstructSpdyBodyFrame(5, true));
+  scoped_ptr<SpdySerializedFrame> resp3(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5));
+  scoped_ptr<SpdySerializedFrame> body3(
+      spdy_util_.ConstructSpdyBodyFrame(5, false));
+  scoped_ptr<SpdySerializedFrame> fbody3(
+      spdy_util_.ConstructSpdyBodyFrame(5, true));
 
   MockWrite writes[] = {
       CreateMockWrite(*req, 0),
@@ -903,17 +915,23 @@
 }
 
 TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBinding) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
-  scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdySerializedFrame> fbody(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
 
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true));
-  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
-  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false));
-  scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true));
+  scoped_ptr<SpdySerializedFrame> resp2(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdySerializedFrame> body2(
+      spdy_util_.ConstructSpdyBodyFrame(3, false));
+  scoped_ptr<SpdySerializedFrame> fbody2(
+      spdy_util_.ConstructSpdyBodyFrame(3, true));
 
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*req2, 3),
@@ -988,17 +1006,23 @@
 }
 
 TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
-  scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdySerializedFrame> fbody(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
 
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true));
-  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
-  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false));
-  scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true));
+  scoped_ptr<SpdySerializedFrame> resp2(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdySerializedFrame> body2(
+      spdy_util_.ConstructSpdyBodyFrame(3, false));
+  scoped_ptr<SpdySerializedFrame> fbody2(
+      spdy_util_.ConstructSpdyBodyFrame(3, true));
 
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*req2, 3),
@@ -1093,33 +1117,43 @@
 TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) {
   // Construct the request.
   // Each request fully completes before the next starts.
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
-  scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdySerializedFrame> fbody(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   spdy_util_.UpdateWithStreamDestruction(1);
 
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true));
-  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
-  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false));
-  scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true));
+  scoped_ptr<SpdySerializedFrame> resp2(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdySerializedFrame> body2(
+      spdy_util_.ConstructSpdyBodyFrame(3, false));
+  scoped_ptr<SpdySerializedFrame> fbody2(
+      spdy_util_.ConstructSpdyBodyFrame(3, true));
   spdy_util_.UpdateWithStreamDestruction(3);
 
-  scoped_ptr<SpdyFrame> req3(
+  scoped_ptr<SpdySerializedFrame> req3(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 5, LOWEST, true));
-  scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5));
-  scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(5, false));
-  scoped_ptr<SpdyFrame> fbody3(spdy_util_.ConstructSpdyBodyFrame(5, true));
+  scoped_ptr<SpdySerializedFrame> resp3(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5));
+  scoped_ptr<SpdySerializedFrame> body3(
+      spdy_util_.ConstructSpdyBodyFrame(5, false));
+  scoped_ptr<SpdySerializedFrame> fbody3(
+      spdy_util_.ConstructSpdyBodyFrame(5, true));
 
   SettingsMap settings;
   const uint32_t max_concurrent_streams = 1;
   settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
-  scoped_ptr<SpdyFrame> settings_frame(
+  scoped_ptr<SpdySerializedFrame> settings_frame(
       spdy_util_.ConstructSpdySettings(settings));
-  scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
+  scoped_ptr<SpdySerializedFrame> settings_ack(
+      spdy_util_.ConstructSpdySettingsAck());
 
   MockWrite writes[] = {
       CreateMockWrite(*req, 0),
@@ -1223,39 +1257,51 @@
 // the response from the server.
 TEST_P(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) {
   // Construct the request.
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
-  scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdySerializedFrame> fbody(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   spdy_util_.UpdateWithStreamDestruction(1);
 
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true));
-  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
-  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false));
-  scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true));
+  scoped_ptr<SpdySerializedFrame> resp2(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdySerializedFrame> body2(
+      spdy_util_.ConstructSpdyBodyFrame(3, false));
+  scoped_ptr<SpdySerializedFrame> fbody2(
+      spdy_util_.ConstructSpdyBodyFrame(3, true));
   spdy_util_.UpdateWithStreamDestruction(3);
 
-  scoped_ptr<SpdyFrame> req4(
+  scoped_ptr<SpdySerializedFrame> req4(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 5, HIGHEST, true));
-  scoped_ptr<SpdyFrame> resp4(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5));
-  scoped_ptr<SpdyFrame> fbody4(spdy_util_.ConstructSpdyBodyFrame(5, true));
+  scoped_ptr<SpdySerializedFrame> resp4(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5));
+  scoped_ptr<SpdySerializedFrame> fbody4(
+      spdy_util_.ConstructSpdyBodyFrame(5, true));
   spdy_util_.UpdateWithStreamDestruction(5);
 
-  scoped_ptr<SpdyFrame> req3(
+  scoped_ptr<SpdySerializedFrame> req3(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 7, LOWEST, true));
-  scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 7));
-  scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(7, false));
-  scoped_ptr<SpdyFrame> fbody3(spdy_util_.ConstructSpdyBodyFrame(7, true));
+  scoped_ptr<SpdySerializedFrame> resp3(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 7));
+  scoped_ptr<SpdySerializedFrame> body3(
+      spdy_util_.ConstructSpdyBodyFrame(7, false));
+  scoped_ptr<SpdySerializedFrame> fbody3(
+      spdy_util_.ConstructSpdyBodyFrame(7, true));
 
   SettingsMap settings;
   const uint32_t max_concurrent_streams = 1;
   settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
-  scoped_ptr<SpdyFrame> settings_frame(
+  scoped_ptr<SpdySerializedFrame> settings_frame(
       spdy_util_.ConstructSpdySettings(settings));
-  scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
+  scoped_ptr<SpdySerializedFrame> settings_ack(
+      spdy_util_.ConstructSpdySettingsAck());
   MockWrite writes[] = {
       CreateMockWrite(*req, 0),
       CreateMockWrite(*settings_ack, 5),
@@ -1375,26 +1421,33 @@
 // the spdy_session
 TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentDelete) {
   // Construct the request.
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
-  scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdySerializedFrame> fbody(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   spdy_util_.UpdateWithStreamDestruction(1);
 
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true));
-  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
-  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false));
-  scoped_ptr<SpdyFrame> fbody2(spdy_util_.ConstructSpdyBodyFrame(3, true));
+  scoped_ptr<SpdySerializedFrame> resp2(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdySerializedFrame> body2(
+      spdy_util_.ConstructSpdyBodyFrame(3, false));
+  scoped_ptr<SpdySerializedFrame> fbody2(
+      spdy_util_.ConstructSpdyBodyFrame(3, true));
 
   SettingsMap settings;
   const uint32_t max_concurrent_streams = 1;
   settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
-  scoped_ptr<SpdyFrame> settings_frame(
+  scoped_ptr<SpdySerializedFrame> settings_frame(
       spdy_util_.ConstructSpdySettings(settings));
-  scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
+  scoped_ptr<SpdySerializedFrame> settings_ack(
+      spdy_util_.ConstructSpdySettingsAck());
 
   MockWrite writes[] = {
       CreateMockWrite(*req, 0),
@@ -1507,24 +1560,29 @@
 // a pending stream creation.  http://crbug.com/52901
 TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentSocketClose) {
   // Construct the request.
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
-  scoped_ptr<SpdyFrame> fin_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdySerializedFrame> fin_body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   spdy_util_.UpdateWithStreamDestruction(1);
 
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true));
-  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdySerializedFrame> resp2(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
 
   SettingsMap settings;
   const uint32_t max_concurrent_streams = 1;
   settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
-  scoped_ptr<SpdyFrame> settings_frame(
+  scoped_ptr<SpdySerializedFrame> settings_frame(
       spdy_util_.ConstructSpdySettings(settings));
-  scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
+  scoped_ptr<SpdySerializedFrame> settings_ack(
+      spdy_util_.ConstructSpdySettingsAck());
 
   MockWrite writes[] = {
       CreateMockWrite(*req, 0),
@@ -1607,14 +1665,16 @@
 
   scoped_ptr<SpdyHeaderBlock> put_headers(
       spdy_util_.ConstructPutHeaderBlock(GetDefaultUrl(), 0));
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdySyn(1, *put_headers, LOWEST, true));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0),
   };
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       CreateMockRead(*resp, 1),
       CreateMockRead(*body, 2),
@@ -1640,14 +1700,16 @@
 
   scoped_ptr<SpdyHeaderBlock> head_headers(
       spdy_util_.ConstructHeadHeaderBlock(GetDefaultUrl(), 0));
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdySyn(1, *head_headers, LOWEST, true));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0),
   };
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       CreateMockRead(*resp, 1),
       CreateMockRead(*body, 2),
@@ -1666,14 +1728,16 @@
 
 // Test that a simple POST works.
 TEST_P(SpdyNetworkTransactionTest, Post) {
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
       GetDefaultUrl(), 1, kUploadDataSize, LOWEST, NULL, 0));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*body, 1),  // POST upload frame
   };
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
   MockRead reads[] = {
       CreateMockRead(*resp, 2),
       CreateMockRead(*body, 3),
@@ -1692,14 +1756,16 @@
 
 // Test that a POST with a file works.
 TEST_P(SpdyNetworkTransactionTest, FilePost) {
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
       GetDefaultUrl(), 1, kUploadDataSize, LOWEST, NULL, 0));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*body, 1),  // POST upload frame
   };
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
   MockRead reads[] = {
       CreateMockRead(*resp, 2),
       CreateMockRead(*body, 3),
@@ -1740,14 +1806,16 @@
 
 // Test that a complex POST works.
 TEST_P(SpdyNetworkTransactionTest, ComplexPost) {
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
       GetDefaultUrl(), 1, kUploadDataSize, LOWEST, NULL, 0));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*body, 1),  // POST upload frame
   };
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
   MockRead reads[] = {
       CreateMockRead(*resp, 2),
       CreateMockRead(*body, 3),
@@ -1767,13 +1835,16 @@
 
 // Test that a chunked POST works.
 TEST_P(SpdyNetworkTransactionTest, ChunkedPost) {
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> req(
+      spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*body, 1),
   };
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
   MockRead reads[] = {
       CreateMockRead(*resp, 2),
       CreateMockRead(*body, 3),
@@ -1800,10 +1871,14 @@
 
 // Test that a chunked POST works with chunks appended after transaction starts.
 TEST_P(SpdyNetworkTransactionTest, DelayedChunkedPost) {
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
-  scoped_ptr<SpdyFrame> chunk1(spdy_util_.ConstructSpdyBodyFrame(1, false));
-  scoped_ptr<SpdyFrame> chunk2(spdy_util_.ConstructSpdyBodyFrame(1, false));
-  scoped_ptr<SpdyFrame> chunk3(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> req(
+      spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> chunk1(
+      spdy_util_.ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdySerializedFrame> chunk2(
+      spdy_util_.ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdySerializedFrame> chunk3(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0),
       CreateMockWrite(*chunk1, 1),
@@ -1811,7 +1886,8 @@
       CreateMockWrite(*chunk3, 3),
   };
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
   MockRead reads[] = {
       CreateMockRead(*resp, 4),
       CreateMockRead(*chunk1, 5),
@@ -1864,15 +1940,17 @@
   // expected to be 0.
   scoped_ptr<SpdyHeaderBlock> req_block(
       spdy_util_.ConstructPostHeaderBlock(GetDefaultUrl(), 0));
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdySyn(1, *req_block, LOWEST, true));
 
   MockWrite writes[] = {
       CreateMockWrite(*req, 0),
   };
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       CreateMockRead(*resp, 1),
       CreateMockRead(*body, 2),
@@ -1907,15 +1985,17 @@
 
   scoped_ptr<SpdyHeaderBlock> req_block(
       spdy_util_.ConstructPostHeaderBlock(GetDefaultUrl(), kContentLength));
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdySyn(1, *req_block, LOWEST, true));
 
   MockWrite writes[] = {
       CreateMockWrite(*req, 0),
   };
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       CreateMockRead(*resp, 1),
       CreateMockRead(*body, 2),
@@ -1935,13 +2015,16 @@
 
 // While we're doing a post, the server sends the reply before upload completes.
 TEST_P(SpdyNetworkTransactionTest, ResponseBeforePostCompletes) {
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> req(
+      spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockWrite writes[] = {
     CreateMockWrite(*req, 0),
     CreateMockWrite(*body, 3),
   };
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
   MockRead reads[] = {
     CreateMockRead(*resp, 1),
     CreateMockRead(*body, 2),
@@ -1980,9 +2063,9 @@
 // socket causes the TCP write to return zero. This test checks that the client
 // tries to queue up the RST_STREAM frame again.
 TEST_P(SpdyNetworkTransactionTest, SocketWriteReturnsZero) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   MockWrite writes[] = {
     CreateMockWrite(*req.get(), 0, SYNCHRONOUS),
@@ -1990,7 +2073,8 @@
     CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   MockRead reads[] = {
     CreateMockRead(*resp.get(), 1, ASYNC),
     MockRead(ASYNC, 0, 0, 4)  // EOF
@@ -2016,14 +2100,15 @@
 
 // Test that the transaction doesn't crash when we don't have a reply.
 TEST_P(SpdyNetworkTransactionTest, ResponseWithoutSynReply) {
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       CreateMockRead(*body, 1), MockRead(ASYNC, 0, 3)  // EOF
   };
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*rst, 2),
@@ -2039,19 +2124,20 @@
 // Test that the transaction doesn't crash when we get two replies on the same
 // stream ID. See http://crbug.com/45639.
 TEST_P(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4),
   };
 
-  scoped_ptr<SpdyFrame> resp0(
+  scoped_ptr<SpdySerializedFrame> resp0(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> resp1(
+  scoped_ptr<SpdySerializedFrame> resp1(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       CreateMockRead(*resp0, 1), CreateMockRead(*resp1, 2),
       CreateMockRead(*body, 3), MockRead(ASYNC, 0, 5)  // EOF
@@ -2085,9 +2171,9 @@
 
 TEST_P(SpdyNetworkTransactionTest, ResetReplyWithTransferEncoding) {
   // Construct the request.
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*rst, 2),
@@ -2096,9 +2182,9 @@
   const char* const headers[] = {
     "transfer-encoding", "chunked"
   };
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(headers, 1, 1));
-  scoped_ptr<SpdyFrame> body(
+  scoped_ptr<SpdySerializedFrame> body(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       CreateMockRead(*resp, 1),
@@ -2119,22 +2205,24 @@
 
 TEST_P(SpdyNetworkTransactionTest, ResetPushWithTransferEncoding) {
   // Construct the request.
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4),
   };
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   const char* const headers[] = {
     "transfer-encoding", "chunked"
   };
-  scoped_ptr<SpdyFrame> push(
+  scoped_ptr<SpdySerializedFrame> push(
       spdy_util_.ConstructSpdyPush(headers, arraysize(headers) / 2, 2, 1,
                                    GetDefaultUrlWithPath("/1").c_str()));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       CreateMockRead(*resp, 1),
       CreateMockRead(*push, 2),
@@ -2157,13 +2245,14 @@
 
 TEST_P(SpdyNetworkTransactionTest, CancelledTransaction) {
   // Construct the request.
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite writes[] = {
     CreateMockWrite(*req),
   };
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   MockRead reads[] = {
     CreateMockRead(*resp),
     // This following read isn't used by the test, except during the
@@ -2196,16 +2285,17 @@
 
 // Verify that the client sends a Rst Frame upon cancelling the stream.
 TEST_P(SpdyNetworkTransactionTest, CancelledTransactionSendRst) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   MockWrite writes[] = {
     CreateMockWrite(*req, 0, SYNCHRONOUS),
     CreateMockWrite(*rst, 2, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   MockRead reads[] = {
     CreateMockRead(*resp, 1, ASYNC),
     MockRead(ASYNC, 0, 0, 3)  // EOF
@@ -2236,7 +2326,7 @@
 // to start another transaction on a session that is closing down. See
 // http://crbug.com/47455
 TEST_P(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite writes[] = {CreateMockWrite(*req)};
   MockWrite writes2[] = {CreateMockWrite(*req, 0)};
@@ -2249,7 +2339,8 @@
       0x07, 'h',  'e',  'l',  'l',  'o',  '!',
   };
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   MockRead reads[] = {
       CreateMockRead(*resp, 1),
       MockRead(ASYNC, ERR_IO_PENDING, 2),  // Force a pause
@@ -2300,12 +2391,14 @@
 // transaction. Failures will usually be valgrind errors. See
 // http://crbug.com/46925
 TEST_P(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite writes[] = {CreateMockWrite(*req, 0)};
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       CreateMockRead(*resp.get(), 1),
       MockRead(ASYNC, ERR_IO_PENDING, 2),  // Force a pause
@@ -2356,11 +2449,12 @@
   (*headers2)["accept-encoding"] = "gzip, deflate";
 
   // Setup writes/reads to www.example.org
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, true));
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_.ConstructSpdySyn(1, *headers2, LOWEST, true));
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReplyRedirect(1));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReplyRedirect(1));
   MockWrite writes[] = {
     CreateMockWrite(*req, 1),
   };
@@ -2370,8 +2464,10 @@
   };
 
   // Setup writes/reads to www.foo.com
-  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp2(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body2(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockWrite writes2[] = {
     CreateMockWrite(*req2, 1),
   };
@@ -2424,14 +2520,16 @@
   (*headers)["accept-encoding"] = "gzip, deflate";
 
   // Setup writes/reads to www.example.org
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, true));
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> rep(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> rep(spdy_util_.ConstructSpdyPush(
       NULL, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str(),
       "301 Moved Permanently", "http://www.foo.com/index.php"));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_CANCEL));
   MockWrite writes[] = {
     CreateMockWrite(*req, 1),
@@ -2450,10 +2548,12 @@
       spdy_util_.ConstructGetHeaderBlock("http://www.foo.com/index.php"));
   (*headers2)["user-agent"] = "";
   (*headers2)["accept-encoding"] = "gzip, deflate";
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_.ConstructSpdySyn(1, *headers2, LOWEST, true));
-  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp2(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body2(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockWrite writes2[] = {
     CreateMockWrite(*req2, 1),
   };
@@ -2508,22 +2608,22 @@
 }
 
 TEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame) {
-  scoped_ptr<SpdyFrame> stream1_syn(
+  scoped_ptr<SpdySerializedFrame> stream1_syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> stream1_body(
+  scoped_ptr<SpdySerializedFrame> stream1_body(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockWrite writes[] = {
       CreateMockWrite(*stream1_syn, 0),
   };
 
-  scoped_ptr<SpdyFrame>
-      stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> stream1_reply(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
       NULL, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str()));
   const char kPushedData[] = "pushed";
-  scoped_ptr<SpdyFrame> stream2_body(
-      spdy_util_.ConstructSpdyBodyFrame(
-          2, kPushedData, strlen(kPushedData), true));
+  scoped_ptr<SpdySerializedFrame> stream2_body(
+      spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData),
+                                        true));
   MockRead reads[] = {
       CreateMockRead(*stream1_reply, 1),
       CreateMockRead(*stream2_syn, 2),
@@ -2551,22 +2651,22 @@
 }
 
 TEST_P(SpdyNetworkTransactionTest, ServerPushBeforeSynReply) {
-  scoped_ptr<SpdyFrame> stream1_syn(
+  scoped_ptr<SpdySerializedFrame> stream1_syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite writes[] = {
       CreateMockWrite(*stream1_syn, 0),
   };
 
-  scoped_ptr<SpdyFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
       nullptr, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str()));
-  scoped_ptr<SpdyFrame>
-      stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> stream1_body(
+  scoped_ptr<SpdySerializedFrame> stream1_reply(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> stream1_body(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
   const char kPushedData[] = "pushed";
-  scoped_ptr<SpdyFrame> stream2_body(
-      spdy_util_.ConstructSpdyBodyFrame(
-          2, kPushedData, strlen(kPushedData), true));
+  scoped_ptr<SpdySerializedFrame> stream2_body(
+      spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData),
+                                        true));
   MockRead reads[] = {
       CreateMockRead(*stream2_syn, 1),
       CreateMockRead(*stream1_reply, 2),
@@ -2594,22 +2694,22 @@
 }
 
 TEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame2) {
-  scoped_ptr<SpdyFrame> stream1_syn(
+  scoped_ptr<SpdySerializedFrame> stream1_syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite writes[] = {
       CreateMockWrite(*stream1_syn, 0),
   };
 
-  scoped_ptr<SpdyFrame>
-      stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> stream1_reply(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
       NULL, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str()));
   const char kPushedData[] = "pushed";
-  scoped_ptr<SpdyFrame> stream2_body(
-      spdy_util_.ConstructSpdyBodyFrame(
-          2, kPushedData, strlen(kPushedData), true));
-  scoped_ptr<SpdyFrame>
-      stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> stream2_body(
+      spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData),
+                                        true));
+  scoped_ptr<SpdySerializedFrame> stream1_body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       CreateMockRead(*stream1_reply, 1),
       CreateMockRead(*stream2_syn, 2),
@@ -2637,19 +2737,19 @@
 }
 
 TEST_P(SpdyNetworkTransactionTest, ServerPushServerAborted) {
-  scoped_ptr<SpdyFrame> stream1_syn(
+  scoped_ptr<SpdySerializedFrame> stream1_syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> stream1_body(
+  scoped_ptr<SpdySerializedFrame> stream1_body(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockWrite writes[] = {
       CreateMockWrite(*stream1_syn, 0),
   };
 
-  scoped_ptr<SpdyFrame>
-      stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> stream1_reply(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
       NULL, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str()));
-  scoped_ptr<SpdyFrame> stream2_rst(
+  scoped_ptr<SpdySerializedFrame> stream2_rst(
       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR));
   MockRead reads[] = {
       CreateMockRead(*stream1_reply, 1),
@@ -2689,25 +2789,25 @@
 // Verify that we don't leak streams and that we properly send a reset
 // if the server pushes the same stream twice.
 TEST_P(SpdyNetworkTransactionTest, ServerPushDuplicate) {
-  scoped_ptr<SpdyFrame> stream1_syn(
+  scoped_ptr<SpdySerializedFrame> stream1_syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> stream1_body(
+  scoped_ptr<SpdySerializedFrame> stream1_body(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
-  scoped_ptr<SpdyFrame> stream3_rst(
+  scoped_ptr<SpdySerializedFrame> stream3_rst(
       spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_PROTOCOL_ERROR));
   MockWrite writes[] = {
       CreateMockWrite(*stream1_syn, 0), CreateMockWrite(*stream3_rst, 4),
   };
 
-  scoped_ptr<SpdyFrame>
-      stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> stream1_reply(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
       NULL, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str()));
   const char kPushedData[] = "pushed";
-  scoped_ptr<SpdyFrame> stream2_body(
-      spdy_util_.ConstructSpdyBodyFrame(
-          2, kPushedData, strlen(kPushedData), true));
-  scoped_ptr<SpdyFrame> stream3_syn(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> stream2_body(
+      spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData),
+                                        true));
+  scoped_ptr<SpdySerializedFrame> stream3_syn(spdy_util_.ConstructSpdyPush(
       NULL, 0, 4, 1, GetDefaultUrlWithPath("/foo.dat").c_str()));
   MockRead reads[] = {
       CreateMockRead(*stream1_reply, 1),
@@ -2737,33 +2837,32 @@
 }
 
 TEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrame) {
-  scoped_ptr<SpdyFrame> stream1_syn(
+  scoped_ptr<SpdySerializedFrame> stream1_syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> stream1_body(
+  scoped_ptr<SpdySerializedFrame> stream1_body(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockWrite writes[] = {
       CreateMockWrite(*stream1_syn, 0),
   };
 
-  scoped_ptr<SpdyFrame>
-      stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> stream1_reply(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
       NULL, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str()));
   static const char kPushedData[] = "pushed my darling hello my baby";
-  scoped_ptr<SpdyFrame> stream2_body_base(
-      spdy_util_.ConstructSpdyBodyFrame(
-          2, kPushedData, strlen(kPushedData), true));
+  scoped_ptr<SpdySerializedFrame> stream2_body_base(
+      spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData),
+                                        true));
   const size_t kChunkSize = strlen(kPushedData) / 4;
-  scoped_ptr<SpdyFrame> stream2_body1(
-      new SpdyFrame(stream2_body_base->data(), kChunkSize, false));
-  scoped_ptr<SpdyFrame> stream2_body2(
-      new SpdyFrame(stream2_body_base->data() + kChunkSize, kChunkSize, false));
-  scoped_ptr<SpdyFrame> stream2_body3(
-      new SpdyFrame(stream2_body_base->data() + 2 * kChunkSize,
-                    kChunkSize, false));
-  scoped_ptr<SpdyFrame> stream2_body4(
-      new SpdyFrame(stream2_body_base->data() + 3 * kChunkSize,
-                    stream2_body_base->size() - 3 * kChunkSize, false));
+  scoped_ptr<SpdySerializedFrame> stream2_body1(
+      new SpdySerializedFrame(stream2_body_base->data(), kChunkSize, false));
+  scoped_ptr<SpdySerializedFrame> stream2_body2(new SpdySerializedFrame(
+      stream2_body_base->data() + kChunkSize, kChunkSize, false));
+  scoped_ptr<SpdySerializedFrame> stream2_body3(new SpdySerializedFrame(
+      stream2_body_base->data() + 2 * kChunkSize, kChunkSize, false));
+  scoped_ptr<SpdySerializedFrame> stream2_body4(new SpdySerializedFrame(
+      stream2_body_base->data() + 3 * kChunkSize,
+      stream2_body_base->size() - 3 * kChunkSize, false));
   MockRead reads[] = {
       CreateMockRead(*stream1_reply, 1),
       CreateMockRead(*stream2_syn, 2),
@@ -2791,33 +2890,32 @@
 }
 
 TEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrameInterrupted) {
-  scoped_ptr<SpdyFrame> stream1_syn(
+  scoped_ptr<SpdySerializedFrame> stream1_syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> stream1_body(
+  scoped_ptr<SpdySerializedFrame> stream1_body(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockWrite writes[] = {
       CreateMockWrite(*stream1_syn, 0),
   };
 
-  scoped_ptr<SpdyFrame>
-      stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> stream1_reply(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
       NULL, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str()));
   static const char kPushedData[] = "pushed my darling hello my baby";
-  scoped_ptr<SpdyFrame> stream2_body_base(
-      spdy_util_.ConstructSpdyBodyFrame(
-          2, kPushedData, strlen(kPushedData), true));
+  scoped_ptr<SpdySerializedFrame> stream2_body_base(
+      spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData),
+                                        true));
   const size_t kChunkSize = strlen(kPushedData) / 4;
-  scoped_ptr<SpdyFrame> stream2_body1(
-      new SpdyFrame(stream2_body_base->data(), kChunkSize, false));
-  scoped_ptr<SpdyFrame> stream2_body2(
-      new SpdyFrame(stream2_body_base->data() + kChunkSize, kChunkSize, false));
-  scoped_ptr<SpdyFrame> stream2_body3(
-      new SpdyFrame(stream2_body_base->data() + 2 * kChunkSize,
-                    kChunkSize, false));
-  scoped_ptr<SpdyFrame> stream2_body4(
-      new SpdyFrame(stream2_body_base->data() + 3 * kChunkSize,
-                    stream2_body_base->size() - 3 * kChunkSize, false));
+  scoped_ptr<SpdySerializedFrame> stream2_body1(
+      new SpdySerializedFrame(stream2_body_base->data(), kChunkSize, false));
+  scoped_ptr<SpdySerializedFrame> stream2_body2(new SpdySerializedFrame(
+      stream2_body_base->data() + kChunkSize, kChunkSize, false));
+  scoped_ptr<SpdySerializedFrame> stream2_body3(new SpdySerializedFrame(
+      stream2_body_base->data() + 2 * kChunkSize, kChunkSize, false));
+  scoped_ptr<SpdySerializedFrame> stream2_body4(new SpdySerializedFrame(
+      stream2_body_base->data() + 3 * kChunkSize,
+      stream2_body_base->size() - 3 * kChunkSize, false));
   MockRead reads[] = {
       CreateMockRead(*stream1_reply, 1),
       CreateMockRead(*stream2_syn, 2),
@@ -2844,9 +2942,9 @@
 }
 
 TEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID0) {
-  scoped_ptr<SpdyFrame> stream1_syn(
+  scoped_ptr<SpdySerializedFrame> stream1_syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> goaway;
+  scoped_ptr<SpdySerializedFrame> goaway;
   if (spdy_util_.spdy_version() == SPDY3) {
     goaway.reset(spdy_util_.ConstructSpdyGoAway(0, GOAWAY_PROTOCOL_ERROR,
                                                 "Push on even stream id."));
@@ -2858,9 +2956,9 @@
       CreateMockWrite(*stream1_syn, 0), CreateMockWrite(*goaway, 3),
   };
 
-  scoped_ptr<SpdyFrame>
-      stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> stream1_reply(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
       NULL, 0, 2, 0, GetDefaultUrlWithPath("/foo.dat").c_str()));
   MockRead reads[] = {
       CreateMockRead(*stream1_reply, 1),
@@ -2895,19 +2993,19 @@
 }
 
 TEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID9) {
-  scoped_ptr<SpdyFrame> stream1_syn(
+  scoped_ptr<SpdySerializedFrame> stream1_syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> stream1_body(
+  scoped_ptr<SpdySerializedFrame> stream1_body(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
-  scoped_ptr<SpdyFrame> stream2_rst(
+  scoped_ptr<SpdySerializedFrame> stream2_rst(
       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_INVALID_STREAM));
   MockWrite writes[] = {
       CreateMockWrite(*stream1_syn, 0), CreateMockWrite(*stream2_rst, 3),
   };
 
-  scoped_ptr<SpdyFrame>
-      stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> stream1_reply(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
       NULL, 0, 2, 9, GetDefaultUrlWithPath("/foo.dat").c_str()));
   MockRead reads[] = {
       CreateMockRead(*stream1_reply, 1),
@@ -2944,24 +3042,25 @@
 }
 
 TEST_P(SpdyNetworkTransactionTest, ServerPushNoURL) {
-  scoped_ptr<SpdyFrame> stream1_syn(
+  scoped_ptr<SpdySerializedFrame> stream1_syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> stream1_body(
+  scoped_ptr<SpdySerializedFrame> stream1_body(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
-  scoped_ptr<SpdyFrame> stream2_rst(
+  scoped_ptr<SpdySerializedFrame> stream2_rst(
       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR));
   MockWrite writes[] = {
       CreateMockWrite(*stream1_syn, 0), CreateMockWrite(*stream2_rst, 3),
   };
 
-  scoped_ptr<SpdyFrame>
-      stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> stream1_reply(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   scoped_ptr<SpdyHeaderBlock> incomplete_headers(new SpdyHeaderBlock());
   (*incomplete_headers)[spdy_util_.GetStatusKey()] = "200 OK";
   (*incomplete_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
   (*incomplete_headers)["hello"] = "bye";
-  scoped_ptr<SpdyFrame> stream2_syn(spdy_util_.ConstructInitialSpdyPushFrame(
-      std::move(incomplete_headers), 2, 1));
+  scoped_ptr<SpdySerializedFrame> stream2_syn(
+      spdy_util_.ConstructInitialSpdyPushFrame(std::move(incomplete_headers), 2,
+                                               1));
   MockRead reads[] = {
       CreateMockRead(*stream1_reply, 1),
       CreateMockRead(*stream2_syn, 2),
@@ -2998,19 +3097,19 @@
 
 // PUSH_PROMISE on a server-initiated stream should trigger GOAWAY.
 TEST_P(SpdyNetworkTransactionTest, ServerPushOnPushedStream) {
-  scoped_ptr<SpdyFrame> stream1_syn(
+  scoped_ptr<SpdySerializedFrame> stream1_syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(
+  scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(
       2, GOAWAY_PROTOCOL_ERROR, "Push on even stream id."));
   MockWrite writes[] = {
       CreateMockWrite(*stream1_syn, 0), CreateMockWrite(*goaway, 4),
   };
 
-  scoped_ptr<SpdyFrame> stream1_reply(
+  scoped_ptr<SpdySerializedFrame> stream1_reply(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
       nullptr, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str()));
-  scoped_ptr<SpdyFrame> stream3_syn(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> stream3_syn(spdy_util_.ConstructSpdyPush(
       nullptr, 0, 4, 2, GetDefaultUrlWithPath("/bar.dat").c_str()));
   MockRead reads[] = {
       CreateMockRead(*stream1_reply, 1), CreateMockRead(*stream2_syn, 2),
@@ -3025,19 +3124,19 @@
 
 // PUSH_PROMISE on a closed client-initiated stream should trigger RST_STREAM.
 TEST_P(SpdyNetworkTransactionTest, ServerPushOnClosedStream) {
-  scoped_ptr<SpdyFrame> stream1_syn(
+  scoped_ptr<SpdySerializedFrame> stream1_syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_INVALID_STREAM));
   MockWrite writes[] = {
       CreateMockWrite(*stream1_syn, 0), CreateMockWrite(*rst, 5),
   };
 
-  scoped_ptr<SpdyFrame> stream1_reply(
+  scoped_ptr<SpdySerializedFrame> stream1_reply(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> stream1_body(
+  scoped_ptr<SpdySerializedFrame> stream1_body(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
-  scoped_ptr<SpdyFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
       nullptr, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str()));
   MockRead reads[] = {
       CreateMockRead(*stream1_reply, 1), CreateMockRead(*stream1_body, 2),
@@ -3069,24 +3168,25 @@
 // PUSH_PROMISE on a server-initiated stream should trigger GOAWAY even if
 // stream is closed.
 TEST_P(SpdyNetworkTransactionTest, ServerPushOnClosedPushedStream) {
-  scoped_ptr<SpdyFrame> stream1_syn(
+  scoped_ptr<SpdySerializedFrame> stream1_syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(
+  scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(
       2, GOAWAY_PROTOCOL_ERROR, "Push on even stream id."));
   MockWrite writes[] = {
       CreateMockWrite(*stream1_syn, 0), CreateMockWrite(*goaway, 7),
   };
 
-  scoped_ptr<SpdyFrame> stream1_reply(
+  scoped_ptr<SpdySerializedFrame> stream1_reply(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush(
       nullptr, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str()));
-  scoped_ptr<SpdyFrame> stream1_body(
+  scoped_ptr<SpdySerializedFrame> stream1_body(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
   const char kPushedData[] = "pushed";
-  scoped_ptr<SpdyFrame> stream2_body(spdy_util_.ConstructSpdyBodyFrame(
-      2, kPushedData, strlen(kPushedData), true));
-  scoped_ptr<SpdyFrame> stream3_syn(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> stream2_body(
+      spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData),
+                                        true));
+  scoped_ptr<SpdySerializedFrame> stream3_syn(spdy_util_.ConstructSpdyPush(
       nullptr, 0, 4, 2, GetDefaultUrlWithPath("/bar.dat").c_str()));
 
   MockRead reads[] = {
@@ -3181,13 +3281,15 @@
     SpdyTestUtil spdy_test_util(GetParam().protocol,
                                 GetParam().priority_to_dependency);
     spdy_test_util.set_default_url(GURL(GetDefaultUrl()));
-    scoped_ptr<SpdyFrame> req(
+    scoped_ptr<SpdySerializedFrame> req(
         spdy_test_util.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
     MockWrite writes[] = {CreateMockWrite(*req, 0)};
 
-    scoped_ptr<SpdyFrame> resp(spdy_test_util.ConstructSpdyGetSynReply(
-        test_cases[i].extra_headers, test_cases[i].num_headers, 1));
-    scoped_ptr<SpdyFrame> body(spdy_test_util.ConstructSpdyBodyFrame(1, true));
+    scoped_ptr<SpdySerializedFrame> resp(
+        spdy_test_util.ConstructSpdyGetSynReply(test_cases[i].extra_headers,
+                                                test_cases[i].num_headers, 1));
+    scoped_ptr<SpdySerializedFrame> body(
+        spdy_test_util.ConstructSpdyBodyFrame(1, true));
     MockRead reads[] = {
         CreateMockRead(*resp, 1),
         CreateMockRead(*body, 2),
@@ -3271,7 +3373,7 @@
     spdy_test_util.set_default_url(GURL(GetDefaultUrl()));
 
     // Construct the request.
-    scoped_ptr<SpdyFrame> frame_req(spdy_test_util.ConstructSpdyGet(
+    scoped_ptr<SpdySerializedFrame> frame_req(spdy_test_util.ConstructSpdyGet(
         test_cases[i].extra_headers[0], test_cases[i].num_headers[0], 1, LOWEST,
         true));
 
@@ -3284,10 +3386,11 @@
     AppendToHeaderBlock(test_cases[i].extra_headers[1],
                         test_cases[i].num_headers[1],
                         &reply_headers);
-    scoped_ptr<SpdyFrame> frame_reply(
+    scoped_ptr<SpdySerializedFrame> frame_reply(
         spdy_test_util.ConstructSpdyReply(1, reply_headers));
 
-    scoped_ptr<SpdyFrame> body(spdy_test_util.ConstructSpdyBodyFrame(1, true));
+    scoped_ptr<SpdySerializedFrame> body(
+        spdy_test_util.ConstructSpdyBodyFrame(1, true));
     MockRead reads[] = {
         CreateMockRead(*frame_reply, 1),
         CreateMockRead(*body, 2),
@@ -3365,9 +3468,9 @@
                                 GetParam().priority_to_dependency);
     spdy_test_util.set_default_url(GURL(GetDefaultUrl()));
 
-    scoped_ptr<SpdyFrame> req(
+    scoped_ptr<SpdySerializedFrame> req(
         spdy_test_util.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-    scoped_ptr<SpdyFrame> rst(
+    scoped_ptr<SpdySerializedFrame> rst(
         spdy_test_util.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
     MockWrite writes[] = {
         CreateMockWrite(*req, 0), CreateMockWrite(*rst, 2),
@@ -3377,7 +3480,7 @@
     SpdyHeaderBlock reply_headers;
     AppendToHeaderBlock(
         test_cases[i].headers, test_cases[i].num_headers, &reply_headers);
-    scoped_ptr<SpdyFrame> resp(
+    scoped_ptr<SpdySerializedFrame> resp(
         spdy_test_util.ConstructSpdyReply(1, reply_headers));
     MockRead reads[] = {
         CreateMockRead(*resp, 1), MockRead(ASYNC, 0, 3)  // EOF
@@ -3398,16 +3501,16 @@
     return;
   }
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(
+  scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(
       0, GOAWAY_COMPRESSION_ERROR, "Framer error: 5 (DECOMPRESS_FAILURE)."));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*goaway, 3),
   };
 
   // This is the length field that's too short.
-  scoped_ptr<SpdyFrame> syn_reply_wrong_length(
+  scoped_ptr<SpdySerializedFrame> syn_reply_wrong_length(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
   size_t right_size =
       syn_reply_wrong_length->size() -
@@ -3416,7 +3519,8 @@
   test::SetFrameLength(syn_reply_wrong_length.get(),
                        wrong_size,
                        spdy_util_.spdy_version());
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       MockRead(ASYNC, syn_reply_wrong_length->data(),
                syn_reply_wrong_length->size(), 1),
@@ -3436,14 +3540,14 @@
     return;
   }
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(
+  scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(
       0, GOAWAY_COMPRESSION_ERROR, "Framer error: 5 (DECOMPRESS_FAILURE)."));
   MockWrite writes[] = {CreateMockWrite(*req, 0), CreateMockWrite(*goaway, 2)};
 
   // This is the length field that's too short.
-  scoped_ptr<SpdyFrame> syn_reply_wrong_length(
+  scoped_ptr<SpdySerializedFrame> syn_reply_wrong_length(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
   size_t right_size =
       syn_reply_wrong_length->size() -
@@ -3471,14 +3575,15 @@
     // Decompression failures are a stream error in SPDY3.
     return;
   }
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(
+  scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(
       0, GOAWAY_COMPRESSION_ERROR, "Framer error: 5 (DECOMPRESS_FAILURE)."));
   MockWrite writes[] = {CreateMockWrite(*req, 0), CreateMockWrite(*goaway, 2)};
 
   // Read HEADERS with corrupted payload.
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   memset(resp->data() + 12, 0xcf, resp->size() - 12);
   MockRead reads[] = {CreateMockRead(*resp, 1)};
 
@@ -3491,16 +3596,16 @@
 }
 
 TEST_P(SpdyNetworkTransactionTest, GoAwayOnFrameSizeError) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(
+  scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(
       0, GOAWAY_PROTOCOL_ERROR, "Framer error: 1 (INVALID_CONTROL_FRAME)."));
   MockWrite writes[] = {CreateMockWrite(*req, 0), CreateMockWrite(*goaway, 2)};
 
   // Read WINDOW_UPDATE with incorrectly-sized payload.
   // TODO(jgraettinger): SpdyFramer signals this as an INVALID_CONTROL_FRAME,
   // which is mapped to a protocol error, and not a frame size error.
-  scoped_ptr<SpdyFrame> bad_window_update(
+  scoped_ptr<SpdySerializedFrame> bad_window_update(
       spdy_util_.ConstructSpdyWindowUpdate(1, 1));
   test::SetFrameLength(bad_window_update.get(),
                        bad_window_update->size() - 1,
@@ -3517,7 +3622,7 @@
 
 // Test that we shutdown correctly on write errors.
 TEST_P(SpdyNetworkTransactionTest, WriteError) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite writes[] = {
       // We'll write 10 bytes successfully
@@ -3547,7 +3652,7 @@
 // Test that partial writes work.
 TEST_P(SpdyNetworkTransactionTest, PartialWrite) {
   // Chop the SYN_STREAM frame into 5 chunks.
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   const int kChunks = 5;
   scoped_ptr<MockWrite[]> writes(ChopWriteFrame(*req.get(), kChunks));
@@ -3555,8 +3660,10 @@
     writes[i].sequence_number = i;
   }
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       CreateMockRead(*resp, kChunks),
       CreateMockRead(*body, kChunks + 1),
@@ -3578,12 +3685,14 @@
   static const char* const kExtraHeaders[] = {
     "user-agent",   "Chrome",
   };
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(kExtraHeaders, 1, 1, LOWEST, true));
   MockWrite writes[] = {CreateMockWrite(*req, 0)};
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       CreateMockRead(*resp, 1),
       CreateMockRead(*body, 2),
@@ -3669,27 +3778,27 @@
 TEST_P(SpdyNetworkTransactionTest, BufferFull) {
   BufferedSpdyFramer framer(spdy_util_.spdy_version());
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite writes[] = {CreateMockWrite(*req, 0)};
 
   // 2 data frames in a single read.
-  scoped_ptr<SpdyFrame> data_frame_1(
+  scoped_ptr<SpdySerializedFrame> data_frame_1(
       framer.CreateDataFrame(1, "goodby", 6, DATA_FLAG_NONE));
-  scoped_ptr<SpdyFrame> data_frame_2(
+  scoped_ptr<SpdySerializedFrame> data_frame_2(
       framer.CreateDataFrame(1, "e worl", 6, DATA_FLAG_NONE));
-  const SpdyFrame* data_frames[2] = {
-    data_frame_1.get(),
-    data_frame_2.get(),
+  const SpdySerializedFrame* data_frames[2] = {
+      data_frame_1.get(), data_frame_2.get(),
   };
   char combined_data_frames[100];
   int combined_data_frames_len =
       CombineFrames(data_frames, arraysize(data_frames),
                     combined_data_frames, arraysize(combined_data_frames));
-  scoped_ptr<SpdyFrame> last_frame(
+  scoped_ptr<SpdySerializedFrame> last_frame(
       framer.CreateDataFrame(1, "d", 1, DATA_FLAG_FIN));
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   MockRead reads[] = {
       CreateMockRead(*resp, 1),
       MockRead(ASYNC, ERR_IO_PENDING, 2),  // Force a pause
@@ -3762,27 +3871,25 @@
 TEST_P(SpdyNetworkTransactionTest, Buffering) {
   BufferedSpdyFramer framer(spdy_util_.spdy_version());
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite writes[] = {CreateMockWrite(*req, 0)};
 
   // 4 data frames in a single read.
-  scoped_ptr<SpdyFrame> data_frame(
+  scoped_ptr<SpdySerializedFrame> data_frame(
       framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE));
-  scoped_ptr<SpdyFrame> data_frame_fin(
+  scoped_ptr<SpdySerializedFrame> data_frame_fin(
       framer.CreateDataFrame(1, "message", 7, DATA_FLAG_FIN));
-  const SpdyFrame* data_frames[4] = {
-    data_frame.get(),
-    data_frame.get(),
-    data_frame.get(),
-    data_frame_fin.get()
-  };
+  const SpdySerializedFrame* data_frames[4] = {
+      data_frame.get(), data_frame.get(), data_frame.get(),
+      data_frame_fin.get()};
   char combined_data_frames[100];
   int combined_data_frames_len =
       CombineFrames(data_frames, arraysize(data_frames),
                     combined_data_frames, arraysize(combined_data_frames));
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   MockRead reads[] = {
       CreateMockRead(*resp, 1),
       MockRead(ASYNC, ERR_IO_PENDING, 2),  // Force a pause
@@ -3856,18 +3963,20 @@
 TEST_P(SpdyNetworkTransactionTest, BufferedAll) {
   BufferedSpdyFramer framer(spdy_util_.spdy_version());
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite writes[] = {CreateMockWrite(*req, 0)};
 
   // 5 data frames in a single read.
-  scoped_ptr<SpdyFrame> reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> data_frame(
+  scoped_ptr<SpdySerializedFrame> reply(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> data_frame(
       framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE));
-  scoped_ptr<SpdyFrame> data_frame_fin(
+  scoped_ptr<SpdySerializedFrame> data_frame_fin(
       framer.CreateDataFrame(1, "message", 7, DATA_FLAG_FIN));
-  const SpdyFrame* frames[5] = {reply.get(), data_frame.get(), data_frame.get(),
-                                data_frame.get(), data_frame_fin.get()};
+  const SpdySerializedFrame* frames[5] = {reply.get(), data_frame.get(),
+                                          data_frame.get(), data_frame.get(),
+                                          data_frame_fin.get()};
   char combined_frames[200];
   int combined_frames_len =
       CombineFrames(frames, arraysize(frames),
@@ -3940,25 +4049,22 @@
 TEST_P(SpdyNetworkTransactionTest, BufferedClosed) {
   BufferedSpdyFramer framer(spdy_util_.spdy_version());
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite writes[] = {CreateMockWrite(*req, 0)};
 
   // All data frames in a single read.
   // NOTE: We don't FIN the stream.
-  scoped_ptr<SpdyFrame> data_frame(
+  scoped_ptr<SpdySerializedFrame> data_frame(
       framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE));
-  const SpdyFrame* data_frames[4] = {
-    data_frame.get(),
-    data_frame.get(),
-    data_frame.get(),
-    data_frame.get()
-  };
+  const SpdySerializedFrame* data_frames[4] = {
+      data_frame.get(), data_frame.get(), data_frame.get(), data_frame.get()};
   char combined_data_frames[100];
   int combined_data_frames_len =
       CombineFrames(data_frames, arraysize(data_frames),
                     combined_data_frames, arraysize(combined_data_frames));
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   MockRead reads[] = {
       CreateMockRead(*resp, 1),
       MockRead(ASYNC, ERR_IO_PENDING, 2),  // Force a wait
@@ -4030,17 +4136,18 @@
 TEST_P(SpdyNetworkTransactionTest, BufferedCancelled) {
   BufferedSpdyFramer framer(spdy_util_.spdy_version());
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   MockWrite writes[] = {CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4)};
 
   // NOTE: We don't FIN the stream.
-  scoped_ptr<SpdyFrame> data_frame(
+  scoped_ptr<SpdySerializedFrame> data_frame(
       framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE));
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   MockRead reads[] = {
       CreateMockRead(*resp, 1),
       MockRead(ASYNC, ERR_IO_PENDING, 2),  // Force a wait
@@ -4126,7 +4233,7 @@
       host_port_pair).empty());
 
   // Construct the request.
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite writes[] = {CreateMockWrite(*req, 0)};
 
@@ -4134,7 +4241,7 @@
   scoped_ptr<SpdyHeaderBlock> reply_headers(new SpdyHeaderBlock());
   (*reply_headers)[spdy_util_.GetStatusKey()] = "200";
   (*reply_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
-  scoped_ptr<SpdyFrame> reply(
+  scoped_ptr<SpdySerializedFrame> reply(
       spdy_util_.ConstructSpdyFrame(kSynReplyInfo, std::move(reply_headers)));
 
   const SpdySettingsIds kSampleId1 = SETTINGS_UPLOAD_BANDWIDTH;
@@ -4143,7 +4250,7 @@
   unsigned int kSampleValue2 = 0x0b0b0b0b;
   const SpdySettingsIds kSampleId3 = SETTINGS_ROUND_TRIP_TIME;
   unsigned int kSampleValue3 = 0x0c0c0c0c;
-  scoped_ptr<SpdyFrame> settings_frame;
+  scoped_ptr<SpdySerializedFrame> settings_frame;
   {
     // Construct the SETTINGS frame.
     SettingsMap settings;
@@ -4159,7 +4266,8 @@
     settings_frame.reset(spdy_util_.ConstructSpdySettings(settings));
   }
 
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       CreateMockRead(*reply, 1),
       CreateMockRead(*body, 2),
@@ -4260,18 +4368,18 @@
   SettingsMap initial_settings;
   initial_settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams);
-  scoped_ptr<SpdyFrame> initial_settings_frame(
+  scoped_ptr<SpdySerializedFrame> initial_settings_frame(
       spdy_util_.ConstructSpdySettings(initial_settings));
 
   // Construct the persisted SETTINGS frame.
   const SettingsMap& settings =
       spdy_session_pool->http_server_properties()->GetSpdySettings(
           host_port_pair);
-  scoped_ptr<SpdyFrame> settings_frame(
+  scoped_ptr<SpdySerializedFrame> settings_frame(
       spdy_util_.ConstructSpdySettings(settings));
 
   // Construct the request.
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
 
   MockWrite writes[] = {
@@ -4284,10 +4392,11 @@
   scoped_ptr<SpdyHeaderBlock> reply_headers(new SpdyHeaderBlock());
   (*reply_headers)[spdy_util_.GetStatusKey()] = "200";
   (*reply_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
-  scoped_ptr<SpdyFrame> reply(
+  scoped_ptr<SpdySerializedFrame> reply(
       spdy_util_.ConstructSpdyFrame(kSynReplyInfo, std::move(reply_headers)));
 
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       CreateMockRead(*reply, 3),
       CreateMockRead(*body, 4),
@@ -4327,11 +4436,11 @@
 }
 
 TEST_P(SpdyNetworkTransactionTest, GoAwayWithActiveStream) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite writes[] = {CreateMockWrite(*req, 0)};
 
-  scoped_ptr<SpdyFrame> go_away(spdy_util_.ConstructSpdyGoAway());
+  scoped_ptr<SpdySerializedFrame> go_away(spdy_util_.ConstructSpdyGoAway());
   MockRead reads[] = {
       CreateMockRead(*go_away, 1),
   };
@@ -4346,11 +4455,12 @@
 }
 
 TEST_P(SpdyNetworkTransactionTest, CloseWithActiveStream) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite writes[] = {CreateMockWrite(*req, 0)};
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   MockRead reads[] = {
       CreateMockRead(*resp, 1), MockRead(SYNCHRONOUS, 0, 2)  // EOF
   };
@@ -4390,7 +4500,7 @@
   NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
                                      BoundNetLog(), GetParam(), nullptr);
 
-  scoped_ptr<SpdyFrame> go_away(spdy_util_.ConstructSpdyGoAway(
+  scoped_ptr<SpdySerializedFrame> go_away(spdy_util_.ConstructSpdyGoAway(
       0, GOAWAY_HTTP_1_1_REQUIRED, "Try again using HTTP/1.1 please."));
   MockRead reads[] = {
       CreateMockRead(*go_away, 0),
@@ -4426,10 +4536,10 @@
   // First socket: HTTP/2 request rejected with HTTP_1_1_REQUIRED.
   const char* url = request.url.spec().c_str();
   scoped_ptr<SpdyHeaderBlock> headers(spdy_util_.ConstructGetHeaderBlock(url));
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, true));
   MockWrite writes0[] = {CreateMockWrite(*req, 0)};
-  scoped_ptr<SpdyFrame> go_away(spdy_util_.ConstructSpdyGoAway(
+  scoped_ptr<SpdySerializedFrame> go_away(spdy_util_.ConstructSpdyGoAway(
       0, GOAWAY_HTTP_1_1_REQUIRED, "Try again using HTTP/1.1 please."));
   MockRead reads0[] = {CreateMockRead(*go_away, 1)};
   SequencedSocketData data0(reads0, arraysize(reads0), writes0,
@@ -4515,10 +4625,10 @@
                                      GetParam(), std::move(session_deps));
 
   // First socket: HTTP/2 CONNECT rejected with HTTP_1_1_REQUIRED.
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyConnect(
       nullptr, 0, 1, LOWEST, HostPortPair("www.example.org", 443)));
   MockWrite writes0[] = {CreateMockWrite(*req, 0)};
-  scoped_ptr<SpdyFrame> go_away(spdy_util_.ConstructSpdyGoAway(
+  scoped_ptr<SpdySerializedFrame> go_away(spdy_util_.ConstructSpdyGoAway(
       0, GOAWAY_HTTP_1_1_REQUIRED, "Try again using HTTP/1.1 please."));
   MockRead reads0[] = {CreateMockRead(*go_away, 1)};
   SequencedSocketData data0(reads0, arraysize(reads0), writes0,
@@ -4612,10 +4722,12 @@
       "Host: www.example.org:443\r\n"
       "Proxy-Connection: keep-alive\r\n\r\n"};
   const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"};
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
 
   MockWrite writes[] = {
       MockWrite(SYNCHRONOUS, kConnect443, arraysize(kConnect443) - 1, 0),
@@ -4674,14 +4786,16 @@
   helper.RunPreTestSetup();
 
   // Construct and send a simple GET request.
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0),
   };
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       CreateMockRead(*resp, 1),
       CreateMockRead(*body, 2),
@@ -4731,10 +4845,12 @@
       "Host: www.example.org:443\r\n"
       "Proxy-Connection: keep-alive\r\n\r\n"};
   const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"};
-  scoped_ptr<SpdyFrame> req2(spdy_util_2.ConstructSpdyGet(
+  scoped_ptr<SpdySerializedFrame> req2(spdy_util_2.ConstructSpdyGet(
       GetDefaultUrlWithPath("/foo.dat").c_str(), 1, LOWEST));
-  scoped_ptr<SpdyFrame> resp2(spdy_util_2.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body2(spdy_util_2.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp2(
+      spdy_util_2.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body2(
+      spdy_util_2.ConstructSpdyBodyFrame(1, true));
 
   MockWrite writes2[] = {
       MockWrite(SYNCHRONOUS, kConnect443, arraysize(kConnect443) - 1, 0),
@@ -4795,8 +4911,10 @@
 // This can happen when a server reboots without saying goodbye, or when
 // we're behind a NAT that masked the RST.
 TEST_P(SpdyNetworkTransactionTest, VerifyRetryOnConnectionReset) {
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       CreateMockRead(*resp, 1),
       CreateMockRead(*body, 2),
@@ -4810,12 +4928,12 @@
       MockRead(ASYNC, 0, 3)  // EOF
   };
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   // In all cases the connection will be reset before req3 can be
   // dispatched, destroying both streams.
   spdy_util_.UpdateWithStreamDestruction(1);
-  scoped_ptr<SpdyFrame> req3(
+  scoped_ptr<SpdySerializedFrame> req3(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true));
   MockWrite writes1[] = {CreateMockWrite(*req, 0), CreateMockWrite(*req3, 5)};
   MockWrite writes2[] = {CreateMockWrite(*req, 0)};
@@ -4885,12 +5003,14 @@
 // Test that turning SPDY on and off works properly.
 TEST_P(SpdyNetworkTransactionTest, SpdyOnOffToggle) {
   HttpStreamFactory::set_spdy_enabled(true);
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)};
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead spdy_reads[] = {
       CreateMockRead(*resp, 1),
       CreateMockRead(*body, 2),
@@ -4940,16 +5060,17 @@
 
   // The first request will be a bare GET, the second request will be a
   // GET with an Authorization header.
-  scoped_ptr<SpdyFrame> req_get(
+  scoped_ptr<SpdySerializedFrame> req_get(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   // Will be refused for lack of auth.
   spdy_util_.UpdateWithStreamDestruction(1);
   const char* const kExtraAuthorizationHeaders[] = {
     "authorization", "Basic Zm9vOmJhcg=="
   };
-  scoped_ptr<SpdyFrame> req_get_authorization(spdy_util_.ConstructSpdyGet(
-      kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3,
-      LOWEST, true));
+  scoped_ptr<SpdySerializedFrame> req_get_authorization(
+      spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
+                                  arraysize(kExtraAuthorizationHeaders) / 2, 3,
+                                  LOWEST, true));
   MockWrite spdy_writes[] = {
       CreateMockWrite(*req_get, 0), CreateMockWrite(*req_get_authorization, 3),
   };
@@ -4961,17 +5082,16 @@
     "www-authenticate",
     "Basic realm=\"MyRealm\""
   };
-  scoped_ptr<SpdyFrame> resp_authentication(
+  scoped_ptr<SpdySerializedFrame> resp_authentication(
       spdy_util_.ConstructSpdySynReplyError(
-          "401 Authentication Required",
-          kExtraAuthenticationHeaders,
-          arraysize(kExtraAuthenticationHeaders) / 2,
-          1));
-  scoped_ptr<SpdyFrame> body_authentication(
+          "401 Authentication Required", kExtraAuthenticationHeaders,
+          arraysize(kExtraAuthenticationHeaders) / 2, 1));
+  scoped_ptr<SpdySerializedFrame> body_authentication(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
-  scoped_ptr<SpdyFrame> resp_data(
+  scoped_ptr<SpdySerializedFrame> resp_data(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
-  scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
+  scoped_ptr<SpdySerializedFrame> body_data(
+      spdy_util_.ConstructSpdyBodyFrame(3, true));
   MockRead spdy_reads[] = {
       CreateMockRead(*resp_authentication, 1),
       CreateMockRead(*body_authentication, 2),
@@ -5027,35 +5147,36 @@
 }
 
 TEST_P(SpdyNetworkTransactionTest, ServerPushWithHeaders) {
-  scoped_ptr<SpdyFrame> stream1_syn(
+  scoped_ptr<SpdySerializedFrame> stream1_syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite writes[] = {
       CreateMockWrite(*stream1_syn, 0),
   };
 
-  scoped_ptr<SpdyFrame> stream1_reply(
+  scoped_ptr<SpdySerializedFrame> stream1_reply(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
 
   scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
   spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"),
                                  initial_headers.get());
-  scoped_ptr<SpdyFrame> stream2_syn(spdy_util_.ConstructInitialSpdyPushFrame(
-      std::move(initial_headers), 2, 1));
+  scoped_ptr<SpdySerializedFrame> stream2_syn(
+      spdy_util_.ConstructInitialSpdyPushFrame(std::move(initial_headers), 2,
+                                               1));
 
   SpdyHeaderBlock late_headers;
   late_headers[spdy_util_.GetStatusKey()] = "200";
   late_headers[spdy_util_.GetVersionKey()] = "HTTP/1.1";
   late_headers["hello"] = "bye";
-  scoped_ptr<SpdyFrame> stream2_headers(
+  scoped_ptr<SpdySerializedFrame> stream2_headers(
       spdy_util_.ConstructSpdyResponseHeaders(2, late_headers, false));
 
-  scoped_ptr<SpdyFrame> stream1_body(
+  scoped_ptr<SpdySerializedFrame> stream1_body(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
 
   const char kPushedData[] = "pushed";
-  scoped_ptr<SpdyFrame> stream2_body(
-      spdy_util_.ConstructSpdyBodyFrame(
-          2, kPushedData, strlen(kPushedData), true));
+  scoped_ptr<SpdySerializedFrame> stream2_body(
+      spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData),
+                                        true));
 
   MockRead reads[] = {
       CreateMockRead(*stream1_reply, 1),
@@ -5086,31 +5207,32 @@
 
 TEST_P(SpdyNetworkTransactionTest, ServerPushClaimBeforeHeaders) {
   // We push a stream and attempt to claim it before the headers come down.
-  scoped_ptr<SpdyFrame> stream1_syn(
+  scoped_ptr<SpdySerializedFrame> stream1_syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite writes[] = {
     CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> stream1_reply(
+  scoped_ptr<SpdySerializedFrame> stream1_reply(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
   scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
   spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"),
                                  initial_headers.get());
-  scoped_ptr<SpdyFrame> stream2_syn(spdy_util_.ConstructInitialSpdyPushFrame(
-      std::move(initial_headers), 2, 1));
-  scoped_ptr<SpdyFrame> stream1_body(
+  scoped_ptr<SpdySerializedFrame> stream2_syn(
+      spdy_util_.ConstructInitialSpdyPushFrame(std::move(initial_headers), 2,
+                                               1));
+  scoped_ptr<SpdySerializedFrame> stream1_body(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
   SpdyHeaderBlock late_headers;
   late_headers[spdy_util_.GetStatusKey()] = "200";
   late_headers[spdy_util_.GetVersionKey()] = "HTTP/1.1";
   late_headers["hello"] = "bye";
-  scoped_ptr<SpdyFrame> stream2_headers(
+  scoped_ptr<SpdySerializedFrame> stream2_headers(
       spdy_util_.ConstructSpdyResponseHeaders(2, late_headers, false));
   const char kPushedData[] = "pushed";
-  scoped_ptr<SpdyFrame> stream2_body(
-      spdy_util_.ConstructSpdyBodyFrame(
-          2, kPushedData, strlen(kPushedData), true));
+  scoped_ptr<SpdySerializedFrame> stream2_body(
+      spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData),
+                                        true));
   MockRead reads[] = {
       CreateMockRead(*stream1_reply, 1),   CreateMockRead(*stream2_syn, 2),
       CreateMockRead(*stream1_body, 3),    MockRead(ASYNC, ERR_IO_PENDING, 4),
@@ -5193,13 +5315,13 @@
 // TODO(baranovich): HTTP 2 does not allow multiple HEADERS frames
 TEST_P(SpdyNetworkTransactionTest, ServerPushWithTwoHeaderFrames) {
   // We push a stream and attempt to claim it before the headers come down.
-  scoped_ptr<SpdyFrame> stream1_syn(
+  scoped_ptr<SpdySerializedFrame> stream1_syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite writes[] = {
     CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> stream1_reply(
+  scoped_ptr<SpdySerializedFrame> stream1_reply(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
 
   scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
@@ -5209,15 +5331,16 @@
   }
   spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"),
                                  initial_headers.get());
-  scoped_ptr<SpdyFrame> stream2_syn(spdy_util_.ConstructInitialSpdyPushFrame(
-      std::move(initial_headers), 2, 1));
+  scoped_ptr<SpdySerializedFrame> stream2_syn(
+      spdy_util_.ConstructInitialSpdyPushFrame(std::move(initial_headers), 2,
+                                               1));
 
-  scoped_ptr<SpdyFrame> stream1_body(
+  scoped_ptr<SpdySerializedFrame> stream1_body(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
 
   SpdyHeaderBlock middle_headers;
   middle_headers["hello"] = "bye";
-  scoped_ptr<SpdyFrame> stream2_headers1(
+  scoped_ptr<SpdySerializedFrame> stream2_headers1(
       spdy_util_.ConstructSpdyResponseHeaders(2, middle_headers, false));
 
   SpdyHeaderBlock late_headers;
@@ -5226,13 +5349,13 @@
     // HTTP/2 eliminates use of the :version header.
     late_headers[spdy_util_.GetVersionKey()] = "HTTP/1.1";
   }
-  scoped_ptr<SpdyFrame> stream2_headers2(
+  scoped_ptr<SpdySerializedFrame> stream2_headers2(
       spdy_util_.ConstructSpdyResponseHeaders(2, late_headers, false));
 
   const char kPushedData[] = "pushed";
-  scoped_ptr<SpdyFrame> stream2_body(
-      spdy_util_.ConstructSpdyBodyFrame(
-          2, kPushedData, strlen(kPushedData), true));
+  scoped_ptr<SpdySerializedFrame> stream2_body(
+      spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData),
+                                        true));
 
   MockRead reads[] = {
       CreateMockRead(*stream1_reply, 1), CreateMockRead(*stream2_syn, 2),
@@ -5324,33 +5447,34 @@
 
 TEST_P(SpdyNetworkTransactionTest, ServerPushWithNoStatusHeaderFrames) {
   // We push a stream and attempt to claim it before the headers come down.
-  scoped_ptr<SpdyFrame> stream1_syn(
+  scoped_ptr<SpdySerializedFrame> stream1_syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite writes[] = {
     CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> stream1_reply(
+  scoped_ptr<SpdySerializedFrame> stream1_reply(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
 
   scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
   spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"),
                                  initial_headers.get());
-  scoped_ptr<SpdyFrame> stream2_syn(spdy_util_.ConstructInitialSpdyPushFrame(
-      std::move(initial_headers), 2, 1));
+  scoped_ptr<SpdySerializedFrame> stream2_syn(
+      spdy_util_.ConstructInitialSpdyPushFrame(std::move(initial_headers), 2,
+                                               1));
 
-  scoped_ptr<SpdyFrame> stream1_body(
+  scoped_ptr<SpdySerializedFrame> stream1_body(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
 
   SpdyHeaderBlock middle_headers;
   middle_headers["hello"] = "bye";
-  scoped_ptr<SpdyFrame> stream2_headers1(
+  scoped_ptr<SpdySerializedFrame> stream2_headers1(
       spdy_util_.ConstructSpdyResponseHeaders(2, middle_headers, false));
 
   const char kPushedData[] = "pushed";
-  scoped_ptr<SpdyFrame> stream2_body(
-      spdy_util_.ConstructSpdyBodyFrame(
-          2, kPushedData, strlen(kPushedData), true));
+  scoped_ptr<SpdySerializedFrame> stream2_body(
+      spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData),
+                                        true));
 
   MockRead reads[] = {
       CreateMockRead(*stream1_reply, 1),    CreateMockRead(*stream2_syn, 2),
@@ -5421,22 +5545,22 @@
 }
 
 TEST_P(SpdyNetworkTransactionTest, SynReplyWithHeaders) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4),
   };
 
-  scoped_ptr<SpdyFrame> stream1_reply(
+  scoped_ptr<SpdySerializedFrame> stream1_reply(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
 
   SpdyHeaderBlock late_headers;
   late_headers["hello"] = "bye";
-  scoped_ptr<SpdyFrame> stream1_headers(
+  scoped_ptr<SpdySerializedFrame> stream1_headers(
       spdy_util_.ConstructSpdyResponseHeaders(1, late_headers, false));
-  scoped_ptr<SpdyFrame> stream1_body(
+  scoped_ptr<SpdySerializedFrame> stream1_body(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       CreateMockRead(*stream1_reply, 1),
@@ -5457,24 +5581,24 @@
 // trigger a ERR_SPDY_PROTOCOL_ERROR because trailing HEADERS must not be
 // followed by any DATA frames.
 TEST_P(SpdyNetworkTransactionTest, SyncReplyDataAfterTrailers) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*rst, 5),
   };
 
-  scoped_ptr<SpdyFrame> stream1_reply(
+  scoped_ptr<SpdySerializedFrame> stream1_reply(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> stream1_body(
+  scoped_ptr<SpdySerializedFrame> stream1_body(
       spdy_util_.ConstructSpdyBodyFrame(1, false));
 
   SpdyHeaderBlock late_headers;
   late_headers["hello"] = "bye";
-  scoped_ptr<SpdyFrame> stream1_headers(
+  scoped_ptr<SpdySerializedFrame> stream1_headers(
       spdy_util_.ConstructSpdyResponseHeaders(1, late_headers, false));
-  scoped_ptr<SpdyFrame> stream1_body2(
+  scoped_ptr<SpdySerializedFrame> stream1_body2(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       CreateMockRead(*stream1_reply, 1), CreateMockRead(*stream1_body, 2),
@@ -5522,24 +5646,25 @@
 
     SpdyTestUtil spdy_test_util(GetParam().protocol,
                                 GetParam().priority_to_dependency);
-    scoped_ptr<SpdyFrame> stream1_syn(
+    scoped_ptr<SpdySerializedFrame> stream1_syn(
         spdy_test_util.ConstructSpdyGet(url_to_fetch, 1, LOWEST));
-    scoped_ptr<SpdyFrame> stream1_body(
+    scoped_ptr<SpdySerializedFrame> stream1_body(
         spdy_test_util.ConstructSpdyBodyFrame(1, true));
-    scoped_ptr<SpdyFrame> push_rst(
+    scoped_ptr<SpdySerializedFrame> push_rst(
         spdy_test_util.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
     MockWrite writes[] = {
         CreateMockWrite(*stream1_syn, 0), CreateMockWrite(*push_rst, 3),
     };
 
-    scoped_ptr<SpdyFrame> stream1_reply(
+    scoped_ptr<SpdySerializedFrame> stream1_reply(
         spdy_test_util.ConstructSpdyGetSynReply(nullptr, 0, 1));
-    scoped_ptr<SpdyFrame> stream2_syn(
+    scoped_ptr<SpdySerializedFrame> stream2_syn(
         spdy_test_util.ConstructSpdyPush(nullptr, 0, 2, 1, url_to_push));
     const char kPushedData[] = "pushed";
-    scoped_ptr<SpdyFrame> stream2_body(spdy_test_util.ConstructSpdyBodyFrame(
-        2, kPushedData, strlen(kPushedData), true));
-    scoped_ptr<SpdyFrame> rst(
+    scoped_ptr<SpdySerializedFrame> stream2_body(
+        spdy_test_util.ConstructSpdyBodyFrame(2, kPushedData,
+                                              strlen(kPushedData), true));
+    scoped_ptr<SpdySerializedFrame> rst(
         spdy_test_util.ConstructSpdyRstStream(2, RST_STREAM_CANCEL));
 
     MockRead reads[] = {
@@ -5608,19 +5733,20 @@
   const char* url_to_fetch = "https://www.example.org";
   const char* url_to_push = "https://mail.example.org";
 
-  scoped_ptr<SpdyFrame> headers(
+  scoped_ptr<SpdySerializedFrame> headers(
       spdy_util_.ConstructSpdyGet(url_to_fetch, 1, LOWEST));
   MockWrite writes[] = {
       CreateMockWrite(*headers, 0),
   };
 
-  scoped_ptr<SpdyFrame> reply(
+  scoped_ptr<SpdySerializedFrame> reply(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> push(
+  scoped_ptr<SpdySerializedFrame> push(
       spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, url_to_push));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   const char kPushedData[] = "pushed";
-  scoped_ptr<SpdyFrame> pushed_body(spdy_util_.ConstructSpdyBodyFrame(
+  scoped_ptr<SpdySerializedFrame> pushed_body(spdy_util_.ConstructSpdyBodyFrame(
       2, kPushedData, strlen(kPushedData), true));
   MockRead reads[] = {
       CreateMockRead(*reply, 1),
@@ -5709,16 +5835,16 @@
   SpdyTestUtil spdy_util_0(GetParam().protocol,
                            GetParam().priority_to_dependency);
 
-  scoped_ptr<SpdyFrame> headers0(
+  scoped_ptr<SpdySerializedFrame> headers0(
       spdy_util_0.ConstructSpdyGet(url_to_fetch0, 1, LOWEST));
   MockWrite writes0[] = {
       CreateMockWrite(*headers0, 0),
   };
 
-  scoped_ptr<SpdyFrame> reply0(
+  scoped_ptr<SpdySerializedFrame> reply0(
       spdy_util_0.ConstructSpdyGetSynReply(nullptr, 0, 1));
   const char kData0[] = "first";
-  scoped_ptr<SpdyFrame> body0(
+  scoped_ptr<SpdySerializedFrame> body0(
       spdy_util_0.ConstructSpdyBodyFrame(1, kData0, strlen(kData0), true));
   MockRead reads0[] = {
       CreateMockRead(*reply0, 1),
@@ -5732,22 +5858,23 @@
   SpdyTestUtil spdy_util_1(GetParam().protocol,
                            GetParam().priority_to_dependency);
 
-  scoped_ptr<SpdyFrame> headers1(
+  scoped_ptr<SpdySerializedFrame> headers1(
       spdy_util_1.ConstructSpdyGet(url_to_fetch1, 1, LOWEST));
   MockWrite writes1[] = {
       CreateMockWrite(*headers1, 0),
   };
 
-  scoped_ptr<SpdyFrame> reply1(
+  scoped_ptr<SpdySerializedFrame> reply1(
       spdy_util_1.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> push(
+  scoped_ptr<SpdySerializedFrame> push(
       spdy_util_1.ConstructSpdyPush(nullptr, 0, 2, 1, url_to_push));
   const char kData1[] = "second";
-  scoped_ptr<SpdyFrame> body1(
+  scoped_ptr<SpdySerializedFrame> body1(
       spdy_util_1.ConstructSpdyBodyFrame(1, kData1, strlen(kData1), true));
   const char kPushedData[] = "pushed";
-  scoped_ptr<SpdyFrame> pushed_body(spdy_util_1.ConstructSpdyBodyFrame(
-      2, kPushedData, strlen(kPushedData), true));
+  scoped_ptr<SpdySerializedFrame> pushed_body(
+      spdy_util_1.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData),
+                                         true));
 
   MockRead reads1[] = {
       CreateMockRead(*reply1, 1),
@@ -5879,22 +6006,23 @@
   const char* url_to_fetch = "https://www.example.org";
   const char* url_to_push = "https://invalid.example.org";
 
-  scoped_ptr<SpdyFrame> headers(
+  scoped_ptr<SpdySerializedFrame> headers(
       spdy_util_.ConstructSpdyGet(url_to_fetch, 1, LOWEST));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
   MockWrite writes[] = {
       CreateMockWrite(*headers, 0),
       CreateMockWrite(*rst, 3),
   };
 
-  scoped_ptr<SpdyFrame> reply(
+  scoped_ptr<SpdySerializedFrame> reply(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> push(
+  scoped_ptr<SpdySerializedFrame> push(
       spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, url_to_push));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   const char kPushedData[] = "pushed";
-  scoped_ptr<SpdyFrame> pushed_body(spdy_util_.ConstructSpdyBodyFrame(
+  scoped_ptr<SpdySerializedFrame> pushed_body(spdy_util_.ConstructSpdyBodyFrame(
       2, kPushedData, strlen(kPushedData), true));
   MockRead reads[] = {
       CreateMockRead(*reply, 1),
@@ -5921,20 +6049,22 @@
 
 TEST_P(SpdyNetworkTransactionTest, RetryAfterRefused) {
   // Construct the request.
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   // Will be destroyed by the RST before stream 3 starts.
   spdy_util_.UpdateWithStreamDestruction(1);
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*req2, 2),
   };
 
-  scoped_ptr<SpdyFrame> refused(
+  scoped_ptr<SpdySerializedFrame> refused(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_REFUSED_STREAM));
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(3, true));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(3, true));
   MockRead reads[] = {
       CreateMockRead(*refused, 1),
       CreateMockRead(*resp, 3),
@@ -5986,24 +6116,30 @@
   // req1 is alive when req2 is attempted (during but not after the
   // |data.RunFor(2);| statement below) but not when req3 is attempted.
   // The call to spdy_util_.UpdateWithStreamDestruction() reflects this.
-  scoped_ptr<SpdyFrame> req1(
+  scoped_ptr<SpdySerializedFrame> req1(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, HIGHEST, true));
   spdy_util_.UpdateWithStreamDestruction(1);
-  scoped_ptr<SpdyFrame> req3(
+  scoped_ptr<SpdySerializedFrame> req3(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 5, MEDIUM, true));
   MockWrite writes[] = {
       MockWrite(ASYNC, ERR_IO_PENDING, 0), CreateMockWrite(*req1, 1),
       CreateMockWrite(*req2, 5), CreateMockWrite(*req3, 6),
   };
 
-  scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
-  scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
-  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
-  scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5));
-  scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(5, true));
+  scoped_ptr<SpdySerializedFrame> resp1(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> body1(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> resp2(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
+  scoped_ptr<SpdySerializedFrame> body2(
+      spdy_util_.ConstructSpdyBodyFrame(3, true));
+  scoped_ptr<SpdySerializedFrame> resp3(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5));
+  scoped_ptr<SpdySerializedFrame> body3(
+      spdy_util_.ConstructSpdyBodyFrame(5, true));
   MockRead reads[] = {
       CreateMockRead(*resp1, 2), MockRead(ASYNC, ERR_IO_PENDING, 3),
       CreateMockRead(*body1, 4), CreateMockRead(*resp2, 7),
@@ -6089,15 +6225,13 @@
   static int kFrameCount = 2;
   scoped_ptr<std::string> content(
       new std::string(kMaxSpdyFrameChunkSize, 'a'));
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
       GetDefaultUrl(), 1, kMaxSpdyFrameChunkSize * kFrameCount, LOWEST, NULL,
       0));
-  scoped_ptr<SpdyFrame> body(
-      spdy_util_.ConstructSpdyBodyFrame(
-          1, content->c_str(), content->size(), false));
-  scoped_ptr<SpdyFrame> body_end(
-      spdy_util_.ConstructSpdyBodyFrame(
-          1, content->c_str(), content->size(), true));
+  scoped_ptr<SpdySerializedFrame> body(spdy_util_.ConstructSpdyBodyFrame(
+      1, content->c_str(), content->size(), false));
+  scoped_ptr<SpdySerializedFrame> body_end(spdy_util_.ConstructSpdyBodyFrame(
+      1, content->c_str(), content->size(), true));
 
   MockWrite writes[] = {
     CreateMockWrite(*req, 0),
@@ -6107,11 +6241,12 @@
 
   static const int32_t kDeltaWindowSize = 0xff;
   static const int kDeltaCount = 4;
-  scoped_ptr<SpdyFrame> window_update(
+  scoped_ptr<SpdySerializedFrame> window_update(
       spdy_util_.ConstructSpdyWindowUpdate(1, kDeltaWindowSize));
-  scoped_ptr<SpdyFrame> window_update_dummy(
+  scoped_ptr<SpdySerializedFrame> window_update_dummy(
       spdy_util_.ConstructSpdyWindowUpdate(2, kDeltaWindowSize));
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
   MockRead reads[] = {
       CreateMockRead(*window_update_dummy, 3),
       CreateMockRead(*window_update_dummy, 4),
@@ -6209,17 +6344,17 @@
       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams);
   initial_settings[SETTINGS_INITIAL_WINDOW_SIZE] =
       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, stream_max_recv_window_size);
-  scoped_ptr<SpdyFrame> initial_settings_frame(
+  scoped_ptr<SpdySerializedFrame> initial_settings_frame(
       spdy_util_.ConstructSpdySettings(initial_settings));
-  scoped_ptr<SpdyFrame> initial_window_update(
+  scoped_ptr<SpdySerializedFrame> initial_window_update(
       spdy_util_.ConstructSpdyWindowUpdate(
           kSessionFlowControlStreamId,
           session_max_recv_window_size - default_initial_window_size));
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> session_window_update(
+  scoped_ptr<SpdySerializedFrame> session_window_update(
       spdy_util_.ConstructSpdyWindowUpdate(0, session_window_update_delta));
-  scoped_ptr<SpdyFrame> stream_window_update(
+  scoped_ptr<SpdySerializedFrame> stream_window_update(
       spdy_util_.ConstructSpdyWindowUpdate(1, stream_window_update_delta));
 
   std::vector<MockWrite> writes;
@@ -6232,11 +6367,11 @@
   writes.push_back(CreateMockWrite(*req, writes.size()));
 
   std::vector<MockRead> reads;
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   reads.push_back(CreateMockRead(*resp, writes.size() + reads.size()));
 
-  std::vector<scoped_ptr<SpdyFrame>> body_frames;
+  std::vector<scoped_ptr<SpdySerializedFrame>> body_frames;
   const std::string body_data(kChunkSize, 'x');
   for (size_t remaining = kTargetSize; remaining != 0;) {
     size_t frame_size = std::min(remaining, body_data.size());
@@ -6314,13 +6449,12 @@
 
   scoped_ptr<std::string> content(
       new std::string(kMaxSpdyFrameChunkSize, 'a'));
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
       GetDefaultUrl(), 1, kMaxSpdyFrameChunkSize * kFrameCount, LOWEST, NULL,
       0));
-  scoped_ptr<SpdyFrame> body(
-      spdy_util_.ConstructSpdyBodyFrame(
-          1, content->c_str(), content->size(), false));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> body(spdy_util_.ConstructSpdyBodyFrame(
+      1, content->c_str(), content->size(), false));
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_FLOW_CONTROL_ERROR));
 
   // We're not going to write a data frame with FIN, we'll receive a bad
@@ -6332,7 +6466,7 @@
   };
 
   static const int32_t kDeltaWindowSize = 0x7fffffff;  // cause an overflow
-  scoped_ptr<SpdyFrame> window_update(
+  scoped_ptr<SpdySerializedFrame> window_update(
       spdy_util_.ConstructSpdyWindowUpdate(1, kDeltaWindowSize));
   MockRead reads[] = {
     CreateMockRead(*window_update, 1),
@@ -6400,22 +6534,21 @@
   // Construct content for a data frame of maximum size.
   std::string content(kMaxSpdyFrameChunkSize, 'a');
 
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
       GetDefaultUrl(), 1, initial_window_size + kUploadDataSize, LOWEST, NULL,
       0));
 
   // Full frames.
-  scoped_ptr<SpdyFrame> body1(
-      spdy_util_.ConstructSpdyBodyFrame(
-          1, content.c_str(), content.size(), false));
+  scoped_ptr<SpdySerializedFrame> body1(spdy_util_.ConstructSpdyBodyFrame(
+      1, content.c_str(), content.size(), false));
 
   // Last frame to zero out the window size.
-  scoped_ptr<SpdyFrame> body2(
-      spdy_util_.ConstructSpdyBodyFrame(
-          1, content.c_str(), last_frame_size, false));
+  scoped_ptr<SpdySerializedFrame> body2(spdy_util_.ConstructSpdyBodyFrame(
+      1, content.c_str(), last_frame_size, false));
 
   // Data frame to be sent once WINDOW_UPDATE frame is received.
-  scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> body3(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
 
   // Fill in mock writes.
   scoped_ptr<MockWrite[]> writes(new MockWrite[num_writes]);
@@ -6430,11 +6563,12 @@
 
   // Construct read frame, give enough space to upload the rest of the
   // data.
-  scoped_ptr<SpdyFrame> session_window_update(
+  scoped_ptr<SpdySerializedFrame> session_window_update(
       spdy_util_.ConstructSpdyWindowUpdate(0, kUploadDataSize));
-  scoped_ptr<SpdyFrame> window_update(
+  scoped_ptr<SpdySerializedFrame> window_update(
       spdy_util_.ConstructSpdyWindowUpdate(1, kUploadDataSize));
-  scoped_ptr<SpdyFrame> reply(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> reply(
+      spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
   MockRead reads[] = {
       MockRead(ASYNC, ERR_IO_PENDING, i + 1),  // Force a pause
       CreateMockRead(*session_window_update, i + 2),
@@ -6506,22 +6640,21 @@
   // Construct content for a data frame of maximum size.
   std::string content(kMaxSpdyFrameChunkSize, 'a');
 
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
       GetDefaultUrl(), 1, initial_window_size + kUploadDataSize, LOWEST, NULL,
       0));
 
   // Full frames.
-  scoped_ptr<SpdyFrame> body1(
-      spdy_util_.ConstructSpdyBodyFrame(
-          1, content.c_str(), content.size(), false));
+  scoped_ptr<SpdySerializedFrame> body1(spdy_util_.ConstructSpdyBodyFrame(
+      1, content.c_str(), content.size(), false));
 
   // Last frame to zero out the window size.
-  scoped_ptr<SpdyFrame> body2(
-      spdy_util_.ConstructSpdyBodyFrame(
-          1, content.c_str(), last_frame_size, false));
+  scoped_ptr<SpdySerializedFrame> body2(spdy_util_.ConstructSpdyBodyFrame(
+      1, content.c_str(), last_frame_size, false));
 
   // Data frame to be sent once SETTINGS frame is received.
-  scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> body3(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
 
   // Fill in mock reads/writes.
   std::vector<MockRead> reads;
@@ -6539,21 +6672,23 @@
   SettingsMap settings;
   settings[SETTINGS_INITIAL_WINDOW_SIZE] =
       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, initial_window_size * 2);
-  scoped_ptr<SpdyFrame> settings_frame_large(
+  scoped_ptr<SpdySerializedFrame> settings_frame_large(
       spdy_util_.ConstructSpdySettings(settings));
 
   reads.push_back(CreateMockRead(*settings_frame_large, i++));
 
-  scoped_ptr<SpdyFrame> session_window_update(
+  scoped_ptr<SpdySerializedFrame> session_window_update(
       spdy_util_.ConstructSpdyWindowUpdate(0, kUploadDataSize));
   reads.push_back(CreateMockRead(*session_window_update, i++));
 
-  scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
+  scoped_ptr<SpdySerializedFrame> settings_ack(
+      spdy_util_.ConstructSpdySettingsAck());
   writes.push_back(CreateMockWrite(*settings_ack, i++));
 
   writes.push_back(CreateMockWrite(*body3, i++));
 
-  scoped_ptr<SpdyFrame> reply(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> reply(
+      spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
   reads.push_back(CreateMockRead(*reply, i++));
   reads.push_back(CreateMockRead(*body2, i++));
   reads.push_back(CreateMockRead(*body3, i++));
@@ -6628,22 +6763,21 @@
   // Construct content for a data frame of maximum size.
   std::string content(kMaxSpdyFrameChunkSize, 'a');
 
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
       GetDefaultUrl(), 1, initial_window_size + kUploadDataSize, LOWEST, NULL,
       0));
 
   // Full frames.
-  scoped_ptr<SpdyFrame> body1(
-      spdy_util_.ConstructSpdyBodyFrame(
-          1, content.c_str(), content.size(), false));
+  scoped_ptr<SpdySerializedFrame> body1(spdy_util_.ConstructSpdyBodyFrame(
+      1, content.c_str(), content.size(), false));
 
   // Last frame to zero out the window size.
-  scoped_ptr<SpdyFrame> body2(
-      spdy_util_.ConstructSpdyBodyFrame(
-          1, content.c_str(), last_frame_size, false));
+  scoped_ptr<SpdySerializedFrame> body2(spdy_util_.ConstructSpdyBodyFrame(
+      1, content.c_str(), last_frame_size, false));
 
   // Data frame to be sent once SETTINGS frame is received.
-  scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> body3(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
 
   // Fill in mock reads/writes.
   std::vector<MockRead> reads;
@@ -6661,25 +6795,27 @@
   SettingsMap new_settings;
   new_settings[SETTINGS_INITIAL_WINDOW_SIZE] =
       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, initial_window_size / 2);
-  scoped_ptr<SpdyFrame> settings_frame_small(
+  scoped_ptr<SpdySerializedFrame> settings_frame_small(
       spdy_util_.ConstructSpdySettings(new_settings));
   // Construct read frames for WINDOW_UPDATE that makes the send_window_size
   // positive.
-  scoped_ptr<SpdyFrame> session_window_update_init_size(
+  scoped_ptr<SpdySerializedFrame> session_window_update_init_size(
       spdy_util_.ConstructSpdyWindowUpdate(0, initial_window_size));
-  scoped_ptr<SpdyFrame> window_update_init_size(
+  scoped_ptr<SpdySerializedFrame> window_update_init_size(
       spdy_util_.ConstructSpdyWindowUpdate(1, initial_window_size));
 
   reads.push_back(CreateMockRead(*settings_frame_small, i++));
   reads.push_back(CreateMockRead(*session_window_update_init_size, i++));
   reads.push_back(CreateMockRead(*window_update_init_size, i++));
 
-  scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
+  scoped_ptr<SpdySerializedFrame> settings_ack(
+      spdy_util_.ConstructSpdySettingsAck());
   writes.push_back(CreateMockWrite(*settings_ack, i++));
 
   writes.push_back(CreateMockWrite(*body3, i++));
 
-  scoped_ptr<SpdyFrame> reply(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> reply(
+      spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
   reads.push_back(CreateMockRead(*reply, i++));
   reads.push_back(CreateMockRead(*body2, i++));
   reads.push_back(CreateMockRead(*body3, i++));
@@ -6739,13 +6875,13 @@
   scoped_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock);
   spdy_util_.AddUrlToHeaderBlock("http://www.example.org/a.dat",
                                  push_headers.get());
-  scoped_ptr<SpdyFrame> push(
+  scoped_ptr<SpdySerializedFrame> push(
       spdy_util_.ConstructInitialSpdyPushFrame(std::move(push_headers), 3, 1));
   MockRead reads[] = {CreateMockRead(*push, 1)};
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(
+  scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(
       0, GOAWAY_PROTOCOL_ERROR, "Odd push stream id."));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*goaway, 2),
@@ -6761,22 +6897,22 @@
 
 TEST_P(SpdyNetworkTransactionTest,
        GoAwayOnPushStreamIdLesserOrEqualThanLastAccepted) {
-  scoped_ptr<SpdyFrame> push_a(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> push_a(spdy_util_.ConstructSpdyPush(
       NULL, 0, 4, 1, GetDefaultUrlWithPath("/a.dat").c_str()));
   scoped_ptr<SpdyHeaderBlock> push_b_headers(new SpdyHeaderBlock);
   spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/b.dat"),
                                  push_b_headers.get());
-  scoped_ptr<SpdyFrame> push_b(spdy_util_.ConstructInitialSpdyPushFrame(
-      std::move(push_b_headers), 2, 1));
+  scoped_ptr<SpdySerializedFrame> push_b(
+      spdy_util_.ConstructInitialSpdyPushFrame(std::move(push_b_headers), 2,
+                                               1));
   MockRead reads[] = {
       CreateMockRead(*push_a, 1), CreateMockRead(*push_b, 2),
   };
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(
-      4,
-      GOAWAY_PROTOCOL_ERROR,
+  scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(
+      4, GOAWAY_PROTOCOL_ERROR,
       "New push stream id must be greater than the last accepted."));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*goaway, 3),
@@ -6804,15 +6940,16 @@
   scoped_ptr<SpdyHeaderBlock> headers(
       spdy_util_.ConstructGetHeaderBlock(GetDefaultUrl()));
   (*headers)[kKey] = kValue;
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, true));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0),
   };
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       CreateMockRead(*resp, 1),
       CreateMockRead(*body, 2),
@@ -6834,7 +6971,7 @@
 TEST_P(SpdyNetworkTransactionTest, LargeResponseHeader) {
   scoped_ptr<SpdyHeaderBlock> headers(
       spdy_util_.ConstructGetHeaderBlock(GetDefaultUrl()));
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, true));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0),
@@ -6847,9 +6984,10 @@
   const std::string kValue(16 * 1024, 'b');
   response_headers[1] = kValue.data();
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(response_headers, 1, 1));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       CreateMockRead(*resp, 1), CreateMockRead(*body, 2),
       MockRead(ASYNC, 0, 3)  // EOF
@@ -6876,12 +7014,14 @@
  protected:
   void RunNoTLSUsageCheckTest(scoped_ptr<SSLSocketDataProvider> ssl_provider) {
     // Construct the request.
-    scoped_ptr<SpdyFrame> req(
+    scoped_ptr<SpdySerializedFrame> req(
         spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
     MockWrite writes[] = {CreateMockWrite(*req, 0)};
 
-    scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
-    scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+    scoped_ptr<SpdySerializedFrame> resp(
+        spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+    scoped_ptr<SpdySerializedFrame> body(
+        spdy_util_.ConstructSpdyBodyFrame(1, true));
     MockRead reads[] = {
         CreateMockRead(*resp, 1),
         CreateMockRead(*body, 2),
@@ -6938,7 +7078,7 @@
     : public SpdyNetworkTransactionTest {
  protected:
   void RunTLSUsageCheckTest(scoped_ptr<SSLSocketDataProvider> ssl_provider) {
-    scoped_ptr<SpdyFrame> goaway(
+    scoped_ptr<SpdySerializedFrame> goaway(
         spdy_util_.ConstructSpdyGoAway(0, GOAWAY_INADEQUATE_SECURITY, ""));
     MockWrite writes[] = {CreateMockWrite(*goaway)};
 
diff --git a/net/spdy/spdy_protocol.h b/net/spdy/spdy_protocol.h
index 2f2d06d..e22f89c 100644
--- a/net/spdy/spdy_protocol.h
+++ b/net/spdy/spdy_protocol.h
@@ -522,14 +522,9 @@
   static std::string GetVersionString(SpdyMajorVersion version);
 };
 
-class SpdyFrame;
-typedef SpdyFrame SpdySerializedFrame;
-
 class SpdyFrameVisitor;
 
 // Intermediate representation for SPDY frames.
-// TODO(hkhalil): Rename this class to SpdyFrame when the existing SpdyFrame is
-// gone.
 class NET_EXPORT_PRIVATE SpdyFrameIR {
  public:
   virtual ~SpdyFrameIR() {}
@@ -987,35 +982,50 @@
   DISALLOW_COPY_AND_ASSIGN(SpdyPriorityIR);
 };
 
-// -------------------------------------------------------------------------
-// Wrapper classes for various SPDY frames.
-
-// All Spdy Frame types derive from this SpdyFrame class.
-class SpdyFrame {
+class SpdySerializedFrame {
  public:
-  // Create a SpdyFrame using a pre-created buffer.
-  // If |owns_buffer| is true, this class takes ownership of the buffer
-  // and will delete it on cleanup.  The buffer must have been created using
-  // new char[].
+  SpdySerializedFrame()
+      : frame_(const_cast<char*>("")), size_(0), owns_buffer_(false) {}
+
+  // Create a valid SpdySerializedFrame using a pre-created buffer.
+  // If |owns_buffer| is true, this class takes ownership of the buffer and will
+  // delete it on cleanup.  The buffer must have been created using new char[].
   // If |owns_buffer| is false, the caller retains ownership of the buffer and
   // is responsible for making sure the buffer outlives this frame.  In other
   // words, this class does NOT create a copy of the buffer.
-  SpdyFrame(char* data, size_t size, bool owns_buffer)
-      : frame_(data),
-        size_(size),
-        owns_buffer_(owns_buffer) {
-    DCHECK(frame_);
+  SpdySerializedFrame(char* data, size_t size, bool owns_buffer)
+      : frame_(data), size_(size), owns_buffer_(owns_buffer) {}
+
+  SpdySerializedFrame(SpdySerializedFrame&& other)
+      : frame_(other.frame_),
+        size_(other.size_),
+        owns_buffer_(other.owns_buffer_) {
+    // |other| is no longer responsible for the buffer.
+    other.owns_buffer_ = false;
   }
 
-  ~SpdyFrame() {
+  SpdySerializedFrame& operator=(SpdySerializedFrame&& other) {
+    // Free buffer if necessary.
     if (owns_buffer_) {
-      delete [] frame_;
+      delete[] frame_;
     }
-    frame_ = NULL;
+    // Take over |other|.
+    frame_ = other.frame_;
+    size_ = other.size_;
+    owns_buffer_ = other.owns_buffer_;
+    // |other| is no longer responsible for the buffer.
+    other.owns_buffer_ = false;
+    return *this;
   }
 
-  // Provides access to the frame bytes, which is a buffer containing
-  // the frame packed as expected for sending over the wire.
+  ~SpdySerializedFrame() {
+    if (owns_buffer_) {
+      delete[] frame_;
+    }
+  }
+
+  // Provides access to the frame bytes, which is a buffer containing the frame
+  // packed as expected for sending over the wire.
   char* data() const { return frame_; }
 
   // Returns the actual size of the underlying buffer.
@@ -1027,7 +1037,7 @@
  private:
   size_t size_;
   bool owns_buffer_;
-  DISALLOW_COPY_AND_ASSIGN(SpdyFrame);
+  DISALLOW_COPY_AND_ASSIGN(SpdySerializedFrame);
 };
 
 // This interface is for classes that want to process SpdyFrameIRs without
diff --git a/net/spdy/spdy_proxy_client_socket_unittest.cc b/net/spdy/spdy_proxy_client_socket_unittest.cc
index cda99f0..6e83c39 100644
--- a/net/spdy/spdy_proxy_client_socket_unittest.cc
+++ b/net/spdy/spdy_proxy_client_socket_unittest.cc
@@ -92,13 +92,13 @@
                   size_t writes_count);
   void PopulateConnectRequestIR(SpdyHeaderBlock* syn_ir);
   void PopulateConnectReplyIR(SpdyHeaderBlock* block, const char* status);
-  SpdyFrame* ConstructConnectRequestFrame();
-  SpdyFrame* ConstructConnectAuthRequestFrame();
-  SpdyFrame* ConstructConnectReplyFrame();
-  SpdyFrame* ConstructConnectAuthReplyFrame();
-  SpdyFrame* ConstructConnectRedirectReplyFrame();
-  SpdyFrame* ConstructConnectErrorReplyFrame();
-  SpdyFrame* ConstructBodyFrame(const char* data, int length);
+  SpdySerializedFrame* ConstructConnectRequestFrame();
+  SpdySerializedFrame* ConstructConnectAuthRequestFrame();
+  SpdySerializedFrame* ConstructConnectReplyFrame();
+  SpdySerializedFrame* ConstructConnectAuthReplyFrame();
+  SpdySerializedFrame* ConstructConnectRedirectReplyFrame();
+  SpdySerializedFrame* ConstructConnectErrorReplyFrame();
+  SpdySerializedFrame* ConstructBodyFrame(const char* data, int length);
   scoped_refptr<IOBufferWithSize> CreateBuffer(const char* data, int size);
   void AssertConnectSucceeds();
   void AssertConnectFails(int result);
@@ -335,8 +335,7 @@
 }
 
 // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
-SpdyFrame*
-SpdyProxyClientSocketTest::ConstructConnectRequestFrame() {
+SpdySerializedFrame* SpdyProxyClientSocketTest::ConstructConnectRequestFrame() {
   SpdyHeaderBlock block;
   PopulateConnectRequestIR(&block);
   return spdy_util_.ConstructSpdySyn(kStreamId, block, LOWEST, false);
@@ -344,7 +343,8 @@
 
 // Constructs a SPDY SYN_STREAM frame for a CONNECT request which includes
 // Proxy-Authorization headers.
-SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthRequestFrame() {
+SpdySerializedFrame*
+SpdyProxyClientSocketTest::ConstructConnectAuthRequestFrame() {
   SpdyHeaderBlock block;
   PopulateConnectRequestIR(&block);
   block["proxy-authorization"] = "Basic Zm9vOmJhcg==";
@@ -352,7 +352,7 @@
 }
 
 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT.
-SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectReplyFrame() {
+SpdySerializedFrame* SpdyProxyClientSocketTest::ConstructConnectReplyFrame() {
   SpdyHeaderBlock block;
   PopulateConnectReplyIR(&block, "200");
   SpdySynReplyIR reply_ir(kStreamId);
@@ -361,7 +361,8 @@
 
 // Constructs a standard SPDY SYN_REPLY frame to match the SPDY CONNECT,
 // including Proxy-Authenticate headers.
-SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectAuthReplyFrame() {
+SpdySerializedFrame*
+SpdyProxyClientSocketTest::ConstructConnectAuthReplyFrame() {
   SpdyHeaderBlock block;
   PopulateConnectReplyIR(&block, "407");
   block["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
@@ -369,7 +370,8 @@
 }
 
 // Constructs a SPDY SYN_REPLY frame with an HTTP 302 redirect.
-SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectRedirectReplyFrame() {
+SpdySerializedFrame*
+SpdyProxyClientSocketTest::ConstructConnectRedirectReplyFrame() {
   SpdyHeaderBlock block;
   PopulateConnectReplyIR(&block, "302");
   block["location"] = kRedirectUrl;
@@ -378,13 +380,14 @@
 }
 
 // Constructs a SPDY SYN_REPLY frame with an HTTP 500 error.
-SpdyFrame* SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() {
+SpdySerializedFrame*
+SpdyProxyClientSocketTest::ConstructConnectErrorReplyFrame() {
   SpdyHeaderBlock block;
   PopulateConnectReplyIR(&block, "500");
   return spdy_util_.ConstructSpdyReply(kStreamId, block);
 }
 
-SpdyFrame* SpdyProxyClientSocketTest::ConstructBodyFrame(
+SpdySerializedFrame* SpdyProxyClientSocketTest::ConstructBodyFrame(
     const char* data,
     int length) {
   return framer_.CreateDataFrame(kStreamId, data, length, DATA_FLAG_NONE);
@@ -393,12 +396,12 @@
 // ----------- Connect
 
 TEST_P(SpdyProxyClientSocketTest, ConnectSendsCorrectRequest) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
   MockWrite writes[] = {
     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
   };
@@ -413,12 +416,12 @@
 }
 
 TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthRequested) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
   MockWrite writes[] = {
     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectAuthReplyFrame());
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
   };
@@ -433,12 +436,12 @@
 }
 
 TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectAuthRequestFrame());
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectAuthRequestFrame());
   MockWrite writes[] = {
     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
   };
@@ -452,14 +455,14 @@
 }
 
 TEST_P(SpdyProxyClientSocketTest, ConnectRedirects) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   MockWrite writes[] = {
       CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectRedirectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectRedirectReplyFrame());
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
   };
@@ -485,12 +488,12 @@
 }
 
 TEST_P(SpdyProxyClientSocketTest, ConnectFails) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
   MockWrite writes[] = {
     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
   MockRead reads[] = {
     MockRead(ASYNC, 0, 1),  // EOF
   };
@@ -507,14 +510,14 @@
 // ----------- WasEverUsed
 
 TEST_P(SpdyProxyClientSocketTest, WasEverUsedReturnsCorrectValues) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   MockWrite writes[] = {
       CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
   };
@@ -534,12 +537,12 @@
 // ----------- GetPeerAddress
 
 TEST_P(SpdyProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
   MockWrite writes[] = {
     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
       MockRead(ASYNC, 0, 3),  // EOF
@@ -567,16 +570,16 @@
 // ----------- Write
 
 TEST_P(SpdyProxyClientSocketTest, WriteSendsDataInDataFrame) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
-  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
-  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
   MockWrite writes[] = {
       CreateMockWrite(*conn, 0, SYNCHRONOUS),
       CreateMockWrite(*msg1, 3, SYNCHRONOUS),
       CreateMockWrite(*msg2, 4, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
   };
@@ -591,15 +594,15 @@
 
 TEST_P(SpdyProxyClientSocketTest, WriteSplitsLargeDataIntoMultipleFrames) {
   std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
-  scoped_ptr<SpdyFrame> chunk(ConstructBodyFrame(chunk_data.data(),
-                                                       chunk_data.length()));
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> chunk(
+      ConstructBodyFrame(chunk_data.data(), chunk_data.length()));
   MockWrite writes[] = {CreateMockWrite(*conn, 0, SYNCHRONOUS),
                         CreateMockWrite(*chunk, 3, SYNCHRONOUS),
                         CreateMockWrite(*chunk, 4, SYNCHRONOUS),
                         CreateMockWrite(*chunk, 5, SYNCHRONOUS)};
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
   };
@@ -620,13 +623,13 @@
 // ----------- Read
 
 TEST_P(SpdyProxyClientSocketTest, ReadReadsDataInDataFrame) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
   MockWrite writes[] = {
     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
-  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
       CreateMockRead(*msg1, 3, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 4),
@@ -642,14 +645,14 @@
 }
 
 TEST_P(SpdyProxyClientSocketTest, ReadDataFromBufferedFrames) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
   MockWrite writes[] = {
     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
-  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
-  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
       CreateMockRead(*msg1, 3, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 4),
@@ -669,14 +672,14 @@
 }
 
 TEST_P(SpdyProxyClientSocketTest, ReadDataMultipleBufferedFrames) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
   MockWrite writes[] = {
     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
-  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
-  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC),
       MockRead(ASYNC, ERR_IO_PENDING, 2),
@@ -698,14 +701,14 @@
 
 TEST_P(SpdyProxyClientSocketTest,
        LargeReadWillMergeDataFromDifferentFrames) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
   MockWrite writes[] = {
     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
-  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
-  scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdySerializedFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC),
       MockRead(ASYNC, ERR_IO_PENDING, 2),
@@ -727,15 +730,15 @@
 }
 
 TEST_P(SpdyProxyClientSocketTest, MultipleShortReadsThenMoreRead) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
   MockWrite writes[] = {
     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
-  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
-  scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
-  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdySerializedFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
+  scoped_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC),
       MockRead(ASYNC, ERR_IO_PENDING, 2),
@@ -761,15 +764,15 @@
 }
 
 TEST_P(SpdyProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
   MockWrite writes[] = {
     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
-  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
-  scoped_ptr<SpdyFrame> msg33(ConstructBodyFrame(kMsg33, kLen33));
-  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdySerializedFrame> msg33(ConstructBodyFrame(kMsg33, kLen33));
+  scoped_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC),
       MockRead(ASYNC, ERR_IO_PENDING, 2),
@@ -793,13 +796,13 @@
 }
 
 TEST_P(SpdyProxyClientSocketTest, MultipleReadsFromSameLargeFrame) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
   MockWrite writes[] = {
     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
-  scoped_ptr<SpdyFrame> msg333(ConstructBodyFrame(kMsg333, kLen333));
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> msg333(ConstructBodyFrame(kMsg333, kLen333));
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
       CreateMockRead(*msg333, 3, ASYNC),
@@ -824,14 +827,14 @@
 }
 
 TEST_P(SpdyProxyClientSocketTest, ReadAuthResponseBody) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
   MockWrite writes[] = {
     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectAuthReplyFrame());
-  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
-  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectAuthReplyFrame());
+  scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC),
       MockRead(ASYNC, ERR_IO_PENDING, 2),
@@ -852,14 +855,14 @@
 }
 
 TEST_P(SpdyProxyClientSocketTest, ReadErrorResponseBody) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
   MockWrite writes[] = {
     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectErrorReplyFrame());
-  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
-  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectErrorReplyFrame());
+  scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
   MockRead reads[] = {
     CreateMockRead(*resp, 1, ASYNC),
     CreateMockRead(*msg1, 2, ASYNC),
@@ -875,16 +878,16 @@
 // ----------- Reads and Writes
 
 TEST_P(SpdyProxyClientSocketTest, AsyncReadAroundWrite) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
-  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
   MockWrite writes[] = {
       CreateMockWrite(*conn, 0, SYNCHRONOUS),
       CreateMockWrite(*msg2, 4, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
-  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
-  scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdySerializedFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC),
       MockRead(ASYNC, ERR_IO_PENDING, 2),
@@ -913,16 +916,16 @@
 }
 
 TEST_P(SpdyProxyClientSocketTest, AsyncWriteAroundReads) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
-  scoped_ptr<SpdyFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2));
   MockWrite writes[] = {
       CreateMockWrite(*conn, 0, SYNCHRONOUS),
       MockWrite(ASYNC, ERR_IO_PENDING, 7), CreateMockWrite(*msg2, 8, ASYNC),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
-  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
-  scoped_ptr<SpdyFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdySerializedFrame> msg3(ConstructBodyFrame(kMsg3, kLen3));
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
       CreateMockRead(*msg1, 3, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 4),
@@ -951,12 +954,12 @@
 
 // Reading from an already closed socket should return 0
 TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsZero) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
   MockWrite writes[] = {
     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
       MockRead(ASYNC, 0, 3),  // EOF
@@ -977,12 +980,12 @@
 
 // Read pending when socket is closed should return 0
 TEST_P(SpdyProxyClientSocketTest, PendingReadOnCloseReturnsZero) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
   MockWrite writes[] = {
     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
       MockRead(ASYNC, 0, 3),  // EOF
@@ -1002,14 +1005,14 @@
 // Reading from a disconnected socket is an error
 TEST_P(SpdyProxyClientSocketTest,
        ReadOnDisconnectSocketReturnsNotConnected) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   MockWrite writes[] = {
       CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
   };
@@ -1030,13 +1033,13 @@
 // Reading buffered data from an already closed socket should return
 // buffered data, then 0.
 TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsBufferedData) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
   MockWrite writes[] = {
     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
-  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
       CreateMockRead(*msg1, 3, ASYNC), MockRead(ASYNC, 0, 4),  // EOF
@@ -1062,13 +1065,13 @@
 
 // Calling Write() on a closed socket is an error
 TEST_P(SpdyProxyClientSocketTest, WriteOnClosedStream) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
   MockWrite writes[] = {
     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
-  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
       MockRead(ASYNC, 0, 3),  // EOF
@@ -1087,15 +1090,15 @@
 
 // Calling Write() on a disconnected socket is an error.
 TEST_P(SpdyProxyClientSocketTest, WriteOnDisconnectedSocket) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   MockWrite writes[] = {
       CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
-  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
   };
@@ -1117,13 +1120,13 @@
 // If the socket is closed with a pending Write(), the callback
 // should be called with ERR_CONNECTION_CLOSED.
 TEST_P(SpdyProxyClientSocketTest, WritePendingOnClose) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
   MockWrite writes[] = {
       CreateMockWrite(*conn, 0, SYNCHRONOUS),
       MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 3),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
   };
@@ -1148,14 +1151,14 @@
 // If the socket is Disconnected with a pending Write(), the callback
 // should not be called.
 TEST_P(SpdyProxyClientSocketTest, DisconnectWithWritePending) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   MockWrite writes[] = {
       CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
   };
@@ -1182,14 +1185,14 @@
 // If the socket is Disconnected with a pending Read(), the callback
 // should not be called.
 TEST_P(SpdyProxyClientSocketTest, DisconnectWithReadPending) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   MockWrite writes[] = {
       CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2),
   };
@@ -1216,13 +1219,13 @@
 // If the socket is Reset when both a read and write are pending,
 // both should be called back.
 TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePending) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
   MockWrite writes[] = {
     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
@@ -1258,15 +1261,15 @@
 // Makes sure the proxy client socket's source gets the expected NetLog events
 // and only the expected NetLog events (No SpdySession events).
 TEST_P(SpdyProxyClientSocketTest, NetLog) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   MockWrite writes[] = {
       CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 5),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
-  scoped_ptr<SpdyFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1));
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
       CreateMockRead(*msg1, 3, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 4),
@@ -1344,13 +1347,13 @@
 // read callback causes the socket to be deleted, the write callback should
 // not be called.
 TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePendingDelete) {
-  scoped_ptr<SpdyFrame> conn(ConstructConnectRequestFrame());
+  scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame());
   MockWrite writes[] = {
     CreateMockWrite(*conn, 0, SYNCHRONOUS),
   };
 
-  scoped_ptr<SpdyFrame> resp(ConstructConnectReplyFrame());
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame());
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   MockRead reads[] = {
       CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2),
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index 6a1a37a9..1a3a3ac 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -1086,7 +1086,7 @@
   EnqueueWrite(stream->priority(), frame_type, std::move(producer), stream);
 }
 
-scoped_ptr<SpdyFrame> SpdySession::CreateSynStream(
+scoped_ptr<SpdySerializedFrame> SpdySession::CreateSynStream(
     SpdyStreamId stream_id,
     RequestPriority priority,
     SpdyControlFlags flags,
@@ -1101,7 +1101,7 @@
   SpdyPriority spdy_priority =
       ConvertRequestPriorityToSpdyPriority(priority, GetProtocolVersion());
 
-  scoped_ptr<SpdyFrame> syn_frame;
+  scoped_ptr<SpdySerializedFrame> syn_frame;
   // TODO(hkhalil): Avoid copy of |block|.
   if (GetProtocolVersion() <= SPDY3) {
     SpdySynStreamIR syn_stream(stream_id);
@@ -1110,7 +1110,8 @@
     syn_stream.set_fin((flags & CONTROL_FLAG_FIN) != 0);
     syn_stream.set_unidirectional((flags & CONTROL_FLAG_UNIDIRECTIONAL) != 0);
     syn_stream.set_header_block(block);
-    syn_frame.reset(buffered_spdy_framer_->SerializeFrame(syn_stream));
+    syn_frame.reset(new SpdySerializedFrame(
+        buffered_spdy_framer_->SerializeFrame(syn_stream)));
 
     if (net_log().IsCapturing()) {
       net_log().AddEvent(NetLog::TYPE_HTTP2_SESSION_SYN_STREAM,
@@ -1135,7 +1136,8 @@
 
     headers.set_fin((flags & CONTROL_FLAG_FIN) != 0);
     headers.set_header_block(block);
-    syn_frame.reset(buffered_spdy_framer_->SerializeFrame(headers));
+    syn_frame.reset(new SpdySerializedFrame(
+        buffered_spdy_framer_->SerializeFrame(headers)));
 
     if (net_log().IsCapturing()) {
       net_log().AddEvent(
@@ -1243,7 +1245,7 @@
 
   // TODO(mbelshe): reduce memory copies here.
   DCHECK(buffered_spdy_framer_.get());
-  scoped_ptr<SpdyFrame> frame(buffered_spdy_framer_->CreateDataFrame(
+  scoped_ptr<SpdySerializedFrame> frame(buffered_spdy_framer_->CreateDataFrame(
       stream_id, data->data(), static_cast<uint32_t>(effective_len), flags));
 
   scoped_ptr<SpdyBuffer> data_buffer(new SpdyBuffer(std::move(frame)));
@@ -1376,7 +1378,7 @@
       base::Bind(&NetLogSpdyRstCallback, stream_id, status, &description));
 
   DCHECK(buffered_spdy_framer_.get());
-  scoped_ptr<SpdyFrame> rst_frame(
+  scoped_ptr<SpdySerializedFrame> rst_frame(
       buffered_spdy_framer_->CreateRstStream(stream_id, status));
 
   EnqueueSessionWrite(priority, RST_STREAM, std::move(rst_frame));
@@ -1775,10 +1777,9 @@
     SpdyGoAwayIR goaway_ir(last_accepted_push_stream_id_,
                            MapNetErrorToGoAwayStatus(err),
                            description);
-    EnqueueSessionWrite(HIGHEST,
-                        GOAWAY,
-                        scoped_ptr<SpdyFrame>(
-                            buffered_spdy_framer_->SerializeFrame(goaway_ir)));
+    EnqueueSessionWrite(HIGHEST, GOAWAY,
+                        scoped_ptr<SpdySerializedFrame>(new SpdySerializedFrame(
+                            buffered_spdy_framer_->SerializeFrame(goaway_ir))));
   }
 
   availability_state_ = STATE_DRAINING;
@@ -1938,7 +1939,7 @@
 
 void SpdySession::EnqueueSessionWrite(RequestPriority priority,
                                       SpdyFrameType frame_type,
-                                      scoped_ptr<SpdyFrame> frame) {
+                                      scoped_ptr<SpdySerializedFrame> frame) {
   DCHECK(frame_type == RST_STREAM || frame_type == SETTINGS ||
          frame_type == WINDOW_UPDATE || frame_type == PING ||
          frame_type == GOAWAY);
@@ -2192,10 +2193,9 @@
     SpdySettingsIR settings_ir;
     settings_ir.set_is_ack(true);
     EnqueueSessionWrite(
-        HIGHEST,
-        SETTINGS,
-        scoped_ptr<SpdyFrame>(
-            buffered_spdy_framer_->SerializeFrame(settings_ir)));
+        HIGHEST, SETTINGS,
+        scoped_ptr<SpdySerializedFrame>(new SpdySerializedFrame(
+            buffered_spdy_framer_->SerializeFrame(settings_ir))));
   }
 }
 
@@ -2830,10 +2830,10 @@
 
   if (send_connection_header_prefix_) {
     DCHECK_EQ(protocol_, kProtoHTTP2);
-    scoped_ptr<SpdyFrame> connection_header_prefix_frame(
-        new SpdyFrame(const_cast<char*>(kHttp2ConnectionHeaderPrefix),
-                      kHttp2ConnectionHeaderPrefixSize,
-                      false /* take_ownership */));
+    scoped_ptr<SpdySerializedFrame> connection_header_prefix_frame(
+        new SpdySerializedFrame(const_cast<char*>(kHttp2ConnectionHeaderPrefix),
+                                kHttp2ConnectionHeaderPrefixSize,
+                                false /* take_ownership */));
     // Count the prefix as part of the subsequent SETTINGS frame.
     EnqueueSessionWrite(HIGHEST, SETTINGS,
                         std::move(connection_header_prefix_frame));
@@ -2898,7 +2898,7 @@
       base::Bind(&NetLogSpdySendSettingsCallback, &settings, protocol_version));
   // Create the SETTINGS frame and send it.
   DCHECK(buffered_spdy_framer_.get());
-  scoped_ptr<SpdyFrame> settings_frame(
+  scoped_ptr<SpdySerializedFrame> settings_frame(
       buffered_spdy_framer_->CreateSettings(settings));
   sent_settings_ = true;
   EnqueueSessionWrite(HIGHEST, SETTINGS, std::move(settings_frame));
@@ -2973,14 +2973,14 @@
                                delta_window_size));
 
   DCHECK(buffered_spdy_framer_.get());
-  scoped_ptr<SpdyFrame> window_update_frame(
+  scoped_ptr<SpdySerializedFrame> window_update_frame(
       buffered_spdy_framer_->CreateWindowUpdate(stream_id, delta_window_size));
   EnqueueSessionWrite(priority, WINDOW_UPDATE, std::move(window_update_frame));
 }
 
 void SpdySession::WritePingFrame(SpdyPingId unique_id, bool is_ack) {
   DCHECK(buffered_spdy_framer_.get());
-  scoped_ptr<SpdyFrame> ping_frame(
+  scoped_ptr<SpdySerializedFrame> ping_frame(
       buffered_spdy_framer_->CreatePingFrame(unique_id, is_ack));
   EnqueueSessionWrite(HIGHEST, PING, std::move(ping_frame));
 
diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h
index 5ce8fec..57e16d7 100644
--- a/net/spdy/spdy_session.h
+++ b/net/spdy/spdy_session.h
@@ -366,7 +366,7 @@
                           scoped_ptr<SpdyBufferProducer> producer);
 
   // Creates and returns a SYN frame for |stream_id|.
-  scoped_ptr<SpdyFrame> CreateSynStream(
+  scoped_ptr<SpdySerializedFrame> CreateSynStream(
       SpdyStreamId stream_id,
       RequestPriority priority,
       SpdyControlFlags flags,
@@ -789,7 +789,7 @@
   // queue for the session.
   void EnqueueSessionWrite(RequestPriority priority,
                            SpdyFrameType frame_type,
-                           scoped_ptr<SpdyFrame> frame);
+                           scoped_ptr<SpdySerializedFrame> frame);
 
   // Puts |producer| associated with |stream| onto the write queue
   // with the given priority.
diff --git a/net/spdy/spdy_session_pool_unittest.cc b/net/spdy/spdy_session_pool_unittest.cc
index cbd41c27..4d34869f 100644
--- a/net/spdy/spdy_session_pool_unittest.cc
+++ b/net/spdy/spdy_session_pool_unittest.cc
@@ -526,7 +526,7 @@
   MockRead reads[] = {
       MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
   };
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util.ConstructSpdyGet("http://www.a.com", 1, MEDIUM));
   MockWrite writes[] = {CreateMockWrite(*req, 1)};
 
diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc
index 91547b46..0cd890f 100644
--- a/net/spdy/spdy_session_unittest.cc
+++ b/net/spdy/spdy_session_unittest.cc
@@ -312,7 +312,7 @@
 TEST_P(SpdySessionTest, GoAwayWithNoActiveStreams) {
   session_deps_.host_resolver->set_synchronous_mode(true);
 
-  scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
+  scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
   MockRead reads[] = {
     CreateMockRead(*goaway, 0),
   };
@@ -337,7 +337,7 @@
 TEST_P(SpdySessionTest, GoAwayImmediatelyWithNoActiveStreams) {
   session_deps_.host_resolver->set_synchronous_mode(true);
 
-  scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
+  scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
   MockRead reads[] = {
       CreateMockRead(*goaway, 0, SYNCHRONOUS), MockRead(ASYNC, 0, 1)  // EOF
   };
@@ -360,16 +360,16 @@
 TEST_P(SpdySessionTest, GoAwayWithActiveStreams) {
   session_deps_.host_resolver->set_synchronous_mode(true);
 
-  scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
+  scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
   MockRead reads[] = {
       MockRead(ASYNC, ERR_IO_PENDING, 2),
       CreateMockRead(*goaway, 3),
       MockRead(ASYNC, ERR_IO_PENDING, 4),
       MockRead(ASYNC, 0, 5)  // EOF
   };
-  scoped_ptr<SpdyFrame> req1(
+  scoped_ptr<SpdySerializedFrame> req1(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true));
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM, true));
   MockWrite writes[] = {
     CreateMockWrite(*req1, 0),
@@ -435,13 +435,13 @@
 TEST_P(SpdySessionTest, GoAwayWithActiveAndCreatedStream) {
   session_deps_.host_resolver->set_synchronous_mode(true);
 
-  scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(0));
+  scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(0));
   MockRead reads[] = {
       MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(*goaway, 2),
   };
 
   // No |req2|, because the second stream will never get activated.
-  scoped_ptr<SpdyFrame> req1(
+  scoped_ptr<SpdySerializedFrame> req1(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true));
   MockWrite writes[] = {
       CreateMockWrite(*req1, 0),
@@ -493,8 +493,8 @@
 TEST_P(SpdySessionTest, GoAwayTwice) {
   session_deps_.host_resolver->set_synchronous_mode(true);
 
-  scoped_ptr<SpdyFrame> goaway1(spdy_util_.ConstructSpdyGoAway(1));
-  scoped_ptr<SpdyFrame> goaway2(spdy_util_.ConstructSpdyGoAway(0));
+  scoped_ptr<SpdySerializedFrame> goaway1(spdy_util_.ConstructSpdyGoAway(1));
+  scoped_ptr<SpdySerializedFrame> goaway2(spdy_util_.ConstructSpdyGoAway(0));
   MockRead reads[] = {
       MockRead(ASYNC, ERR_IO_PENDING, 2),
       CreateMockRead(*goaway1, 3),
@@ -503,9 +503,9 @@
       MockRead(ASYNC, ERR_IO_PENDING, 6),
       MockRead(ASYNC, 0, 7)  // EOF
   };
-  scoped_ptr<SpdyFrame> req1(
+  scoped_ptr<SpdySerializedFrame> req1(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true));
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM, true));
   MockWrite writes[] = {
     CreateMockWrite(*req1, 0),
@@ -569,16 +569,16 @@
 TEST_P(SpdySessionTest, GoAwayWithActiveStreamsThenClose) {
   session_deps_.host_resolver->set_synchronous_mode(true);
 
-  scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
+  scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
   MockRead reads[] = {
       MockRead(ASYNC, ERR_IO_PENDING, 2),
       CreateMockRead(*goaway, 3),
       MockRead(ASYNC, ERR_IO_PENDING, 4),
       MockRead(ASYNC, 0, 5)  // EOF
   };
-  scoped_ptr<SpdyFrame> req1(
+  scoped_ptr<SpdySerializedFrame> req1(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true));
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM, true));
   MockWrite writes[] = {
     CreateMockWrite(*req1, 0),
@@ -643,16 +643,17 @@
 TEST_P(SpdySessionTest, GoAwayWhileDraining) {
   session_deps_.host_resolver->set_synchronous_mode(true);
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0),
   };
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   size_t joint_size = goaway->size() * 2 + body->size();
 
   // Compose interleaved |goaway| and |body| frames into a single read.
@@ -667,7 +668,7 @@
     out += goaway->size();
     ASSERT_EQ(out, joint_size);
   }
-  SpdyFrame joint_frames(buffer.get(), joint_size, false);
+  SpdySerializedFrame joint_frames(buffer.get(), joint_size, false);
 
   MockRead reads[] = {
       CreateMockRead(*resp, 1), CreateMockRead(joint_frames, 2),
@@ -704,14 +705,14 @@
 TEST_P(SpdySessionTest, CreateStreamAfterGoAway) {
   session_deps_.host_resolver->set_synchronous_mode(true);
 
-  scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
+  scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
   MockRead reads[] = {
       MockRead(ASYNC, ERR_IO_PENDING, 1),
       CreateMockRead(*goaway, 2),
       MockRead(ASYNC, ERR_IO_PENDING, 3),
       MockRead(ASYNC, 0, 4)  // EOF
   };
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true));
   MockWrite writes[] = {
     CreateMockWrite(*req, 0),
@@ -764,8 +765,8 @@
 TEST_P(SpdySessionTest, SynStreamAfterGoAway) {
   session_deps_.host_resolver->set_synchronous_mode(true);
 
-  scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
-  scoped_ptr<SpdyFrame> push(
+  scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(1));
+  scoped_ptr<SpdySerializedFrame> push(
       spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kDefaultURL));
   MockRead reads[] = {
       MockRead(ASYNC, ERR_IO_PENDING, 1),
@@ -774,9 +775,9 @@
       CreateMockRead(*push, 4),
       MockRead(ASYNC, 0, 6)  // EOF
   };
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
   MockWrite writes[] = {CreateMockWrite(*req, 0), CreateMockWrite(*rst, 5)};
   SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));
@@ -825,7 +826,7 @@
   MockRead reads[] = {
       MockRead(ASYNC, ERR_IO_PENDING, 1), MockRead(ASYNC, 0, 2)  // EOF
   };
-  scoped_ptr<SpdyFrame> req1(
+  scoped_ptr<SpdySerializedFrame> req1(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true));
   MockWrite writes[] = {
     CreateMockWrite(*req1, 0),
@@ -884,13 +885,15 @@
   session_deps_.enable_ping = true;
   session_deps_.host_resolver->set_synchronous_mode(true);
 
-  scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(1, true));
+  scoped_ptr<SpdySerializedFrame> read_ping(
+      spdy_util_.ConstructSpdyPing(1, true));
   MockRead reads[] = {
       CreateMockRead(*read_ping, 1),
       MockRead(ASYNC, ERR_IO_PENDING, 2),
       MockRead(ASYNC, 0, 3)  // EOF
   };
-  scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1, false));
+  scoped_ptr<SpdySerializedFrame> write_ping(
+      spdy_util_.ConstructSpdyPing(1, false));
   MockWrite writes[] = {
     CreateMockWrite(*write_ping, 0),
   };
@@ -935,12 +938,14 @@
 TEST_P(SpdySessionTest, ServerPing) {
   session_deps_.host_resolver->set_synchronous_mode(true);
 
-  scoped_ptr<SpdyFrame> read_ping(spdy_util_.ConstructSpdyPing(2, false));
+  scoped_ptr<SpdySerializedFrame> read_ping(
+      spdy_util_.ConstructSpdyPing(2, false));
   MockRead reads[] = {
     CreateMockRead(*read_ping),
     MockRead(SYNCHRONOUS, 0, 0)  // EOF
   };
-  scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(2, true));
+  scoped_ptr<SpdySerializedFrame> write_ping(
+      spdy_util_.ConstructSpdyPing(2, true));
   MockWrite writes[] = {
     CreateMockWrite(*write_ping),
   };
@@ -974,8 +979,9 @@
   session_deps_.enable_ping = true;
   session_deps_.time_func = TheNearFuture;
 
-  scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1, false));
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> write_ping(
+      spdy_util_.ConstructSpdyPing(1, false));
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite writes[] = {
     CreateMockWrite(*req, 0),
@@ -1025,23 +1031,23 @@
   // stalled streams are aborted. Also verify the activated streams complete,
   // at which point the session closes.
 
-  scoped_ptr<SpdyFrame> req1(
+  scoped_ptr<SpdySerializedFrame> req1(
       spdy_util_.ConstructSpdyGet(nullptr, 0, kLastStreamId - 2, MEDIUM, true));
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_.ConstructSpdyGet(nullptr, 0, kLastStreamId, MEDIUM, true));
 
   MockWrite writes[] = {
       CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1),
   };
 
-  scoped_ptr<SpdyFrame> resp1(
+  scoped_ptr<SpdySerializedFrame> resp1(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, kLastStreamId - 2));
-  scoped_ptr<SpdyFrame> resp2(
+  scoped_ptr<SpdySerializedFrame> resp2(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, kLastStreamId));
 
-  scoped_ptr<SpdyFrame> body1(
+  scoped_ptr<SpdySerializedFrame> body1(
       spdy_util_.ConstructSpdyBodyFrame(kLastStreamId - 2, true));
-  scoped_ptr<SpdyFrame> body2(
+  scoped_ptr<SpdySerializedFrame> body2(
       spdy_util_.ConstructSpdyBodyFrame(kLastStreamId, true));
 
   MockRead reads[] = {
@@ -1145,13 +1151,13 @@
   SettingsMap settings_zero;
   settings_zero[SETTINGS_MAX_CONCURRENT_STREAMS] =
       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, 0);
-  scoped_ptr<SpdyFrame> settings_frame_zero(
+  scoped_ptr<SpdySerializedFrame> settings_frame_zero(
       spdy_util_.ConstructSpdySettings(settings_zero));
   reads.push_back(CreateMockRead(*settings_frame_zero, seq++));
 
   // Acknowledge it.
   std::vector<MockWrite> writes;
-  scoped_ptr<SpdyFrame> settings_ack0;
+  scoped_ptr<SpdySerializedFrame> settings_ack0;
   if (GetProtocol() == kProtoHTTP2) {
     settings_ack0.reset(spdy_util_.ConstructSpdySettingsAck());
     writes.push_back(CreateMockWrite(*settings_ack0, seq++));
@@ -1164,27 +1170,28 @@
   SettingsMap settings_one;
   settings_one[SETTINGS_MAX_CONCURRENT_STREAMS] =
       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, 1);
-  scoped_ptr<SpdyFrame> settings_frame_one(
+  scoped_ptr<SpdySerializedFrame> settings_frame_one(
       spdy_util_.ConstructSpdySettings(settings_one));
   reads.push_back(CreateMockRead(*settings_frame_one, seq++));
 
   // Acknowledge it.
-  scoped_ptr<SpdyFrame> settings_ack1;
+  scoped_ptr<SpdySerializedFrame> settings_ack1;
   if (GetProtocol() == kProtoHTTP2) {
     settings_ack1.reset(spdy_util_.ConstructSpdySettingsAck());
     writes.push_back(CreateMockWrite(*settings_ack1, seq++));
   }
 
   // Request and response.
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true));
   writes.push_back(CreateMockWrite(*req, seq++));
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
   reads.push_back(CreateMockRead(*resp, seq++));
 
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   reads.push_back(CreateMockRead(*body, seq++));
 
   reads.push_back(MockRead(ASYNC, 0, seq++));
@@ -1306,19 +1313,19 @@
   session_deps_.host_resolver->set_synchronous_mode(true);
   session_deps_.time_func = TheNearFuture;
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
   MockWrite writes[] = {CreateMockWrite(*req, 0), CreateMockWrite(*rst, 5)};
 
-  scoped_ptr<SpdyFrame> push_a(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> push_a(spdy_util_.ConstructSpdyPush(
       nullptr, 0, 2, 1, "http://www.example.org/a.dat"));
-  scoped_ptr<SpdyFrame> push_a_body(
+  scoped_ptr<SpdySerializedFrame> push_a_body(
       spdy_util_.ConstructSpdyBodyFrame(2, false));
   // In ascii "0" < "a". We use it to verify that we properly handle std::map
   // iterators inside. See http://crbug.com/443490
-  scoped_ptr<SpdyFrame> push_b(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> push_b(spdy_util_.ConstructSpdyPush(
       nullptr, 0, 4, 1, "http://www.example.org/0.dat"));
   MockRead reads[] = {
       CreateMockRead(*push_a, 1),
@@ -1387,8 +1394,9 @@
   MockRead reads[] = {
       MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
   };
-  scoped_ptr<SpdyFrame> write_ping(spdy_util_.ConstructSpdyPing(1, false));
-  scoped_ptr<SpdyFrame> goaway(
+  scoped_ptr<SpdySerializedFrame> write_ping(
+      spdy_util_.ConstructSpdyPing(1, false));
+  scoped_ptr<SpdySerializedFrame> goaway(
       spdy_util_.ConstructSpdyGoAway(0, GOAWAY_PROTOCOL_ERROR, "Failed ping."));
   MockWrite writes[] = {CreateMockWrite(*write_ping), CreateMockWrite(*goaway)};
 
@@ -1444,7 +1452,8 @@
 
   int seq = 0;
   std::vector<MockWrite> writes;
-  scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
+  scoped_ptr<SpdySerializedFrame> settings_ack(
+      spdy_util_.ConstructSpdySettingsAck());
   if (GetProtocol() == kProtoHTTP2) {
     writes.push_back(CreateMockWrite(*settings_ack, ++seq));
   }
@@ -1453,7 +1462,7 @@
   const uint32_t max_concurrent_streams = kInitialMaxConcurrentStreams + 1;
   new_settings[kSpdySettingsIds] =
       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
-  scoped_ptr<SpdyFrame> settings_frame(
+  scoped_ptr<SpdySerializedFrame> settings_frame(
       spdy_util_.ConstructSpdySettings(new_settings));
   MockRead reads[] = {
       CreateMockRead(*settings_frame, 0),
@@ -1510,7 +1519,7 @@
   const uint32_t max_concurrent_streams = kInitialMaxConcurrentStreams + 1;
   new_settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
-  scoped_ptr<SpdyFrame> settings_frame(
+  scoped_ptr<SpdySerializedFrame> settings_frame(
       spdy_util_.ConstructSpdySettings(new_settings));
   uint8_t flags = SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS;
   test::SetFrameFlags(settings_frame.get(), flags, spdy_util_.spdy_version());
@@ -1639,7 +1648,7 @@
   SettingsMap settings;
   settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams);
-  scoped_ptr<SpdyFrame> settings_frame(
+  scoped_ptr<SpdySerializedFrame> settings_frame(
       spdy_util_.ConstructSpdySettings(settings));
   std::vector<MockWrite> writes;
   if (GetProtocol() == kProtoHTTP2) {
@@ -1655,7 +1664,7 @@
   server_settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
       SettingsFlagsAndValue(SETTINGS_FLAG_PERSISTED,
                             initial_max_concurrent_streams);
-  scoped_ptr<SpdyFrame> server_settings_frame(
+  scoped_ptr<SpdySerializedFrame> server_settings_frame(
       spdy_util_.ConstructSpdySettings(server_settings));
   if (GetProtocol() == kProtoSPDY31) {
     writes.push_back(CreateMockWrite(*server_settings_frame));
@@ -1737,7 +1746,7 @@
 TEST_P(SpdySessionTest, NetLogOnSessionGoaway) {
   session_deps_.host_resolver->set_synchronous_mode(true);
 
-  scoped_ptr<SpdyFrame> goaway(
+  scoped_ptr<SpdySerializedFrame> goaway(
       spdy_util_.ConstructSpdyGoAway(42, GOAWAY_ENHANCE_YOUR_CALM, "foo"));
   MockRead reads[] = {
     CreateMockRead(*goaway),
@@ -1833,7 +1842,7 @@
 }
 
 TEST_P(SpdySessionTest, SynCompressionHistograms) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true));
   MockWrite writes[] = {
     CreateMockWrite(*req, 0),
@@ -1887,22 +1896,22 @@
 // first.
 TEST_P(SpdySessionTest, OutOfOrderSynStreams) {
   // Construct the request.
-  scoped_ptr<SpdyFrame> req_highest(
+  scoped_ptr<SpdySerializedFrame> req_highest(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST, true));
-  scoped_ptr<SpdyFrame> req_lowest(
+  scoped_ptr<SpdySerializedFrame> req_lowest(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true));
   MockWrite writes[] = {
     CreateMockWrite(*req_highest, 0),
     CreateMockWrite(*req_lowest, 1),
   };
 
-  scoped_ptr<SpdyFrame> resp_highest(
+  scoped_ptr<SpdySerializedFrame> resp_highest(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> body_highest(
+  scoped_ptr<SpdySerializedFrame> body_highest(
       spdy_util_.ConstructSpdyBodyFrame(1, true));
-  scoped_ptr<SpdyFrame> resp_lowest(
+  scoped_ptr<SpdySerializedFrame> resp_lowest(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 3));
-  scoped_ptr<SpdyFrame> body_lowest(
+  scoped_ptr<SpdySerializedFrame> body_lowest(
       spdy_util_.ConstructSpdyBodyFrame(3, true));
   MockRead reads[] = {
     CreateMockRead(*resp_highest, 2),
@@ -1960,15 +1969,16 @@
 TEST_P(SpdySessionTest, CancelStream) {
   // Request 1, at HIGHEST priority, will be cancelled before it writes data.
   // Request 2, at LOWEST priority, will be a full request and will be id 1.
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite writes[] = {
     CreateMockWrite(*req2, 0),
   };
 
-  scoped_ptr<SpdyFrame> resp2(
+  scoped_ptr<SpdySerializedFrame> resp2(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> body2(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       CreateMockRead(*resp2, 1),
       MockRead(ASYNC, ERR_IO_PENDING, 2),
@@ -2150,9 +2160,9 @@
 TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedSelfClosingStreams) {
   session_deps_.host_resolver->set_synchronous_mode(true);
 
-  scoped_ptr<SpdyFrame> req1(
+  scoped_ptr<SpdySerializedFrame> req1(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true));
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM, true));
   MockWrite writes[] = {
     CreateMockWrite(*req1, 0),
@@ -2224,9 +2234,9 @@
 TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedMutuallyClosingStreams) {
   session_deps_.host_resolver->set_synchronous_mode(true);
 
-  scoped_ptr<SpdyFrame> req1(
+  scoped_ptr<SpdySerializedFrame> req1(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true));
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM, true));
   MockWrite writes[] = {
     CreateMockWrite(*req1, 0),
@@ -2318,11 +2328,11 @@
 TEST_P(SpdySessionTest, CloseActivatedStreamThatClosesSession) {
   session_deps_.host_resolver->set_synchronous_mode(true);
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
-  scoped_ptr<SpdyFrame> goaway(
+  scoped_ptr<SpdySerializedFrame> goaway(
       spdy_util_.ConstructSpdyGoAway(0, GOAWAY_PROTOCOL_ERROR, "Error"));
   // The GOAWAY has higher-priority than the RST_STREAM, and is written first
   // despite being queued second.
@@ -2441,14 +2451,15 @@
   new_settings[kSpdySettingsIds1] =
       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams);
 
-  scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
-  scoped_ptr<SpdyFrame> req1(
+  scoped_ptr<SpdySerializedFrame> settings_ack(
+      spdy_util_.ConstructSpdySettingsAck());
+  scoped_ptr<SpdySerializedFrame> req1(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   spdy_util_.UpdateWithStreamDestruction(1);
-  scoped_ptr<SpdyFrame> req2(
+  scoped_ptr<SpdySerializedFrame> req2(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true));
   spdy_util_.UpdateWithStreamDestruction(3);
-  scoped_ptr<SpdyFrame> req3(
+  scoped_ptr<SpdySerializedFrame> req3(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 5, LOWEST, true));
   MockWrite writes[] = {
     CreateMockWrite(*settings_ack, 1),
@@ -2459,20 +2470,23 @@
 
   // Set up the socket so we read a SETTINGS frame that sets max concurrent
   // streams to 1.
-  scoped_ptr<SpdyFrame> settings_frame(
+  scoped_ptr<SpdySerializedFrame> settings_frame(
       spdy_util_.ConstructSpdySettings(new_settings));
 
-  scoped_ptr<SpdyFrame> resp1(
+  scoped_ptr<SpdySerializedFrame> resp1(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> body1(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
 
-  scoped_ptr<SpdyFrame> resp2(
+  scoped_ptr<SpdySerializedFrame> resp2(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 3));
-  scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
+  scoped_ptr<SpdySerializedFrame> body2(
+      spdy_util_.ConstructSpdyBodyFrame(3, true));
 
-  scoped_ptr<SpdyFrame> resp3(
+  scoped_ptr<SpdySerializedFrame> resp3(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 5));
-  scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(5, true));
+  scoped_ptr<SpdySerializedFrame> body3(
+      spdy_util_.ConstructSpdyBodyFrame(5, true));
 
   MockRead reads[] = {
       CreateMockRead(*settings_frame, 0),
@@ -2669,7 +2683,7 @@
 
   BufferedSpdyFramer framer(spdy_util_.spdy_version());
 
-  scoped_ptr<SpdyFrame> req1(
+  scoped_ptr<SpdySerializedFrame> req1(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true));
   MockWrite writes[] = {
     CreateMockWrite(*req1, 0),
@@ -2685,12 +2699,12 @@
   char* payload_data = payload->data();
   test_stream.GetBytes(payload_data, kPayloadSize);
 
-  scoped_ptr<SpdyFrame> partial_data_frame(
+  scoped_ptr<SpdySerializedFrame> partial_data_frame(
       framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE));
-  scoped_ptr<SpdyFrame> finish_data_frame(
+  scoped_ptr<SpdySerializedFrame> finish_data_frame(
       framer.CreateDataFrame(1, payload_data, kPayloadSize - 1, DATA_FLAG_FIN));
 
-  scoped_ptr<SpdyFrame> resp1(
+  scoped_ptr<SpdySerializedFrame> resp1(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
 
   // Write 1 byte less than kMaxReadBytes to check that DoRead reads up to 32k
@@ -2756,13 +2770,13 @@
 
   BufferedSpdyFramer framer(spdy_util_.spdy_version());
 
-  scoped_ptr<SpdyFrame> req1(
+  scoped_ptr<SpdySerializedFrame> req1(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true));
   MockWrite writes[] = {
       CreateMockWrite(*req1, 0),
   };
 
-  scoped_ptr<SpdyFrame> resp1(
+  scoped_ptr<SpdySerializedFrame> resp1(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
 
   MockRead reads[] = {
@@ -2817,18 +2831,18 @@
 
   BufferedSpdyFramer framer(spdy_util_.spdy_version());
 
-  scoped_ptr<SpdyFrame> req1(
+  scoped_ptr<SpdySerializedFrame> req1(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true));
   MockWrite writes[] = {
       CreateMockWrite(*req1, 0),
   };
 
-  scoped_ptr<SpdyFrame> partial_data_frame(
+  scoped_ptr<SpdySerializedFrame> partial_data_frame(
       framer.CreateDataFrame(1, "foo ", 4, DATA_FLAG_NONE));
-  scoped_ptr<SpdyFrame> finish_data_frame(
+  scoped_ptr<SpdySerializedFrame> finish_data_frame(
       framer.CreateDataFrame(1, "bar", 3, DATA_FLAG_FIN));
 
-  scoped_ptr<SpdyFrame> resp1(
+  scoped_ptr<SpdySerializedFrame> resp1(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
 
   MockRead reads[] = {
@@ -2885,7 +2899,7 @@
 
   BufferedSpdyFramer framer(spdy_util_.spdy_version());
 
-  scoped_ptr<SpdyFrame> req1(
+  scoped_ptr<SpdySerializedFrame> req1(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true));
   MockWrite writes[] = {
     CreateMockWrite(*req1, 0),
@@ -2901,12 +2915,12 @@
   char* payload_data = payload->data();
   test_stream.GetBytes(payload_data, kPayloadSize);
 
-  scoped_ptr<SpdyFrame> partial_data_frame(
+  scoped_ptr<SpdySerializedFrame> partial_data_frame(
       framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE));
-  scoped_ptr<SpdyFrame> finish_data_frame(
+  scoped_ptr<SpdySerializedFrame> finish_data_frame(
       framer.CreateDataFrame(1, "h", 1, DATA_FLAG_FIN));
 
-  scoped_ptr<SpdyFrame> resp1(
+  scoped_ptr<SpdySerializedFrame> resp1(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
 
   // Write 1 byte more than kMaxReadBytes to check that DoRead yields.
@@ -2979,7 +2993,7 @@
 
   BufferedSpdyFramer framer(spdy_util_.spdy_version());
 
-  scoped_ptr<SpdyFrame> req1(
+  scoped_ptr<SpdySerializedFrame> req1(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true));
   MockWrite writes[] = {
     CreateMockWrite(*req1, 0),
@@ -3002,14 +3016,14 @@
   char* twok_payload_data = twok_payload->data();
   test_stream2.GetBytes(twok_payload_data, kTwoKPayloadSize);
 
-  scoped_ptr<SpdyFrame> eightk_data_frame(framer.CreateDataFrame(
+  scoped_ptr<SpdySerializedFrame> eightk_data_frame(framer.CreateDataFrame(
       1, eightk_payload_data, kEightKPayloadSize, DATA_FLAG_NONE));
-  scoped_ptr<SpdyFrame> twok_data_frame(framer.CreateDataFrame(
+  scoped_ptr<SpdySerializedFrame> twok_data_frame(framer.CreateDataFrame(
       1, twok_payload_data, kTwoKPayloadSize, DATA_FLAG_NONE));
-  scoped_ptr<SpdyFrame> finish_data_frame(framer.CreateDataFrame(
-      1, "h", 1, DATA_FLAG_FIN));
+  scoped_ptr<SpdySerializedFrame> finish_data_frame(
+      framer.CreateDataFrame(1, "h", 1, DATA_FLAG_FIN));
 
-  scoped_ptr<SpdyFrame> resp1(
+  scoped_ptr<SpdySerializedFrame> resp1(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
 
   MockRead reads[] = {
@@ -3078,16 +3092,17 @@
 
   BufferedSpdyFramer framer(spdy_util_.spdy_version());
 
-  scoped_ptr<SpdyFrame> req1(
+  scoped_ptr<SpdySerializedFrame> req1(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true));
   MockWrite writes[] = {
     CreateMockWrite(*req1, 0),
   };
 
-  scoped_ptr<SpdyFrame> resp1(
+  scoped_ptr<SpdySerializedFrame> resp1(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
-  scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway());
+  scoped_ptr<SpdySerializedFrame> body1(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway());
 
   MockRead reads[] = {
       CreateMockRead(*resp1, 1),
@@ -3287,9 +3302,9 @@
   MockRead reads[] = {
     MockRead(SYNCHRONOUS, ERR_IO_PENDING)  // Stall forever.
   };
-  scoped_ptr<SpdyFrame> req1(
+  scoped_ptr<SpdySerializedFrame> req1(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> cancel1(
+  scoped_ptr<SpdySerializedFrame> cancel1(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   MockWrite writes[] = {
     CreateMockWrite(*req1, 1),
@@ -3429,13 +3444,13 @@
 TEST_P(SpdySessionTest, CreateStreamOnStreamReset) {
   session_deps_.host_resolver->set_synchronous_mode(true);
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true));
   MockWrite writes[] = {
     CreateMockWrite(*req, 0),
   };
 
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_REFUSED_STREAM));
   MockRead reads[] = {
       MockRead(ASYNC, ERR_IO_PENDING, 1),
@@ -3493,7 +3508,7 @@
 
   // Set up the socket so we read a SETTINGS frame that sets
   // INITIAL_WINDOW_SIZE.
-  scoped_ptr<SpdyFrame> settings_frame(
+  scoped_ptr<SpdySerializedFrame> settings_frame(
       spdy_util_.ConstructSpdySettings(new_settings));
   MockRead reads[] = {
       CreateMockRead(*settings_frame, 0),
@@ -3501,7 +3516,8 @@
       MockRead(ASYNC, 0, 2)  // EOF
   };
 
-  scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
+  scoped_ptr<SpdySerializedFrame> settings_ack(
+      spdy_util_.ConstructSpdySettingsAck());
   MockWrite writes[] = {
       CreateMockWrite(*settings_ack, 3),
   };
@@ -3555,8 +3571,10 @@
   MockRead reads[] = {
       MockRead(ASYNC, ERR_IO_PENDING, 1), MockRead(ASYNC, 0, 2)  // EOF
   };
-  scoped_ptr<SpdyFrame> window_update(spdy_util_.ConstructSpdyWindowUpdate(
-      kSessionFlowControlStreamId, initial_window_size + delta_window_size));
+  scoped_ptr<SpdySerializedFrame> window_update(
+      spdy_util_.ConstructSpdyWindowUpdate(
+          kSessionFlowControlStreamId,
+          initial_window_size + delta_window_size));
   MockWrite writes[] = {
     CreateMockWrite(*window_update, 0),
   };
@@ -3631,7 +3649,8 @@
 TEST_P(SpdySessionTest, SessionFlowControlInactiveStream) {
   session_deps_.host_resolver->set_synchronous_mode(true);
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyBodyFrame(1, false));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyBodyFrame(1, false));
   MockRead reads[] = {
       CreateMockRead(*resp, 0),
       MockRead(ASYNC, ERR_IO_PENDING, 1),
@@ -3669,7 +3688,7 @@
   session_deps_.host_resolver->set_synchronous_mode(true);
 
   const int padding_length = 42;
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyBodyFrame(
+  scoped_ptr<SpdySerializedFrame> resp(spdy_util_.ConstructSpdyBodyFrame(
       1, kUploadData, kUploadDataSize, false, padding_length));
   MockRead reads[] = {
       CreateMockRead(*resp, 0),
@@ -3703,18 +3722,18 @@
   const int32_t stream_max_recv_window_size = 1024;
   const int32_t data_frame_size = 2 * stream_max_recv_window_size;
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_FLOW_CONTROL_ERROR));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4),
   };
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
   const std::string payload(data_frame_size, 'a');
-  scoped_ptr<SpdyFrame> data_frame(spdy_util_.ConstructSpdyBodyFrame(
+  scoped_ptr<SpdySerializedFrame> data_frame(spdy_util_.ConstructSpdyBodyFrame(
       1, payload.data(), data_frame_size, false));
   MockRead reads[] = {
       CreateMockRead(*resp, 1),
@@ -3778,7 +3797,7 @@
 
   session_deps_.host_resolver->set_synchronous_mode(true);
 
-  scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(
+  scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(
       0, GOAWAY_FLOW_CONTROL_ERROR,
       "delta_window_size is 400 in DecreaseRecvWindowSize, which is larger "
       "than the receive window size of 500"));
@@ -3787,10 +3806,10 @@
   };
 
   const std::string first_data_frame(first_data_frame_size, 'a');
-  scoped_ptr<SpdyFrame> first(spdy_util_.ConstructSpdyBodyFrame(
+  scoped_ptr<SpdySerializedFrame> first(spdy_util_.ConstructSpdyBodyFrame(
       1, first_data_frame.data(), first_data_frame_size, false));
   const std::string second_data_frame(second_data_frame_size, 'b');
-  scoped_ptr<SpdyFrame> second(spdy_util_.ConstructSpdyBodyFrame(
+  scoped_ptr<SpdySerializedFrame> second(spdy_util_.ConstructSpdyBodyFrame(
       1, second_data_frame.data(), second_data_frame_size, false));
   MockRead reads[] = {
       CreateMockRead(*first, 0),
@@ -3837,21 +3856,21 @@
   ASSERT_LT(stream_max_recv_window_size,
             first_data_frame_size + second_data_frame_size);
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_FLOW_CONTROL_ERROR));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*rst, 6),
   };
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
   const std::string first_data_frame(first_data_frame_size, 'a');
-  scoped_ptr<SpdyFrame> first(spdy_util_.ConstructSpdyBodyFrame(
+  scoped_ptr<SpdySerializedFrame> first(spdy_util_.ConstructSpdyBodyFrame(
       1, first_data_frame.data(), first_data_frame_size, false));
   const std::string second_data_frame(second_data_frame_size, 'b');
-  scoped_ptr<SpdyFrame> second(spdy_util_.ConstructSpdyBodyFrame(
+  scoped_ptr<SpdySerializedFrame> second(spdy_util_.ConstructSpdyBodyFrame(
       1, second_data_frame.data(), second_data_frame_size, false));
   MockRead reads[] = {
       CreateMockRead(*resp, 1),
@@ -3931,21 +3950,22 @@
   const int32_t kMsgDataSize = 100;
   const std::string msg_data(kMsgDataSize, 'a');
 
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
       kDefaultURL, 1, kMsgDataSize, MEDIUM, nullptr, 0));
-  scoped_ptr<SpdyFrame> msg(spdy_util_.ConstructSpdyBodyFrame(
+  scoped_ptr<SpdySerializedFrame> msg(spdy_util_.ConstructSpdyBodyFrame(
       1, msg_data.data(), kMsgDataSize, false));
   MockWrite writes[] = {
     CreateMockWrite(*req, 0),
     CreateMockWrite(*msg, 2),
   };
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> echo(spdy_util_.ConstructSpdyBodyFrame(
+  scoped_ptr<SpdySerializedFrame> echo(spdy_util_.ConstructSpdyBodyFrame(
       1, msg_data.data(), kMsgDataSize, false));
-  scoped_ptr<SpdyFrame> window_update(spdy_util_.ConstructSpdyWindowUpdate(
-      kSessionFlowControlStreamId, kMsgDataSize));
+  scoped_ptr<SpdySerializedFrame> window_update(
+      spdy_util_.ConstructSpdyWindowUpdate(kSessionFlowControlStreamId,
+                                           kMsgDataSize));
   MockRead reads[] = {
       CreateMockRead(*resp, 1),
       CreateMockRead(*echo, 3),
@@ -4005,13 +4025,13 @@
   const int32_t kMsgDataSize = 100;
   const std::string msg_data(kMsgDataSize, 'a');
 
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
       kDefaultURL, 1, kMsgDataSize, MEDIUM, nullptr, 0));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0),
   };
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
   MockRead reads[] = {
       MockRead(ASYNC, ERR_IO_PENDING, 1),
@@ -4078,21 +4098,22 @@
   const int32_t kMsgDataSize = 100;
   const std::string msg_data(kMsgDataSize, 'a');
 
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
       kDefaultURL, 1, kMsgDataSize, MEDIUM, nullptr, 0));
-  scoped_ptr<SpdyFrame> msg(spdy_util_.ConstructSpdyBodyFrame(
+  scoped_ptr<SpdySerializedFrame> msg(spdy_util_.ConstructSpdyBodyFrame(
       1, msg_data.data(), kMsgDataSize, false));
   MockWrite writes[] = {
     CreateMockWrite(*req, 0),
     CreateMockWrite(*msg, 2),
   };
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> echo(spdy_util_.ConstructSpdyBodyFrame(
+  scoped_ptr<SpdySerializedFrame> echo(spdy_util_.ConstructSpdyBodyFrame(
       1, msg_data.data(), kMsgDataSize, false));
-  scoped_ptr<SpdyFrame> window_update(spdy_util_.ConstructSpdyWindowUpdate(
-      kSessionFlowControlStreamId, kMsgDataSize));
+  scoped_ptr<SpdySerializedFrame> window_update(
+      spdy_util_.ConstructSpdyWindowUpdate(kSessionFlowControlStreamId,
+                                           kMsgDataSize));
   MockRead reads[] = {
       CreateMockRead(*resp, 1),
       MockRead(ASYNC, ERR_IO_PENDING, 3),
@@ -4187,18 +4208,18 @@
     const base::Callback<void(SpdyStream*, int32_t)>& unstall_function) {
   session_deps_.host_resolver->set_synchronous_mode(true);
 
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
       kDefaultURL, 1, kBodyDataSize, LOWEST, nullptr, 0));
-  scoped_ptr<SpdyFrame> body(
+  scoped_ptr<SpdySerializedFrame> body(
       spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, true));
   MockWrite writes[] = {
     CreateMockWrite(*req, 0),
     CreateMockWrite(*body, 1),
   };
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> echo(
+  scoped_ptr<SpdySerializedFrame> echo(
       spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, false));
   MockRead reads[] = {
       CreateMockRead(*resp, 2), MockRead(ASYNC, 0, 3)  // EOF
@@ -4305,13 +4326,13 @@
 TEST_P(SpdySessionTest, ResumeByPriorityAfterSendWindowSizeIncrease) {
   session_deps_.host_resolver->set_synchronous_mode(true);
 
-  scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req1(spdy_util_.ConstructSpdyPost(
       kDefaultURL, 1, kBodyDataSize, LOWEST, nullptr, 0));
-  scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req2(spdy_util_.ConstructSpdyPost(
       kDefaultURL, 3, kBodyDataSize, MEDIUM, nullptr, 0));
-  scoped_ptr<SpdyFrame> body1(
+  scoped_ptr<SpdySerializedFrame> body1(
       spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, true));
-  scoped_ptr<SpdyFrame> body2(
+  scoped_ptr<SpdySerializedFrame> body2(
       spdy_util_.ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, true));
   MockWrite writes[] = {
     CreateMockWrite(*req1, 0),
@@ -4320,9 +4341,9 @@
     CreateMockWrite(*body1, 3),
   };
 
-  scoped_ptr<SpdyFrame> resp1(
+  scoped_ptr<SpdySerializedFrame> resp1(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> resp2(
+  scoped_ptr<SpdySerializedFrame> resp2(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 3));
   MockRead reads[] = {
       CreateMockRead(*resp1, 4),
@@ -4446,13 +4467,13 @@
 TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) {
   session_deps_.host_resolver->set_synchronous_mode(true);
 
-  scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req1(spdy_util_.ConstructSpdyPost(
       kDefaultURL, 1, kBodyDataSize, LOWEST, nullptr, 0));
-  scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req2(spdy_util_.ConstructSpdyPost(
       kDefaultURL, 3, kBodyDataSize, LOWEST, nullptr, 0));
-  scoped_ptr<SpdyFrame> req3(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req3(spdy_util_.ConstructSpdyPost(
       kDefaultURL, 5, kBodyDataSize, LOWEST, nullptr, 0));
-  scoped_ptr<SpdyFrame> body2(
+  scoped_ptr<SpdySerializedFrame> body2(
       spdy_util_.ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, true));
   MockWrite writes[] = {
     CreateMockWrite(*req1, 0),
@@ -4461,7 +4482,7 @@
     CreateMockWrite(*body2, 3),
   };
 
-  scoped_ptr<SpdyFrame> resp2(
+  scoped_ptr<SpdySerializedFrame> resp2(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 3));
   MockRead reads[] = {
       CreateMockRead(*resp2, 4),
@@ -4593,11 +4614,11 @@
 TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) {
   session_deps_.host_resolver->set_synchronous_mode(true);
 
-  scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req1(spdy_util_.ConstructSpdyPost(
       kDefaultURL, 1, kBodyDataSize, LOWEST, nullptr, 0));
-  scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req2(spdy_util_.ConstructSpdyPost(
       kDefaultURL, 3, kBodyDataSize, LOWEST, nullptr, 0));
-  scoped_ptr<SpdyFrame> body1(
+  scoped_ptr<SpdySerializedFrame> body1(
       spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, false));
   MockWrite writes[] = {
     CreateMockWrite(*req1, 0),
@@ -4686,9 +4707,9 @@
 }
 
 TEST_P(SpdySessionTest, GoAwayOnSessionFlowControlError) {
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> goaway(spdy_util_.ConstructSpdyGoAway(
+  scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(
       0, GOAWAY_FLOW_CONTROL_ERROR,
       "delta_window_size is 6 in DecreaseRecvWindowSize, which is larger than "
       "the receive window size of 1"));
@@ -4696,9 +4717,10 @@
       CreateMockWrite(*req, 0), CreateMockWrite(*goaway, 4),
   };
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1));
-  scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
+  scoped_ptr<SpdySerializedFrame> body(
+      spdy_util_.ConstructSpdyBodyFrame(1, true));
   MockRead reads[] = {
       MockRead(ASYNC, ERR_IO_PENDING, 1),
       CreateMockRead(*resp, 2),
@@ -4764,9 +4786,9 @@
   SettingsMap new_settings;
   new_settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, 2);
-  scoped_ptr<SpdyFrame> settings_frame(
+  scoped_ptr<SpdySerializedFrame> settings_frame(
       spdy_util_.ConstructSpdySettings(new_settings));
-  scoped_ptr<SpdyFrame> pushed(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> pushed(spdy_util_.ConstructSpdyPush(
       nullptr, 0, 2, 1, "http://www.example.org/a.dat"));
   MockRead reads[] = {
       CreateMockRead(*settings_frame, 0),
@@ -4776,8 +4798,9 @@
       MockRead(ASYNC, 0, 6),
   };
 
-  scoped_ptr<SpdyFrame> settings_ack(spdy_util_.ConstructSpdySettingsAck());
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> settings_ack(
+      spdy_util_.ConstructSpdySettingsAck());
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   MockWrite writes[] = {
       CreateMockWrite(*settings_ack, 1), CreateMockWrite(*req, 2),
@@ -4844,9 +4867,9 @@
 }
 
 TEST_P(SpdySessionTest, RejectPushedStreamExceedingConcurrencyLimit) {
-  scoped_ptr<SpdyFrame> push_a(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> push_a(spdy_util_.ConstructSpdyPush(
       nullptr, 0, 2, 1, "http://www.example.org/a.dat"));
-  scoped_ptr<SpdyFrame> push_b(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> push_b(spdy_util_.ConstructSpdyPush(
       nullptr, 0, 4, 1, "http://www.example.org/b.dat"));
   MockRead reads[] = {
       MockRead(ASYNC, ERR_IO_PENDING, 1),
@@ -4857,9 +4880,9 @@
       MockRead(ASYNC, 0, 7),
   };
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_REFUSED_STREAM));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*rst, 5),
@@ -4930,11 +4953,13 @@
 
   // cross_origin_push contains HTTP resource for an origin different from the
   // origin of kDefaultURL, and should be accepted.
-  scoped_ptr<SpdyFrame> cross_origin_push(spdy_util_.ConstructSpdyPush(
-      nullptr, 0, 2, 1, kHttpURLFromAnotherOrigin));
+  scoped_ptr<SpdySerializedFrame> cross_origin_push(
+      spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1,
+                                   kHttpURLFromAnotherOrigin));
   // cross_origin_https_push contains HTTPS resource, and should be refused.
-  scoped_ptr<SpdyFrame> cross_origin_https_push(spdy_util_.ConstructSpdyPush(
-      nullptr, 0, 4, 1, kHttpsURLFromAnotherOrigin));
+  scoped_ptr<SpdySerializedFrame> cross_origin_https_push(
+      spdy_util_.ConstructSpdyPush(nullptr, 0, 4, 1,
+                                   kHttpsURLFromAnotherOrigin));
   MockRead reads[] = {
       MockRead(ASYNC, ERR_IO_PENDING, 1),
       CreateMockRead(*cross_origin_push, 2),
@@ -4944,9 +4969,9 @@
       MockRead(ASYNC, 0, 7),
   };
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_REFUSED_STREAM));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*rst, 5),
@@ -5021,16 +5046,17 @@
 
   // cross_origin_push contains resource for an origin different from the
   // origin of kDefaultURL, and should be refused.
-  scoped_ptr<SpdyFrame> cross_origin_push(spdy_util_.ConstructSpdyPush(
-      nullptr, 0, 2, 1, kHttpURLFromAnotherOrigin));
+  scoped_ptr<SpdySerializedFrame> cross_origin_push(
+      spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1,
+                                   kHttpURLFromAnotherOrigin));
   MockRead reads[] = {
       MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(*cross_origin_push, 2),
       MockRead(ASYNC, 0, 4),
   };
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*rst, 3),
@@ -5079,14 +5105,14 @@
   if (spdy_util_.spdy_version() < HTTP2)
     return;
 
-  scoped_ptr<SpdyFrame> push_a(spdy_util_.ConstructSpdyPush(
+  scoped_ptr<SpdySerializedFrame> push_a(spdy_util_.ConstructSpdyPush(
       nullptr, 0, 2, 1, "http://www.example.org/a.dat"));
   scoped_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock);
   spdy_util_.AddUrlToHeaderBlock("http://www.example.org/b.dat",
                                  push_headers.get());
-  scoped_ptr<SpdyFrame> push_b(
+  scoped_ptr<SpdySerializedFrame> push_b(
       spdy_util_.ConstructInitialSpdyPushFrame(std::move(push_headers), 4, 1));
-  scoped_ptr<SpdyFrame> headers_b(
+  scoped_ptr<SpdySerializedFrame> headers_b(
       spdy_util_.ConstructSpdyPushHeaders(4, nullptr, 0));
   MockRead reads[] = {
       MockRead(ASYNC, ERR_IO_PENDING, 1),
@@ -5099,9 +5125,9 @@
       MockRead(ASYNC, 0, 9),
   };
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_REFUSED_STREAM));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*rst, 7),
@@ -5179,9 +5205,9 @@
   const char kPushedUrl[] = "http://www.example.org/a.dat";
   scoped_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock);
   spdy_util_.AddUrlToHeaderBlock(kPushedUrl, push_headers.get());
-  scoped_ptr<SpdyFrame> push_promise(
+  scoped_ptr<SpdySerializedFrame> push_promise(
       spdy_util_.ConstructInitialSpdyPushFrame(std::move(push_headers), 2, 1));
-  scoped_ptr<SpdyFrame> headers_frame(
+  scoped_ptr<SpdySerializedFrame> headers_frame(
       spdy_util_.ConstructSpdyPushHeaders(2, nullptr, 0));
   MockRead reads[] = {
       MockRead(ASYNC, ERR_IO_PENDING, 1),
@@ -5192,9 +5218,9 @@
       MockRead(ASYNC, 0, 7),
   };
 
-  scoped_ptr<SpdyFrame> req(
+  scoped_ptr<SpdySerializedFrame> req(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_CANCEL));
   MockWrite writes[] = {
       CreateMockWrite(*req, 0), CreateMockWrite(*rst, 5),
diff --git a/net/spdy/spdy_stream.cc b/net/spdy/spdy_stream.cc
index 214a67f..9a7ddef 100644
--- a/net/spdy/spdy_stream.cc
+++ b/net/spdy/spdy_stream.cc
@@ -203,7 +203,7 @@
   }
 }
 
-scoped_ptr<SpdyFrame> SpdyStream::ProduceSynStreamFrame() {
+scoped_ptr<SpdySerializedFrame> SpdyStream::ProduceSynStreamFrame() {
   CHECK_EQ(io_state_, STATE_IDLE);
   CHECK(request_headers_);
   CHECK_GT(stream_id_, 0u);
@@ -211,7 +211,7 @@
   SpdyControlFlags flags =
       (pending_send_status_ == NO_MORE_DATA_TO_SEND) ?
       CONTROL_FLAG_FIN : CONTROL_FLAG_NONE;
-  scoped_ptr<SpdyFrame> frame(session_->CreateSynStream(
+  scoped_ptr<SpdySerializedFrame> frame(session_->CreateSynStream(
       stream_id_, priority_, flags, *request_headers_));
   send_time_ = base::TimeTicks::Now();
   return frame;
diff --git a/net/spdy/spdy_stream.h b/net/spdy/spdy_stream.h
index 4362995..742f248 100644
--- a/net/spdy/spdy_stream.h
+++ b/net/spdy/spdy_stream.h
@@ -481,11 +481,11 @@
 
   // Produces the SYN_STREAM frame for the stream. The stream must
   // already be activated.
-  scoped_ptr<SpdyFrame> ProduceSynStreamFrame();
+  scoped_ptr<SpdySerializedFrame> ProduceSynStreamFrame();
 
   // Produce the initial HEADER frame for the stream with the given
   // block. The stream must already be activated.
-  scoped_ptr<SpdyFrame> ProduceHeaderFrame(
+  scoped_ptr<SpdySerializedFrame> ProduceHeaderFrame(
       scoped_ptr<SpdyHeaderBlock> header_block);
 
   // Queues the send for next frame of the remaining data in
diff --git a/net/spdy/spdy_stream_unittest.cc b/net/spdy/spdy_stream_unittest.cc
index 70bbc49..e9867dc1 100644
--- a/net/spdy/spdy_stream_unittest.cc
+++ b/net/spdy/spdy_stream_unittest.cc
@@ -102,11 +102,11 @@
   // Add{Read,Write}() populates lists that are eventually passed to a
   // SocketData class. |frame| must live for the whole test.
 
-  void AddRead(const SpdyFrame& frame) {
+  void AddRead(const SpdySerializedFrame& frame) {
     reads_.push_back(CreateMockRead(frame, offset_++));
   }
 
-  void AddWrite(const SpdyFrame& frame) {
+  void AddWrite(const SpdySerializedFrame& frame) {
     writes_.push_back(CreateMockWrite(frame, offset_++));
   }
 
@@ -154,20 +154,19 @@
 TEST_P(SpdyStreamTest, SendDataAfterOpen) {
   GURL url(kStreamUrl);
 
-  scoped_ptr<SpdyFrame> req(
-      spdy_util_.ConstructSpdyPost(
-          kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0));
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
+      kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0));
   AddWrite(*req);
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
   AddRead(*resp);
 
-  scoped_ptr<SpdyFrame> msg(
+  scoped_ptr<SpdySerializedFrame> msg(
       spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, false));
   AddWrite(*msg);
 
-  scoped_ptr<SpdyFrame> echo(
+  scoped_ptr<SpdySerializedFrame> echo(
       spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, false));
   AddRead(*echo);
 
@@ -231,24 +230,25 @@
 TEST_P(SpdyStreamTest, Trailers) {
   GURL url(kStreamUrl);
 
-  scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
       kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0));
   AddWrite(*req);
 
-  scoped_ptr<SpdyFrame> msg(
+  scoped_ptr<SpdySerializedFrame> msg(
       spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, true));
   AddWrite(*msg);
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
   AddRead(*resp);
 
-  scoped_ptr<SpdyFrame> echo(
+  scoped_ptr<SpdySerializedFrame> echo(
       spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, false));
   AddRead(*echo);
 
   SpdyHeaderBlock late_headers;
   late_headers["foo"] = "bar";
-  scoped_ptr<SpdyFrame> trailers(
+  scoped_ptr<SpdySerializedFrame> trailers(
       spdy_util_.ConstructSpdyResponseHeaders(1, late_headers, false));
   AddRead(*trailers);
 
@@ -346,20 +346,19 @@
 TEST_P(SpdyStreamTest, StreamError) {
   GURL url(kStreamUrl);
 
-  scoped_ptr<SpdyFrame> req(
-      spdy_util_.ConstructSpdyPost(
-          kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0));
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
+      kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0));
   AddWrite(*req);
 
-  scoped_ptr<SpdyFrame> resp(
+  scoped_ptr<SpdySerializedFrame> resp(
       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   AddRead(*resp);
 
-  scoped_ptr<SpdyFrame> msg(
+  scoped_ptr<SpdySerializedFrame> msg(
       spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, false));
   AddWrite(*msg);
 
-  scoped_ptr<SpdyFrame> echo(
+  scoped_ptr<SpdySerializedFrame> echo(
       spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, false));
   AddRead(*echo);
 
@@ -423,24 +422,22 @@
 TEST_P(SpdyStreamTest, SendLargeDataAfterOpenRequestResponse) {
   GURL url(kStreamUrl);
 
-  scoped_ptr<SpdyFrame> req(
-      spdy_util_.ConstructSpdyPost(
-          kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0));
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
+      kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0));
   AddWrite(*req);
 
   std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
-  scoped_ptr<SpdyFrame> chunk(
-      spdy_util_.ConstructSpdyBodyFrame(
-          1, chunk_data.data(), chunk_data.length(), false));
+  scoped_ptr<SpdySerializedFrame> chunk(spdy_util_.ConstructSpdyBodyFrame(
+      1, chunk_data.data(), chunk_data.length(), false));
   AddWrite(*chunk);
   AddWrite(*chunk);
 
-  scoped_ptr<SpdyFrame> last_chunk(
-      spdy_util_.ConstructSpdyBodyFrame(
-          1, chunk_data.data(), chunk_data.length(), true));
+  scoped_ptr<SpdySerializedFrame> last_chunk(spdy_util_.ConstructSpdyBodyFrame(
+      1, chunk_data.data(), chunk_data.length(), true));
   AddWrite(*last_chunk);
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
   AddRead(*resp);
 
   AddReadEOF();
@@ -486,18 +483,17 @@
 TEST_P(SpdyStreamTest, SendLargeDataAfterOpenBidirectional) {
   GURL url(kStreamUrl);
 
-  scoped_ptr<SpdyFrame> req(
-      spdy_util_.ConstructSpdyPost(
-          kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0));
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
+      kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0));
   AddWrite(*req);
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
   AddRead(*resp);
 
   std::string chunk_data(kMaxSpdyFrameChunkSize, 'x');
-  scoped_ptr<SpdyFrame> chunk(
-      spdy_util_.ConstructSpdyBodyFrame(
-          1, chunk_data.data(), chunk_data.length(), false));
+  scoped_ptr<SpdySerializedFrame> chunk(spdy_util_.ConstructSpdyBodyFrame(
+      1, chunk_data.data(), chunk_data.length(), false));
   AddWrite(*chunk);
   AddWrite(*chunk);
   AddWrite(*chunk);
@@ -544,16 +540,16 @@
 TEST_P(SpdyStreamTest, UpperCaseHeaders) {
   GURL url(kStreamUrl);
 
-  scoped_ptr<SpdyFrame> syn(
+  scoped_ptr<SpdySerializedFrame> syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   AddWrite(*syn);
 
   const char* const kExtraHeaders[] = {"X-UpperCase", "yes"};
-  scoped_ptr<SpdyFrame>
-      reply(spdy_util_.ConstructSpdyGetSynReply(kExtraHeaders, 1, 1));
+  scoped_ptr<SpdySerializedFrame> reply(
+      spdy_util_.ConstructSpdyGetSynReply(kExtraHeaders, 1, 1));
   AddRead(*reply);
 
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
   AddWrite(*rst);
 
@@ -593,20 +589,20 @@
 TEST_P(SpdyStreamTest, UpperCaseHeadersOnPush) {
   GURL url(kStreamUrl);
 
-  scoped_ptr<SpdyFrame> syn(
+  scoped_ptr<SpdySerializedFrame> syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   AddWrite(*syn);
 
-  scoped_ptr<SpdyFrame>
-      reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> reply(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   AddRead(*reply);
 
   const char* const extra_headers[] = {"X-UpperCase", "yes"};
-  scoped_ptr<SpdyFrame>
-      push(spdy_util_.ConstructSpdyPush(extra_headers, 1, 2, 1, kStreamUrl));
+  scoped_ptr<SpdySerializedFrame> push(
+      spdy_util_.ConstructSpdyPush(extra_headers, 1, 2, 1, kStreamUrl));
   AddRead(*push);
 
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR));
   AddWrite(*rst);
 
@@ -656,29 +652,29 @@
 TEST_P(SpdyStreamTest, UpperCaseHeadersInHeadersFrame) {
   GURL url(kStreamUrl);
 
-  scoped_ptr<SpdyFrame> syn(
+  scoped_ptr<SpdySerializedFrame> syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   AddWrite(*syn);
 
-  scoped_ptr<SpdyFrame>
-      reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> reply(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   AddRead(*reply);
 
-  scoped_ptr<SpdyFrame>
-      push(spdy_util_.ConstructSpdyPush(NULL, 0, 2, 1, kStreamUrl));
+  scoped_ptr<SpdySerializedFrame> push(
+      spdy_util_.ConstructSpdyPush(NULL, 0, 2, 1, kStreamUrl));
   AddRead(*push);
 
   AddReadPause();
 
   SpdyHeaderBlock late_headers;
   late_headers["X-UpperCase"] = "yes";
-  scoped_ptr<SpdyFrame> headers_frame(
+  scoped_ptr<SpdySerializedFrame> headers_frame(
       spdy_util_.ConstructSpdyReply(2, late_headers));
   AddRead(*headers_frame);
 
   AddWritePause();
 
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR));
   AddWrite(*rst);
 
@@ -732,29 +728,29 @@
 TEST_P(SpdyStreamTest, DuplicateHeaders) {
   GURL url(kStreamUrl);
 
-  scoped_ptr<SpdyFrame> syn(
+  scoped_ptr<SpdySerializedFrame> syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   AddWrite(*syn);
 
-  scoped_ptr<SpdyFrame>
-      reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> reply(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   AddRead(*reply);
 
-  scoped_ptr<SpdyFrame>
-      push(spdy_util_.ConstructSpdyPush(NULL, 0, 2, 1, kStreamUrl));
+  scoped_ptr<SpdySerializedFrame> push(
+      spdy_util_.ConstructSpdyPush(NULL, 0, 2, 1, kStreamUrl));
   AddRead(*push);
 
   AddReadPause();
 
   SpdyHeaderBlock late_headers;
   late_headers[spdy_util_.GetStatusKey()] = "500 Server Error";
-  scoped_ptr<SpdyFrame> headers_frame(
+  scoped_ptr<SpdySerializedFrame> headers_frame(
       spdy_util_.ConstructSpdyReply(2, late_headers));
   AddRead(*headers_frame);
 
   AddReadPause();
 
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR));
   AddWrite(*rst);
 
@@ -807,16 +803,15 @@
 // to overflow an int32_t. The SpdyStream should handle that case
 // gracefully.
 TEST_P(SpdyStreamTest, IncreaseSendWindowSizeOverflow) {
-  scoped_ptr<SpdyFrame> req(
-      spdy_util_.ConstructSpdyPost(
-          kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0));
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
+      kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0));
   AddWrite(*req);
 
   AddReadPause();
 
   // Triggered by the overflowing call to IncreaseSendWindowSize
   // below.
-  scoped_ptr<SpdyFrame> rst(
+  scoped_ptr<SpdySerializedFrame> rst(
       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_FLOW_CONTROL_ERROR));
   AddWrite(*rst);
 
@@ -900,16 +895,16 @@
     const UnstallFunction& unstall_function) {
   GURL url(kStreamUrl);
 
-  scoped_ptr<SpdyFrame> req(
-      spdy_util_.ConstructSpdyPost(
-          kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0));
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
+      kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0));
   AddWrite(*req);
 
-  scoped_ptr<SpdyFrame> body(
+  scoped_ptr<SpdySerializedFrame> body(
       spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, true));
   AddWrite(*body);
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   AddRead(*resp);
 
   AddReadEOF();
@@ -976,21 +971,21 @@
     const UnstallFunction& unstall_function) {
   GURL url(kStreamUrl);
 
-  scoped_ptr<SpdyFrame> req(
-      spdy_util_.ConstructSpdyPost(
-          kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0));
+  scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost(
+      kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0));
   AddWrite(*req);
 
   AddReadPause();
 
-  scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> resp(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   AddRead(*resp);
 
-  scoped_ptr<SpdyFrame> msg(
+  scoped_ptr<SpdySerializedFrame> msg(
       spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, false));
   AddWrite(*msg);
 
-  scoped_ptr<SpdyFrame> echo(
+  scoped_ptr<SpdySerializedFrame> echo(
       spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, false));
   AddRead(*echo);
 
@@ -1060,19 +1055,19 @@
 TEST_P(SpdyStreamTest, ReceivedBytes) {
   GURL url(kStreamUrl);
 
-  scoped_ptr<SpdyFrame> syn(
+  scoped_ptr<SpdySerializedFrame> syn(
       spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true));
   AddWrite(*syn);
 
   AddReadPause();
 
-  scoped_ptr<SpdyFrame>
-      reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
+  scoped_ptr<SpdySerializedFrame> reply(
+      spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   AddRead(*reply);
 
   AddReadPause();
 
-  scoped_ptr<SpdyFrame> msg(
+  scoped_ptr<SpdySerializedFrame> msg(
       spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, false));
   AddRead(*msg);
 
diff --git a/net/spdy/spdy_test_util_common.cc b/net/spdy/spdy_test_util_common.cc
index 5149cb5..d871236e 100644
--- a/net/spdy/spdy_test_util_common.cc
+++ b/net/spdy/spdy_test_util_common.cc
@@ -58,7 +58,7 @@
 // Chop a frame into an array of MockWrites.
 // |frame| is the frame to chop.
 // |num_chunks| is the number of chunks to create.
-MockWrite* ChopWriteFrame(const SpdyFrame& frame, int num_chunks) {
+MockWrite* ChopWriteFrame(const SpdySerializedFrame& frame, int num_chunks) {
   MockWrite* chunks = new MockWrite[num_chunks];
   int chunk_size = frame.size() / num_chunks;
   for (int index = 0; index < num_chunks; index++) {
@@ -118,39 +118,41 @@
   }
 }
 
-// Create a MockWrite from the given SpdyFrame.
-MockWrite CreateMockWrite(const SpdyFrame& req) {
+// Create a MockWrite from the given SpdySerializedFrame.
+MockWrite CreateMockWrite(const SpdySerializedFrame& req) {
   return MockWrite(ASYNC, req.data(), req.size());
 }
 
-// Create a MockWrite from the given SpdyFrame and sequence number.
-MockWrite CreateMockWrite(const SpdyFrame& req, int seq) {
+// Create a MockWrite from the given SpdySerializedFrame and sequence number.
+MockWrite CreateMockWrite(const SpdySerializedFrame& req, int seq) {
   return CreateMockWrite(req, seq, ASYNC);
 }
 
-// Create a MockWrite from the given SpdyFrame and sequence number.
-MockWrite CreateMockWrite(const SpdyFrame& req, int seq, IoMode mode) {
+// Create a MockWrite from the given SpdySerializedFrame and sequence number.
+MockWrite CreateMockWrite(const SpdySerializedFrame& req,
+                          int seq,
+                          IoMode mode) {
   return MockWrite(mode, req.data(), req.size(), seq);
 }
 
-// Create a MockRead from the given SpdyFrame.
-MockRead CreateMockRead(const SpdyFrame& resp) {
+// Create a MockRead from the given SpdySerializedFrame.
+MockRead CreateMockRead(const SpdySerializedFrame& resp) {
   return MockRead(ASYNC, resp.data(), resp.size());
 }
 
-// Create a MockRead from the given SpdyFrame and sequence number.
-MockRead CreateMockRead(const SpdyFrame& resp, int seq) {
+// Create a MockRead from the given SpdySerializedFrame and sequence number.
+MockRead CreateMockRead(const SpdySerializedFrame& resp, int seq) {
   return CreateMockRead(resp, seq, ASYNC);
 }
 
-// Create a MockRead from the given SpdyFrame and sequence number.
-MockRead CreateMockRead(const SpdyFrame& resp, int seq, IoMode mode) {
+// Create a MockRead from the given SpdySerializedFrame and sequence number.
+MockRead CreateMockRead(const SpdySerializedFrame& resp, int seq, IoMode mode) {
   return MockRead(mode, resp.data(), resp.size(), seq);
 }
 
 // Combines the given SpdyFrames into the given char array and returns
 // the total length.
-int CombineFrames(const SpdyFrame** frames,
+int CombineFrames(const SpdySerializedFrame** frames,
                   int num_frames,
                   char* buf,
                   int buf_len) {
@@ -240,7 +242,7 @@
 }  // namespace
 
 bool GetSpdyPriority(SpdyMajorVersion version,
-                     const SpdyFrame& frame,
+                     const SpdySerializedFrame& frame,
                      SpdyPriority* priority) {
   BufferedSpdyFramer framer(version);
   PriorityGetter priority_getter;
@@ -738,11 +740,11 @@
   return ConstructHeaderBlock("PUT", url, &content_length);
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdyFrame(
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdyFrame(
     const SpdyHeaderInfo& header_info,
     scoped_ptr<SpdyHeaderBlock> headers) const {
   BufferedSpdyFramer framer(spdy_version_);
-  SpdyFrame* frame = NULL;
+  SpdySerializedFrame* frame = NULL;
   switch (header_info.kind) {
     case DATA:
       frame = framer.CreateDataFrame(header_info.id, header_info.data,
@@ -776,11 +778,12 @@
   return frame;
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdyFrame(const SpdyHeaderInfo& header_info,
-                                            const char* const extra_headers[],
-                                            int extra_header_count,
-                                            const char* const tail_headers[],
-                                            int tail_header_count) const {
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdyFrame(
+    const SpdyHeaderInfo& header_info,
+    const char* const extra_headers[],
+    int extra_header_count,
+    const char* const tail_headers[],
+    int tail_header_count) const {
   scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock());
   AppendToHeaderBlock(extra_headers, extra_header_count, headers.get());
   if (tail_headers && tail_header_count)
@@ -809,7 +812,8 @@
 
 // TODO(jgraettinger): Eliminate uses of this method in tests (prefer
 // SpdySettingsIR).
-SpdyFrame* SpdyTestUtil::ConstructSpdySettings(const SettingsMap& settings) {
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdySettings(
+    const SettingsMap& settings) {
   SpdySettingsIR settings_ir;
   for (SettingsMap::const_iterator it = settings.begin();
        it != settings.end();
@@ -820,69 +824,81 @@
         (it->second.first & SETTINGS_FLAG_PERSISTED) != 0,
         it->second.second);
   }
-  return headerless_spdy_framer_.SerializeFrame(settings_ir);
+  return new SpdySerializedFrame(
+      headerless_spdy_framer_.SerializeFrame(settings_ir));
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdySettingsAck() {
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdySettingsAck() {
   char kEmptyWrite[] = "";
 
   if (spdy_version() > SPDY3) {
     SpdySettingsIR settings_ir;
     settings_ir.set_is_ack(true);
-    return headerless_spdy_framer_.SerializeFrame(settings_ir);
+    return new SpdySerializedFrame(
+        headerless_spdy_framer_.SerializeFrame(settings_ir));
   }
   // No settings ACK write occurs. Create an empty placeholder write.
-  return new SpdyFrame(kEmptyWrite, 0, false);
+  return new SpdySerializedFrame(kEmptyWrite, 0, false);
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdyPing(uint32_t ping_id, bool is_ack) {
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdyPing(uint32_t ping_id,
+                                                     bool is_ack) {
   SpdyPingIR ping_ir(ping_id);
   ping_ir.set_is_ack(is_ack);
-  return headerless_spdy_framer_.SerializeFrame(ping_ir);
+  return new SpdySerializedFrame(
+      headerless_spdy_framer_.SerializeFrame(ping_ir));
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdyGoAway() {
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdyGoAway() {
   return ConstructSpdyGoAway(0);
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdyGoAway(SpdyStreamId last_good_stream_id) {
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdyGoAway(
+    SpdyStreamId last_good_stream_id) {
   SpdyGoAwayIR go_ir(last_good_stream_id, GOAWAY_OK, "go away");
-  return headerless_spdy_framer_.SerializeFrame(go_ir);
+  return new SpdySerializedFrame(headerless_spdy_framer_.SerializeFrame(go_ir));
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdyGoAway(SpdyStreamId last_good_stream_id,
-                                             SpdyGoAwayStatus status,
-                                             const std::string& desc) {
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdyGoAway(
+    SpdyStreamId last_good_stream_id,
+    SpdyGoAwayStatus status,
+    const std::string& desc) {
   SpdyGoAwayIR go_ir(last_good_stream_id, status, desc);
-  return headerless_spdy_framer_.SerializeFrame(go_ir);
+  return new SpdySerializedFrame(headerless_spdy_framer_.SerializeFrame(go_ir));
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdyWindowUpdate(const SpdyStreamId stream_id,
-                                                   uint32_t delta_window_size) {
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdyWindowUpdate(
+    const SpdyStreamId stream_id,
+    uint32_t delta_window_size) {
   SpdyWindowUpdateIR update_ir(stream_id, delta_window_size);
-  return headerless_spdy_framer_.SerializeFrame(update_ir);
+  return new SpdySerializedFrame(
+      headerless_spdy_framer_.SerializeFrame(update_ir));
 }
 
 // TODO(jgraettinger): Eliminate uses of this method in tests (prefer
 // SpdyRstStreamIR).
-SpdyFrame* SpdyTestUtil::ConstructSpdyRstStream(SpdyStreamId stream_id,
-                                                SpdyRstStreamStatus status) {
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdyRstStream(
+    SpdyStreamId stream_id,
+    SpdyRstStreamStatus status) {
   SpdyRstStreamIR rst_ir(stream_id, status);
-  return headerless_spdy_framer_.SerializeRstStream(rst_ir);
+  return new SpdySerializedFrame(
+      headerless_spdy_framer_.SerializeRstStream(rst_ir));
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdyGet(const char* const url,
-                                          SpdyStreamId stream_id,
-                                          RequestPriority request_priority) {
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdyGet(
+    const char* const url,
+    SpdyStreamId stream_id,
+    RequestPriority request_priority) {
   scoped_ptr<SpdyHeaderBlock> block(ConstructGetHeaderBlock(url));
   return ConstructSpdySyn(stream_id, *block, request_priority, true);
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdyGet(const char* const extra_headers[],
-                                          int extra_header_count,
-                                          int stream_id,
-                                          RequestPriority request_priority,
-                                          bool direct) {
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdyGet(
+    const char* const extra_headers[],
+    int extra_header_count,
+    int stream_id,
+    RequestPriority request_priority,
+    bool direct) {
   SpdyHeaderBlock block;
   MaybeAddVersionHeader(&block);
   block[GetMethodKey()] = "GET";
@@ -891,7 +907,7 @@
   return ConstructSpdySyn(stream_id, block, request_priority, true);
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdyConnect(
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdyConnect(
     const char* const extra_headers[],
     int extra_header_count,
     int stream_id,
@@ -912,11 +928,12 @@
   return ConstructSpdySyn(stream_id, block, priority, false);
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdyPush(const char* const extra_headers[],
-                                           int extra_header_count,
-                                           int stream_id,
-                                           int associated_stream_id,
-                                           const char* url) {
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdyPush(
+    const char* const extra_headers[],
+    int extra_header_count,
+    int stream_id,
+    int associated_stream_id,
+    const char* url) {
   if (spdy_version() < HTTP2) {
     SpdySynStreamIR syn_stream(stream_id);
     syn_stream.set_associated_to_stream_id(associated_stream_id);
@@ -926,11 +943,12 @@
     AddUrlToHeaderBlock(url, syn_stream.mutable_header_block());
     AppendToHeaderBlock(extra_headers, extra_header_count,
                         syn_stream.mutable_header_block());
-    return response_spdy_framer_.SerializeFrame(syn_stream);
+    return new SpdySerializedFrame(
+        response_spdy_framer_.SerializeFrame(syn_stream));
   } else {
     SpdyPushPromiseIR push_promise(associated_stream_id, stream_id);
     AddUrlToHeaderBlock(url, push_promise.mutable_header_block());
-    scoped_ptr<SpdyFrame> push_promise_frame(
+    SpdySerializedFrame push_promise_frame(
         response_spdy_framer_.SerializeFrame(push_promise));
 
     SpdyHeadersIR headers(stream_id);
@@ -938,28 +956,29 @@
     headers.SetHeader("hello", "bye");
     AppendToHeaderBlock(extra_headers, extra_header_count,
                         headers.mutable_header_block());
-    scoped_ptr<SpdyFrame> headers_frame(
+    SpdySerializedFrame headers_frame(
         response_spdy_framer_.SerializeFrame(headers));
 
-    int joint_data_size = push_promise_frame->size() + headers_frame->size();
+    int joint_data_size = push_promise_frame.size() + headers_frame.size();
     scoped_ptr<char[]> data(new char[joint_data_size]);
-    const SpdyFrame* frames[2] = {
-        push_promise_frame.get(), headers_frame.get(),
+    const SpdySerializedFrame* frames[2] = {
+        &push_promise_frame, &headers_frame,
     };
     int combined_size =
         CombineFrames(frames, arraysize(frames), data.get(), joint_data_size);
     DCHECK_EQ(combined_size, joint_data_size);
-    return new SpdyFrame(data.release(), joint_data_size, true);
+    return new SpdySerializedFrame(data.release(), joint_data_size, true);
   }
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdyPush(const char* const extra_headers[],
-                                           int extra_header_count,
-                                           int stream_id,
-                                           int associated_stream_id,
-                                           const char* url,
-                                           const char* status,
-                                           const char* location) {
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdyPush(
+    const char* const extra_headers[],
+    int extra_header_count,
+    int stream_id,
+    int associated_stream_id,
+    const char* url,
+    const char* status,
+    const char* location) {
   if (spdy_version() < HTTP2) {
     SpdySynStreamIR syn_stream(stream_id);
     syn_stream.set_associated_to_stream_id(associated_stream_id);
@@ -970,11 +989,12 @@
     AddUrlToHeaderBlock(url, syn_stream.mutable_header_block());
     AppendToHeaderBlock(extra_headers, extra_header_count,
                         syn_stream.mutable_header_block());
-    return response_spdy_framer_.SerializeFrame(syn_stream);
+    return new SpdySerializedFrame(
+        response_spdy_framer_.SerializeFrame(syn_stream));
   } else {
     SpdyPushPromiseIR push_promise(associated_stream_id, stream_id);
     AddUrlToHeaderBlock(url, push_promise.mutable_header_block());
-    scoped_ptr<SpdyFrame> push_promise_frame(
+    SpdySerializedFrame push_promise_frame(
         response_spdy_framer_.SerializeFrame(push_promise));
 
     SpdyHeadersIR headers(stream_id);
@@ -983,22 +1003,22 @@
     headers.SetHeader("location", location);
     AppendToHeaderBlock(extra_headers, extra_header_count,
                         headers.mutable_header_block());
-    scoped_ptr<SpdyFrame> headers_frame(
+    SpdySerializedFrame headers_frame(
         response_spdy_framer_.SerializeFrame(headers));
 
-    int joint_data_size = push_promise_frame->size() + headers_frame->size();
+    int joint_data_size = push_promise_frame.size() + headers_frame.size();
     scoped_ptr<char[]> data(new char[joint_data_size]);
-    const SpdyFrame* frames[2] = {
-        push_promise_frame.get(), headers_frame.get(),
+    const SpdySerializedFrame* frames[2] = {
+        &push_promise_frame, &headers_frame,
     };
     int combined_size =
         CombineFrames(frames, arraysize(frames), data.get(), joint_data_size);
     DCHECK_EQ(combined_size, joint_data_size);
-    return new SpdyFrame(data.release(), joint_data_size, true);
+    return new SpdySerializedFrame(data.release(), joint_data_size, true);
   }
 }
 
-SpdyFrame* SpdyTestUtil::ConstructInitialSpdyPushFrame(
+SpdySerializedFrame* SpdyTestUtil::ConstructInitialSpdyPushFrame(
     scoped_ptr<SpdyHeaderBlock> headers,
     int stream_id,
     int associated_stream_id) {
@@ -1007,15 +1027,17 @@
     syn_stream.set_associated_to_stream_id(associated_stream_id);
     SetPriority(LOWEST, &syn_stream);
     syn_stream.set_header_block(*headers);
-    return response_spdy_framer_.SerializeFrame(syn_stream);
+    return new SpdySerializedFrame(
+        response_spdy_framer_.SerializeFrame(syn_stream));
   } else {
     SpdyPushPromiseIR push_promise(associated_stream_id, stream_id);
     push_promise.set_header_block(*headers);
-    return response_spdy_framer_.SerializeFrame(push_promise);
+    return new SpdySerializedFrame(
+        response_spdy_framer_.SerializeFrame(push_promise));
   }
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdyPushHeaders(
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdyPushHeaders(
     int stream_id,
     const char* const extra_headers[],
     int extra_header_count) {
@@ -1024,23 +1046,25 @@
   MaybeAddVersionHeader(&headers);
   AppendToHeaderBlock(extra_headers, extra_header_count,
                       headers.mutable_header_block());
-  return response_spdy_framer_.SerializeFrame(headers);
+  return new SpdySerializedFrame(response_spdy_framer_.SerializeFrame(headers));
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdyResponseHeaders(
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdyResponseHeaders(
     int stream_id,
     const SpdyHeaderBlock& headers,
     bool fin) {
   SpdyHeadersIR spdy_headers(stream_id);
   spdy_headers.set_header_block(headers);
   spdy_headers.set_fin(fin);
-  return response_spdy_framer_.SerializeFrame(spdy_headers);
+  return new SpdySerializedFrame(
+      response_spdy_framer_.SerializeFrame(spdy_headers));
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdySyn(int stream_id,
-                                          const SpdyHeaderBlock& block,
-                                          RequestPriority priority,
-                                          bool fin) {
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdySyn(
+    int stream_id,
+    const SpdyHeaderBlock& block,
+    RequestPriority priority,
+    bool fin) {
   // Get the stream id of the next highest priority request
   // (most recent request of the same priority, or last request of
   // an earlier priority).
@@ -1065,7 +1089,8 @@
     syn_stream.set_priority(
         ConvertRequestPriorityToSpdyPriority(priority, spdy_version()));
     syn_stream.set_fin(fin);
-    return request_spdy_framer_.SerializeFrame(syn_stream);
+    return new SpdySerializedFrame(
+        request_spdy_framer_.SerializeFrame(syn_stream));
   } else {
     SpdyHeadersIR headers(stream_id);
     headers.set_header_block(block);
@@ -1077,24 +1102,27 @@
       headers.set_exclusive(true);
     }
     headers.set_fin(fin);
-    return request_spdy_framer_.SerializeFrame(headers);
+    return new SpdySerializedFrame(
+        request_spdy_framer_.SerializeFrame(headers));
   }
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdyReply(int stream_id,
-                                            const SpdyHeaderBlock& headers) {
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdyReply(
+    int stream_id,
+    const SpdyHeaderBlock& headers) {
   if (protocol_ < kProtoHTTP2) {
     SpdySynReplyIR syn_reply(stream_id);
     syn_reply.set_header_block(headers);
-    return response_spdy_framer_.SerializeFrame(syn_reply);
+    return new SpdySerializedFrame(
+        response_spdy_framer_.SerializeFrame(syn_reply));
   } else {
     SpdyHeadersIR reply(stream_id);
     reply.set_header_block(headers);
-    return response_spdy_framer_.SerializeFrame(reply);
+    return new SpdySerializedFrame(response_spdy_framer_.SerializeFrame(reply));
   }
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdySynReplyError(
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdySynReplyError(
     const char* const status,
     const char* const* const extra_headers,
     int extra_header_count,
@@ -1108,7 +1136,8 @@
   return ConstructSpdyReply(stream_id, block);
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdyGetSynReplyRedirect(int stream_id) {
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdyGetSynReplyRedirect(
+    int stream_id) {
   static const char* const kExtraHeaders[] = {
     "location", "http://www.foo.com/index.php",
   };
@@ -1116,11 +1145,11 @@
                                     arraysize(kExtraHeaders)/2, stream_id);
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdySynReplyError(int stream_id) {
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdySynReplyError(int stream_id) {
   return ConstructSpdySynReplyError("500 Internal Server Error", NULL, 0, 1);
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdyGetSynReply(
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdyGetSynReply(
     const char* const extra_headers[],
     int extra_header_count,
     int stream_id) {
@@ -1133,19 +1162,20 @@
   return ConstructSpdyReply(stream_id, block);
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdyPost(const char* url,
-                                           SpdyStreamId stream_id,
-                                           int64_t content_length,
-                                           RequestPriority priority,
-                                           const char* const extra_headers[],
-                                           int extra_header_count) {
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdyPost(
+    const char* url,
+    SpdyStreamId stream_id,
+    int64_t content_length,
+    RequestPriority priority,
+    const char* const extra_headers[],
+    int extra_header_count) {
   scoped_ptr<SpdyHeaderBlock> block(
       ConstructPostHeaderBlock(url, content_length));
   AppendToHeaderBlock(extra_headers, extra_header_count, block.get());
   return ConstructSpdySyn(stream_id, *block, priority, false);
 }
 
-SpdyFrame* SpdyTestUtil::ConstructChunkedSpdyPost(
+SpdySerializedFrame* SpdyTestUtil::ConstructChunkedSpdyPost(
     const char* const extra_headers[],
     int extra_header_count) {
   SpdyHeaderBlock block;
@@ -1156,45 +1186,46 @@
   return ConstructSpdySyn(1, block, LOWEST, false);
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdyPostSynReply(
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdyPostSynReply(
     const char* const extra_headers[],
     int extra_header_count) {
   // TODO(jgraettinger): Remove this method.
   return ConstructSpdyGetSynReply(extra_headers, extra_header_count, 1);
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdyBodyFrame(int stream_id, bool fin) {
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdyBodyFrame(int stream_id,
+                                                          bool fin) {
   SpdyFramer framer(spdy_version_);
   SpdyDataIR data_ir(stream_id,
                      base::StringPiece(kUploadData, kUploadDataSize));
   data_ir.set_fin(fin);
-  return framer.SerializeData(data_ir);
+  return new SpdySerializedFrame(framer.SerializeData(data_ir));
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdyBodyFrame(int stream_id,
-                                                const char* data,
-                                                uint32_t len,
-                                                bool fin) {
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdyBodyFrame(int stream_id,
+                                                          const char* data,
+                                                          uint32_t len,
+                                                          bool fin) {
   SpdyFramer framer(spdy_version_);
   SpdyDataIR data_ir(stream_id, base::StringPiece(data, len));
   data_ir.set_fin(fin);
-  return framer.SerializeData(data_ir);
+  return new SpdySerializedFrame(framer.SerializeData(data_ir));
 }
 
-SpdyFrame* SpdyTestUtil::ConstructSpdyBodyFrame(int stream_id,
-                                                const char* data,
-                                                uint32_t len,
-                                                bool fin,
-                                                int padding_length) {
+SpdySerializedFrame* SpdyTestUtil::ConstructSpdyBodyFrame(int stream_id,
+                                                          const char* data,
+                                                          uint32_t len,
+                                                          bool fin,
+                                                          int padding_length) {
   SpdyFramer framer(spdy_version_);
   SpdyDataIR data_ir(stream_id, base::StringPiece(data, len));
   data_ir.set_fin(fin);
   data_ir.set_padding_len(padding_length);
-  return framer.SerializeData(data_ir);
+  return new SpdySerializedFrame(framer.SerializeData(data_ir));
 }
 
-SpdyFrame* SpdyTestUtil::ConstructWrappedSpdyFrame(
-    const scoped_ptr<SpdyFrame>& frame,
+SpdySerializedFrame* SpdyTestUtil::ConstructWrappedSpdyFrame(
+    const scoped_ptr<SpdySerializedFrame>& frame,
     int stream_id) {
   return ConstructSpdyBodyFrame(stream_id, frame->data(),
                                 frame->size(), false);
diff --git a/net/spdy/spdy_test_util_common.h b/net/spdy/spdy_test_util_common.h
index f7b4800d..cc4cb57 100644
--- a/net/spdy/spdy_test_util_common.h
+++ b/net/spdy/spdy_test_util_common.h
@@ -55,10 +55,10 @@
 const char kUploadData[] = "hello!";
 const int kUploadDataSize = arraysize(kUploadData)-1;
 
-// Chop a SpdyFrame into an array of MockWrites.
+// Chop a SpdySerializedFrame into an array of MockWrites.
 // |frame| is the frame to chop.
 // |num_chunks| is the number of chunks to create.
-MockWrite* ChopWriteFrame(const SpdyFrame& frame, int num_chunks);
+MockWrite* ChopWriteFrame(const SpdySerializedFrame& frame, int num_chunks);
 
 // Adds headers and values to a map.
 // |extra_headers| is an array of { name, value } pairs, arranged as strings
@@ -69,25 +69,26 @@
                          int extra_header_count,
                          SpdyHeaderBlock* headers);
 
-// Create an async MockWrite from the given SpdyFrame.
-MockWrite CreateMockWrite(const SpdyFrame& req);
+// Create an async MockWrite from the given SpdySerializedFrame.
+MockWrite CreateMockWrite(const SpdySerializedFrame& req);
 
-// Create an async MockWrite from the given SpdyFrame and sequence number.
-MockWrite CreateMockWrite(const SpdyFrame& req, int seq);
+// Create an async MockWrite from the given SpdySerializedFrame and sequence
+// number.
+MockWrite CreateMockWrite(const SpdySerializedFrame& req, int seq);
 
-MockWrite CreateMockWrite(const SpdyFrame& req, int seq, IoMode mode);
+MockWrite CreateMockWrite(const SpdySerializedFrame& req, int seq, IoMode mode);
 
-// Create a MockRead from the given SpdyFrame.
-MockRead CreateMockRead(const SpdyFrame& resp);
+// Create a MockRead from the given SpdySerializedFrame.
+MockRead CreateMockRead(const SpdySerializedFrame& resp);
 
-// Create a MockRead from the given SpdyFrame and sequence number.
-MockRead CreateMockRead(const SpdyFrame& resp, int seq);
+// Create a MockRead from the given SpdySerializedFrame and sequence number.
+MockRead CreateMockRead(const SpdySerializedFrame& resp, int seq);
 
-MockRead CreateMockRead(const SpdyFrame& resp, int seq, IoMode mode);
+MockRead CreateMockRead(const SpdySerializedFrame& resp, int seq, IoMode mode);
 
-// Combines the given SpdyFrames into the given char array and returns
+// Combines the given SpdySerializedFrame into the given char array and returns
 // the total length.
-int CombineFrames(const SpdyFrame** frames,
+int CombineFrames(const SpdySerializedFrame** frames,
                   int num_frames,
                   char* buf,
                   int buf_len);
@@ -95,7 +96,7 @@
 // Returns the SpdyPriority embedded in the given frame.  Returns true
 // and fills in |priority| on success.
 bool GetSpdyPriority(SpdyMajorVersion version,
-                     const SpdyFrame& frame,
+                     const SpdySerializedFrame& frame,
                      SpdyPriority* priority);
 
 // Tries to create a stream in |session| synchronously. Returns NULL
@@ -306,7 +307,7 @@
   // Construct a SPDY frame.  If it is a SYN_STREAM or SYN_REPLY frame (as
   // specified in header_info.kind), the provided headers are included in the
   // frame.
-  SpdyFrame* ConstructSpdyFrame(
+  SpdySerializedFrame* ConstructSpdyFrame(
       const SpdyHeaderInfo& header_info,
       scoped_ptr<SpdyHeaderBlock> headers) const;
 
@@ -314,11 +315,11 @@
   // specified in header_info.kind), the headers provided in extra_headers and
   // (if non-NULL) tail_headers are concatenated and included in the frame.
   // (extra_headers must always be non-NULL.)
-  SpdyFrame* ConstructSpdyFrame(const SpdyHeaderInfo& header_info,
-                                const char* const extra_headers[],
-                                int extra_header_count,
-                                const char* const tail_headers[],
-                                int tail_header_count) const;
+  SpdySerializedFrame* ConstructSpdyFrame(const SpdyHeaderInfo& header_info,
+                                          const char* const extra_headers[],
+                                          int extra_header_count,
+                                          const char* const tail_headers[],
+                                          int tail_header_count) const;
 
   // Construct an expected SPDY reply string from the given headers.
   std::string ConstructSpdyReplyString(const SpdyHeaderBlock& headers) const;
@@ -326,181 +327,189 @@
   // Construct an expected SPDY SETTINGS frame.
   // |settings| are the settings to set.
   // Returns the constructed frame.  The caller takes ownership of the frame.
-  SpdyFrame* ConstructSpdySettings(const SettingsMap& settings);
+  SpdySerializedFrame* ConstructSpdySettings(const SettingsMap& settings);
 
   // Constructs an expected SPDY SETTINGS acknowledgement frame, if the protocol
   // version is SPDY4 or higher, or an empty placeholder frame otherwise.
-  SpdyFrame* ConstructSpdySettingsAck();
+  SpdySerializedFrame* ConstructSpdySettingsAck();
 
   // Construct a SPDY PING frame.
   // Returns the constructed frame.  The caller takes ownership of the frame.
-  SpdyFrame* ConstructSpdyPing(uint32_t ping_id, bool is_ack);
+  SpdySerializedFrame* ConstructSpdyPing(uint32_t ping_id, bool is_ack);
 
   // Construct a SPDY GOAWAY frame with last_good_stream_id = 0.
   // Returns the constructed frame.  The caller takes ownership of the frame.
-  SpdyFrame* ConstructSpdyGoAway();
+  SpdySerializedFrame* ConstructSpdyGoAway();
 
   // Construct a SPDY GOAWAY frame with the specified last_good_stream_id.
   // Returns the constructed frame.  The caller takes ownership of the frame.
-  SpdyFrame* ConstructSpdyGoAway(SpdyStreamId last_good_stream_id);
+  SpdySerializedFrame* ConstructSpdyGoAway(SpdyStreamId last_good_stream_id);
 
   // Construct a SPDY GOAWAY frame with the specified last_good_stream_id,
   // status, and description. Returns the constructed frame. The caller takes
   // ownership of the frame.
-  SpdyFrame* ConstructSpdyGoAway(SpdyStreamId last_good_stream_id,
-                                 SpdyGoAwayStatus status,
-                                 const std::string& desc);
+  SpdySerializedFrame* ConstructSpdyGoAway(SpdyStreamId last_good_stream_id,
+                                           SpdyGoAwayStatus status,
+                                           const std::string& desc);
 
   // Construct a SPDY WINDOW_UPDATE frame.
   // Returns the constructed frame.  The caller takes ownership of the frame.
-  SpdyFrame* ConstructSpdyWindowUpdate(SpdyStreamId stream_id,
-                                       uint32_t delta_window_size);
+  SpdySerializedFrame* ConstructSpdyWindowUpdate(SpdyStreamId stream_id,
+                                                 uint32_t delta_window_size);
 
   // Construct a SPDY RST_STREAM frame.
   // Returns the constructed frame.  The caller takes ownership of the frame.
-  SpdyFrame* ConstructSpdyRstStream(SpdyStreamId stream_id,
-                                    SpdyRstStreamStatus status);
+  SpdySerializedFrame* ConstructSpdyRstStream(SpdyStreamId stream_id,
+                                              SpdyRstStreamStatus status);
 
   // Constructs a standard SPDY GET SYN frame for |url| with header compression.
   // |extra_headers| are the extra header-value pairs, which typically
   // will vary the most between calls.
-  // Returns a SpdyFrame.
-  SpdyFrame* ConstructSpdyGet(const char* const url,
-                              SpdyStreamId stream_id,
-                              RequestPriority request_priority);
+  // Returns a SpdySerializedFrame.
+  SpdySerializedFrame* ConstructSpdyGet(const char* const url,
+                                        SpdyStreamId stream_id,
+                                        RequestPriority request_priority);
 
   // Constructs a standard SPDY GET SYN frame with header compression.
   // |extra_headers| are the extra header-value pairs, which typically
   // will vary the most between calls.  If |direct| is false, the
   // the full url will be used instead of simply the path.
-  // Returns a SpdyFrame.
-  SpdyFrame* ConstructSpdyGet(const char* const extra_headers[],
-                              int extra_header_count,
-                              int stream_id,
-                              RequestPriority request_priority,
-                              bool direct);
+  // Returns a SpdySerializedFrame.
+  SpdySerializedFrame* ConstructSpdyGet(const char* const extra_headers[],
+                                        int extra_header_count,
+                                        int stream_id,
+                                        RequestPriority request_priority,
+                                        bool direct);
 
   // Constructs a standard SPDY SYN_STREAM frame for a CONNECT request.
-  SpdyFrame* ConstructSpdyConnect(const char* const extra_headers[],
-                                  int extra_header_count,
-                                  int stream_id,
-                                  RequestPriority priority,
-                                  const HostPortPair& host_port_pair);
+  SpdySerializedFrame* ConstructSpdyConnect(const char* const extra_headers[],
+                                            int extra_header_count,
+                                            int stream_id,
+                                            RequestPriority priority,
+                                            const HostPortPair& host_port_pair);
 
   // Constructs a standard SPDY push SYN frame.
   // |extra_headers| are the extra header-value pairs, which typically
   // will vary the most between calls.
-  // Returns a SpdyFrame.
-  SpdyFrame* ConstructSpdyPush(const char* const extra_headers[],
-                               int extra_header_count,
-                               int stream_id,
-                               int associated_stream_id,
-                               const char* url);
-  SpdyFrame* ConstructSpdyPush(const char* const extra_headers[],
-                               int extra_header_count,
-                               int stream_id,
-                               int associated_stream_id,
-                               const char* url,
-                               const char* status,
-                               const char* location);
+  // Returns a SpdySerializedFrame.
+  SpdySerializedFrame* ConstructSpdyPush(const char* const extra_headers[],
+                                         int extra_header_count,
+                                         int stream_id,
+                                         int associated_stream_id,
+                                         const char* url);
+  SpdySerializedFrame* ConstructSpdyPush(const char* const extra_headers[],
+                                         int extra_header_count,
+                                         int stream_id,
+                                         int associated_stream_id,
+                                         const char* url,
+                                         const char* status,
+                                         const char* location);
 
-  SpdyFrame* ConstructInitialSpdyPushFrame(scoped_ptr<SpdyHeaderBlock> headers,
-                                           int stream_id,
-                                           int associated_stream_id);
+  SpdySerializedFrame* ConstructInitialSpdyPushFrame(
+      scoped_ptr<SpdyHeaderBlock> headers,
+      int stream_id,
+      int associated_stream_id);
 
-  SpdyFrame* ConstructSpdyPushHeaders(int stream_id,
-                                      const char* const extra_headers[],
-                                      int extra_header_count);
+  SpdySerializedFrame* ConstructSpdyPushHeaders(
+      int stream_id,
+      const char* const extra_headers[],
+      int extra_header_count);
 
   // Constructs a SPDY header frame with the request header compression context
   // with END_STREAM flag set to |fin|.
-  SpdyFrame* ConstructSpdyResponseHeaders(int stream_id,
-                                          const SpdyHeaderBlock& headers,
-                                          bool fin);
+  SpdySerializedFrame* ConstructSpdyResponseHeaders(
+      int stream_id,
+      const SpdyHeaderBlock& headers,
+      bool fin);
 
   // Construct a SPDY syn (HEADERS or SYN_STREAM, depending on protocol
   // version) carrying exactly the given headers and priority.
-  SpdyFrame* ConstructSpdySyn(int stream_id,
-                              const SpdyHeaderBlock& headers,
-                              RequestPriority priority,
-                              bool fin);
+  SpdySerializedFrame* ConstructSpdySyn(int stream_id,
+                                        const SpdyHeaderBlock& headers,
+                                        RequestPriority priority,
+                                        bool fin);
 
   // Construct a SPDY reply (HEADERS or SYN_REPLY, depending on protocol
   // version) carrying exactly the given headers, and the default priority
   // (or no priority, depending on protocol version).
-  SpdyFrame* ConstructSpdyReply(int stream_id, const SpdyHeaderBlock& headers);
+  SpdySerializedFrame* ConstructSpdyReply(int stream_id,
+                                          const SpdyHeaderBlock& headers);
 
   // Constructs a standard SPDY SYN_REPLY frame to match the SPDY GET.
   // |extra_headers| are the extra header-value pairs, which typically
   // will vary the most between calls.
-  // Returns a SpdyFrame.
-  SpdyFrame* ConstructSpdyGetSynReply(const char* const extra_headers[],
-                                      int extra_header_count,
-                                      int stream_id);
+  // Returns a SpdySerializedFrame.
+  SpdySerializedFrame* ConstructSpdyGetSynReply(
+      const char* const extra_headers[],
+      int extra_header_count,
+      int stream_id);
 
   // Constructs a standard SPDY SYN_REPLY frame to match the SPDY GET.
   // |extra_headers| are the extra header-value pairs, which typically
   // will vary the most between calls.
-  // Returns a SpdyFrame.
-  SpdyFrame* ConstructSpdyGetSynReplyRedirect(int stream_id);
+  // Returns a SpdySerializedFrame.
+  SpdySerializedFrame* ConstructSpdyGetSynReplyRedirect(int stream_id);
 
   // Constructs a standard SPDY SYN_REPLY frame with an Internal Server
   // Error status code.
-  // Returns a SpdyFrame.
-  SpdyFrame* ConstructSpdySynReplyError(int stream_id);
+  // Returns a SpdySerializedFrame.
+  SpdySerializedFrame* ConstructSpdySynReplyError(int stream_id);
 
   // Constructs a standard SPDY SYN_REPLY frame with the specified status code.
-  // Returns a SpdyFrame.
-  SpdyFrame* ConstructSpdySynReplyError(const char* const status,
-                                        const char* const* const extra_headers,
-                                        int extra_header_count,
-                                        int stream_id);
+  // Returns a SpdySerializedFrame.
+  SpdySerializedFrame* ConstructSpdySynReplyError(
+      const char* const status,
+      const char* const* const extra_headers,
+      int extra_header_count,
+      int stream_id);
 
   // Constructs a standard SPDY POST SYN frame.
   // |extra_headers| are the extra header-value pairs, which typically
   // will vary the most between calls.
-  // Returns a SpdyFrame.
-  SpdyFrame* ConstructSpdyPost(const char* url,
-                               SpdyStreamId stream_id,
-                               int64_t content_length,
-                               RequestPriority priority,
-                               const char* const extra_headers[],
-                               int extra_header_count);
+  // Returns a SpdySerializedFrame.
+  SpdySerializedFrame* ConstructSpdyPost(const char* url,
+                                         SpdyStreamId stream_id,
+                                         int64_t content_length,
+                                         RequestPriority priority,
+                                         const char* const extra_headers[],
+                                         int extra_header_count);
 
   // Constructs a chunked transfer SPDY POST SYN frame.
   // |extra_headers| are the extra header-value pairs, which typically
   // will vary the most between calls.
-  // Returns a SpdyFrame.
-  SpdyFrame* ConstructChunkedSpdyPost(const char* const extra_headers[],
-                                      int extra_header_count);
+  // Returns a SpdySerializedFrame.
+  SpdySerializedFrame* ConstructChunkedSpdyPost(
+      const char* const extra_headers[],
+      int extra_header_count);
 
   // Constructs a standard SPDY SYN_REPLY frame to match the SPDY POST.
   // |extra_headers| are the extra header-value pairs, which typically
   // will vary the most between calls.
-  // Returns a SpdyFrame.
-  SpdyFrame* ConstructSpdyPostSynReply(const char* const extra_headers[],
-                                       int extra_header_count);
+  // Returns a SpdySerializedFrame.
+  SpdySerializedFrame* ConstructSpdyPostSynReply(
+      const char* const extra_headers[],
+      int extra_header_count);
 
   // Constructs a single SPDY data frame with the contents "hello!"
-  SpdyFrame* ConstructSpdyBodyFrame(int stream_id,
-                                    bool fin);
+  SpdySerializedFrame* ConstructSpdyBodyFrame(int stream_id, bool fin);
 
   // Constructs a single SPDY data frame with the given content.
-  SpdyFrame* ConstructSpdyBodyFrame(int stream_id,
-                                    const char* data,
-                                    uint32_t len,
-                                    bool fin);
+  SpdySerializedFrame* ConstructSpdyBodyFrame(int stream_id,
+                                              const char* data,
+                                              uint32_t len,
+                                              bool fin);
 
   // Constructs a single SPDY data frame with the given content and padding.
-  SpdyFrame* ConstructSpdyBodyFrame(int stream_id,
-                                    const char* data,
-                                    uint32_t len,
-                                    bool fin,
-                                    int padding_length);
+  SpdySerializedFrame* ConstructSpdyBodyFrame(int stream_id,
+                                              const char* data,
+                                              uint32_t len,
+                                              bool fin,
+                                              int padding_length);
 
   // Wraps |frame| in the payload of a data frame in stream |stream_id|.
-  SpdyFrame* ConstructWrappedSpdyFrame(const scoped_ptr<SpdyFrame>& frame,
-                                       int stream_id);
+  SpdySerializedFrame* ConstructWrappedSpdyFrame(
+      const scoped_ptr<SpdySerializedFrame>& frame,
+      int stream_id);
 
   // Called when necessary (when it will affect stream dependency specification
   // when setting dependencies based on priorioties) to notify the utility
diff --git a/net/spdy/spdy_test_utils.cc b/net/spdy/spdy_test_utils.cc
index 7af09fd..acc61c1 100644
--- a/net/spdy/spdy_test_utils.cc
+++ b/net/spdy/spdy_test_utils.cc
@@ -91,7 +91,7 @@
       << HexDumpWithMarks(actual, actual_len, marks.get(), max_len);
 }
 
-void SetFrameFlags(SpdyFrame* frame,
+void SetFrameFlags(SpdySerializedFrame* frame,
                    uint8_t flags,
                    SpdyMajorVersion spdy_version) {
   switch (spdy_version) {
@@ -104,7 +104,7 @@
   }
 }
 
-void SetFrameLength(SpdyFrame* frame,
+void SetFrameLength(SpdySerializedFrame* frame,
                     size_t length,
                     SpdyMajorVersion spdy_version) {
   switch (spdy_version) {
diff --git a/net/spdy/spdy_test_utils.h b/net/spdy/spdy_test_utils.h
index 16157ba71..388cb2b 100644
--- a/net/spdy/spdy_test_utils.h
+++ b/net/spdy/spdy_test_utils.h
@@ -37,11 +37,11 @@
     const unsigned char* expected,
     const int expected_len);
 
-void SetFrameFlags(SpdyFrame* frame,
+void SetFrameFlags(SpdySerializedFrame* frame,
                    uint8_t flags,
                    SpdyMajorVersion spdy_version);
 
-void SetFrameLength(SpdyFrame* frame,
+void SetFrameLength(SpdySerializedFrame* frame,
                     size_t length,
                     SpdyMajorVersion spdy_version);
 
diff --git a/net/spdy/spdy_write_queue_unittest.cc b/net/spdy/spdy_write_queue_unittest.cc
index 1c7bc0a..da9d9877 100644
--- a/net/spdy/spdy_write_queue_unittest.cc
+++ b/net/spdy/spdy_write_queue_unittest.cc
@@ -35,12 +35,9 @@
 scoped_ptr<SpdyBufferProducer> StringToProducer(const std::string& s) {
   scoped_ptr<char[]> data(new char[s.size()]);
   std::memcpy(data.get(), s.data(), s.size());
-  return scoped_ptr<SpdyBufferProducer>(
-      new SimpleBufferProducer(
-          scoped_ptr<SpdyBuffer>(
-              new SpdyBuffer(
-                  scoped_ptr<SpdyFrame>(
-                      new SpdyFrame(data.release(), s.size(), true))))));
+  return scoped_ptr<SpdyBufferProducer>(new SimpleBufferProducer(
+      scoped_ptr<SpdyBuffer>(new SpdyBuffer(scoped_ptr<SpdySerializedFrame>(
+          new SpdySerializedFrame(data.release(), s.size(), true))))));
 }
 
 // Makes a SpdyBufferProducer producing a frame with the data in the
diff --git a/net/tools/flip_server/spdy_interface.cc b/net/tools/flip_server/spdy_interface.cc
index fbb1439..5dbd7cb 100644
--- a/net/tools/flip_server/spdy_interface.cc
+++ b/net/tools/flip_server/spdy_interface.cc
@@ -22,14 +22,15 @@
 
 class SpdyFrameDataFrame : public DataFrame {
  public:
-  explicit SpdyFrameDataFrame(SpdyFrame* spdy_frame) : frame(spdy_frame) {
+  explicit SpdyFrameDataFrame(SpdySerializedFrame* spdy_frame)
+      : frame(spdy_frame) {
     data = spdy_frame->data();
     size = spdy_frame->size();
   }
 
   ~SpdyFrameDataFrame() override { delete frame; }
 
-  const SpdyFrame* frame;
+  const SpdySerializedFrame* frame;
 };
 
 SpdySM::SpdySM(SMConnection* connection,
@@ -344,7 +345,8 @@
   SettingsMap settings;
   settings[SETTINGS_MAX_CONCURRENT_STREAMS] =
       SettingsFlagsAndValue(SETTINGS_FLAG_NONE, 100);
-  SpdyFrame* settings_frame = buffered_spdy_framer_->CreateSettings(settings);
+  SpdySerializedFrame* settings_frame =
+      buffered_spdy_framer_->CreateSettings(settings);
 
   VLOG(1) << ACCEPTOR_CLIENT_IDENT << "Sending Settings Frame";
   EnqueueDataFrame(new SpdyFrameDataFrame(settings_frame));
@@ -467,7 +469,7 @@
   }
 
   DCHECK(buffered_spdy_framer_);
-  SpdyFrame* fsrcf = buffered_spdy_framer_->CreateSynStream(
+  SpdySerializedFrame* fsrcf = buffered_spdy_framer_->CreateSynStream(
       stream_id, 0, 0, CONTROL_FLAG_NONE, &block);
   size_t df_size = fsrcf->size();
   EnqueueDataFrame(new SpdyFrameDataFrame(fsrcf));
@@ -486,7 +488,7 @@
   block[":version"] = headers.response_version().as_string();
 
   DCHECK(buffered_spdy_framer_);
-  SpdyFrame* fsrcf = buffered_spdy_framer_->CreateSynReply(
+  SpdySerializedFrame* fsrcf = buffered_spdy_framer_->CreateSynReply(
       stream_id, CONTROL_FLAG_NONE, &block);
   size_t df_size = fsrcf->size();
   EnqueueDataFrame(new SpdyFrameDataFrame(fsrcf));
@@ -506,7 +508,7 @@
   //                 priority queue.  Compression needs to be done
   //                 with late binding.
   if (len == 0) {
-    SpdyFrame* fdf =
+    SpdySerializedFrame* fdf =
         buffered_spdy_framer_->CreateDataFrame(stream_id, data, len, flags);
     EnqueueDataFrame(new SpdyFrameDataFrame(fdf));
     return;
@@ -523,7 +525,7 @@
     if ((size < len) && (flags & DATA_FLAG_FIN))
       chunk_flags = static_cast<SpdyDataFlags>(chunk_flags & ~DATA_FLAG_FIN);
 
-    SpdyFrame* fdf = buffered_spdy_framer_->CreateDataFrame(
+    SpdySerializedFrame* fdf = buffered_spdy_framer_->CreateDataFrame(
         stream_id, data, size, chunk_flags);
     EnqueueDataFrame(new SpdyFrameDataFrame(fdf));
 
diff --git a/net/tools/flip_server/spdy_interface_test.cc b/net/tools/flip_server/spdy_interface_test.cc
index 3bb2ce03..dc172fc 100644
--- a/net/tools/flip_server/spdy_interface_test.cc
+++ b/net/tools/flip_server/spdy_interface_test.cc
@@ -236,7 +236,8 @@
   SpdyHeaderBlock block;
   testing::MockFunction<void(int)> checkpoint;  // NOLINT
 
-  scoped_ptr<SpdyFrame> frame(spdy_framer_->CreatePingFrame(12, false));
+  scoped_ptr<SpdySerializedFrame> frame(
+      spdy_framer_->CreatePingFrame(12, false));
   block[":method"] = "GET";
   block[":host"] = "www.example.com";
   block[":path"] = "/path";
diff --git a/net/tools/quic/end_to_end_test.cc b/net/tools/quic/end_to_end_test.cc
index 75b5dd5..095142d6 100644
--- a/net/tools/quic/end_to_end_test.cc
+++ b/net/tools/quic/end_to_end_test.cc
@@ -2021,6 +2021,133 @@
   }
 };
 
+// A test server stream that sends response with body size greater than 4GB.
+class ServerStreamThatSendsHugeResponse : public QuicSimpleServerStream {
+ public:
+  ServerStreamThatSendsHugeResponse(QuicStreamId id,
+                                    QuicSpdySession* session,
+                                    int64_t body_bytes)
+      : QuicSimpleServerStream(id, session), body_bytes_(body_bytes) {}
+
+  ~ServerStreamThatSendsHugeResponse() override {}
+
+ protected:
+  void SendResponse() override {
+    QuicInMemoryCache::Response response;
+    string body;
+    test::GenerateBody(&body, body_bytes_);
+    response.set_body(body);
+    SendHeadersAndBodyAndTrailers(response.headers(), response.body(),
+                                  response.trailers());
+  }
+
+ private:
+  // Use a explicit int64 rather than size_t to simulate a 64-bit server talking
+  // to a 32-bit client.
+  int64_t body_bytes_;
+};
+
+class ServerStreamThatSendsHugeResponseFactory
+    : public QuicTestServer::StreamFactory {
+ public:
+  explicit ServerStreamThatSendsHugeResponseFactory(int64_t body_bytes)
+      : body_bytes_(body_bytes) {}
+
+  ~ServerStreamThatSendsHugeResponseFactory() override{};
+
+  QuicSimpleServerStream* CreateStream(QuicStreamId id,
+                                       QuicSpdySession* session) override {
+    return new ServerStreamThatSendsHugeResponse(id, session, body_bytes_);
+  }
+
+  int64_t body_bytes_;
+};
+
+// A test client stream that drops all received body.
+class ClientStreamThatDropsBody : public QuicSpdyClientStream {
+ public:
+  ClientStreamThatDropsBody(QuicStreamId id, QuicClientSession* session)
+      : QuicSpdyClientStream(id, session) {}
+  ~ClientStreamThatDropsBody() override {}
+
+  void OnDataAvailable() override {
+    while (HasBytesToRead()) {
+      struct iovec iov;
+      if (GetReadableRegions(&iov, 1) == 0) {
+        break;
+      }
+      MarkConsumed(iov.iov_len);
+    }
+    if (sequencer()->IsClosed()) {
+      OnFinRead();
+    } else {
+      sequencer()->SetUnblocked();
+    }
+  }
+};
+
+class ClientSessionThatDropsBody : public QuicClientSession {
+ public:
+  ClientSessionThatDropsBody(const QuicConfig& config,
+                             QuicConnection* connection,
+                             const QuicServerId& server_id,
+                             QuicCryptoClientConfig* crypto_config,
+                             QuicClientPushPromiseIndex* push_promise_index)
+      : QuicClientSession(config,
+                          connection,
+                          server_id,
+                          crypto_config,
+                          push_promise_index) {}
+
+  ~ClientSessionThatDropsBody() override {}
+
+  QuicSpdyClientStream* CreateClientStream() override {
+    return new ClientStreamThatDropsBody(GetNextOutgoingStreamId(), this);
+  }
+};
+
+class MockableQuicClientThatDropsBody : public MockableQuicClient {
+ public:
+  MockableQuicClientThatDropsBody(IPEndPoint server_address,
+                                  const QuicServerId& server_id,
+                                  const QuicConfig& config,
+                                  const QuicVersionVector& supported_versions,
+                                  EpollServer* epoll_server)
+      : MockableQuicClient(server_address,
+                           server_id,
+                           config,
+                           supported_versions,
+                           epoll_server) {}
+  ~MockableQuicClientThatDropsBody() override {}
+
+  QuicClientSession* CreateQuicClientSession(
+      QuicConnection* connection) override {
+    auto session =
+        new ClientSessionThatDropsBody(*config(), connection, server_id(),
+                                       crypto_config(), push_promise_index());
+    set_session(session);
+    return session;
+  }
+};
+
+class QuicTestClientThatDropsBody : public QuicTestClient {
+ public:
+  QuicTestClientThatDropsBody(IPEndPoint server_address,
+                              const string& server_hostname,
+                              const QuicConfig& config,
+                              const QuicVersionVector& supported_versions)
+      : QuicTestClient(server_address,
+                       server_hostname,
+                       config,
+                       supported_versions) {
+    set_client(new MockableQuicClientThatDropsBody(
+        server_address, QuicServerId(server_hostname, server_address.port(),
+                                     PRIVACY_MODE_DISABLED),
+        config, supported_versions, epoll_server()));
+  }
+  ~QuicTestClientThatDropsBody() override {}
+};
+
 TEST_P(EndToEndTest, EarlyResponseFinRecording) {
   set_smaller_flow_control_receive_window();
 
@@ -2174,7 +2301,6 @@
 
   EndToEndTestServerPush() : EndToEndTest() {
     FLAGS_quic_supports_push_promise = true;
-    FLAGS_quic_different_max_num_open_streams = true;
     client_config_.SetMaxStreamsPerConnection(kNumMaxStreams, kNumMaxStreams);
   }
 
@@ -2216,6 +2342,11 @@
   }
 };
 
+// Run all server push end to end tests with all supported versions.
+INSTANTIATE_TEST_CASE_P(EndToEndTestsServerPush,
+                        EndToEndTestServerPush,
+                        ::testing::ValuesIn(GetTestParams()));
+
 TEST_P(EndToEndTestServerPush, ServerPush) {
   ASSERT_TRUE(Initialize());
   client_->client()->WaitForCryptoHandshakeConfirmed();
@@ -2277,7 +2408,6 @@
   // client.
   EXPECT_EQ(kBody, client_->SendSynchronousRequest(
                        "https://example.com/push_example"));
-  EXPECT_EQ(1u + kNumResources, client_->num_responses());
 
   for (string url : push_urls) {
     // Sending subsequent requesets will not actually send anything on the wire,
@@ -2291,6 +2421,7 @@
   // Expect only original request has been sent and push responses have been
   // received as normal response.
   EXPECT_EQ(1u, client_->num_requests());
+  EXPECT_EQ(1u + kNumResources, client_->num_responses());
 }
 
 TEST_P(EndToEndTestServerPush, ServerPushOverLimitNonBlocking) {
@@ -2323,9 +2454,6 @@
   // client.
   EXPECT_EQ(kBody, client_->SendSynchronousRequest(
                        "https://example.com/push_example"));
-  // The responses to the original request and all the promised resources
-  // should have been received.
-  EXPECT_EQ(12u, client_->num_responses());
 
   for (const string& url : push_urls) {
     // Sending subsequent requesets will not actually send anything on the wire,
@@ -2336,6 +2464,9 @@
 
   // Only 1 request should have been sent.
   EXPECT_EQ(1u, client_->num_requests());
+  // The responses to the original request and all the promised resources
+  // should have been received.
+  EXPECT_EQ(12u, client_->num_responses());
 }
 
 TEST_P(EndToEndTestServerPush, ServerPushOverLimitWithBlocking) {
@@ -2419,9 +2550,10 @@
 }
 
 // TODO(fayang): this test seems to cause net_unittests timeouts :|
-TEST_P(EndToEndTest, DISABLED_TestHugePost) {
-  // This test tests a huge post with body size greater than 4GB, making sure
-  // QUIC code does not broke for 32-bit builds.
+TEST_P(EndToEndTest, DISABLED_TestHugePostWithPacketLoss) {
+  // This test tests a huge post with introduced packet loss from client to
+  // server and body size greater than 4GB, making sure QUIC code does not break
+  // for 32-bit builds.
   ServerStreamThatDropsBodyFactory stream_factory;
   SetSpdyStreamFactory(&stream_factory);
   ASSERT_TRUE(Initialize());
@@ -2430,13 +2562,14 @@
   client_->epoll_server()->set_timeout_in_us(0);
 
   client_->client()->WaitForCryptoHandshakeConfirmed();
-
+  SetPacketLossPercentage(1);
   // To avoid storing the whole request body in memory, use a loop to repeatedly
   // send body size of kSizeBytes until the whole request body size is reached.
   const int kSizeBytes = 128 * 1024;
   HTTPMessage request(HttpConstants::HTTP_1_1, HttpConstants::POST, "/foo");
   // Request body size is 4G plus one more kSizeBytes.
   int64_t request_body_size_bytes = pow(2, 32) + kSizeBytes;
+  ASSERT_LT(INT64_C(4294967296), request_body_size_bytes);
   request.AddHeader("content-length", IntToString(request_body_size_bytes));
   request.set_has_complete_message(false);
   string body;
@@ -2451,6 +2584,41 @@
   VerifyCleanConnection(false);
 }
 
+// TODO(fayang): this test seems to cause net_unittests timeouts :|
+TEST_P(EndToEndTest, DISABLED_TestHugeResponseWithPacketLoss) {
+  // This test tests a huge response with introduced loss from server to client
+  // and body size greater than 4GB, making sure QUIC code does not break for
+  // 32-bit builds.
+  const int kSizeBytes = 128 * 1024;
+  int64_t response_body_size_bytes = pow(2, 32) + kSizeBytes;
+  ASSERT_LT(4294967296, response_body_size_bytes);
+  ServerStreamThatSendsHugeResponseFactory stream_factory(
+      response_body_size_bytes);
+  SetSpdyStreamFactory(&stream_factory);
+
+  StartServer();
+
+  // Use a quic client that drops received body.
+  QuicTestClient* client = new QuicTestClientThatDropsBody(
+      server_address_, server_hostname_, client_config_,
+      client_supported_versions_);
+  client->UseWriter(client_writer_);
+  client->Connect();
+  client_.reset(client);
+  static EpollEvent event(EPOLLOUT, false);
+  client_writer_->Initialize(
+      QuicConnectionPeer::GetHelper(client_->client()->session()->connection()),
+      new ClientDelegate(client_->client()));
+  initialized_ = true;
+  ASSERT_TRUE(client_->client()->connected());
+
+  client_->client()->WaitForCryptoHandshakeConfirmed();
+  SetPacketLossPercentage(1);
+  client_->SendRequest("/huge_response");
+  client_->WaitForResponse();
+  VerifyCleanConnection(false);
+}
+
 }  // namespace
 }  // namespace test
 }  // namespace net
diff --git a/net/tools/quic/quic_client.cc b/net/tools/quic/quic_client.cc
index e5a0d45..15f6f5c 100644
--- a/net/tools/quic/quic_client.cc
+++ b/net/tools/quic/quic_client.cc
@@ -63,11 +63,12 @@
                        const QuicConfig& config,
                        EpollServer* epoll_server,
                        ProofVerifier* proof_verifier)
-    : QuicClientBase(server_id,
-                     supported_versions,
-                     config,
-                     new QuicEpollConnectionHelper(epoll_server),
-                     proof_verifier),
+    : QuicClientBase(
+          server_id,
+          supported_versions,
+          config,
+          new QuicEpollConnectionHelper(epoll_server, QuicAllocator::SIMPLE),
+          proof_verifier),
       server_address_(server_address),
       local_port_(0),
       epoll_server_(epoll_server),
@@ -280,7 +281,7 @@
                              StringPiece body,
                              bool fin) {
   QuicClientPushPromiseIndex::TryHandle* handle;
-  QuicAsyncStatus rv = push_promise_index_.Try(
+  QuicAsyncStatus rv = push_promise_index()->Try(
       SpdyBalsaUtils::RequestHeadersToSpdyHeaders(headers), this, &handle);
   if (rv == QUIC_SUCCESS)
     return;
diff --git a/net/tools/quic/quic_client.h b/net/tools/quic/quic_client.h
index 1df8514..56a0246 100644
--- a/net/tools/quic/quic_client.h
+++ b/net/tools/quic/quic_client.h
@@ -189,10 +189,6 @@
                      const IPEndPoint& peer_address,
                      const QuicReceivedPacket& packet) override;
 
-  QuicClientPushPromiseIndex* push_promise_index() {
-    return &push_promise_index_;
-  }
-
   virtual QuicPacketWriter* CreateQuicPacketWriter();
 
   // If |fd| is an open UDP socket, unregister and close it. Otherwise, do
@@ -264,9 +260,6 @@
   // map, the order of socket creation can be recorded.
   linked_hash_map<int, IPEndPoint> fd_address_map_;
 
-  // For requests to claim matching push promised streams.
-  QuicClientPushPromiseIndex push_promise_index_;
-
   // Listens for full responses.
   scoped_ptr<ResponseListener> response_listener_;
 
diff --git a/net/tools/quic/quic_client_base.h b/net/tools/quic/quic_client_base.h
index 90e96c7..af44bda 100644
--- a/net/tools/quic/quic_client_base.h
+++ b/net/tools/quic/quic_client_base.h
@@ -156,6 +156,12 @@
 
   ProofVerifier* proof_verifier() const;
 
+  void set_session(QuicClientSession* session) { session_.reset(session); }
+
+  QuicClientPushPromiseIndex* push_promise_index() {
+    return &push_promise_index_;
+  }
+
  protected:
   virtual QuicClientSession* CreateQuicClientSession(
       QuicConnection* connection);
diff --git a/net/tools/quic/quic_dispatcher_test.cc b/net/tools/quic/quic_dispatcher_test.cc
index d3cc1dfc..a8c8ab4 100644
--- a/net/tools/quic/quic_dispatcher_test.cc
+++ b/net/tools/quic/quic_dispatcher_test.cc
@@ -95,10 +95,11 @@
   TestDispatcher(const QuicConfig& config,
                  const QuicCryptoServerConfig* crypto_config,
                  EpollServer* eps)
-      : QuicDispatcher(config,
-                       crypto_config,
-                       QuicSupportedVersions(),
-                       new QuicEpollConnectionHelper(eps)) {}
+      : QuicDispatcher(
+            config,
+            crypto_config,
+            QuicSupportedVersions(),
+            new QuicEpollConnectionHelper(eps, QuicAllocator::BUFFER_POOL)) {}
 
   MOCK_METHOD2(CreateQuicSession,
                QuicServerSessionBase*(QuicConnectionId connection_id,
@@ -156,7 +157,7 @@
 class QuicDispatcherTest : public ::testing::Test {
  public:
   QuicDispatcherTest()
-      : helper_(&eps_),
+      : helper_(&eps_, QuicAllocator::BUFFER_POOL),
         crypto_config_(QuicCryptoServerConfig::TESTING,
                        QuicRandom::GetInstance(),
                        CryptoTestUtils::ProofSourceForTesting()),
diff --git a/net/tools/quic/quic_epoll_connection_helper.cc b/net/tools/quic/quic_epoll_connection_helper.cc
index ec839b3f..2534ade 100644
--- a/net/tools/quic/quic_epoll_connection_helper.cc
+++ b/net/tools/quic/quic_epoll_connection_helper.cc
@@ -61,10 +61,12 @@
 
 }  // namespace
 
-QuicEpollConnectionHelper::QuicEpollConnectionHelper(EpollServer* epoll_server)
+QuicEpollConnectionHelper::QuicEpollConnectionHelper(EpollServer* epoll_server,
+                                                     QuicAllocator type)
     : epoll_server_(epoll_server),
       clock_(epoll_server),
-      random_generator_(QuicRandom::GetInstance()) {}
+      random_generator_(QuicRandom::GetInstance()),
+      allocator_type_(type) {}
 
 QuicEpollConnectionHelper::~QuicEpollConnectionHelper() {}
 
@@ -94,7 +96,12 @@
 }
 
 QuicBufferAllocator* QuicEpollConnectionHelper::GetBufferAllocator() {
-  return &buffer_allocator_;
+  if (allocator_type_ == QuicAllocator::BUFFER_POOL) {
+    return &buffer_allocator_;
+  } else {
+    DCHECK(allocator_type_ == QuicAllocator::SIMPLE);
+    return &simple_buffer_allocator_;
+  }
 }
 
 }  // namespace net
diff --git a/net/tools/quic/quic_epoll_connection_helper.h b/net/tools/quic/quic_epoll_connection_helper.h
index 6e1fd48..fd18fb3 100644
--- a/net/tools/quic/quic_epoll_connection_helper.h
+++ b/net/tools/quic/quic_epoll_connection_helper.h
@@ -33,9 +33,11 @@
 
 using QuicStreamBufferAllocator = SimpleBufferAllocator;
 
+enum class QuicAllocator { SIMPLE, BUFFER_POOL };
+
 class QuicEpollConnectionHelper : public QuicConnectionHelperInterface {
  public:
-  explicit QuicEpollConnectionHelper(EpollServer* eps);
+  QuicEpollConnectionHelper(EpollServer* eps, QuicAllocator allocator);
   ~QuicEpollConnectionHelper() override;
 
   // QuicEpollConnectionHelperInterface
@@ -57,7 +59,10 @@
 
   const QuicEpollClock clock_;
   QuicRandom* random_generator_;
+  // Set up both allocators.  They take up minimal memory before use.
   QuicStreamBufferAllocator buffer_allocator_;
+  SimpleBufferAllocator simple_buffer_allocator_;
+  QuicAllocator allocator_type_;
 
   DISALLOW_COPY_AND_ASSIGN(QuicEpollConnectionHelper);
 };
diff --git a/net/tools/quic/quic_epoll_connection_helper_test.cc b/net/tools/quic/quic_epoll_connection_helper_test.cc
index f79e0ff..caa44a83 100644
--- a/net/tools/quic/quic_epoll_connection_helper_test.cc
+++ b/net/tools/quic/quic_epoll_connection_helper_test.cc
@@ -28,7 +28,8 @@
 
 class QuicEpollConnectionHelperTest : public ::testing::Test {
  protected:
-  QuicEpollConnectionHelperTest() : helper_(&epoll_server_) {}
+  QuicEpollConnectionHelperTest()
+      : helper_(&epoll_server_, QuicAllocator::BUFFER_POOL) {}
 
   MockEpollServer epoll_server_;
   QuicEpollConnectionHelper helper_;
diff --git a/net/tools/quic/quic_server.cc b/net/tools/quic/quic_server.cc
index 832c1b6..c67e554f 100644
--- a/net/tools/quic/quic_server.cc
+++ b/net/tools/quic/quic_server.cc
@@ -143,7 +143,8 @@
 
 QuicDispatcher* QuicServer::CreateQuicDispatcher() {
   return new QuicDispatcher(config_, &crypto_config_, supported_versions_,
-                            new QuicEpollConnectionHelper(&epoll_server_));
+                            new QuicEpollConnectionHelper(
+                                &epoll_server_, QuicAllocator::BUFFER_POOL));
 }
 
 void QuicServer::WaitForEvents() {
diff --git a/net/tools/quic/quic_server_session_base.cc b/net/tools/quic/quic_server_session_base.cc
index 78ddf0f8..e2341906 100644
--- a/net/tools/quic/quic_server_session_base.cc
+++ b/net/tools/quic/quic_server_session_base.cc
@@ -156,11 +156,20 @@
   int32_t max_bandwidth_timestamp = bandwidth_recorder.MaxBandwidthTimestamp();
 
   // Fill the proto before passing it to the crypto stream to send.
+  const int32_t bw_estimate_bytes_per_second =
+      BandwidthToCachedParameterBytesPerSecond(
+          bandwidth_estimate_sent_to_client_);
+  const int32_t max_bw_estimate_bytes_per_second =
+      BandwidthToCachedParameterBytesPerSecond(max_bandwidth_estimate);
+  QUIC_BUG_IF(max_bw_estimate_bytes_per_second < 0)
+      << max_bw_estimate_bytes_per_second;
+  QUIC_BUG_IF(bw_estimate_bytes_per_second < 0) << bw_estimate_bytes_per_second;
+
   CachedNetworkParameters cached_network_params;
   cached_network_params.set_bandwidth_estimate_bytes_per_second(
-      bandwidth_estimate_sent_to_client_.ToBytesPerSecond());
+      bw_estimate_bytes_per_second);
   cached_network_params.set_max_bandwidth_estimate_bytes_per_second(
-      max_bandwidth_estimate.ToBytesPerSecond());
+      max_bw_estimate_bytes_per_second);
   cached_network_params.set_max_bandwidth_timestamp_seconds(
       max_bandwidth_timestamp);
   cached_network_params.set_min_rtt_ms(
@@ -220,4 +229,12 @@
   return crypto_stream_.get();
 }
 
+int32_t QuicServerSessionBase::BandwidthToCachedParameterBytesPerSecond(
+    const QuicBandwidth& bandwidth) {
+  int64_t bytes_per_second = bandwidth.ToBytesPerSecond();
+  return (bytes_per_second > static_cast<int64_t>(INT32_MAX)
+              ? INT32_MAX
+              : static_cast<int32_t>(bytes_per_second));
+}
+
 }  // namespace net
diff --git a/net/tools/quic/quic_server_session_base.h b/net/tools/quic/quic_server_session_base.h
index c8d11a24..1f19de4 100644
--- a/net/tools/quic/quic_server_session_base.h
+++ b/net/tools/quic/quic_server_session_base.h
@@ -139,6 +139,12 @@
   // Number of packets sent to the peer, at the time we last sent a SCUP.
   int64_t last_scup_packet_number_;
 
+  // Converts QuicBandwidth to an int32 bytes/second that can be
+  // stored in CachedNetworkParameters.  TODO(jokulik): This function
+  // should go away once we fix http://b//27897982
+  int32_t BandwidthToCachedParameterBytesPerSecond(
+      const QuicBandwidth& bandwidth);
+
   DISALLOW_COPY_AND_ASSIGN(QuicServerSessionBase);
 };
 
diff --git a/net/tools/quic/quic_server_test.cc b/net/tools/quic/quic_server_test.cc
index d59bc70..6cd0d49d 100644
--- a/net/tools/quic/quic_server_test.cc
+++ b/net/tools/quic/quic_server_test.cc
@@ -26,9 +26,10 @@
       : crypto_config_("blah",
                        QuicRandom::GetInstance(),
                        CryptoTestUtils::ProofSourceForTesting()),
-        dispatcher_(config_,
-                    &crypto_config_,
-                    new QuicEpollConnectionHelper(&eps_)) {
+        dispatcher_(
+            config_,
+            &crypto_config_,
+            new QuicEpollConnectionHelper(&eps_, QuicAllocator::BUFFER_POOL)) {
     dispatcher_.InitializeWithWriter(new QuicDefaultPacketWriter(1234));
   }
 
diff --git a/net/tools/quic/quic_simple_server_session_test.cc b/net/tools/quic/quic_simple_server_session_test.cc
index fb188a89..ccc9573c 100644
--- a/net/tools/quic/quic_simple_server_session_test.cc
+++ b/net/tools/quic/quic_simple_server_session_test.cc
@@ -386,10 +386,6 @@
   const size_t kStreamFlowControlWindowSize = 32 * 1024;  // 32KB.
 
   QuicSimpleServerSessionServerPushTest() : QuicSimpleServerSessionTest() {
-    // This flag has to be true for negotiation of max number of outgoing
-    // streams to work correctly.
-    FLAGS_quic_different_max_num_open_streams = true;
-
     config_.SetMaxStreamsPerConnection(kMaxStreamsForTest, kMaxStreamsForTest);
 
     // Reset stream level flow control window to be 32KB.
diff --git a/net/tools/quic/quic_time_wait_list_manager_test.cc b/net/tools/quic/quic_time_wait_list_manager_test.cc
index 0ddfb4f0..58c9112d 100644
--- a/net/tools/quic/quic_time_wait_list_manager_test.cc
+++ b/net/tools/quic/quic_time_wait_list_manager_test.cc
@@ -94,7 +94,7 @@
 class QuicTimeWaitListManagerTest : public ::testing::Test {
  protected:
   QuicTimeWaitListManagerTest()
-      : helper_(&epoll_server_),
+      : helper_(&epoll_server_, QuicAllocator::BUFFER_POOL),
         time_wait_list_manager_(&writer_, &visitor_, &helper_),
         connection_id_(45),
         client_address_(net::test::TestPeerIPAddress(), kTestPort),
diff --git a/net/tools/quic/test_tools/quic_test_server.cc b/net/tools/quic/test_tools/quic_test_server.cc
index d513a696..dc5fc451 100644
--- a/net/tools/quic/test_tools/quic_test_server.cc
+++ b/net/tools/quic/test_tools/quic_test_server.cc
@@ -148,9 +148,10 @@
                  supported_versions) {}
 
 QuicDispatcher* QuicTestServer::CreateQuicDispatcher() {
-  return new QuicTestDispatcher(config(), &crypto_config(),
-                                supported_versions(),
-                                new QuicEpollConnectionHelper(epoll_server()));
+  return new QuicTestDispatcher(
+      config(), &crypto_config(), supported_versions(),
+      new QuicEpollConnectionHelper(epoll_server(),
+                                    QuicAllocator::BUFFER_POOL));
 }
 
 void QuicTestServer::SetSessionFactory(SessionFactory* factory) {
diff --git a/sandbox/linux/integration_tests/bpf_dsl_seccomp_unittest.cc b/sandbox/linux/integration_tests/bpf_dsl_seccomp_unittest.cc
index 3b0d6ac46..0a3dadb 100644
--- a/sandbox/linux/integration_tests/bpf_dsl_seccomp_unittest.cc
+++ b/sandbox/linux/integration_tests/bpf_dsl_seccomp_unittest.cc
@@ -27,7 +27,6 @@
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/posix/eintr_wrapper.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/sys_info.h"
diff --git a/sandbox/linux/integration_tests/seccomp_broker_process_unittest.cc b/sandbox/linux/integration_tests/seccomp_broker_process_unittest.cc
index c46b808..73dc58c9 100644
--- a/sandbox/linux/integration_tests/seccomp_broker_process_unittest.cc
+++ b/sandbox/linux/integration_tests/seccomp_broker_process_unittest.cc
@@ -8,11 +8,11 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <memory>
 #include <vector>
 
 #include "base/bind.h"
 #include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/posix/eintr_wrapper.h"
 #include "build/build_config.h"
 #include "sandbox/linux/bpf_dsl/bpf_dsl.h"
@@ -63,7 +63,7 @@
 
  private:
   bool initialized_;
-  scoped_ptr<class syscall_broker::BrokerProcess> broker_process_;
+  std::unique_ptr<class syscall_broker::BrokerProcess> broker_process_;
   DISALLOW_COPY_AND_ASSIGN(InitializedOpenBroker);
 };
 
diff --git a/sandbox/linux/seccomp-bpf/bpf_tester_compatibility_delegate.h b/sandbox/linux/seccomp-bpf/bpf_tester_compatibility_delegate.h
index 00d415c3..a4315ba 100644
--- a/sandbox/linux/seccomp-bpf/bpf_tester_compatibility_delegate.h
+++ b/sandbox/linux/seccomp-bpf/bpf_tester_compatibility_delegate.h
@@ -5,8 +5,9 @@
 #ifndef SANDBOX_LINUX_SECCOMP_BPF_BPF_TESTER_COMPATIBILITY_DELEGATE_H_
 #define SANDBOX_LINUX_SECCOMP_BPF_BPF_TESTER_COMPATIBILITY_DELEGATE_H_
 
+#include <memory>
+
 #include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
 #include "sandbox/linux/seccomp-bpf/sandbox_bpf_test_runner.h"
 
 namespace sandbox {
@@ -28,12 +29,12 @@
 
   ~BPFTesterCompatibilityDelegate() override {}
 
-  scoped_ptr<bpf_dsl::Policy> GetSandboxBPFPolicy() override {
+  std::unique_ptr<bpf_dsl::Policy> GetSandboxBPFPolicy() override {
     // The current method is guaranteed to only run in the child process
     // running the test. In this process, the current object is guaranteed
     // to live forever. So it's ok to pass aux_pointer_for_policy_ to
     // the policy, which could in turn pass it to the kernel via Trap().
-    return scoped_ptr<bpf_dsl::Policy>(new Policy(&aux_));
+    return std::unique_ptr<bpf_dsl::Policy>(new Policy(&aux_));
   }
 
   void RunTestFunction() override {
diff --git a/sandbox/linux/seccomp-bpf/bpf_tests.h b/sandbox/linux/seccomp-bpf/bpf_tests.h
index cc4debd..8b2b12a 100644
--- a/sandbox/linux/seccomp-bpf/bpf_tests.h
+++ b/sandbox/linux/seccomp-bpf/bpf_tests.h
@@ -5,6 +5,8 @@
 #ifndef SANDBOX_LINUX_SECCOMP_BPF_BPF_TESTS_H__
 #define SANDBOX_LINUX_SECCOMP_BPF_BPF_TESTS_H__
 
+#include <memory>
+
 #include "base/logging.h"
 #include "base/macros.h"
 #include "build/build_config.h"
@@ -104,8 +106,8 @@
       : test_function_(test_function) {}
   ~BPFTesterSimpleDelegate() override {}
 
-  scoped_ptr<bpf_dsl::Policy> GetSandboxBPFPolicy() override {
-    return scoped_ptr<bpf_dsl::Policy>(new PolicyClass());
+  std::unique_ptr<bpf_dsl::Policy> GetSandboxBPFPolicy() override {
+    return std::unique_ptr<bpf_dsl::Policy>(new PolicyClass());
   }
   void RunTestFunction() override {
     DCHECK(test_function_);
diff --git a/sandbox/linux/seccomp-bpf/bpf_tests_unittest.cc b/sandbox/linux/seccomp-bpf/bpf_tests_unittest.cc
index e300baf..c16cd72 100644
--- a/sandbox/linux/seccomp-bpf/bpf_tests_unittest.cc
+++ b/sandbox/linux/seccomp-bpf/bpf_tests_unittest.cc
@@ -10,9 +10,10 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <memory>
+
 #include "base/logging.h"
 #include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
 #include "build/build_config.h"
 #include "sandbox/linux/bpf_dsl/bpf_dsl.h"
 #include "sandbox/linux/bpf_dsl/policy.h"
@@ -76,7 +77,7 @@
   }
   {
     // Test polymorphism.
-    scoped_ptr<BPFTesterDelegate> simple_delegate(
+    std::unique_ptr<BPFTesterDelegate> simple_delegate(
         new BPFTesterCompatibilityDelegate<EmptyClassTakingPolicy, FourtyTwo>(
             DummyTestFunction));
   }
@@ -113,8 +114,8 @@
   BasicBPFTesterDelegate() {}
   ~BasicBPFTesterDelegate() override {}
 
-  scoped_ptr<bpf_dsl::Policy> GetSandboxBPFPolicy() override {
-    return scoped_ptr<bpf_dsl::Policy>(new EnosysPtracePolicy());
+  std::unique_ptr<bpf_dsl::Policy> GetSandboxBPFPolicy() override {
+    return std::unique_ptr<bpf_dsl::Policy>(new EnosysPtracePolicy());
   }
   void RunTestFunction() override {
     errno = 0;
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
index b48682b..4d8d436 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
@@ -14,7 +14,6 @@
 #include "base/files/scoped_file.h"
 #include "base/logging.h"
 #include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/posix/eintr_wrapper.h"
 #include "base/third_party/valgrind/valgrind.h"
 #include "sandbox/linux/bpf_dsl/bpf_dsl.h"
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf.h b/sandbox/linux/seccomp-bpf/sandbox_bpf.h
index e758e031..1637b26 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf.h
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf.h
@@ -7,9 +7,10 @@
 
 #include <stdint.h>
 
+#include <memory>
+
 #include "base/files/scoped_file.h"
 #include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
 #include "sandbox/linux/bpf_dsl/codegen.h"
 #include "sandbox/sandbox_export.h"
 
@@ -104,7 +105,7 @@
 
   base::ScopedFD proc_fd_;
   bool sandbox_has_started_;
-  scoped_ptr<bpf_dsl::Policy> policy_;
+  std::unique_ptr<bpf_dsl::Policy> policy_;
 
   DISALLOW_COPY_AND_ASSIGN(SandboxBPF);
 };
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf_test_runner.cc b/sandbox/linux/seccomp-bpf/sandbox_bpf_test_runner.cc
index c0193f9..7a675db3 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf_test_runner.cc
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf_test_runner.cc
@@ -6,8 +6,9 @@
 
 #include <fcntl.h>
 
+#include <memory>
+
 #include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
 #include "sandbox/linux/bpf_dsl/policy.h"
 #include "sandbox/linux/seccomp-bpf/die.h"
 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
@@ -28,7 +29,7 @@
   DCHECK(bpf_tester_delegate_);
   sandbox::Die::EnableSimpleExit();
 
-  scoped_ptr<bpf_dsl::Policy> policy =
+  std::unique_ptr<bpf_dsl::Policy> policy =
       bpf_tester_delegate_->GetSandboxBPFPolicy();
 
   if (sandbox::SandboxBPF::SupportsSeccompSandbox(
diff --git a/sandbox/linux/seccomp-bpf/sandbox_bpf_test_runner.h b/sandbox/linux/seccomp-bpf/sandbox_bpf_test_runner.h
index fef6240d..1cf1c2f 100644
--- a/sandbox/linux/seccomp-bpf/sandbox_bpf_test_runner.h
+++ b/sandbox/linux/seccomp-bpf/sandbox_bpf_test_runner.h
@@ -5,8 +5,9 @@
 #ifndef SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_TEST_RUNNER_H_
 #define SANDBOX_LINUX_SECCOMP_BPF_SANDBOX_BPF_TEST_RUNNER_H_
 
+#include <memory>
+
 #include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
 #include "sandbox/linux/tests/sandbox_test_runner.h"
 
 namespace sandbox {
@@ -26,7 +27,7 @@
   // This will instanciate a policy suitable for the test we want to run. It is
   // guaranteed to only be called from the child process that will run the
   // test.
-  virtual scoped_ptr<bpf_dsl::Policy> GetSandboxBPFPolicy() = 0;
+  virtual std::unique_ptr<bpf_dsl::Policy> GetSandboxBPFPolicy() = 0;
   // This will be called from a child process with the BPF sandbox turned on.
   virtual void RunTestFunction() = 0;
 
@@ -43,7 +44,7 @@
 class SandboxBPFTestRunner : public SandboxTestRunner {
  public:
   // This constructor takes ownership of the |bpf_tester_delegate| object.
-  // (It doesn't take a scoped_ptr since they make polymorphism verbose).
+  // (It doesn't take a std::unique_ptr since they make polymorphism verbose).
   explicit SandboxBPFTestRunner(BPFTesterDelegate* bpf_tester_delegate);
   ~SandboxBPFTestRunner() override;
 
@@ -52,7 +53,7 @@
   bool ShouldCheckForLeaks() const override;
 
  private:
-  scoped_ptr<BPFTesterDelegate> bpf_tester_delegate_;
+  std::unique_ptr<BPFTesterDelegate> bpf_tester_delegate_;
   DISALLOW_COPY_AND_ASSIGN(SandboxBPFTestRunner);
 };
 
diff --git a/sandbox/linux/services/credentials.h b/sandbox/linux/services/credentials.h
index 095d636..b89a6aa 100644
--- a/sandbox/linux/services/credentials.h
+++ b/sandbox/linux/services/credentials.h
@@ -16,7 +16,6 @@
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
 #include "sandbox/linux/system_headers/capability.h"
 #include "sandbox/sandbox_export.h"
 
diff --git a/sandbox/linux/services/credentials_unittest.cc b/sandbox/linux/services/credentials_unittest.cc
index d666a0c..b95ba0ba 100644
--- a/sandbox/linux/services/credentials_unittest.cc
+++ b/sandbox/linux/services/credentials_unittest.cc
@@ -15,13 +15,13 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <memory>
 #include <vector>
 
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_file.h"
 #include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
 #include "sandbox/linux/services/proc_util.h"
 #include "sandbox/linux/services/syscall_wrappers.h"
 #include "sandbox/linux/system_headers/capability.h"
@@ -40,7 +40,7 @@
 };
 
 // Wrapper to manage libcap2's cap_t type.
-typedef scoped_ptr<typeof(*((cap_t)0)), CapFreeDeleter> ScopedCap;
+typedef std::unique_ptr<typeof(*((cap_t)0)), CapFreeDeleter> ScopedCap;
 
 bool WorkingDirectoryIsRoot() {
   char current_dir[PATH_MAX];
diff --git a/sandbox/linux/services/namespace_sandbox_unittest.cc b/sandbox/linux/services/namespace_sandbox_unittest.cc
index 43e0ae5..c1acca6 100644
--- a/sandbox/linux/services/namespace_sandbox_unittest.cc
+++ b/sandbox/linux/services/namespace_sandbox_unittest.cc
@@ -16,7 +16,6 @@
 #include "base/files/file_enumerator.h"
 #include "base/files/file_path.h"
 #include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/process/launch.h"
 #include "base/process/process.h"
 #include "base/test/multiprocess_test.h"
diff --git a/sandbox/linux/services/proc_util.cc b/sandbox/linux/services/proc_util.cc
index 247c29c..b6d58de5 100644
--- a/sandbox/linux/services/proc_util.cc
+++ b/sandbox/linux/services/proc_util.cc
@@ -11,8 +11,9 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
+#include <memory>
+
 #include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/posix/eintr_wrapper.h"
 #include "base/strings/string_number_conversions.h"
 
@@ -26,7 +27,7 @@
   }
 };
 
-typedef scoped_ptr<DIR, DIRCloser> ScopedDIR;
+typedef std::unique_ptr<DIR, DIRCloser> ScopedDIR;
 
 base::ScopedFD OpenDirectory(const char* path) {
   DCHECK(path);
diff --git a/sandbox/linux/services/thread_helpers_unittests.cc b/sandbox/linux/services/thread_helpers_unittests.cc
index 6dcae0f..fe1080b 100644
--- a/sandbox/linux/services/thread_helpers_unittests.cc
+++ b/sandbox/linux/services/thread_helpers_unittests.cc
@@ -12,7 +12,6 @@
 
 #include "base/logging.h"
 #include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/posix/eintr_wrapper.h"
 #include "base/process/process_metrics.h"
 #include "base/threading/platform_thread.h"
diff --git a/sandbox/linux/suid/client/setuid_sandbox_client.h b/sandbox/linux/suid/client/setuid_sandbox_client.h
index 026894fc..d1cff42 100644
--- a/sandbox/linux/suid/client/setuid_sandbox_client.h
+++ b/sandbox/linux/suid/client/setuid_sandbox_client.h
@@ -5,9 +5,10 @@
 #ifndef SANDBOX_LINUX_SUID_SETUID_SANDBOX_CLIENT_H_
 #define SANDBOX_LINUX_SUID_SETUID_SANDBOX_CLIENT_H_
 
+#include <memory>
+
 #include "base/environment.h"
 #include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
 #include "sandbox/sandbox_export.h"
 
 namespace sandbox {
@@ -60,7 +61,7 @@
   explicit SetuidSandboxClient(base::Environment* env);
 
   // Holds the environment. Will never be NULL.
-  scoped_ptr<base::Environment> env_;
+  std::unique_ptr<base::Environment> env_;
   bool sandboxed_;
 
   DISALLOW_COPY_AND_ASSIGN(SetuidSandboxClient);
diff --git a/sandbox/linux/suid/client/setuid_sandbox_client_unittest.cc b/sandbox/linux/suid/client/setuid_sandbox_client_unittest.cc
index 2acd8fb..a5f96bef 100644
--- a/sandbox/linux/suid/client/setuid_sandbox_client_unittest.cc
+++ b/sandbox/linux/suid/client/setuid_sandbox_client_unittest.cc
@@ -4,8 +4,9 @@
 
 #include "sandbox/linux/suid/client/setuid_sandbox_client.h"
 
+#include <memory>
+
 #include "base/environment.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/strings/string_number_conversions.h"
 #include "sandbox/linux/suid/common/sandbox.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -13,11 +14,11 @@
 namespace sandbox {
 
 TEST(SetuidSandboxClient, SandboxedClientAPI) {
-  scoped_ptr<base::Environment> env(base::Environment::Create());
+  std::unique_ptr<base::Environment> env(base::Environment::Create());
   EXPECT_TRUE(env != NULL);
 
-  scoped_ptr<SetuidSandboxClient>
-      sandbox_client(SetuidSandboxClient::Create());
+  std::unique_ptr<SetuidSandboxClient> sandbox_client(
+      SetuidSandboxClient::Create());
   EXPECT_TRUE(sandbox_client != NULL);
 
   // Set-up a fake environment as if we went through the setuid sandbox.
diff --git a/sandbox/linux/suid/client/setuid_sandbox_host.cc b/sandbox/linux/suid/client/setuid_sandbox_host.cc
index 24ef4b39..278f1d2 100644
--- a/sandbox/linux/suid/client/setuid_sandbox_host.cc
+++ b/sandbox/linux/suid/client/setuid_sandbox_host.cc
@@ -10,6 +10,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
+#include <memory>
 #include <string>
 #include <utility>
 
@@ -20,7 +21,6 @@
 #include "base/files/scoped_file.h"
 #include "base/logging.h"
 #include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/path_service.h"
 #include "base/posix/eintr_wrapper.h"
 #include "base/process/launch.h"
@@ -79,7 +79,8 @@
   for (unsigned i = 0; kSUIDUnsafeEnvironmentVariables[i]; ++i) {
     const char* env_var = kSUIDUnsafeEnvironmentVariables[i];
     // Get the saved environment variable corresponding to envvar.
-    scoped_ptr<std::string> saved_env_var(CreateSavedVariableName(env_var));
+    std::unique_ptr<std::string> saved_env_var(
+        CreateSavedVariableName(env_var));
     if (saved_env_var == NULL)
       continue;
 
diff --git a/sandbox/linux/suid/client/setuid_sandbox_host.h b/sandbox/linux/suid/client/setuid_sandbox_host.h
index 67888924..c69c2c0c 100644
--- a/sandbox/linux/suid/client/setuid_sandbox_host.h
+++ b/sandbox/linux/suid/client/setuid_sandbox_host.h
@@ -5,10 +5,11 @@
 #ifndef SANDBOX_LINUX_SUID_SETUID_SANDBOX_HOST_H_
 #define SANDBOX_LINUX_SUID_SETUID_SANDBOX_HOST_H_
 
+#include <memory>
+
 #include "base/files/file_path.h"
 #include "base/files/scoped_file.h"
 #include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/process/launch.h"
 #include "sandbox/sandbox_export.h"
 
@@ -60,7 +61,7 @@
   explicit SetuidSandboxHost(base::Environment* env);
 
   // Holds the environment. Will never be NULL.
-  scoped_ptr<base::Environment> env_;
+  std::unique_ptr<base::Environment> env_;
 
   DISALLOW_COPY_AND_ASSIGN(SetuidSandboxHost);
 };
diff --git a/sandbox/linux/suid/client/setuid_sandbox_host_unittest.cc b/sandbox/linux/suid/client/setuid_sandbox_host_unittest.cc
index 8415abb..efbd931 100644
--- a/sandbox/linux/suid/client/setuid_sandbox_host_unittest.cc
+++ b/sandbox/linux/suid/client/setuid_sandbox_host_unittest.cc
@@ -4,11 +4,11 @@
 
 #include "sandbox/linux/suid/client/setuid_sandbox_host.h"
 
+#include <memory>
 #include <string>
 
 #include "base/environment.h"
 #include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/strings/string_number_conversions.h"
 #include "sandbox/linux/suid/common/sandbox.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -17,7 +17,7 @@
 
 TEST(SetuidSandboxHost, SetupLaunchEnvironment) {
   const char kTestValue[] = "This is a test";
-  scoped_ptr<base::Environment> env(base::Environment::Create());
+  std::unique_ptr<base::Environment> env(base::Environment::Create());
   EXPECT_TRUE(env != NULL);
 
   std::string saved_ld_preload;
@@ -28,7 +28,7 @@
   EXPECT_TRUE(env->SetVar("LD_PRELOAD", kTestValue));
   EXPECT_TRUE(env->UnSetVar("LD_ORIGIN_PATH"));
 
-  scoped_ptr<SetuidSandboxHost> sandbox_host(SetuidSandboxHost::Create());
+  std::unique_ptr<SetuidSandboxHost> sandbox_host(SetuidSandboxHost::Create());
   EXPECT_TRUE(sandbox_host != NULL);
 
   // Make sure the environment is clean.
@@ -64,7 +64,7 @@
 // This test doesn't accomplish much, but will make sure that analysis tools
 // will run this codepath.
 TEST(SetuidSandboxHost, GetSandboxBinaryPath) {
-  scoped_ptr<SetuidSandboxHost> setuid_sandbox_host(
+  std::unique_ptr<SetuidSandboxHost> setuid_sandbox_host(
       SetuidSandboxHost::Create());
   ignore_result(setuid_sandbox_host->GetSandboxBinaryPath());
 }
diff --git a/sandbox/linux/syscall_broker/broker_process.cc b/sandbox/linux/syscall_broker/broker_process.cc
index 5ab8c6c..30713ce 100644
--- a/sandbox/linux/syscall_broker/broker_process.cc
+++ b/sandbox/linux/syscall_broker/broker_process.cc
@@ -19,7 +19,6 @@
 
 #include "base/callback.h"
 #include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/posix/eintr_wrapper.h"
 #include "base/process/process_metrics.h"
 #include "build/build_config.h"
diff --git a/sandbox/linux/syscall_broker/broker_process.h b/sandbox/linux/syscall_broker/broker_process.h
index 8a512a0c..3c0c809 100644
--- a/sandbox/linux/syscall_broker/broker_process.h
+++ b/sandbox/linux/syscall_broker/broker_process.h
@@ -5,12 +5,12 @@
 #ifndef SANDBOX_LINUX_SERVICES_BROKER_PROCESS_H_
 #define SANDBOX_LINUX_SERVICES_BROKER_PROCESS_H_
 
+#include <memory>
 #include <string>
 #include <vector>
 
 #include "base/callback_forward.h"
 #include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/pickle.h"
 #include "base/process/process.h"
 #include "sandbox/linux/syscall_broker/broker_policy.h"
@@ -82,7 +82,7 @@
   const bool quiet_failures_for_tests_;
   pid_t broker_pid_;                     // The PID of the broker (child).
   syscall_broker::BrokerPolicy policy_;  // The sandboxing policy.
-  scoped_ptr<syscall_broker::BrokerClient> broker_client_;
+  std::unique_ptr<syscall_broker::BrokerClient> broker_client_;
 
   DISALLOW_COPY_AND_ASSIGN(BrokerProcess);
 };
diff --git a/sandbox/linux/syscall_broker/broker_process_unittest.cc b/sandbox/linux/syscall_broker/broker_process_unittest.cc
index c760084e..229764a 100644
--- a/sandbox/linux/syscall_broker/broker_process_unittest.cc
+++ b/sandbox/linux/syscall_broker/broker_process_unittest.cc
@@ -15,6 +15,7 @@
 #include <unistd.h>
 
 #include <algorithm>
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -23,7 +24,6 @@
 #include "base/files/scoped_file.h"
 #include "base/logging.h"
 #include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/posix/eintr_wrapper.h"
 #include "base/posix/unix_domain_socket_linux.h"
 #include "sandbox/linux/syscall_broker/broker_client.h"
@@ -58,7 +58,8 @@
   std::vector<BrokerFilePermission> permissions;
   permissions.push_back(BrokerFilePermission::ReadOnly("/proc/cpuinfo"));
 
-  scoped_ptr<BrokerProcess> open_broker(new BrokerProcess(EPERM, permissions));
+  std::unique_ptr<BrokerProcess> open_broker(
+      new BrokerProcess(EPERM, permissions));
   ASSERT_TRUE(open_broker->Init(base::Bind(&NoOpCallback)));
 
   ASSERT_TRUE(TestUtils::CurrentProcessHasChildren());
@@ -251,7 +252,7 @@
   std::vector<BrokerFilePermission> permissions;
 
   permissions.push_back(BrokerFilePermission::ReadOnlyRecursive("/proc/"));
-  scoped_ptr<BrokerProcess> open_broker(
+  std::unique_ptr<BrokerProcess> open_broker(
       new BrokerProcess(EPERM, permissions, fast_check_in_client));
   ASSERT_TRUE(open_broker->Init(base::Bind(&NoOpCallback)));
   // Open cpuinfo via the broker.
@@ -310,7 +311,7 @@
   else
     permissions.push_back(BrokerFilePermission::ReadOnly(kFileCpuInfo));
 
-  scoped_ptr<BrokerProcess> open_broker(
+  std::unique_ptr<BrokerProcess> open_broker(
       new BrokerProcess(EPERM, permissions, fast_check_in_client));
   ASSERT_TRUE(open_broker->Init(base::Bind(&NoOpCallback)));
 
diff --git a/sandbox/mac/bootstrap_sandbox.cc b/sandbox/mac/bootstrap_sandbox.cc
index dee7903c..4b3a1c6c 100644
--- a/sandbox/mac/bootstrap_sandbox.cc
+++ b/sandbox/mac/bootstrap_sandbox.cc
@@ -12,6 +12,7 @@
 #include "base/mac/foundation_util.h"
 #include "base/mac/mach_logging.h"
 #include "base/macros.h"
+#include "base/memory/ptr_util.h"
 #include "base/rand_util.h"
 #include "base/strings/stringprintf.h"
 #include "sandbox/mac/launchd_interception_server.h"
@@ -55,9 +56,9 @@
 }  // namespace
 
 // static
-scoped_ptr<BootstrapSandbox> BootstrapSandbox::Create() {
-  scoped_ptr<BootstrapSandbox> null;  // Used for early returns.
-  scoped_ptr<BootstrapSandbox> sandbox(new BootstrapSandbox());
+std::unique_ptr<BootstrapSandbox> BootstrapSandbox::Create() {
+  std::unique_ptr<BootstrapSandbox> null;  // Used for early returns.
+  std::unique_ptr<BootstrapSandbox> sandbox(new BootstrapSandbox());
   sandbox->launchd_server_.reset(new LaunchdInterceptionServer(sandbox.get()));
 
   // Check in with launchd to get the receive right for the server that is
@@ -143,7 +144,8 @@
   policies_.insert(std::make_pair(sandbox_policy_id, policy));
 }
 
-scoped_ptr<PreExecDelegate> BootstrapSandbox::NewClient(int sandbox_policy_id) {
+std::unique_ptr<PreExecDelegate> BootstrapSandbox::NewClient(
+    int sandbox_policy_id) {
   base::AutoLock lock(lock_);
 
   DCHECK(policies_.find(sandbox_policy_id) != policies_.end());
@@ -156,7 +158,7 @@
   }
 
   awaiting_processes_[token] = sandbox_policy_id;
-  return make_scoped_ptr(new PreExecDelegate(server_bootstrap_name_, token));
+  return base::WrapUnique(new PreExecDelegate(server_bootstrap_name_, token));
 }
 
 void BootstrapSandbox::RevokeToken(uint64_t token) {
diff --git a/sandbox/mac/bootstrap_sandbox.h b/sandbox/mac/bootstrap_sandbox.h
index 2ae4513..793649ea 100644
--- a/sandbox/mac/bootstrap_sandbox.h
+++ b/sandbox/mac/bootstrap_sandbox.h
@@ -9,11 +9,11 @@
 #include <stdint.h>
 
 #include <map>
+#include <memory>
 #include <string>
 
 #include "base/mac/dispatch_source_mach.h"
 #include "base/mac/scoped_mach_port.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/process/process_handle.h"
 #include "base/synchronization/lock.h"
 #include "sandbox/mac/policy.h"
@@ -48,7 +48,7 @@
 class SANDBOX_EXPORT BootstrapSandbox {
  public:
   // Creates a new sandbox manager. Returns NULL on failure.
-  static scoped_ptr<BootstrapSandbox> Create();
+  static std::unique_ptr<BootstrapSandbox> Create();
 
   // For use in newly created child processes. Checks in with the bootstrap
   // sandbox manager running in the parent process. |sandbox_server_port| is
@@ -69,7 +69,7 @@
 
   // Creates a new PreExecDelegate to pass to base::LaunchOptions. This will
   // enforce the policy with |sandbox_policy_id| on the new process.
-  scoped_ptr<PreExecDelegate> NewClient(int sandbox_policy_id);
+  std::unique_ptr<PreExecDelegate> NewClient(int sandbox_policy_id);
 
   // If a client did not launch properly, the sandbox provided to the
   // PreExecDelegate should be invalidated using this method.
@@ -118,12 +118,12 @@
 
   // A Mach IPC message server that is used to intercept and filter bootstrap
   // requests.
-  scoped_ptr<LaunchdInterceptionServer> launchd_server_;
+  std::unique_ptr<LaunchdInterceptionServer> launchd_server_;
 
   // The port and dispatch source for receiving client check in messages sent
   // via ClientCheckIn().
   base::mac::ScopedMachReceiveRight check_in_port_;
-  scoped_ptr<base::DispatchSourceMach> check_in_server_;
+  std::unique_ptr<base::DispatchSourceMach> check_in_server_;
 };
 
 }  // namespace sandbox
diff --git a/sandbox/mac/bootstrap_sandbox_unittest.mm b/sandbox/mac/bootstrap_sandbox_unittest.mm
index e4c13e5d..f81cd114 100644
--- a/sandbox/mac/bootstrap_sandbox_unittest.mm
+++ b/sandbox/mac/bootstrap_sandbox_unittest.mm
@@ -98,7 +98,7 @@
   void RunChildWithPolicy(int policy_id,
                           const char* child_name,
                           base::ProcessHandle* out_pid) {
-    scoped_ptr<PreExecDelegate> pre_exec_delegate(
+    std::unique_ptr<PreExecDelegate> pre_exec_delegate(
         sandbox_->NewClient(policy_id));
 
     base::LaunchOptions options;
@@ -114,7 +114,7 @@
   }
 
  protected:
-  scoped_ptr<BootstrapSandbox> sandbox_;
+  std::unique_ptr<BootstrapSandbox> sandbox_;
 };
 
 const char kNotificationTestMain[] = "PostNotification";
@@ -434,7 +434,7 @@
   sandbox_->RegisterSandboxPolicy(kTestPolicyId, policy);
 
   // Launch the child.
-  scoped_ptr<PreExecDelegate> pre_exec_delegate(
+  std::unique_ptr<PreExecDelegate> pre_exec_delegate(
       sandbox_->NewClient(kTestPolicyId));
   base::LaunchOptions options;
   options.pre_exec_delegate = pre_exec_delegate.get();
diff --git a/sandbox/mac/launchd_interception_server.h b/sandbox/mac/launchd_interception_server.h
index 0375ca2..9ed38f1 100644
--- a/sandbox/mac/launchd_interception_server.h
+++ b/sandbox/mac/launchd_interception_server.h
@@ -5,10 +5,11 @@
 #ifndef SANDBOX_MAC_LAUNCHD_INTERCEPTION_SERVER_H_
 #define SANDBOX_MAC_LAUNCHD_INTERCEPTION_SERVER_H_
 
+#include <memory>
+
 #include <dispatch/dispatch.h>
 
 #include "base/mac/scoped_mach_port.h"
-#include "base/memory/scoped_ptr.h"
 #include "sandbox/mac/message_server.h"
 
 namespace sandbox {
@@ -54,7 +55,7 @@
   const BootstrapSandbox* sandbox_;
 
   // The Mach IPC server.
-  scoped_ptr<MessageServer> message_server_;
+  std::unique_ptr<MessageServer> message_server_;
 
   // Whether or not the system is using an XPC-based launchd.
   bool xpc_launchd_;
@@ -68,7 +69,7 @@
 
   // The compatibility shim that handles differences in message header IDs and
   // request/reply structures between different OS X versions.
-  scoped_ptr<OSCompatibility> compat_shim_;
+  std::unique_ptr<OSCompatibility> compat_shim_;
 };
 
 }  // namespace sandbox
diff --git a/sandbox/mac/mach_message_server.h b/sandbox/mac/mach_message_server.h
index 515d565..ace30ec 100644
--- a/sandbox/mac/mach_message_server.h
+++ b/sandbox/mac/mach_message_server.h
@@ -8,10 +8,11 @@
 #include <mach/mach.h>
 #include <stddef.h>
 
+#include <memory>
+
 #include "base/mac/dispatch_source_mach.h"
 #include "base/mac/scoped_mach_port.h"
 #include "base/mac/scoped_mach_vm.h"
-#include "base/memory/scoped_ptr.h"
 #include "sandbox/mac/message_server.h"
 
 namespace sandbox {
@@ -63,7 +64,7 @@
   base::mac::ScopedMachVM reply_buffer_;
 
   // MACH_RECV dispatch source that handles the |server_port_|.
-  scoped_ptr<base::DispatchSourceMach> dispatch_source_;
+  std::unique_ptr<base::DispatchSourceMach> dispatch_source_;
 
   // Whether or not ForwardMessage() was called during ReceiveMessage().
   bool did_forward_message_;
diff --git a/sandbox/mac/os_compatibility.cc b/sandbox/mac/os_compatibility.cc
index 1ec0e3a..538efef 100644
--- a/sandbox/mac/os_compatibility.cc
+++ b/sandbox/mac/os_compatibility.cc
@@ -11,6 +11,7 @@
 
 #include "base/logging.h"
 #include "base/mac/mac_util.h"
+#include "base/memory/ptr_util.h"
 #include "sandbox/mac/xpc.h"
 
 namespace sandbox {
@@ -179,11 +180,11 @@
 }  // namespace
 
 // static
-scoped_ptr<OSCompatibility> OSCompatibility::CreateForPlatform() {
+std::unique_ptr<OSCompatibility> OSCompatibility::CreateForPlatform() {
   if (base::mac::IsOSLionOrLater() && base::mac::IsOSMavericksOrEarlier())
-    return make_scoped_ptr(new OSCompatibility_10_7());
+    return base::WrapUnique(new OSCompatibility_10_7());
   else
-    return make_scoped_ptr(new OSCompatibility_10_10());
+    return base::WrapUnique(new OSCompatibility_10_10());
 }
 
 OSCompatibility::~OSCompatibility() {}
diff --git a/sandbox/mac/os_compatibility.h b/sandbox/mac/os_compatibility.h
index 4f18c34..c341888 100644
--- a/sandbox/mac/os_compatibility.h
+++ b/sandbox/mac/os_compatibility.h
@@ -15,9 +15,9 @@
 #include <mach/mach.h>
 #include <stdint.h>
 
+#include <memory>
 #include <string>
 
-#include "base/memory/scoped_ptr.h"
 #include "sandbox/mac/message_server.h"
 
 namespace sandbox {
@@ -25,7 +25,7 @@
 class OSCompatibility {
  public:
   // Creates an OSCompatibility instance for the current OS X version.
-  static scoped_ptr<OSCompatibility> CreateForPlatform();
+  static std::unique_ptr<OSCompatibility> CreateForPlatform();
 
   virtual ~OSCompatibility();
 
diff --git a/sandbox/mac/xpc_message_server.h b/sandbox/mac/xpc_message_server.h
index c509bab..9342ef06 100644
--- a/sandbox/mac/xpc_message_server.h
+++ b/sandbox/mac/xpc_message_server.h
@@ -7,10 +7,11 @@
 
 #include <AvailabilityMacros.h>
 
+#include <memory>
+
 #include "base/mac/dispatch_source_mach.h"
 #include "base/mac/scoped_mach_port.h"
 #include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
 #include "sandbox/mac/message_server.h"
 #include "sandbox/mac/xpc.h"
 #include "sandbox/sandbox_export.h"
@@ -51,7 +52,7 @@
   base::mac::ScopedMachReceiveRight server_port_;
 
   // MACH_RECV dispatch source that handles the |server_port_|.
-  scoped_ptr<base::DispatchSourceMach> dispatch_source_;
+  std::unique_ptr<base::DispatchSourceMach> dispatch_source_;
 
   // The reply message, if one has been created.
   xpc_object_t reply_message_;
diff --git a/sandbox/win/src/acl.cc b/sandbox/win/src/acl.cc
index f5de098..539c180 100644
--- a/sandbox/win/src/acl.cc
+++ b/sandbox/win/src/acl.cc
@@ -14,7 +14,7 @@
 
 bool GetDefaultDacl(
     HANDLE token,
-    scoped_ptr<TOKEN_DEFAULT_DACL, base::FreeDeleter>* default_dacl) {
+    std::unique_ptr<TOKEN_DEFAULT_DACL, base::FreeDeleter>* default_dacl) {
   if (token == NULL)
     return false;
 
@@ -64,7 +64,7 @@
   if (token == NULL)
     return false;
 
-  scoped_ptr<TOKEN_DEFAULT_DACL, base::FreeDeleter> default_dacl;
+  std::unique_ptr<TOKEN_DEFAULT_DACL, base::FreeDeleter> default_dacl;
   if (!GetDefaultDacl(token, &default_dacl))
     return false;
 
@@ -86,7 +86,7 @@
   DWORD size = sizeof(TOKEN_GROUPS) + SECURITY_MAX_SID_SIZE;
   TOKEN_GROUPS* logon_sid = reinterpret_cast<TOKEN_GROUPS*>(malloc(size));
 
-  scoped_ptr<TOKEN_GROUPS, base::FreeDeleter> logon_sid_ptr(logon_sid);
+  std::unique_ptr<TOKEN_GROUPS, base::FreeDeleter> logon_sid_ptr(logon_sid);
 
   if (!::GetTokenInformation(token, TokenLogonSid, logon_sid, size, &size))
     return false;
@@ -103,7 +103,7 @@
   DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE;
   TOKEN_USER* token_user = reinterpret_cast<TOKEN_USER*>(malloc(size));
 
-  scoped_ptr<TOKEN_USER, base::FreeDeleter> token_user_ptr(token_user);
+  std::unique_ptr<TOKEN_USER, base::FreeDeleter> token_user_ptr(token_user);
 
   if (!::GetTokenInformation(token, TokenUser, token_user, size, &size))
     return false;
diff --git a/sandbox/win/src/acl.h b/sandbox/win/src/acl.h
index 0749367..7104155 100644
--- a/sandbox/win/src/acl.h
+++ b/sandbox/win/src/acl.h
@@ -8,8 +8,9 @@
 #include <AccCtrl.h>
 #include <windows.h>
 
+#include <memory>
+
 #include "base/memory/free_deleter.h"
-#include "base/memory/scoped_ptr.h"
 #include "sandbox/win/src/sid.h"
 
 namespace sandbox {
@@ -17,7 +18,7 @@
 // Returns the default dacl from the token passed in.
 bool GetDefaultDacl(
     HANDLE token,
-    scoped_ptr<TOKEN_DEFAULT_DACL, base::FreeDeleter>* default_dacl);
+    std::unique_ptr<TOKEN_DEFAULT_DACL, base::FreeDeleter>* default_dacl);
 
 // Appends an ACE represented by |sid|, |access_mode|, and |access| to
 // |old_dacl|. If the function succeeds, new_dacl contains the new dacl and
diff --git a/sandbox/win/src/address_sanitizer_test.cc b/sandbox/win/src/address_sanitizer_test.cc
index db39d6b9..d7e5e46 100644
--- a/sandbox/win/src/address_sanitizer_test.cc
+++ b/sandbox/win/src/address_sanitizer_test.cc
@@ -4,6 +4,8 @@
 
 #include <stdio.h>
 
+#include <memory>
+
 #include "base/environment.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -32,7 +34,7 @@
   }
 
  protected:
-  scoped_ptr<base::Environment> env_;
+  std::unique_ptr<base::Environment> env_;
   bool had_asan_options_;
   std::string old_asan_options_;
 };
diff --git a/sandbox/win/src/app_container.cc b/sandbox/win/src/app_container.cc
index da8fa88..78d949c 100644
--- a/sandbox/win/src/app_container.cc
+++ b/sandbox/win/src/app_container.cc
@@ -9,7 +9,6 @@
 #include <vector>
 
 #include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/win/startup_information.h"
 #include "sandbox/win/src/internal_types.h"
 
diff --git a/sandbox/win/src/app_container.h b/sandbox/win/src/app_container.h
index fe2b189..e61cba6 100644
--- a/sandbox/win/src/app_container.h
+++ b/sandbox/win/src/app_container.h
@@ -10,7 +10,6 @@
 #include <vector>
 
 #include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/strings/string16.h"
 #include "sandbox/win/src/sandbox_types.h"
 
diff --git a/sandbox/win/src/app_container_unittest.cc b/sandbox/win/src/app_container_unittest.cc
index 4bce16a..5aa8b5d 100644
--- a/sandbox/win/src/app_container_unittest.cc
+++ b/sandbox/win/src/app_container_unittest.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <memory>
+
 #include "base/win/windows_version.h"
 #include "sandbox/win/src/app_container.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -36,7 +38,8 @@
   if (base::win::OSInfo::GetInstance()->version() < base::win::VERSION_WIN8)
     return;
 
-  scoped_ptr<AppContainerAttributes> attributes(new AppContainerAttributes);
+  std::unique_ptr<AppContainerAttributes> attributes(
+      new AppContainerAttributes);
   std::vector<base::string16> capabilities;
   EXPECT_EQ(SBOX_ERROR_INVALID_APP_CONTAINER,
             attributes->SetAppContainer(L"S-1-foo", capabilities));
diff --git a/sandbox/win/src/broker_services.cc b/sandbox/win/src/broker_services.cc
index 26b2561..838d49468 100644
--- a/sandbox/win/src/broker_services.cc
+++ b/sandbox/win/src/broker_services.cc
@@ -6,11 +6,12 @@
 
 #include <AclAPI.h>
 #include <stddef.h>
+
+#include <memory>
 #include <utility>
 
 #include "base/logging.h"
 #include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/stl_util.h"
 #include "base/threading/platform_thread.h"
 #include "base/win/scoped_handle.h"
@@ -474,7 +475,8 @@
   // the job object generates notifications using the completion port.
   policy_base->AddRef();
   if (job.IsValid()) {
-    scoped_ptr<JobTracker> tracker(new JobTracker(std::move(job), policy_base));
+    std::unique_ptr<JobTracker> tracker(
+        new JobTracker(std::move(job), policy_base));
 
     // There is no obvious recovery after failure here. Previous version with
     // SpawnCleanup() caused deletion of TargetProcess twice. crbug.com/480639
@@ -524,8 +526,8 @@
 }
 
 ResultCode BrokerServicesBase::AddTargetPeer(HANDLE peer_process) {
-  scoped_ptr<PeerTracker> peer(new PeerTracker(::GetProcessId(peer_process),
-                                               job_port_.Get()));
+  std::unique_ptr<PeerTracker> peer(
+      new PeerTracker(::GetProcessId(peer_process), job_port_.Get()));
   if (!peer->id)
     return SBOX_ERROR_GENERIC;
 
diff --git a/sandbox/win/src/handle_closer.cc b/sandbox/win/src/handle_closer.cc
index 962e441..038cae98 100644
--- a/sandbox/win/src/handle_closer.cc
+++ b/sandbox/win/src/handle_closer.cc
@@ -6,9 +6,10 @@
 
 #include <stddef.h>
 
+#include <memory>
+
 #include "base/logging.h"
 #include "base/memory/free_deleter.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/win/windows_version.h"
 #include "sandbox/win/src/interceptors.h"
 #include "sandbox/win/src/internal_types.h"
@@ -96,7 +97,7 @@
     return true;
 
   size_t bytes_needed = GetBufferSize();
-  scoped_ptr<size_t[]> local_buffer(
+  std::unique_ptr<size_t[]> local_buffer(
       new size_t[bytes_needed / sizeof(size_t)]);
 
   if (!SetupHandleList(local_buffer.get(), bytes_needed))
@@ -175,7 +176,7 @@
     ResolveNTFunctionPtr("NtQueryObject", &QueryObject);
 
   ULONG size = MAX_PATH;
-  scoped_ptr<UNICODE_STRING, base::FreeDeleter> name;
+  std::unique_ptr<UNICODE_STRING, base::FreeDeleter> name;
   NTSTATUS result;
 
   do {
diff --git a/sandbox/win/src/interception.cc b/sandbox/win/src/interception.cc
index 0243c24..feb5d896 100644
--- a/sandbox/win/src/interception.cc
+++ b/sandbox/win/src/interception.cc
@@ -7,12 +7,12 @@
 
 #include <stddef.h>
 
+#include <memory>
 #include <set>
 
 #include "sandbox/win/src/interception.h"
 
 #include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/strings/string16.h"
 #include "base/win/pe_image.h"
 #include "base/win/windows_version.h"
@@ -129,7 +129,7 @@
     return true;  // Nothing to do here
 
   size_t buffer_bytes = GetBufferSize();
-  scoped_ptr<char[]> local_buffer(new char[buffer_bytes]);
+  std::unique_ptr<char[]> local_buffer(new char[buffer_bytes]);
 
   if (!SetupConfigBuffer(local_buffer.get(), buffer_bytes))
     return false;
diff --git a/sandbox/win/src/interception_unittest.cc b/sandbox/win/src/interception_unittest.cc
index 7b7932af..a34f574 100644
--- a/sandbox/win/src/interception_unittest.cc
+++ b/sandbox/win/src/interception_unittest.cc
@@ -10,10 +10,10 @@
 #include <stddef.h>
 
 #include <algorithm>
+#include <memory>
 #include <set>
 
 #include "base/bits.h"
-#include "base/memory/scoped_ptr.h"
 #include "sandbox/win/src/interception.h"
 #include "sandbox/win/src/interception_internal.h"
 #include "sandbox/win/src/interceptors.h"
@@ -183,7 +183,7 @@
   ASSERT_EQ(18u, interceptions.interceptions_.size());
 
   size_t buffer_size = interceptions.GetBufferSize();
-  scoped_ptr<BYTE[]> local_buffer(new BYTE[buffer_size]);
+  std::unique_ptr<BYTE[]> local_buffer(new BYTE[buffer_size]);
 
   ASSERT_TRUE(interceptions.SetupConfigBuffer(local_buffer.get(),
                                               buffer_size));
@@ -236,7 +236,7 @@
   ASSERT_EQ(5u, interceptions.interceptions_.size());
 
   size_t buffer_size = interceptions.GetBufferSize();
-  scoped_ptr<BYTE[]> local_buffer(new BYTE[buffer_size]);
+  std::unique_ptr<BYTE[]> local_buffer(new BYTE[buffer_size]);
 
   ASSERT_TRUE(interceptions.SetupConfigBuffer(local_buffer.get(),
                                               buffer_size));
diff --git a/sandbox/win/src/process_mitigations_test.cc b/sandbox/win/src/process_mitigations_test.cc
index 783cc68e..cac31fa 100644
--- a/sandbox/win/src/process_mitigations_test.cc
+++ b/sandbox/win/src/process_mitigations_test.cc
@@ -4,7 +4,6 @@
 
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/path_service.h"
 #include "base/process/launch.h"
 #include "base/strings/stringprintf.h"
diff --git a/sandbox/win/src/process_policy_test.cc b/sandbox/win/src/process_policy_test.cc
index 58767813..2794595 100644
--- a/sandbox/win/src/process_policy_test.cc
+++ b/sandbox/win/src/process_policy_test.cc
@@ -6,7 +6,6 @@
 #include <string>
 
 #include "base/memory/free_deleter.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/strings/string16.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/win/scoped_handle.h"
@@ -31,7 +30,7 @@
   if (!exe.empty())
     exe_name = exe.c_str();
 
-  scoped_ptr<wchar_t, base::FreeDeleter>  writable_command(
+  std::unique_ptr<wchar_t, base::FreeDeleter> writable_command(
       _wcsdup(command.c_str()));
 
   // Create the process with the unicode version of the API.
diff --git a/sandbox/win/src/process_thread_policy.cc b/sandbox/win/src/process_thread_policy.cc
index 514e7d6..40b2453 100644
--- a/sandbox/win/src/process_thread_policy.cc
+++ b/sandbox/win/src/process_thread_policy.cc
@@ -6,10 +6,10 @@
 
 #include <stdint.h>
 
+#include <memory>
 #include <string>
 
 #include "base/memory/free_deleter.h"
-#include "base/memory/scoped_ptr.h"
 #include "sandbox/win/src/ipc_tags.h"
 #include "sandbox/win/src/nt_internals.h"
 #include "sandbox/win/src/policy_engine_opcodes.h"
@@ -79,7 +79,7 @@
 bool ProcessPolicy::GenerateRules(const wchar_t* name,
                                   TargetPolicy::Semantics semantics,
                                   LowLevelPolicy* policy) {
-  scoped_ptr<PolicyRule> process;
+  std::unique_ptr<PolicyRule> process;
   switch (semantics) {
     case TargetPolicy::PROCESS_MIN_EXEC: {
       process.reset(new PolicyRule(GIVE_READONLY));
@@ -226,8 +226,8 @@
 
   STARTUPINFO startup_info = {0};
   startup_info.cb = sizeof(startup_info);
-  scoped_ptr<wchar_t, base::FreeDeleter>
-      cmd_line(_wcsdup(command_line.c_str()));
+  std::unique_ptr<wchar_t, base::FreeDeleter> cmd_line(
+      _wcsdup(command_line.c_str()));
 
   BOOL should_give_full_access = (GIVE_ALLACCESS == eval_result);
   if (!CreateProcessExWHelper(client_info.process, should_give_full_access,
diff --git a/sandbox/win/src/restricted_token.cc b/sandbox/win/src/restricted_token.cc
index ea84d86..b696a24b 100644
--- a/sandbox/win/src/restricted_token.cc
+++ b/sandbox/win/src/restricted_token.cc
@@ -6,10 +6,10 @@
 
 #include <stddef.h>
 
+#include <memory>
 #include <vector>
 
 #include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
 #include "sandbox/win/src/acl.h"
 #include "sandbox/win/src/win_utils.h"
 
@@ -17,9 +17,9 @@
 
 // Calls GetTokenInformation with the desired |info_class| and returns a buffer
 // with the result.
-scoped_ptr<BYTE[]> GetTokenInfo(const base::win::ScopedHandle& token,
-                                TOKEN_INFORMATION_CLASS info_class,
-                                DWORD* error) {
+std::unique_ptr<BYTE[]> GetTokenInfo(const base::win::ScopedHandle& token,
+                                     TOKEN_INFORMATION_CLASS info_class,
+                                     DWORD* error) {
   // Get the required buffer size.
   DWORD size = 0;
   ::GetTokenInformation(token.Get(), info_class, NULL, 0,  &size);
@@ -28,7 +28,7 @@
     return nullptr;
   }
 
-  scoped_ptr<BYTE[]> buffer(new BYTE[size]);
+  std::unique_ptr<BYTE[]> buffer(new BYTE[size]);
   if (!::GetTokenInformation(token.Get(), info_class, buffer.get(), size,
                              &size)) {
     *error = ::GetLastError();
@@ -227,7 +227,7 @@
     return ERROR_NO_TOKEN;
 
   DWORD error;
-  scoped_ptr<BYTE[]> buffer =
+  std::unique_ptr<BYTE[]> buffer =
       GetTokenInfo(effective_token_, TokenGroups, &error);
 
   if (!buffer)
@@ -274,7 +274,7 @@
     return ERROR_NO_TOKEN;
 
   DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE;
-  scoped_ptr<BYTE[]> buffer(new BYTE[size]);
+  std::unique_ptr<BYTE[]> buffer(new BYTE[size]);
   TOKEN_USER* token_user = reinterpret_cast<TOKEN_USER*>(buffer.get());
 
   BOOL result = ::GetTokenInformation(effective_token_.Get(), TokenUser,
@@ -296,7 +296,7 @@
     return ERROR_NO_TOKEN;
 
   DWORD error;
-  scoped_ptr<BYTE[]> buffer =
+  std::unique_ptr<BYTE[]> buffer =
       GetTokenInfo(effective_token_, TokenPrivileges, &error);
 
   if (!buffer)
@@ -356,7 +356,7 @@
     return ERROR_NO_TOKEN;
 
   DWORD error;
-  scoped_ptr<BYTE[]> buffer =
+  std::unique_ptr<BYTE[]> buffer =
       GetTokenInfo(effective_token_, TokenGroups, &error);
 
   if (!buffer)
@@ -384,7 +384,7 @@
     return ERROR_NO_TOKEN;
 
   DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE;
-  scoped_ptr<BYTE[]> buffer(new BYTE[size]);
+  std::unique_ptr<BYTE[]> buffer(new BYTE[size]);
   TOKEN_USER* token_user = reinterpret_cast<TOKEN_USER*>(buffer.get());
 
   BOOL result = ::GetTokenInformation(effective_token_.Get(), TokenUser,
@@ -409,7 +409,7 @@
   if (ERROR_SUCCESS != error)
     return error;
 
-  scoped_ptr<BYTE[]> buffer =
+  std::unique_ptr<BYTE[]> buffer =
       GetTokenInfo(effective_token_, TokenGroups, &error);
 
   if (!buffer)
diff --git a/sandbox/win/src/sandbox_policy_base.h b/sandbox/win/src/sandbox_policy_base.h
index 31f0d9c..a2704a0 100644
--- a/sandbox/win/src/sandbox_policy_base.h
+++ b/sandbox/win/src/sandbox_policy_base.h
@@ -10,11 +10,11 @@
 #include <stdint.h>
 
 #include <list>
+#include <memory>
 #include <vector>
 
 #include "base/compiler_specific.h"
 #include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/process/launch.h"
 #include "base/strings/string16.h"
 #include "base/win/scoped_handle.h"
@@ -155,10 +155,10 @@
   // given type.
   HandleCloser handle_closer_;
   std::vector<base::string16> capabilities_;
-  scoped_ptr<AppContainerAttributes> appcontainer_list_;
+  std::unique_ptr<AppContainerAttributes> appcontainer_list_;
   PSID lowbox_sid_;
   base::win::ScopedHandle lowbox_directory_;
-  scoped_ptr<Dispatcher> dispatcher_;
+  std::unique_ptr<Dispatcher> dispatcher_;
   bool lockdown_default_dacl_;
 
   static HDESK alternate_desktop_handle_;
diff --git a/sandbox/win/src/service_resolver_32.cc b/sandbox/win/src/service_resolver_32.cc
index f809227e9..2fe99b90 100644
--- a/sandbox/win/src/service_resolver_32.cc
+++ b/sandbox/win/src/service_resolver_32.cc
@@ -6,8 +6,9 @@
 
 #include <stddef.h>
 
+#include <memory>
+
 #include "base/bit_cast.h"
-#include "base/memory/scoped_ptr.h"
 #include "sandbox/win/src/win_utils.h"
 
 namespace {
@@ -175,7 +176,7 @@
 
   relative_jump_ = 0;
   size_t thunk_bytes = GetThunkSize();
-  scoped_ptr<char[]> thunk_buffer(new char[thunk_bytes]);
+  std::unique_ptr<char[]> thunk_buffer(new char[thunk_bytes]);
   ServiceFullThunk* thunk = reinterpret_cast<ServiceFullThunk*>(
                                 thunk_buffer.get());
 
diff --git a/sandbox/win/src/service_resolver_64.cc b/sandbox/win/src/service_resolver_64.cc
index 25ee9db..7846ee3 100644
--- a/sandbox/win/src/service_resolver_64.cc
+++ b/sandbox/win/src/service_resolver_64.cc
@@ -6,7 +6,8 @@
 
 #include <stddef.h>
 
-#include "base/memory/scoped_ptr.h"
+#include <memory>
+
 #include "sandbox/win/src/sandbox_nt_util.h"
 #include "sandbox/win/src/win_utils.h"
 
@@ -148,7 +149,7 @@
     return ret;
 
   size_t thunk_bytes = GetThunkSize();
-  scoped_ptr<char[]> thunk_buffer(new char[thunk_bytes]);
+  std::unique_ptr<char[]> thunk_buffer(new char[thunk_bytes]);
   ServiceFullThunk* thunk = reinterpret_cast<ServiceFullThunk*>(
                                 thunk_buffer.get());
 
diff --git a/sandbox/win/src/service_resolver_unittest.cc b/sandbox/win/src/service_resolver_unittest.cc
index 25d0875..ff59629 100644
--- a/sandbox/win/src/service_resolver_unittest.cc
+++ b/sandbox/win/src/service_resolver_unittest.cc
@@ -6,9 +6,10 @@
 
 #include <stddef.h>
 
+#include <memory>
+
 #include "base/bit_cast.h"
 #include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/win/windows_version.h"
 #include "sandbox/win/src/resolver.h"
 #include "sandbox/win/src/sandbox_utils.h"
@@ -108,7 +109,7 @@
   // Any pointer will do as an interception_entry_point
   void* function_entry = resolver;
   size_t thunk_size = resolver->GetThunkSize();
-  scoped_ptr<char[]> thunk(new char[thunk_size]);
+  std::unique_ptr<char[]> thunk(new char[thunk_size]);
   size_t used;
 
   resolver->AllowLocalPatches();
@@ -246,7 +247,7 @@
   // Any pointer will do as an interception_entry_point
   void* function_entry = resolver;
   size_t thunk_size = resolver->GetThunkSize();
-  scoped_ptr<char[]> thunk(new char[thunk_size]);
+  std::unique_ptr<char[]> thunk(new char[thunk_size]);
   size_t used;
 
   NTSTATUS ret = STATUS_UNSUCCESSFUL;
diff --git a/sandbox/win/src/sharedmem_ipc_server.cc b/sandbox/win/src/sharedmem_ipc_server.cc
index cf2d800..672abfac 100644
--- a/sandbox/win/src/sharedmem_ipc_server.cc
+++ b/sandbox/win/src/sharedmem_ipc_server.cc
@@ -5,9 +5,10 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <memory>
+
 #include "base/callback.h"
 #include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/stl_util.h"
 #include "sandbox/win/src/crosscall_params.h"
 #include "sandbox/win/src/crosscall_server.h"
@@ -175,7 +176,7 @@
       ipc_params->args[i] = type;
       switch (type) {
         case WCHAR_TYPE: {
-          scoped_ptr<base::string16> data(new base::string16);
+          std::unique_ptr<base::string16> data(new base::string16);
           if (!params->GetParameterStr(i, data.get())) {
             args[i] = 0;
             ReleaseArgs(ipc_params, args);
@@ -228,10 +229,8 @@
   // Parse, verify and copy the message. The handler operates on a copy
   // of the message so the client cannot play dirty tricks by changing the
   // data in the channel while the IPC is being processed.
-  scoped_ptr<CrossCallParamsEx> params(
-      CrossCallParamsEx::CreateFromBuffer(ipc_buffer,
-                                          service_context->channel_size,
-                                          &output_size));
+  std::unique_ptr<CrossCallParamsEx> params(CrossCallParamsEx::CreateFromBuffer(
+      ipc_buffer, service_context->channel_size, &output_size));
   if (!params.get())
     return false;
 
diff --git a/sandbox/win/src/target_process.cc b/sandbox/win/src/target_process.cc
index 2e0376f..495d35c9d 100644
--- a/sandbox/win/src/target_process.cc
+++ b/sandbox/win/src/target_process.cc
@@ -7,11 +7,11 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <memory>
 #include <utility>
 
 #include "base/macros.h"
 #include "base/memory/free_deleter.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/win/pe_image.h"
 #include "base/win/startup_information.h"
 #include "base/win/windows_version.h"
@@ -133,7 +133,7 @@
   exe_name_.reset(_wcsdup(exe_path));
 
   // the command line needs to be writable by CreateProcess().
-  scoped_ptr<wchar_t, base::FreeDeleter> cmd_line(_wcsdup(command_line));
+  std::unique_ptr<wchar_t, base::FreeDeleter> cmd_line(_wcsdup(command_line));
 
   // Start the target process suspended.
   DWORD flags =
diff --git a/sandbox/win/src/target_process.h b/sandbox/win/src/target_process.h
index 547d4141..90a4aa9e4 100644
--- a/sandbox/win/src/target_process.h
+++ b/sandbox/win/src/target_process.h
@@ -9,9 +9,10 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <memory>
+
 #include "base/macros.h"
 #include "base/memory/free_deleter.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/win/scoped_handle.h"
 #include "base/win/scoped_process_information.h"
 #include "sandbox/win/src/crosscall_server.h"
@@ -119,13 +120,13 @@
   // Job object containing the target process.
   HANDLE job_;
   // Reference to the IPC subsystem.
-  scoped_ptr<SharedMemIPCServer> ipc_server_;
+  std::unique_ptr<SharedMemIPCServer> ipc_server_;
   // Provides the threads used by the IPC. This class does not own this pointer.
   ThreadProvider* thread_pool_;
   // Base address of the main executable
   void* base_address_;
   // Full name of the target executable.
-  scoped_ptr<wchar_t, base::FreeDeleter> exe_name_;
+  std::unique_ptr<wchar_t, base::FreeDeleter> exe_name_;
 
   // Function used for testing.
   friend TargetProcess* MakeTestTargetProcess(HANDLE process,
diff --git a/sandbox/win/src/top_level_dispatcher.cc b/sandbox/win/src/top_level_dispatcher.cc
index 1880c62..f09ca4e 100644
--- a/sandbox/win/src/top_level_dispatcher.cc
+++ b/sandbox/win/src/top_level_dispatcher.cc
@@ -8,7 +8,6 @@
 #include <string.h>
 
 #include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
 #include "sandbox/win/src/crosscall_server.h"
 #include "sandbox/win/src/filesystem_dispatcher.h"
 #include "sandbox/win/src/handle_dispatcher.h"
diff --git a/sandbox/win/src/top_level_dispatcher.h b/sandbox/win/src/top_level_dispatcher.h
index c9306de..c1cf8f6 100644
--- a/sandbox/win/src/top_level_dispatcher.h
+++ b/sandbox/win/src/top_level_dispatcher.h
@@ -5,8 +5,9 @@
 #ifndef SANDBOX_SRC_TOP_LEVEL_DISPATCHER_H__
 #define SANDBOX_SRC_TOP_LEVEL_DISPATCHER_H__
 
+#include <memory>
+
 #include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
 #include "sandbox/win/src/crosscall_server.h"
 #include "sandbox/win/src/interception.h"
 #include "sandbox/win/src/ipc_tags.h"
@@ -34,13 +35,13 @@
   Dispatcher* GetDispatcher(int ipc_tag);
 
   PolicyBase* policy_;
-  scoped_ptr<Dispatcher> filesystem_dispatcher_;
-  scoped_ptr<Dispatcher> named_pipe_dispatcher_;
-  scoped_ptr<Dispatcher> thread_process_dispatcher_;
-  scoped_ptr<Dispatcher> sync_dispatcher_;
-  scoped_ptr<Dispatcher> registry_dispatcher_;
-  scoped_ptr<Dispatcher> handle_dispatcher_;
-  scoped_ptr<Dispatcher> process_mitigations_win32k_dispatcher_;
+  std::unique_ptr<Dispatcher> filesystem_dispatcher_;
+  std::unique_ptr<Dispatcher> named_pipe_dispatcher_;
+  std::unique_ptr<Dispatcher> thread_process_dispatcher_;
+  std::unique_ptr<Dispatcher> sync_dispatcher_;
+  std::unique_ptr<Dispatcher> registry_dispatcher_;
+  std::unique_ptr<Dispatcher> handle_dispatcher_;
+  std::unique_ptr<Dispatcher> process_mitigations_win32k_dispatcher_;
   Dispatcher* ipc_targets_[IPC_LAST_TAG];
 
   DISALLOW_COPY_AND_ASSIGN(TopLevelDispatcher);
diff --git a/sandbox/win/src/win_utils.cc b/sandbox/win/src/win_utils.cc
index ef4d803..178fd91 100644
--- a/sandbox/win/src/win_utils.cc
+++ b/sandbox/win/src/win_utils.cc
@@ -7,9 +7,9 @@
 #include <stddef.h>
 
 #include <map>
+#include <memory>
 
 #include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
 #include "base/strings/string_util.h"
 #include "base/win/pe_image.h"
 #include "sandbox/win/src/internal_types.h"
@@ -294,7 +294,7 @@
   }
 
   DWORD size = MAX_PATH;
-  scoped_ptr<wchar_t[]> long_path_buf(new wchar_t[size]);
+  std::unique_ptr<wchar_t[]> long_path_buf(new wchar_t[size]);
 
   DWORD return_value = ::GetLongPathName(temp_path.c_str(), long_path_buf.get(),
                                          size);
@@ -355,7 +355,7 @@
   NTSTATUS status = NtQueryObject(handle, ObjectNameInformation, name, size,
                                   &size);
 
-  scoped_ptr<BYTE[]> name_ptr;
+  std::unique_ptr<BYTE[]> name_ptr;
   if (size) {
     name_ptr.reset(new BYTE[size]);
     name = reinterpret_cast<OBJECT_NAME_INFORMATION*>(name_ptr.get());
diff --git a/sandbox/win/src/window.cc b/sandbox/win/src/window.cc
index cfbf280..6a873028 100644
--- a/sandbox/win/src/window.cc
+++ b/sandbox/win/src/window.cc
@@ -6,8 +6,9 @@
 
 #include <aclapi.h>
 
+#include <memory>
+
 #include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
 #include "sandbox/win/src/acl.h"
 #include "sandbox/win/src/sid.h"
 
@@ -130,7 +131,7 @@
   }
 
   // Create the buffer that will hold the name.
-  scoped_ptr<wchar_t[]> name_buffer(new wchar_t[size]);
+  std::unique_ptr<wchar_t[]> name_buffer(new wchar_t[size]);
 
   // Query the name of the object.
   if (!::GetUserObjectInformation(handle, UOI_NAME, name_buffer.get(), size,
diff --git a/sandbox/win/wow_helper/service64_resolver.cc b/sandbox/win/wow_helper/service64_resolver.cc
index 0424d9fd..1e71b50 100644
--- a/sandbox/win/wow_helper/service64_resolver.cc
+++ b/sandbox/win/wow_helper/service64_resolver.cc
@@ -7,8 +7,9 @@
 #include <limits.h>
 #include <stddef.h>
 
+#include <memory>
+
 #include "base/bit_cast.h"
-#include "base/memory/scoped_ptr.h"
 #include "sandbox/win/wow_helper/target_code.h"
 
 namespace {
@@ -214,7 +215,7 @@
     return ret;
 
   size_t thunk_bytes = GetThunkSize();
-  scoped_ptr<char[]> thunk_buffer(new char[thunk_bytes]);
+  std::unique_ptr<char[]> thunk_buffer(new char[thunk_bytes]);
   ServiceFullThunk* thunk = reinterpret_cast<ServiceFullThunk*>(
                                 thunk_buffer.get());
 
diff --git a/sandbox/win/wow_helper/wow_helper.vcproj b/sandbox/win/wow_helper/wow_helper.vcproj
index 5482fbd..c8e7c9eb 100644
--- a/sandbox/win/wow_helper/wow_helper.vcproj
+++ b/sandbox/win/wow_helper/wow_helper.vcproj
@@ -178,14 +178,6 @@
 	</References>
 	<Files>
 		<Filter
-			Name="base"
-			>
-			<File
-				RelativePath="..\..\base\scoped_ptr.h"
-				>
-			</File>
-		</Filter>
-		<Filter
 			Name="sandbox"
 			>
 			<File
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h
index 621844f..20b5060f 100644
--- a/skia/config/SkUserConfig.h
+++ b/skia/config/SkUserConfig.h
@@ -234,10 +234,6 @@
 #   define SK_SUPPORT_LEGACY_IMAGEFACTORY
 #endif
 
-#ifndef    SK_SUPPORT_LEGACY_NEW_SURFACE_API
-#   define SK_SUPPORT_LEGACY_NEW_SURFACE_API
-#endif
-
 #ifndef    SK_SUPPORT_LEGACY_IMAGEFILTER_PTR
 #   define SK_SUPPORT_LEGACY_IMAGEFILTER_PTR
 #endif
diff --git a/skia/ext/analysis_canvas_unittest.cc b/skia/ext/analysis_canvas_unittest.cc
index bac22b11..413e493 100644
--- a/skia/ext/analysis_canvas_unittest.cc
+++ b/skia/ext/analysis_canvas_unittest.cc
@@ -330,8 +330,7 @@
   SkPictureRecorder recorder;
 
   // Create a picture with 3 commands, last of which is non-solid.
-  skia::RefPtr<SkCanvas> record_canvas =
-      skia::SharePtr(recorder.beginRecording(256, 256, &factory));
+  sk_sp<SkCanvas> record_canvas = sk_ref_sp(recorder.beginRecording(256, 256, &factory));
 
   std::string text = "text";
   SkPoint point = SkPoint::Make(SkIntToScalar(25), SkIntToScalar(25));
diff --git a/skia/ext/bitmap_platform_device_cairo.cc b/skia/ext/bitmap_platform_device_cairo.cc
index 541e263..2ea1a39 100644
--- a/skia/ext/bitmap_platform_device_cairo.cc
+++ b/skia/ext/bitmap_platform_device_cairo.cc
@@ -190,7 +190,7 @@
 
 SkCanvas* CreatePlatformCanvas(int width, int height, bool is_opaque,
                                uint8_t* data, OnFailureType failureType) {
-  skia::RefPtr<SkBaseDevice> dev = skia::AdoptRef(
+  sk_sp<SkBaseDevice> dev(
       BitmapPlatformDevice::Create(width, height, is_opaque, data));
   return CreateCanvas(dev, failureType);
 }
diff --git a/skia/ext/bitmap_platform_device_mac.cc b/skia/ext/bitmap_platform_device_mac.cc
index eaf979b..e1df85e 100644
--- a/skia/ext/bitmap_platform_device_mac.cc
+++ b/skia/ext/bitmap_platform_device_mac.cc
@@ -299,14 +299,14 @@
 SkCanvas* CreatePlatformCanvas(CGContextRef ctx, int width, int height,
                                bool is_opaque, OnFailureType failureType) {
   const bool do_clear = false;
-  skia::RefPtr<SkBaseDevice> dev = skia::AdoptRef(
+  sk_sp<SkBaseDevice> dev(
       BitmapPlatformDevice::Create(ctx, width, height, is_opaque, do_clear));
   return CreateCanvas(dev, failureType);
 }
 
 SkCanvas* CreatePlatformCanvas(int width, int height, bool is_opaque,
                                uint8_t* data, OnFailureType failureType) {
-  skia::RefPtr<SkBaseDevice> dev = skia::AdoptRef(
+  sk_sp<SkBaseDevice> dev(
       BitmapPlatformDevice::CreateWithData(data, width, height, is_opaque));
   return CreateCanvas(dev, failureType);
 }
diff --git a/skia/ext/bitmap_platform_device_mac.h b/skia/ext/bitmap_platform_device_mac.h
index 69c375d..a03360f 100644
--- a/skia/ext/bitmap_platform_device_mac.h
+++ b/skia/ext/bitmap_platform_device_mac.h
@@ -10,7 +10,6 @@
 #include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "skia/ext/platform_device.h"
-#include "skia/ext/refptr.h"
 
 namespace skia {
 
diff --git a/skia/ext/bitmap_platform_device_skia.cc b/skia/ext/bitmap_platform_device_skia.cc
index f3c97eb9..7491b93 100644
--- a/skia/ext/bitmap_platform_device_skia.cc
+++ b/skia/ext/bitmap_platform_device_skia.cc
@@ -59,7 +59,7 @@
 
 SkCanvas* CreatePlatformCanvas(int width, int height, bool is_opaque,
                                uint8_t* data, OnFailureType failureType) {
-  skia::RefPtr<SkBaseDevice> dev = skia::AdoptRef(
+  sk_sp<SkBaseDevice> dev(
       BitmapPlatformDevice::Create(width, height, is_opaque, data));
   return CreateCanvas(dev, failureType);
 }
diff --git a/skia/ext/bitmap_platform_device_win.cc b/skia/ext/bitmap_platform_device_win.cc
index e262fac6..1e05997 100644
--- a/skia/ext/bitmap_platform_device_win.cc
+++ b/skia/ext/bitmap_platform_device_win.cc
@@ -476,7 +476,7 @@
                                bool is_opaque,
                                HANDLE shared_section,
                                OnFailureType failureType) {
-  skia::RefPtr<SkBaseDevice> dev = skia::AdoptRef(
+  sk_sp<SkBaseDevice> dev(
       BitmapPlatformDevice::Create(width, height, is_opaque, shared_section));
   return CreateCanvas(dev, failureType);
 }
diff --git a/skia/ext/bitmap_platform_device_win.h b/skia/ext/bitmap_platform_device_win.h
index a4702b5..911d0d7 100644
--- a/skia/ext/bitmap_platform_device_win.h
+++ b/skia/ext/bitmap_platform_device_win.h
@@ -8,7 +8,6 @@
 #include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "skia/ext/platform_device.h"
-#include "skia/ext/refptr.h"
 
 namespace skia {
 
diff --git a/skia/ext/pixel_ref_utils_unittest.cc b/skia/ext/pixel_ref_utils_unittest.cc
index 80b53ad..5e363a76 100644
--- a/skia/ext/pixel_ref_utils_unittest.cc
+++ b/skia/ext/pixel_ref_utils_unittest.cc
@@ -8,7 +8,6 @@
 #include "base/memory/scoped_ptr.h"
 #include "cc/test/geometry_test_utils.h"
 #include "skia/ext/pixel_ref_utils.h"
-#include "skia/ext/refptr.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkCanvas.h"
@@ -32,15 +31,14 @@
      : SkImageGenerator(info) { }
 };
 
-skia::RefPtr<SkImage> CreateDiscardableImage(const gfx::Size& size) {
+sk_sp<SkImage> MakeDiscardableImage(const gfx::Size& size) {
   const SkImageInfo info =
       SkImageInfo::MakeN32Premul(size.width(), size.height());
-  return skia::AdoptRef(
-      SkImage::NewFromGenerator(new TestImageGenerator(info)));
+  return SkImage::MakeFromGenerator(new TestImageGenerator(info));
 }
 
 void SetDiscardableShader(SkPaint* paint) {
-  skia::RefPtr<SkImage> image = CreateDiscardableImage(gfx::Size(50, 50));
+  sk_sp<SkImage> image = MakeDiscardableImage(gfx::Size(50, 50));
   paint->setShader(
       image->makeShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode));
 }
@@ -512,12 +510,12 @@
   SkPictureRecorder recorder;
   SkCanvas* canvas = StartRecording(&recorder, layer_rect);
 
-  skia::RefPtr<SkImage> first = CreateDiscardableImage(gfx::Size(50, 50));
-  skia::RefPtr<SkImage> second = CreateDiscardableImage(gfx::Size(50, 50));
-  skia::RefPtr<SkImage> third = CreateDiscardableImage(gfx::Size(50, 50));
-  skia::RefPtr<SkImage> fourth = CreateDiscardableImage(gfx::Size(50, 1));
-  skia::RefPtr<SkImage> fifth = CreateDiscardableImage(gfx::Size(10, 10));
-  skia::RefPtr<SkImage> sixth = CreateDiscardableImage(gfx::Size(10, 10));
+  sk_sp<SkImage> first = MakeDiscardableImage(gfx::Size(50, 50));
+  sk_sp<SkImage> second = MakeDiscardableImage(gfx::Size(50, 50));
+  sk_sp<SkImage> third = MakeDiscardableImage(gfx::Size(50, 50));
+  sk_sp<SkImage> fourth = MakeDiscardableImage(gfx::Size(50, 1));
+  sk_sp<SkImage> fifth = MakeDiscardableImage(gfx::Size(10, 10));
+  sk_sp<SkImage> sixth = MakeDiscardableImage(gfx::Size(10, 10));
 
   canvas->save();
 
@@ -592,9 +590,9 @@
   SkPictureRecorder recorder;
   SkCanvas* canvas = StartRecording(&recorder, layer_rect);
 
-  skia::RefPtr<SkImage> first = CreateDiscardableImage(gfx::Size(50, 50));
-  skia::RefPtr<SkImage> second = CreateDiscardableImage(gfx::Size(50, 50));
-  skia::RefPtr<SkImage> third = CreateDiscardableImage(gfx::Size(50, 50));
+  sk_sp<SkImage> first = MakeDiscardableImage(gfx::Size(50, 50));
+  sk_sp<SkImage> second = MakeDiscardableImage(gfx::Size(50, 50));
+  sk_sp<SkImage> third = MakeDiscardableImage(gfx::Size(50, 50));
 
   SkPaint first_paint;
   SetDiscardableShader(&first_paint);
diff --git a/skia/ext/platform_canvas.cc b/skia/ext/platform_canvas.cc
index 72d81f22..dfd8e8f 100644
--- a/skia/ext/platform_canvas.cc
+++ b/skia/ext/platform_canvas.cc
@@ -69,7 +69,8 @@
   return 4 * width;
 }
 
-SkCanvas* CreateCanvas(const skia::RefPtr<SkBaseDevice>& device, OnFailureType failureType) {
+SkCanvas* CreateCanvas(const sk_sp<SkBaseDevice>& device,
+                       OnFailureType failureType) {
   if (!device) {
     if (CRASH_ON_FAILURE == failureType)
       SK_CRASH();
diff --git a/skia/ext/platform_canvas.h b/skia/ext/platform_canvas.h
index 8455261e..2802743 100644
--- a/skia/ext/platform_canvas.h
+++ b/skia/ext/platform_canvas.h
@@ -12,7 +12,6 @@
 // to get the surface type.
 #include "build/build_config.h"
 #include "skia/ext/platform_surface.h"
-#include "skia/ext/refptr.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkPixelRef.h"
@@ -90,7 +89,7 @@
   return CreatePlatformCanvas(width, height, is_opaque, 0, CRASH_ON_FAILURE);
 }
 
-SK_API SkCanvas* CreateCanvas(const skia::RefPtr<SkBaseDevice>& device,
+SK_API SkCanvas* CreateCanvas(const sk_sp<SkBaseDevice>& device,
                               OnFailureType failure_type);
 
 static inline SkCanvas* CreateBitmapCanvas(int width,
diff --git a/skia/ext/platform_canvas_unittest.cc b/skia/ext/platform_canvas_unittest.cc
index 2271cfad..88313ea 100644
--- a/skia/ext/platform_canvas_unittest.cc
+++ b/skia/ext/platform_canvas_unittest.cc
@@ -214,7 +214,7 @@
 // regular skia primitives.
 TEST(PlatformCanvas, SkLayer) {
   // Create the canvas initialized to opaque white.
-  RefPtr<SkCanvas> canvas = AdoptRef(CreatePlatformCanvas(16, 16, true));
+  sk_sp<SkCanvas> canvas(CreatePlatformCanvas(16, 16, true));
   canvas->drawColor(SK_ColorWHITE);
 
   // Make a layer and fill it completely to make sure that the bounds are
@@ -230,7 +230,7 @@
 // Test native clipping.
 TEST(PlatformCanvas, ClipRegion) {
   // Initialize a white canvas
-  RefPtr<SkCanvas> canvas = AdoptRef(CreatePlatformCanvas(16, 16, true));
+  sk_sp<SkCanvas> canvas(CreatePlatformCanvas(16, 16, true));
   canvas->drawColor(SK_ColorWHITE);
   EXPECT_TRUE(VerifyCanvasColor(*canvas, SK_ColorWHITE));
 
@@ -256,7 +256,7 @@
 // Test the layers get filled properly by native rendering.
 TEST(PlatformCanvas, FillLayer) {
   // Create the canvas initialized to opaque white.
-  RefPtr<SkCanvas> canvas = AdoptRef(CreatePlatformCanvas(16, 16, true));
+  sk_sp<SkCanvas> canvas(CreatePlatformCanvas(16, 16, true));
 
   // Make a layer and fill it completely to make sure that the bounds are
   // correct.
@@ -315,7 +315,7 @@
 // Test that translation + make layer works properly.
 TEST(PlatformCanvas, TranslateLayer) {
   // Create the canvas initialized to opaque white.
-  RefPtr<SkCanvas> canvas = AdoptRef(CreatePlatformCanvas(16, 16, true));
+  sk_sp<SkCanvas> canvas(CreatePlatformCanvas(16, 16, true));
 
   // Make a layer and fill it completely to make sure that the bounds are
   // correct.
diff --git a/storage/browser/blob/blob_async_builder_host.cc b/storage/browser/blob/blob_async_builder_host.cc
index a406f51..c30b3833 100644
--- a/storage/browser/blob/blob_async_builder_host.cc
+++ b/storage/browser/blob/blob_async_builder_host.cc
@@ -120,9 +120,7 @@
     BlobStorageContext* context,
     const RequestMemoryCallback& request_memory) {
   DCHECK(context);
-  if (async_blob_map_.find(uuid) == async_blob_map_.end()) {
-    return BlobTransportResult::BAD_IPC;
-  }
+  DCHECK(async_blob_map_.find(uuid) != async_blob_map_.end());
 
   // Step 1: Get the sizes.
   size_t shortcut_memory_size_bytes = 0;
diff --git a/storage/browser/blob/blob_async_builder_host.h b/storage/browser/blob/blob_async_builder_host.h
index 628bffa..b7e82fb 100644
--- a/storage/browser/blob/blob_async_builder_host.h
+++ b/storage/browser/blob/blob_async_builder_host.h
@@ -72,7 +72,8 @@
       const std::set<std::string>& referenced_blob_uuids,
       BlobStorageContext* context);
 
-  // This method begins the construction of the blob given the descriptions.
+  // This method begins the construction of the blob given the descriptions. The
+  // blob uuid MUST be building in this object.
   // When we return:
   // * DONE: The blob is finished transfering right away, and is now
   //   successfully saved in the context.
@@ -99,8 +100,8 @@
 
   // This removes the BlobBuildingState from our map and flags the blob as
   // broken in the context. This can be called both from our own logic to cancel
-  // the blob, or from the DispatcherHost (Renderer). If the blob isn't being
-  // built then we do nothing.
+  // the blob, or from the DispatcherHost (Renderer). The blob MUST be being
+  // built in this builder.
   // Note: if the blob isn't in the context (renderer dereferenced it before we
   // finished constructing), then we don't bother touching the context.
   void CancelBuildingBlob(const std::string& uuid,
@@ -113,6 +114,8 @@
   // by someone else if they still exist in the context.
   void CancelAll(BlobStorageContext* context);
 
+  bool IsEmpty() const { return async_blob_map_.empty(); }
+
   size_t blob_building_count() const { return async_blob_map_.size(); }
 
   bool IsBeingBuilt(const std::string& key) const {
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json
index 0d4a264..d5cda853 100644
--- a/testing/buildbot/chromium.android.json
+++ b/testing/buildbot/chromium.android.json
@@ -21,30 +21,6 @@
             }
           ]
         },
-        "test": "android_webview_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "build.id": "KTU84P",
-              "product.board": "hammerhead"
-            }
-          ]
-        },
-        "test": "base_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "build.id": "KTU84P",
-              "product.board": "hammerhead"
-            }
-          ]
-        },
         "test": "breakpad_unittests"
       },
       {
@@ -57,223 +33,7 @@
             }
           ]
         },
-        "test": "cc_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "build.id": "KTU84P",
-              "product.board": "hammerhead"
-            }
-          ]
-        },
-        "test": "components_browsertests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "build.id": "KTU84P",
-              "product.board": "hammerhead"
-            }
-          ]
-        },
-        "test": "components_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "build.id": "KTU84P",
-              "product.board": "hammerhead"
-            }
-          ]
-        },
         "test": "content_browsertests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "build.id": "KTU84P",
-              "product.board": "hammerhead"
-            }
-          ]
-        },
-        "test": "content_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "build.id": "KTU84P",
-              "product.board": "hammerhead"
-            }
-          ]
-        },
-        "test": "device_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "build.id": "KTU84P",
-              "product.board": "hammerhead"
-            }
-          ]
-        },
-        "test": "events_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "build.id": "KTU84P",
-              "product.board": "hammerhead"
-            }
-          ]
-        },
-        "test": "gl_tests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "build.id": "KTU84P",
-              "product.board": "hammerhead"
-            }
-          ]
-        },
-        "test": "gl_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "build.id": "KTU84P",
-              "product.board": "hammerhead"
-            }
-          ]
-        },
-        "test": "gpu_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "build.id": "KTU84P",
-              "product.board": "hammerhead"
-            }
-          ]
-        },
-        "test": "ipc_tests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "build.id": "KTU84P",
-              "product.board": "hammerhead"
-            }
-          ]
-        },
-        "test": "media_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "build.id": "KTU84P",
-              "product.board": "hammerhead"
-            }
-          ]
-        },
-        "test": "net_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "build.id": "KTU84P",
-              "product.board": "hammerhead"
-            }
-          ]
-        },
-        "test": "sql_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "build.id": "KTU84P",
-              "product.board": "hammerhead"
-            }
-          ]
-        },
-        "test": "sync_unit_tests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "build.id": "KTU84P",
-              "product.board": "hammerhead"
-            }
-          ]
-        },
-        "test": "ui_android_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "build.id": "KTU84P",
-              "product.board": "hammerhead"
-            }
-          ]
-        },
-        "test": "ui_base_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "build.id": "KTU84P",
-              "product.board": "hammerhead"
-            }
-          ]
-        },
-        "test": "ui_touch_selection_unittests"
-      },
-      {
-        "swarming": {
-          "can_use_on_swarming_builders": true,
-          "dimension_sets": [
-            {
-              "build.id": "KTU84P",
-              "product.board": "hammerhead"
-            }
-          ]
-        },
-        "test": "unit_tests"
       }
     ]
   },
diff --git a/third_party/WebKit/LayoutTests/animations/animation-properties-in-keyframe-are-ignored-expected.txt b/third_party/WebKit/LayoutTests/animations/animation-properties-in-keyframe-are-ignored-expected.txt
index bd0be774..94089d9d 100644
--- a/third_party/WebKit/LayoutTests/animations/animation-properties-in-keyframe-are-ignored-expected.txt
+++ b/third_party/WebKit/LayoutTests/animations/animation-properties-in-keyframe-are-ignored-expected.txt
@@ -2,6 +2,6 @@
 PASS - "left" property for "target" element at 1s saw something close to: 50
 PASS - "left" property for "target" element at 2s saw something close to: 100
 PASS - "left" property for "target" element at 3s saw something close to: 150
-PASS - "left" property for "target" element at 4s saw something close to: auto
-PASS - "left" property for "target" element at 5s saw something close to: auto
+PASS - "left" property for "target" element at 4s saw something close to: 0px
+PASS - "left" property for "target" element at 5s saw something close to: 0px
 
diff --git a/third_party/WebKit/LayoutTests/animations/animation-properties-in-keyframe-are-ignored.html b/third_party/WebKit/LayoutTests/animations/animation-properties-in-keyframe-are-ignored.html
index 779e17c..fdd965d 100644
--- a/third_party/WebKit/LayoutTests/animations/animation-properties-in-keyframe-are-ignored.html
+++ b/third_party/WebKit/LayoutTests/animations/animation-properties-in-keyframe-are-ignored.html
@@ -45,8 +45,8 @@
       [1, "target", "left", 50, 5],
       [2, "target", "left", 100, 5],
       [3, "target", "left", 150, 5],
-      [4, "target", "left", "auto", 0],
-      [5, "target", "left", "auto", 0],
+      [4, "target", "left", "0px", 0],
+      [5, "target", "left", "0px", 0],
     ];
     
     runAnimationTest(expectedValues);
@@ -57,4 +57,4 @@
 <div id="target"></div>
 <div id="result"></div>
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/third_party/WebKit/LayoutTests/animations/change-keyframes.html b/third_party/WebKit/LayoutTests/animations/change-keyframes.html
index 97fda5a4..fc0bef4 100644
--- a/third_party/WebKit/LayoutTests/animations/change-keyframes.html
+++ b/third_party/WebKit/LayoutTests/animations/change-keyframes.html
@@ -43,7 +43,7 @@
 
     // A forced style-recalc aborts the previous animation.
     box.style.animationName = "none";
-    assert_equals(getComputedStyle(box).left, 'auto', 'left');
+    assert_equals(getComputedStyle(box).left, '0px', 'left');
 
     // Change keyframes.
     var keyframes = findKeyframesRule("anim");
@@ -53,8 +53,8 @@
     keyframes.appendRule("100% { top: 150px; }");
     box.style.webkitAnimationName = "anim";
 
-    // The left property should reset to auto and top should be animating.
-    assert_equals(getComputedStyle(box).left, 'auto', 'left');
+    // The left property should reset and top should be animating.
+    assert_equals(getComputedStyle(box).left, '0px', 'left');
     assert_equals(getComputedStyle(box).top, '100px', 'top');
   }, "Check that changes to keyframe rules take effect");
 </script>
diff --git a/third_party/WebKit/LayoutTests/animations/play-state.html b/third_party/WebKit/LayoutTests/animations/play-state.html
index 17dcba0..98e8f46 100644
--- a/third_party/WebKit/LayoutTests/animations/play-state.html
+++ b/third_party/WebKit/LayoutTests/animations/play-state.html
@@ -77,7 +77,7 @@
 
     function end() {
       logPassFail('none', getComputedStyle(document.getElementById('translate')).webkitTransform, 'translate', 'at end');
-      logPassFail('auto', getComputedStyle(document.getElementById('left')).left, 'left', 'at end');
+      logPassFail('0px', getComputedStyle(document.getElementById('left')).left, 'left', 'at end');
       if (window.testRunner) {
         testRunner.notifyDone();
       }
diff --git a/third_party/WebKit/LayoutTests/fast/css/getComputedStyle/getComputedStyle-resolved-values-expected.txt b/third_party/WebKit/LayoutTests/fast/css/getComputedStyle/getComputedStyle-resolved-values-expected.txt
index 051be33a6..f35339b 100644
--- a/third_party/WebKit/LayoutTests/fast/css/getComputedStyle/getComputedStyle-resolved-values-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/css/getComputedStyle/getComputedStyle-resolved-values-expected.txt
@@ -5,6 +5,10 @@
 line-height: 30px
 width: 150px
 height: 100px
+top: auto
+right: auto
+bottom: auto
+left: auto
 margin-top: 15px
 margin-right: 30px
 margin-bottom: 20px
@@ -18,6 +22,10 @@
 line-height: 30px
 width: auto
 height: auto
+top: auto
+right: auto
+bottom: auto
+left: auto
 margin-top: 15px
 margin-right: 30px
 margin-bottom: 20px
@@ -31,6 +39,10 @@
 line-height: 30px
 width: 150px
 height: 100px
+top: auto
+right: auto
+bottom: auto
+left: auto
 margin-top: 15px
 margin-right: 30px
 margin-bottom: 20px
@@ -44,6 +56,10 @@
 line-height: 30px
 width: 150px
 height: 100px
+top: auto
+right: auto
+bottom: auto
+left: auto
 margin-top: 15px
 margin-right: 30px
 margin-bottom: 20px
@@ -58,6 +74,10 @@
 line-height: 36px
 width: 250px
 height: 75px
+top: auto
+right: auto
+bottom: auto
+left: auto
 margin-top: 50px
 margin-right: 25px
 margin-bottom: 50px
@@ -71,6 +91,10 @@
 line-height: 36px
 width: auto
 height: auto
+top: auto
+right: auto
+bottom: auto
+left: auto
 margin-top: 10%
 margin-right: 5%
 margin-bottom: 10%
@@ -84,6 +108,10 @@
 line-height: 36px
 width: 250px
 height: 75px
+top: auto
+right: auto
+bottom: auto
+left: auto
 margin-top: 50px
 margin-right: 25px
 margin-bottom: 50px
@@ -97,6 +125,10 @@
 line-height: 36px
 width: 50%
 height: 25%
+top: auto
+right: auto
+bottom: auto
+left: auto
 margin-top: 10%
 margin-right: 5%
 margin-bottom: 10%
@@ -111,6 +143,10 @@
 line-height: 24px
 width: 240px
 height: 120px
+top: auto
+right: auto
+bottom: auto
+left: auto
 margin-top: 24px
 margin-right: 12px
 margin-bottom: 36px
@@ -124,6 +160,10 @@
 line-height: 24px
 width: auto
 height: auto
+top: auto
+right: auto
+bottom: auto
+left: auto
 margin-top: 24px
 margin-right: 12px
 margin-bottom: 36px
@@ -137,6 +177,10 @@
 line-height: 24px
 width: 240px
 height: 120px
+top: auto
+right: auto
+bottom: auto
+left: auto
 margin-top: 24px
 margin-right: 12px
 margin-bottom: 36px
@@ -150,6 +194,10 @@
 line-height: 24px
 width: 240px
 height: 120px
+top: auto
+right: auto
+bottom: auto
+left: auto
 margin-top: 24px
 margin-right: 12px
 margin-bottom: 36px
@@ -164,6 +212,10 @@
 line-height: 30px
 width: 200px
 height: 30px
+top: auto
+right: auto
+bottom: auto
+left: auto
 margin-top: 0px
 margin-right: 126px
 margin-bottom: 0px
@@ -177,6 +229,10 @@
 line-height: 30px
 width: auto
 height: auto
+top: auto
+right: auto
+bottom: auto
+left: auto
 margin-top: 0px
 margin-right: auto
 margin-bottom: 0px
@@ -190,6 +246,10 @@
 line-height: 30px
 width: 200px
 height: 30px
+top: auto
+right: auto
+bottom: auto
+left: auto
 margin-top: 0px
 margin-right: 0px
 margin-bottom: 0px
@@ -203,6 +263,10 @@
 line-height: 30px
 width: 200px
 height: auto
+top: auto
+right: auto
+bottom: auto
+left: auto
 margin-top: 0px
 margin-right: auto
 margin-bottom: 0px
@@ -217,6 +281,10 @@
 line-height: 48px
 width: 150px
 height: 60px
+top: auto
+right: auto
+bottom: auto
+left: auto
 margin-top: 72px
 margin-right: 0px
 margin-bottom: 0px
@@ -230,6 +298,10 @@
 line-height: 48px
 width: auto
 height: auto
+top: auto
+right: auto
+bottom: auto
+left: auto
 margin-top: 72px
 margin-right: 0px
 margin-bottom: 0px
@@ -243,6 +315,10 @@
 line-height: 48px
 width: 150px
 height: 60px
+top: auto
+right: auto
+bottom: auto
+left: auto
 margin-top: 72px
 margin-right: 0px
 margin-bottom: 0px
@@ -256,6 +332,10 @@
 line-height: 48px
 width: 30%
 height: 20%
+top: auto
+right: auto
+bottom: auto
+left: auto
 margin-top: 72px
 margin-right: 0px
 margin-bottom: 0px
@@ -266,8 +346,148 @@
 padding-left: 0px
 
 
+Resolved values for element "rel_positioned" with display "block":
+line-height: 30px
+width: 150px
+height: 100px
+top: 15px
+right: -10px
+bottom: -15px
+left: 10px
+margin-top: 15px
+margin-right: 30px
+margin-bottom: 20px
+margin-left: 10px
+padding-top: 20px
+padding-right: 20px
+padding-bottom: 20px
+padding-left: 20px
+
+Resolved values for element "rel_positioned" with display "inline":
+line-height: 30px
+width: auto
+height: auto
+top: 15px
+right: -10px
+bottom: -15px
+left: 10px
+margin-top: 15px
+margin-right: 30px
+margin-bottom: 20px
+margin-left: 10px
+padding-top: 20px
+padding-right: 20px
+padding-bottom: 20px
+padding-left: 20px
+
+Resolved values for element "rel_positioned" with display "inline-block":
+line-height: 30px
+width: 150px
+height: 100px
+top: 15px
+right: -10px
+bottom: -15px
+left: 10px
+margin-top: 15px
+margin-right: 30px
+margin-bottom: 20px
+margin-left: 10px
+padding-top: 20px
+padding-right: 20px
+padding-bottom: 20px
+padding-left: 20px
+
+Resolved values for element "rel_positioned" with display "none":
+line-height: 30px
+width: 150px
+height: 100px
+top: 15px
+right: auto
+bottom: auto
+left: 10px
+margin-top: 15px
+margin-right: 30px
+margin-bottom: 20px
+margin-left: 10px
+padding-top: 20px
+padding-right: 20px
+padding-bottom: 20px
+padding-left: 20px
+
+
+Resolved values for element "abs_positioned" with display "block":
+line-height: 30px
+width: 150px
+height: 100px
+top: 62px
+right: 10px
+bottom: 15px
+left: 212px
+margin-top: 15px
+margin-right: 30px
+margin-bottom: 20px
+margin-left: 10px
+padding-top: 20px
+padding-right: 20px
+padding-bottom: 20px
+padding-left: 20px
+
+Resolved values for element "abs_positioned" with display "inline":
+line-height: 30px
+width: 150px
+height: 100px
+top: 62px
+right: 10px
+bottom: 15px
+left: 212px
+margin-top: 15px
+margin-right: 30px
+margin-bottom: 20px
+margin-left: 10px
+padding-top: 20px
+padding-right: 20px
+padding-bottom: 20px
+padding-left: 20px
+
+Resolved values for element "abs_positioned" with display "inline-block":
+line-height: 30px
+width: 150px
+height: 100px
+top: 62px
+right: 10px
+bottom: 15px
+left: 212px
+margin-top: 15px
+margin-right: 30px
+margin-bottom: 20px
+margin-left: 10px
+padding-top: 20px
+padding-right: 20px
+padding-bottom: 20px
+padding-left: 20px
+
+Resolved values for element "abs_positioned" with display "none":
+line-height: 30px
+width: 150px
+height: 100px
+top: auto
+right: 10px
+bottom: 15px
+left: auto
+margin-top: 15px
+margin-right: 30px
+margin-bottom: 20px
+margin-left: 10px
+padding-top: 20px
+padding-right: 20px
+padding-bottom: 20px
+padding-left: 20px
+
+
 Fixed
 Percents
 EMs
 Auto
 Mixed
+Relative Positioned
+Absolute Positioned
diff --git a/third_party/WebKit/LayoutTests/fast/css/getComputedStyle/getComputedStyle-resolved-values.html b/third_party/WebKit/LayoutTests/fast/css/getComputedStyle/getComputedStyle-resolved-values.html
index 4295409..806dc5d 100644
--- a/third_party/WebKit/LayoutTests/fast/css/getComputedStyle/getComputedStyle-resolved-values.html
+++ b/third_party/WebKit/LayoutTests/fast/css/getComputedStyle/getComputedStyle-resolved-values.html
@@ -8,6 +8,10 @@
             border: 1px solid black;
         }
 
+        #abs_container {
+            position: relative;
+        }
+
         .testbox {
             color: white;
             font: 24px 'Lucida Grande';
@@ -68,6 +72,35 @@
             padding-bottom: 1em;
             padding-left: auto;
         }
+
+        #rel_positioned {
+            position: relative;
+            line-height: 30px;
+            width: 150px;
+            height: 100px;
+            left: 10px;
+            top: 15px;
+            margin-top: 15px;
+            margin-right: 30px;
+            margin-bottom: 20px;
+            margin-left: 10px;
+            padding: 20px;
+        }
+
+        #abs_positioned {
+            position: absolute;
+            line-height: 30px;
+            width: 150px;
+            height: 100px;
+            right: 10px;
+            bottom: 15px;
+            margin-top: 15px;
+            margin-right: 30px;
+            margin-bottom: 20px;
+            margin-left: 10px;
+            padding: 20px;
+        }
+
     </style>
     
     <script>
@@ -75,6 +108,10 @@
             'line-height',
             'width',
             'height',
+            'top',
+            'right',
+            'bottom',
+            'left',
             'margin-top',
             'margin-right',
             'margin-bottom',
@@ -124,6 +161,8 @@
             test('ems');
             test('auto');
             test('mixed');
+            test('rel_positioned');
+            test('abs_positioned');
         }
     </script>
 </head>
@@ -150,5 +189,11 @@
     <div class="outer">
         <div class="testbox" id="mixed">Mixed</div>
     </div>
+    <div class="outer">
+        <div class="testbox" id="rel_positioned">Relative Positioned</div>
+    </div>
+    <div class="outer" id="abs_container">
+        <div class="testbox" id="abs_positioned">Absolute Positioned</div>
+    </div>
 </body>
 </html>
diff --git a/third_party/WebKit/LayoutTests/fast/css/hover-affects-child.html b/third_party/WebKit/LayoutTests/fast/css/hover-affects-child.html
index b8cb8aa..cd9e9c3 100644
--- a/third_party/WebKit/LayoutTests/fast/css/hover-affects-child.html
+++ b/third_party/WebKit/LayoutTests/fast/css/hover-affects-child.html
@@ -32,10 +32,10 @@
                 var innerElem = document.getElementById('innerElem');
                 var calculatedStyle = window.getComputedStyle(innerElem);
     
-                if (calculatedStyle.getPropertyValue('left') == "auto")
+                if (calculatedStyle.getPropertyValue('left') == "8px")
                     log("PASSED: Calculated style of inner element is correct");
                 else
-                    log("FAILED: Calculated style of inner element is wrong, should be 'left: auto'");
+                    log("FAILED: Calculated style of inner element is wrong, should be 'left: 8px'");
             }
         
             function runTest() {
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLDialogElement/abspos-dialog-layout-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/HTMLDialogElement/abspos-dialog-layout-expected.txt
index 02101c9c..a6ee007 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/HTMLDialogElement/abspos-dialog-layout-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/dom/HTMLDialogElement/abspos-dialog-layout-expected.txt
@@ -7,9 +7,9 @@
 showModal() should center in the viewport.
 PASS dialog.getBoundingClientRect().top is centeredTop
 
-The computed top and bottom of a centered dialog should still have position auto.
-PASS window.getComputedStyle(dialog).top is "auto"
-PASS window.getComputedStyle(dialog).bottom is "auto"
+The dialog is a positioned element, so the top and bottom should not have style auto.
+PASS window.getComputedStyle(dialog).top is "790px"
+PASS window.getComputedStyle(dialog).bottom is "-210px"
 
 Dialog should be recentered if showModal() is called after close().
 PASS dialog.getBoundingClientRect().top is centeredTop
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLDialogElement/abspos-dialog-layout.html b/third_party/WebKit/LayoutTests/fast/dom/HTMLDialogElement/abspos-dialog-layout.html
index 957197b..e88d8f3 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/HTMLDialogElement/abspos-dialog-layout.html
+++ b/third_party/WebKit/LayoutTests/fast/dom/HTMLDialogElement/abspos-dialog-layout.html
@@ -35,11 +35,14 @@
 }());
 
 (function() {
-    debug('<br>The computed top and bottom of a centered dialog should still have position auto.');
+    debug('<br>The dialog is a positioned element, so the top and bottom should not have style auto.');
 
+    dialog.style.height = '20px';
     dialog.showModal();
-    shouldBeEqualToString('window.getComputedStyle(dialog).top', 'auto');
-    shouldBeEqualToString('window.getComputedStyle(dialog).bottom', 'auto');
+    shouldBeEqualToString('window.getComputedStyle(dialog).top', '790px');
+    shouldBeEqualToString('window.getComputedStyle(dialog).bottom', '-210px');
+
+    dialog.style.height = 'auto';
     reset();
 }());
 
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLDialogElement/fixpos-dialog-layout-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/HTMLDialogElement/fixpos-dialog-layout-expected.txt
index 981152c2..414acbb5 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/HTMLDialogElement/fixpos-dialog-layout-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/dom/HTMLDialogElement/fixpos-dialog-layout-expected.txt
@@ -7,9 +7,9 @@
 showModal() should center in the viewport.
 PASS dialog.getBoundingClientRect().top is centeredTop
 
-The computed top and bottom of a centered dialog should still have position auto.
-PASS window.getComputedStyle(dialog).top is "auto"
-PASS window.getComputedStyle(dialog).bottom is "auto"
+The dialog is a positioned element, so the top and bottom should not have style auto.
+PASS window.getComputedStyle(dialog).top is "290px"
+PASS window.getComputedStyle(dialog).bottom is "290px"
 
 The dialog shold stay centered on scroll.
 PASS dialog.getBoundingClientRect().top is centeredTop
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLDialogElement/fixpos-dialog-layout.html b/third_party/WebKit/LayoutTests/fast/dom/HTMLDialogElement/fixpos-dialog-layout.html
index bab9fe3..b05e74a 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/HTMLDialogElement/fixpos-dialog-layout.html
+++ b/third_party/WebKit/LayoutTests/fast/dom/HTMLDialogElement/fixpos-dialog-layout.html
@@ -40,11 +40,14 @@
 }());
 
 (function() {
-    debug('<br>The computed top and bottom of a centered dialog should still have position auto.');
+    debug('<br>The dialog is a positioned element, so the top and bottom should not have style auto.');
 
+    dialog.style.height = '20px';
     dialog.showModal();
-    shouldBeEqualToString('window.getComputedStyle(dialog).top', 'auto');
-    shouldBeEqualToString('window.getComputedStyle(dialog).bottom', 'auto');
+    shouldBeEqualToString('window.getComputedStyle(dialog).top', '290px');
+    shouldBeEqualToString('window.getComputedStyle(dialog).bottom', '290px');
+
+    dialog.style.height = 'auto';
     reset();
 }());
 
diff --git a/third_party/WebKit/LayoutTests/fast/dom/Range/range-clone-contents-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/Range/range-clone-contents-expected.txt
index 5e5de6c..08930295 100644
--- a/third_party/WebKit/LayoutTests/fast/dom/Range/range-clone-contents-expected.txt
+++ b/third_party/WebKit/LayoutTests/fast/dom/Range/range-clone-contents-expected.txt
@@ -13,7 +13,7 @@
 |     <shadow:root>
 |       <div>
 |         id="alttext-container"
-|         style="overflow: hidden; border: 1px solid silver; display: inline-block; box-sizing: border-box; padding: 1px;"
+|         style="overflow: hidden; border: 1px solid silver; display: inline-block; box-sizing: border-box; padding: 1px; border-radius: inherit;"
 |         <img>
 |           align="left"
 |           height="16"
diff --git a/third_party/WebKit/LayoutTests/fast/dom/custom/custom-elements-registry.html b/third_party/WebKit/LayoutTests/fast/dom/custom/custom-elements-registry.html
new file mode 100644
index 0000000..509762b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/dom/custom/custom-elements-registry.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script>
+test(function () {
+  assert_true('customElements' in window, '"customElements" exists in window');
+  assert_true('define' in window.customElements, '"define" exists in window.customElements');
+}, 'window.customElements.define is defined');
+
+test(function () {
+  assert_throws(null, function () { window.customElements.define(); },
+      '"define" without arguments should throw TypeError');
+  assert_throws(null, function () { window.customElements.define("x-x"); },
+      '"define" with one argument should throw TypeError');
+
+  window.customElements.define('x-empty-function', function () { });
+  window.customElements.define('x-empty-class', class { });
+
+}, 'window.customElements.define requires two arguments');
+</script>
diff --git a/third_party/WebKit/LayoutTests/hittesting/border-hittest-with-image-fallback.html b/third_party/WebKit/LayoutTests/hittesting/border-hittest-with-image-fallback.html
new file mode 100644
index 0000000..e70e6685
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/hittesting/border-hittest-with-image-fallback.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<style>
+img {
+    background-color:red;
+    border-radius: 50px;
+}
+</style>
+<body>
+<img id="roundedImg" src="none" width="100px" height="100px" />
+<div id="log"></div>
+</body>
+<script>
+test(function(t)
+{
+    var element = document.getElementById("roundedImg");
+    var x = element.offsetLeft + element.offsetWidth - 2;
+    var y = element.offsetTop + element.offsetHeight - 2;
+
+    var element = document.elementFromPoint(x, y);
+    assert_equals(element.nodeName, 'BODY');
+}, "elementFromPoint should return an element under a point that is clipped to a border-radius");
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/hittesting/hittest-child-of-inlineblock.html b/third_party/WebKit/LayoutTests/hittesting/hittest-child-of-inlineblock.html
new file mode 100644
index 0000000..97416fa
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/hittesting/hittest-child-of-inlineblock.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<style>
+#roundedDiv {
+    width: 200px;
+    height: 200px;
+    border-radius: 5px;
+    border: 5px solid transparent;
+    display: inline-block;
+}
+#roundedDivChild {
+    width: 200px;
+    height: 100px;
+    margin-left: 400px;
+}
+</style>
+<div id="roundedDiv">
+<div id="roundedDivChild">Mouse over me!<br>The box should turn green.</div>
+</div>
+<div id="log"></div>
+<script>
+test(function(t)
+{
+    var element = document.getElementById("roundedDivChild");
+    var x = element.offsetLeft + element.offsetWidth / 2;
+    var y = element.offsetTop + element.offsetHeight / 2;
+
+    var element = document.elementFromPoint(x, y);
+    assert_equals(element.nodeName, 'DIV');
+    assert_equals(element.id, 'roundedDivChild');
+}, "elementFromPoint should return an element under a point");
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/hittesting/hittest-inline-block-with-abspos.html b/third_party/WebKit/LayoutTests/hittesting/hittest-inline-block-with-abspos.html
new file mode 100644
index 0000000..705ce69f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/hittesting/hittest-inline-block-with-abspos.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<style>
+#abs {
+    position: absolute;
+    top: 0px;
+    left: 0px;
+    visibility: hidden;
+}
+#abs-inner {
+    width: 96px;
+    height: 96px;
+    display: inline-block;
+    border-radius: 50%;
+}
+</style>
+<span id="inner"> Mouse over me! </span>
+<div id="abs"><div id="abs-inner"></div></div>
+<div id="log"></div>
+<script>
+test(function(t)
+{
+    var element = document.getElementById("inner");
+    var x = element.offsetLeft + element.offsetWidth / 2;
+    var y = element.offsetTop + element.offsetHeight / 2;
+
+    var element = document.elementFromPoint(x, y);
+    assert_equals(element.nodeName, 'SPAN');
+    assert_equals(element.id, 'inner');
+}, "elementFromPoint should return an visible element under a point");
+</script>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/http/tests/origin_trials/resources/origin_trials.js b/third_party/WebKit/LayoutTests/http/tests/origin_trials/resources/origin_trials.js
index 08773cc..693cde9 100644
--- a/third_party/WebKit/LayoutTests/http/tests/origin_trials/resources/origin_trials.js
+++ b/third_party/WebKit/LayoutTests/http/tests/origin_trials/resources/origin_trials.js
@@ -1,22 +1,35 @@
 // The sample API integrates origin trial checks at various entry points.
 
 // These tests verify that any gated parts of the API are not available.
-expect_failure = () => {
-test(() => {
-    assert_idl_attribute(window.internals, 'frobulate');
-    assert_throws("NotSupportedError", () => { window.internals.frobulate; },
-       'Accessing attribute should throw error');
-  }, 'Attribute should throw API unavailable error');
+expect_failure = (t) => {
+  tests = [{
+    desc: 'Accessing attribute should throw error',
+    code: () => {
+        assert_idl_attribute(window.internals, 'frobulate');
+        assert_throws("NotSupportedError", () => { window.internals.frobulate; },
+            'Accessing attribute should throw error');
+      }
+  }, {
+    desc: 'Attribute should exist and return value, with trial disabled',
+    code: () => {
+        assert_idl_attribute(window.internals, 'frobulateNoEnabledCheck');
+        assert_true(window.internals.frobulateNoEnabledCheck,
+            'Attribute should return boolean value');
+      }
+  }, {
+    desc: 'Attribute should not exist, with trial disabled',
+    code: () => {
+        assert_not_exists(window.internals, 'frobulateBindings');
+        assert_equals(window.internals['frobulateBindings'], undefined);
+      }
+  }];
 
-test(() => {
-    assert_idl_attribute(window.internals, 'frobulateNoEnabledCheck');
-    assert_true(window.internals.frobulateNoEnabledCheck,
-        'Attribute should return boolean value');
-  }, 'Attribute should exist and return value, with trial disabled');
-
-test(() => {
-    assert_not_exists(window.internals, 'frobulateBindings');
-  }, 'Attribute should not exist, with trial disabled');
+  for (var i = 0; i < tests.length; ++i) {
+    if (t)
+      t.step(tests[i].code);
+    else
+      test(tests[i].code, tests[i].desc);
+  }
 };
 
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-request-css-cross-origin-mime-check.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-request-css-cross-origin-mime-check.html
new file mode 100644
index 0000000..c53f470
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/fetch-request-css-cross-origin-mime-check.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<title>Service Worker: Mime type checking of CSS files fetched via SW.</title>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<script src="../resources/get-host-info.js?pipe=sub"></script>
+<script src="resources/test-helpers.js"></script>
+<script>
+
+function getElementColorInFrame(frame, id) {
+  var element = frame.contentDocument.getElementById(id);
+  var style = frame.contentWindow.getComputedStyle(element, '');
+  return style['color'];
+}
+
+promise_test(function(t) {
+    var SCOPE =
+        'resources/fetch-request-css-cross-origin-mime-check-iframe.html';
+    var SCRIPT =
+        'resources/fetch-request-css-cross-origin-mime-check-worker.js';
+    var EXPECTED_COLOR = 'rgb(0, 0, 255)';
+
+    return service_worker_unregister_and_register(t, SCRIPT, SCOPE)
+      .then(r => wait_for_state(t, r.installing, 'activated'))
+      .then(_ => with_iframe(SCOPE) )
+      .then(f => {
+          assert_equals(
+              getElementColorInFrame(f, 'crossOriginCss'),
+              EXPECTED_COLOR,
+              'The color must be overridden by cross origin CSS.');
+          assert_equals(
+              getElementColorInFrame(f, 'crossOriginHtml'),
+              EXPECTED_COLOR,
+              'The color must not be overridden by cross origin non CSS file.');
+          assert_equals(
+              getElementColorInFrame(f, 'sameOriginCss'),
+              EXPECTED_COLOR,
+              'The color must be overridden by same origin CSS.');
+          assert_equals(
+              getElementColorInFrame(f, 'sameOriginHtml'),
+              EXPECTED_COLOR,
+              'The color must be overridden by same origin non CSS file.');
+          assert_equals(
+              getElementColorInFrame(f, 'synthetic'),
+              EXPECTED_COLOR,
+              'The color must be overridden by synthetic CSS.');
+          f.remove();
+          return service_worker_unregister_and_done(t, SCOPE);
+        });
+  }, 'Mime type checking of CSS files fetched via SW.');
+</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-css-cross-origin-mime-check-cross.css b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-css-cross-origin-mime-check-cross.css
new file mode 100644
index 0000000..9a7545d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-css-cross-origin-mime-check-cross.css
@@ -0,0 +1 @@
+#crossOriginCss { color: blue; }
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-css-cross-origin-mime-check-cross.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-css-cross-origin-mime-check-cross.html
new file mode 100644
index 0000000..3211f78
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-css-cross-origin-mime-check-cross.html
@@ -0,0 +1 @@
+#crossOriginHtml { color: red; }
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-css-cross-origin-mime-check-iframe.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-css-cross-origin-mime-check-iframe.html
new file mode 100644
index 0000000..dcb8287
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-css-cross-origin-mime-check-iframe.html
@@ -0,0 +1,17 @@
+<style type="text/css">
+#crossOriginCss { color: red; }
+#crossOriginHtml { color: blue; }
+#sameOriginCss { color: red; }
+#sameOriginHtml { color: red; }
+#synthetic { color: red; }
+</style>
+<link href="./cross-origin-css.css" rel="stylesheet" type="text/css">
+<link href="./cross-origin-html.css" rel="stylesheet" type="text/css">
+<link href="./fetch-request-css-cross-origin-mime-check-same.css" rel="stylesheet" type="text/css">
+<link href="./fetch-request-css-cross-origin-mime-check-same.html" rel="stylesheet" type="text/css">
+<link href="./synthetic.css" rel="stylesheet" type="text/css">
+<h1 id=crossOriginCss>I should be blue</h1>
+<h1 id=crossOriginHtml>I should be blue</h1>
+<h1 id=sameOriginCss>I should be blue</h1>
+<h1 id=sameOriginHtml>I should be blue</h1>
+<h1 id=synthetic>I should be blue</h1>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-css-cross-origin-mime-check-same.css b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-css-cross-origin-mime-check-same.css
new file mode 100644
index 0000000..55455bd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-css-cross-origin-mime-check-same.css
@@ -0,0 +1 @@
+#sameOriginCss { color: blue; }
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-css-cross-origin-mime-check-same.html b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-css-cross-origin-mime-check-same.html
new file mode 100644
index 0000000..6fad4b9f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-css-cross-origin-mime-check-same.html
@@ -0,0 +1 @@
+#sameOriginHtml { color: blue; }
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-css-cross-origin-mime-check-worker.js b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-css-cross-origin-mime-check-worker.js
new file mode 100644
index 0000000..96c1447
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/resources/fetch-request-css-cross-origin-mime-check-worker.js
@@ -0,0 +1,20 @@
+importScripts('../../resources/get-host-info.js');
+importScripts('test-helpers.js');
+
+self.addEventListener('fetch', function(event) {
+    if (event.request.url.indexOf('cross-origin-css.css') != -1) {
+      event.respondWith(fetch(
+          get_host_info()['HTTP_REMOTE_ORIGIN'] + base_path() +
+          'fetch-request-css-cross-origin-mime-check-cross.css',
+          {mode: 'no-cors'}));
+    } else if (event.request.url.indexOf('cross-origin-html.css') != -1) {
+      event.respondWith(fetch(
+          get_host_info()['HTTP_REMOTE_ORIGIN'] + base_path() +
+          'fetch-request-css-cross-origin-mime-check-cross.html',
+          {mode: 'no-cors'}));
+    } else if (event.request.url.indexOf('synthetic.css') != -1) {
+      event.respondWith(new Response("#synthetic { color: blue; }"));
+    } else {
+      event.respondWith(fetch(event.request));
+    }
+  });
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
index 57987d9..30984411 100644
--- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -774,6 +774,10 @@
     getter type
     getter usages
     method constructor
+interface CustomElementsRegistry
+    attribute @@toStringTag
+    method constructor
+    method define
 interface CustomEvent : Event
     attribute @@toStringTag
     getter detail
@@ -7418,6 +7422,7 @@
     attribute closed
     attribute console
     attribute crypto
+    attribute customElements
     attribute defaultStatus
     attribute defaultstatus
     attribute devicePixelRatio
diff --git a/third_party/WebKit/Source/build/scripts/templates/OriginTrials.cpp.tmpl b/third_party/WebKit/Source/build/scripts/templates/OriginTrials.cpp.tmpl
index 3b20ec1..5201faf 100644
--- a/third_party/WebKit/Source/build/scripts/templates/OriginTrials.cpp.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/OriginTrials.cpp.tmpl
@@ -3,63 +3,40 @@
 
 #include "core/origin_trials/OriginTrials.h"
 
-#include "core/dom/ExecutionContext.h"
 #include "core/origin_trials/OriginTrialContext.h"
 #include "platform/RuntimeEnabledFeatures.h"
 
 namespace blink {
 
-OriginTrials::OriginTrials(RawPtr<OriginTrialContext> originTrialContext)
-    : m_originTrialContext(originTrialContext) {}
-
-// static
-const char* OriginTrials::supplementName()
-{
-   return "OriginTrials";
-}
-
-// static
-OriginTrials* OriginTrials::from(ExecutionContext* host)
-{
-    OriginTrials* originTrials = static_cast<OriginTrials*>(Supplement<ExecutionContext>::from(host, supplementName()));
-    if (!originTrials) {
-        originTrials = new OriginTrials(host->createOriginTrialContext());
-        Supplement<ExecutionContext>::provideTo(*host, supplementName(), originTrials);
-    }
-    return originTrials;
-}
+namespace {
 
 {% for feature in features %}
 {% if feature.origin_trial_feature_name %}
 
-// static
-bool OriginTrials::{{feature.first_lowered_name}}Enabled(ExecutionContext* executionContext, String& errorMessage) {
-    return OriginTrials::from(executionContext)->{{feature.first_lowered_name}}EnabledImpl(&errorMessage);
-}
-
-// static
-bool OriginTrials::{{feature.first_lowered_name}}Enabled(ExecutionContext* executionContext) {
-    return OriginTrials::from(executionContext)->{{feature.first_lowered_name}}EnabledImpl(nullptr);
-}
-
-{% endif %}
-{% endfor %}
-
-{% for feature in features %}
-{% if feature.origin_trial_feature_name %}
-
-bool OriginTrials::{{feature.first_lowered_name}}EnabledImpl(String* errorMessage) {
+bool {{feature.first_lowered_name}}EnabledImpl(ExecutionContext* executionContext, String* errorMessage) {
     if (RuntimeEnabledFeatures::{{feature.first_lowered_name}}Enabled())
         return true;
-    if (!m_originTrialContext) return false;
-    return m_originTrialContext->isFeatureEnabled("{{feature.origin_trial_feature_name}}", errorMessage);
+    OriginTrialContext* context = OriginTrialContext::from(executionContext);
+    return context->isFeatureEnabled("{{feature.origin_trial_feature_name}}", errorMessage);
 }
+
 {% endif %}
 {% endfor %}
 
-DEFINE_TRACE(OriginTrials)
-{
-    visitor->trace(m_originTrialContext);
-    Supplement<ExecutionContext>::trace(visitor);
+} // namespace
+
+{% for feature in features %}
+{% if feature.origin_trial_feature_name %}
+
+bool OriginTrials::{{feature.first_lowered_name}}Enabled(ExecutionContext* executionContext, String& errorMessage) {
+    return {{feature.first_lowered_name}}EnabledImpl(executionContext, &errorMessage);
 }
+
+bool OriginTrials::{{feature.first_lowered_name}}Enabled(ExecutionContext* executionContext) {
+    return {{feature.first_lowered_name}}EnabledImpl(executionContext, nullptr);
+}
+
+{% endif %}
+{% endfor %}
+
 } // namespace blink
diff --git a/third_party/WebKit/Source/build/scripts/templates/OriginTrials.h.tmpl b/third_party/WebKit/Source/build/scripts/templates/OriginTrials.h.tmpl
index a5817b6..62f17339 100644
--- a/third_party/WebKit/Source/build/scripts/templates/OriginTrials.h.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/OriginTrials.h.tmpl
@@ -5,44 +5,22 @@
 #define OriginTrials_h
 
 #include "core/CoreExport.h"
-#include "platform/Supplementable.h"
 #include "wtf/text/WTFString.h"
 
 namespace blink {
 
 class ExecutionContext;
-class OriginTrialContext;
 
-// A class that stores dynamic tests for experimental features which can be
-// enabled through the experimental framework via API keys.
-
-class CORE_EXPORT OriginTrials final : public GarbageCollected<OriginTrials>, public Supplement<ExecutionContext> {
-    USING_GARBAGE_COLLECTED_MIXIN(OriginTrials);
-public:
-    OriginTrials(RawPtr<OriginTrialContext>);
-
-    static const char* supplementName();
-    static OriginTrials* from(ExecutionContext*);
-
+// A namespace with dynamic tests for experimental features which can be enabled through the
+// experimental framework via origin trial tokens.
+namespace OriginTrials {
     {% for feature in features %}
     {% if feature.origin_trial_feature_name %}
-
-    static bool {{feature.first_lowered_name}}Enabled(ExecutionContext* executionContext, String& errorMessage);
-    static bool {{feature.first_lowered_name}}Enabled(ExecutionContext* executionContext);
+    CORE_EXPORT bool {{feature.first_lowered_name}}Enabled(ExecutionContext*, String& errorMessage);
+    CORE_EXPORT bool {{feature.first_lowered_name}}Enabled(ExecutionContext*);
     {% endif %}
     {% endfor %}
-
-    DECLARE_TRACE();
-
-private:
-    {% for feature in features %}
-    {% if feature.origin_trial_feature_name %}
-    bool {{feature.first_lowered_name}}EnabledImpl(String* errorMessage);
-    {% endif %}
-    {% endfor %}
-
-    Member<OriginTrialContext> m_originTrialContext;
-};
+} // namespace OriginTrials
 
 } // namespace blink
 
diff --git a/third_party/WebKit/Source/core/core.gypi b/third_party/WebKit/Source/core/core.gypi
index 012fd4210..9bfe9d6 100644
--- a/third_party/WebKit/Source/core/core.gypi
+++ b/third_party/WebKit/Source/core/core.gypi
@@ -115,6 +115,7 @@
             'dom/Uint8ClampedArray.idl',
             'dom/URLSearchParams.idl',
             'dom/XMLDocument.idl',
+            'dom/custom/CustomElementsRegistry.idl',
             'dom/shadow/ShadowRoot.idl',
             'editing/Selection.idl',
             'events/AnimationEvent.idl',
@@ -1940,8 +1941,6 @@
             'loader/appcache/ApplicationCache.h',
             'loader/appcache/ApplicationCacheHost.cpp',
             'loader/appcache/ApplicationCacheHost.h',
-            'origin_trials/DocumentOriginTrialContext.cpp',
-            'origin_trials/DocumentOriginTrialContext.h',
             'origin_trials/OriginTrialContext.cpp',
             'origin_trials/OriginTrialContext.h',
             'page/AutoscrollController.cpp',
@@ -2655,6 +2654,8 @@
             'dom/custom/CustomElementSyncMicrotaskQueue.h',
             'dom/custom/CustomElementUpgradeCandidateMap.cpp',
             'dom/custom/CustomElementUpgradeCandidateMap.h',
+            'dom/custom/CustomElementsRegistry.cpp',
+            'dom/custom/CustomElementsRegistry.h',
             'dom/shadow/DistributedNodes.cpp',
             'dom/shadow/DistributedNodes.h',
             'dom/shadow/ElementShadow.cpp',
@@ -4051,6 +4052,7 @@
             'layout/PaginationTest.cpp',
             'layout/PaintContainmentTest.cpp',
             'layout/ScrollAnchorTest.cpp',
+            'layout/VisualRectMappingTest.cpp',
             'layout/compositing/CompositedLayerMappingTest.cpp',
             'layout/shapes/BoxShapeTest.cpp',
             'layout/svg/LayoutSVGRootTest.cpp',
@@ -4061,7 +4063,6 @@
             'loader/MixedContentCheckerTest.cpp',
             'loader/TextResourceDecoderBuilderTest.cpp',
             'loader/ThreadableLoaderTest.cpp',
-            'origin_trials/DocumentOriginTrialContextTest.cpp',
             'origin_trials/OriginTrialContextTest.cpp',
             'page/ChromeClientTest.cpp',
             'page/ContextMenuControllerTest.cpp',
diff --git a/third_party/WebKit/Source/core/css/CSSStyleSheetResourceTest.cpp b/third_party/WebKit/Source/core/css/CSSStyleSheetResourceTest.cpp
index 2497f35..778198d 100644
--- a/third_party/WebKit/Source/core/css/CSSStyleSheetResourceTest.cpp
+++ b/third_party/WebKit/Source/core/css/CSSStyleSheetResourceTest.cpp
@@ -29,7 +29,6 @@
 #include "platform/weborigin/KURL.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebURLResponse.h"
-#include "public/platform/WebUnitTestSupport.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "wtf/RefPtr.h"
 #include "wtf/text/WTFString.h"
diff --git a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
index 098c11f..bcb26d9 100644
--- a/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
+++ b/third_party/WebKit/Source/core/css/ComputedStyleCSSValueMapping.cpp
@@ -162,19 +162,23 @@
 
 static RawPtr<CSSValue> valueForPositionOffset(const ComputedStyle& style, CSSPropertyID propertyID, const LayoutObject* layoutObject)
 {
-    Length offset;
+    Length offset, opposite;
     switch (propertyID) {
     case CSSPropertyLeft:
         offset = style.left();
+        opposite = style.right();
         break;
     case CSSPropertyRight:
         offset = style.right();
+        opposite = style.left();
         break;
     case CSSPropertyTop:
         offset = style.top();
+        opposite = style.bottom();
         break;
     case CSSPropertyBottom:
         offset = style.bottom();
+        opposite = style.top();
         break;
     default:
         return nullptr;
@@ -186,13 +190,63 @@
             toLayoutBox(layoutObject)->containingBlockLogicalHeightForGetComputedStyle();
         return zoomAdjustedPixelValue(valueForLength(offset, containingBlockSize), style);
     }
-    if (offset.isAuto()) {
-        // FIXME: It's not enough to simply return "auto" values for one offset if the other side is defined.
-        // In other words if left is auto and right is not auto, then left's computed value is negative right().
-        // So we should get the opposite length unit and see if it is auto.
-        return cssValuePool().createIdentifierValue(CSSValueAuto);
+
+    if (offset.isAuto() && layoutObject) {
+        // If the property applies to a positioned element and the resolved value of the display
+        // property is not none, the resolved value is the used value.
+        if (layoutObject->isInFlowPositioned()) {
+            // If e.g. left is auto and right is not auto, then left's computed value is negative right.
+            // So we get the opposite length unit and see if it is auto.
+            if (opposite.isAuto())
+                return cssValuePool().createValue(0, CSSPrimitiveValue::UnitType::Pixels);
+
+            if (opposite.hasPercent()) {
+                LayoutUnit containingBlockSize =
+                    (propertyID == CSSPropertyLeft || propertyID == CSSPropertyRight) ?
+                    toLayoutBox(layoutObject)->containingBlockLogicalWidthForContent() :
+                    toLayoutBox(layoutObject)->containingBlockLogicalHeightForGetComputedStyle();
+                return zoomAdjustedPixelValue(-floatValueForLength(opposite, containingBlockSize), style);
+            }
+            return zoomAdjustedPixelValue(-opposite.pixels(), style);
+        }
+
+        if (layoutObject->isOutOfFlowPositioned()) {
+            // For fixed and absolute positioned elements, the top, left, bottom, and right
+            // are defined relative to the corresponding sides of the containing block.
+            LayoutBlock* container = layoutObject->containingBlock();
+            const LayoutBox* layoutBox = toLayoutBox(layoutObject);
+
+            // clientOffset is the distance from this object's border edge to the container's
+            // padding edge. Thus it includes margins which we subtract below.
+            const LayoutSize clientOffset =
+                layoutBox->locationOffset() - LayoutSize(container->clientLeft(), container->clientTop());
+            LayoutUnit position;
+
+            switch (propertyID) {
+            case CSSPropertyLeft:
+                position = clientOffset.width() - layoutBox->marginLeft();
+                break;
+            case CSSPropertyTop:
+                position = clientOffset.height() - layoutBox->marginTop();
+                break;
+            case CSSPropertyRight:
+                position = container->clientWidth() - layoutBox->marginRight() -
+                    (layoutBox->offsetWidth() + clientOffset.width());
+                break;
+            case CSSPropertyBottom:
+                position = container->clientHeight() - layoutBox->marginBottom() -
+                    (layoutBox->offsetHeight() + clientOffset.height());
+                break;
+            default:
+                ASSERT_NOT_REACHED();
+            }
+            return zoomAdjustedPixelValue(position, style);
+        }
     }
 
+    if (offset.isAuto())
+        return cssValuePool().createIdentifierValue(CSSValueAuto);
+
     return zoomAdjustedPixelValueForLength(offset, style);
 }
 
diff --git a/third_party/WebKit/Source/core/css/StyleSheetContents.cpp b/third_party/WebKit/Source/core/css/StyleSheetContents.cpp
index f60e9286..7c7dd2e8 100644
--- a/third_party/WebKit/Source/core/css/StyleSheetContents.cpp
+++ b/third_party/WebKit/Source/core/css/StyleSheetContents.cpp
@@ -322,6 +322,16 @@
     TRACE_EVENT1("blink,devtools.timeline", "ParseAuthorStyleSheet", "data", InspectorParseAuthorStyleSheetEvent::data(cachedStyleSheet));
 
     bool isSameOriginRequest = securityOrigin && securityOrigin->canRequest(baseURL());
+
+    // When the response was fetched via the Service Worker, the original URL may not be same as the base URL.
+    // TODO(horo): When we will use the original URL as the base URL, we can remove this check. crbug.com/553535
+    if (cachedStyleSheet->response().wasFetchedViaServiceWorker()) {
+        const KURL originalURL(cachedStyleSheet->response().originalURLViaServiceWorker());
+        // |originalURL| is empty when the response is created in the SW.
+        if (!originalURL.isEmpty() && !securityOrigin->canRequest(originalURL))
+            isSameOriginRequest = false;
+    }
+
     CSSStyleSheetResource::MIMETypeCheck mimeTypeCheck = isQuirksModeBehavior(m_parserContext.mode()) && isSameOriginRequest ? CSSStyleSheetResource::MIMETypeCheck::Lax : CSSStyleSheetResource::MIMETypeCheck::Strict;
     String sheetText = cachedStyleSheet->sheetText(mimeTypeCheck);
 
diff --git a/third_party/WebKit/Source/core/dom/CSSSelectorWatch.h b/third_party/WebKit/Source/core/dom/CSSSelectorWatch.h
index de4b0a9..00e7b22 100644
--- a/third_party/WebKit/Source/core/dom/CSSSelectorWatch.h
+++ b/third_party/WebKit/Source/core/dom/CSSSelectorWatch.h
@@ -37,7 +37,6 @@
 #include "platform/Timer.h"
 #include "wtf/HashCountedSet.h"
 #include "wtf/HashSet.h"
-#include "wtf/RefPtr.h"
 #include "wtf/Vector.h"
 #include "wtf/text/WTFString.h"
 
diff --git a/third_party/WebKit/Source/core/dom/ChildNodeList.h b/third_party/WebKit/Source/core/dom/ChildNodeList.h
index 8423bd25..4f77ec29 100644
--- a/third_party/WebKit/Source/core/dom/ChildNodeList.h
+++ b/third_party/WebKit/Source/core/dom/ChildNodeList.h
@@ -28,7 +28,6 @@
 #include "core/dom/ContainerNode.h"
 #include "core/dom/NodeList.h"
 #include "core/html/CollectionIndexCache.h"
-#include "wtf/PassRefPtr.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/dom/CompositorProxy.h b/third_party/WebKit/Source/core/dom/CompositorProxy.h
index 18a9d74..cbf9766 100644
--- a/third_party/WebKit/Source/core/dom/CompositorProxy.h
+++ b/third_party/WebKit/Source/core/dom/CompositorProxy.h
@@ -9,9 +9,6 @@
 #include "core/dom/DOMMatrix.h"
 #include "core/dom/Element.h"
 #include "platform/heap/Handle.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
 #include "wtf/text/WTFString.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/dom/CrossThreadTask.h b/third_party/WebKit/Source/core/dom/CrossThreadTask.h
index 0e032a8b..45cf03d 100644
--- a/third_party/WebKit/Source/core/dom/CrossThreadTask.h
+++ b/third_party/WebKit/Source/core/dom/CrossThreadTask.h
@@ -35,7 +35,6 @@
 #include "core/dom/ExecutionContextTask.h"
 #include "platform/ThreadSafeFunctional.h"
 #include "wtf/PassOwnPtr.h"
-#include "wtf/PassRefPtr.h"
 #include <type_traits>
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/dom/DOMImplementation.h b/third_party/WebKit/Source/core/dom/DOMImplementation.h
index be6c45c..542e6eb 100644
--- a/third_party/WebKit/Source/core/dom/DOMImplementation.h
+++ b/third_party/WebKit/Source/core/dom/DOMImplementation.h
@@ -26,7 +26,6 @@
 
 #include "core/CoreExport.h"
 #include "core/dom/Document.h"
-#include "wtf/PassRefPtr.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index f023d23a..1f7d4b98 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -186,7 +186,6 @@
 #include "core/loader/ImageLoader.h"
 #include "core/loader/NavigationScheduler.h"
 #include "core/loader/appcache/ApplicationCacheHost.h"
-#include "core/origin_trials/DocumentOriginTrialContext.h"
 #include "core/page/ChromeClient.h"
 #include "core/page/EventWithHitTestResults.h"
 #include "core/page/FocusController.h"
@@ -5969,11 +5968,6 @@
         frame()->loader().client()->didEnforceStrictMixedContentChecking();
 }
 
-RawPtr<OriginTrialContext> Document::createOriginTrialContext()
-{
-    return new DocumentOriginTrialContext(this);
-}
-
 LayoutViewItem Document::layoutViewItem() const
 {
     return LayoutViewItem(m_layoutView);
diff --git a/third_party/WebKit/Source/core/dom/Document.h b/third_party/WebKit/Source/core/dom/Document.h
index 3eb62fdb..00a9dc0 100644
--- a/third_party/WebKit/Source/core/dom/Document.h
+++ b/third_party/WebKit/Source/core/dom/Document.h
@@ -142,7 +142,6 @@
 class NodeIterator;
 class NthIndexCache;
 class OriginAccessEntry;
-class OriginTrialContext;
 class Page;
 class PlatformMouseEvent;
 class ProcessingInstruction;
@@ -1080,7 +1079,6 @@
     ParserSynchronizationPolicy getParserSynchronizationPolicy() const { return m_parserSyncPolicy; }
 
 private:
-    friend class DocumentOriginTrialContextTest;
     friend class IgnoreDestructiveWriteCountIncrementer;
     friend class NthIndexCache;
 
@@ -1164,8 +1162,6 @@
 
     const OriginAccessEntry& accessEntryFromURL();
 
-    RawPtr<OriginTrialContext> createOriginTrialContext() override;
-
     DocumentLifecycle m_lifecycle;
 
     bool m_hasNodesWithPlaceholderStyle;
diff --git a/third_party/WebKit/Source/core/dom/DocumentInit.h b/third_party/WebKit/Source/core/dom/DocumentInit.h
index 36d21d7..2dccc56 100644
--- a/third_party/WebKit/Source/core/dom/DocumentInit.h
+++ b/third_party/WebKit/Source/core/dom/DocumentInit.h
@@ -34,8 +34,6 @@
 #include "core/dom/custom/CustomElementRegistrationContext.h"
 #include "platform/heap/Handle.h"
 #include "platform/weborigin/KURL.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefPtr.h"
 #include "wtf/WeakPtr.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollector.h b/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollector.h
index 61ab31f..e3998f9 100644
--- a/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollector.h
+++ b/third_party/WebKit/Source/core/dom/DocumentStyleSheetCollector.h
@@ -29,7 +29,6 @@
 
 #include "platform/heap/Handle.h"
 #include "wtf/HashSet.h"
-#include "wtf/RefPtr.h"
 #include "wtf/Vector.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/dom/ElementDataCache.h b/third_party/WebKit/Source/core/dom/ElementDataCache.h
index 5d15f8ba..20d6f5c5 100644
--- a/third_party/WebKit/Source/core/dom/ElementDataCache.h
+++ b/third_party/WebKit/Source/core/dom/ElementDataCache.h
@@ -29,9 +29,6 @@
 
 #include "platform/heap/Handle.h"
 #include "wtf/HashMap.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefPtr.h"
 #include "wtf/Vector.h"
 #include "wtf/text/StringHash.h"
 
diff --git a/third_party/WebKit/Source/core/dom/EmptyNodeList.h b/third_party/WebKit/Source/core/dom/EmptyNodeList.h
index c82a24f..13ef180b4 100644
--- a/third_party/WebKit/Source/core/dom/EmptyNodeList.h
+++ b/third_party/WebKit/Source/core/dom/EmptyNodeList.h
@@ -33,7 +33,6 @@
 #define EmptyNodeList_h
 
 #include "core/dom/NodeList.h"
-#include "wtf/RefPtr.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/dom/ExecutionContext.cpp b/third_party/WebKit/Source/core/dom/ExecutionContext.cpp
index 391f391..a190bcd 100644
--- a/third_party/WebKit/Source/core/dom/ExecutionContext.cpp
+++ b/third_party/WebKit/Source/core/dom/ExecutionContext.cpp
@@ -35,7 +35,6 @@
 #include "core/frame/UseCounter.h"
 #include "core/html/PublicURLManager.h"
 #include "core/inspector/InspectorInstrumentation.h"
-#include "core/origin_trials/OriginTrialContext.h"
 #include "core/workers/WorkerGlobalScope.h"
 #include "core/workers/WorkerThread.h"
 
@@ -269,11 +268,6 @@
     m_referrerPolicy = referrerPolicy;
 }
 
-RawPtr<OriginTrialContext> ExecutionContext::createOriginTrialContext()
-{
-    return nullptr;
-}
-
 void ExecutionContext::removeURLFromMemoryCache(const KURL& url)
 {
     memoryCache()->removeURLFromCache(url);
diff --git a/third_party/WebKit/Source/core/dom/ExecutionContext.h b/third_party/WebKit/Source/core/dom/ExecutionContext.h
index 7d445f9..c767839 100644
--- a/third_party/WebKit/Source/core/dom/ExecutionContext.h
+++ b/third_party/WebKit/Source/core/dom/ExecutionContext.h
@@ -53,7 +53,6 @@
 class EventTarget;
 class ExecutionContextTask;
 class LocalDOMWindow;
-class OriginTrialContext;
 class PublicURLManager;
 class SecurityOrigin;
 class ScriptCallStack;
@@ -157,9 +156,6 @@
     void setReferrerPolicy(ReferrerPolicy);
     ReferrerPolicy getReferrerPolicy() const { return m_referrerPolicy; }
 
-    // Override to enable experimental features through origin trials
-    virtual RawPtr<OriginTrialContext> createOriginTrialContext();
-
 protected:
     ExecutionContext();
     virtual ~ExecutionContext();
diff --git a/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.h b/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.h
index 029d2ee..43e971d 100644
--- a/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.h
+++ b/third_party/WebKit/Source/core/dom/IncrementLoadEventDelayCount.h
@@ -8,7 +8,6 @@
 #include "platform/heap/Handle.h"
 #include "wtf/Allocator.h"
 #include "wtf/Noncopyable.h"
-#include "wtf/RefPtr.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/dom/LiveNodeList.h b/third_party/WebKit/Source/core/dom/LiveNodeList.h
index fa483d08..e1ce748 100644
--- a/third_party/WebKit/Source/core/dom/LiveNodeList.h
+++ b/third_party/WebKit/Source/core/dom/LiveNodeList.h
@@ -29,7 +29,6 @@
 #include "core/html/CollectionItemsCache.h"
 #include "core/html/CollectionType.h"
 #include "platform/heap/Handle.h"
-#include "wtf/PassRefPtr.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/dom/MessageChannel.h b/third_party/WebKit/Source/core/dom/MessageChannel.h
index 353e974..377356eb 100644
--- a/third_party/WebKit/Source/core/dom/MessageChannel.h
+++ b/third_party/WebKit/Source/core/dom/MessageChannel.h
@@ -29,7 +29,6 @@
 
 #include "bindings/core/v8/ScriptWrappable.h"
 #include "platform/heap/Handle.h"
-#include "wtf/RefPtr.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/dom/MutationCallback.h b/third_party/WebKit/Source/core/dom/MutationCallback.h
index 9102a4f5..28cebe3c 100644
--- a/third_party/WebKit/Source/core/dom/MutationCallback.h
+++ b/third_party/WebKit/Source/core/dom/MutationCallback.h
@@ -32,7 +32,6 @@
 #define MutationCallback_h
 
 #include "platform/heap/Handle.h"
-#include "wtf/RefPtr.h"
 #include "wtf/Vector.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/dom/MutationObserver.h b/third_party/WebKit/Source/core/dom/MutationObserver.h
index 698863e..347692c 100644
--- a/third_party/WebKit/Source/core/dom/MutationObserver.h
+++ b/third_party/WebKit/Source/core/dom/MutationObserver.h
@@ -34,10 +34,6 @@
 #include "bindings/core/v8/ScriptWrappable.h"
 #include "platform/heap/Handle.h"
 #include "wtf/HashSet.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
-#include "wtf/RefPtr.h"
 #include "wtf/Vector.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/dom/MutationRecord.h b/third_party/WebKit/Source/core/dom/MutationRecord.h
index 4196483..b0b9d03 100644
--- a/third_party/WebKit/Source/core/dom/MutationRecord.h
+++ b/third_party/WebKit/Source/core/dom/MutationRecord.h
@@ -33,8 +33,6 @@
 
 #include "bindings/core/v8/ScriptWrappable.h"
 #include "platform/heap/Handle.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
 #include "wtf/text/WTFString.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/dom/NamedNodeMap.h b/third_party/WebKit/Source/core/dom/NamedNodeMap.h
index e4e9769..ce3634e 100644
--- a/third_party/WebKit/Source/core/dom/NamedNodeMap.h
+++ b/third_party/WebKit/Source/core/dom/NamedNodeMap.h
@@ -27,8 +27,6 @@
 
 #include "bindings/core/v8/ScriptWrappable.h"
 #include "core/dom/Element.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/PassRefPtr.h"
 #include "wtf/text/AtomicString.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/dom/NodeFilter.h b/third_party/WebKit/Source/core/dom/NodeFilter.h
index 9afd9d7..ec42d83 100644
--- a/third_party/WebKit/Source/core/dom/NodeFilter.h
+++ b/third_party/WebKit/Source/core/dom/NodeFilter.h
@@ -28,7 +28,6 @@
 #include "bindings/core/v8/ScriptWrappable.h"
 #include "core/dom/NodeFilterCondition.h"
 #include "platform/heap/Handle.h"
-#include "wtf/RefPtr.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/dom/NodeIterator.h b/third_party/WebKit/Source/core/dom/NodeIterator.h
index 6c6e4163..ec5826e 100644
--- a/third_party/WebKit/Source/core/dom/NodeIterator.h
+++ b/third_party/WebKit/Source/core/dom/NodeIterator.h
@@ -29,8 +29,6 @@
 #include "core/dom/NodeFilter.h"
 #include "core/dom/NodeIteratorBase.h"
 #include "platform/heap/Handle.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/dom/NodeIteratorBase.h b/third_party/WebKit/Source/core/dom/NodeIteratorBase.h
index c5915d0..bd395f4a 100644
--- a/third_party/WebKit/Source/core/dom/NodeIteratorBase.h
+++ b/third_party/WebKit/Source/core/dom/NodeIteratorBase.h
@@ -26,7 +26,6 @@
 #define NodeIteratorBase_h
 
 #include "platform/heap/Handle.h"
-#include "wtf/RefPtr.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/dom/NthIndexCache.h b/third_party/WebKit/Source/core/dom/NthIndexCache.h
index e0dc45ee..43d6e11 100644
--- a/third_party/WebKit/Source/core/dom/NthIndexCache.h
+++ b/third_party/WebKit/Source/core/dom/NthIndexCache.h
@@ -9,8 +9,6 @@
 #include "core/dom/Element.h"
 #include "platform/heap/Handle.h"
 #include "wtf/HashMap.h"
-#include "wtf/OwnPtr.h"
-#include "wtf/RefPtr.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/dom/PendingScript.h b/third_party/WebKit/Source/core/dom/PendingScript.h
index a16d0c7..c258de6 100644
--- a/third_party/WebKit/Source/core/dom/PendingScript.h
+++ b/third_party/WebKit/Source/core/dom/PendingScript.h
@@ -31,8 +31,6 @@
 #include "core/fetch/ResourceOwner.h"
 #include "core/fetch/ScriptResource.h"
 #include "platform/heap/Handle.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefPtr.h"
 #include "wtf/text/TextPosition.h"
 
 namespace blink {
@@ -42,6 +40,7 @@
 
 // A container for an external script which may be loaded and executed.
 //
+// TODO(kochi): The comment below is from pre-oilpan age and may not be correct now.
 // A RefPtr alone does not prevent the underlying Resource
 // from purging its data buffer. This class holds a dummy client open for its
 // lifetime in order to guarantee that the data buffer will not be purged.
diff --git a/third_party/WebKit/Source/core/dom/PresentationAttributeStyle.h b/third_party/WebKit/Source/core/dom/PresentationAttributeStyle.h
index 98c7494..033795d 100644
--- a/third_party/WebKit/Source/core/dom/PresentationAttributeStyle.h
+++ b/third_party/WebKit/Source/core/dom/PresentationAttributeStyle.h
@@ -32,7 +32,6 @@
 #define PresentationAttributeStyle_h
 
 #include "platform/heap/Handle.h"
-#include "wtf/RefPtr.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/dom/ScriptRunner.h b/third_party/WebKit/Source/core/dom/ScriptRunner.h
index abc7e26..bef934b 100644
--- a/third_party/WebKit/Source/core/dom/ScriptRunner.h
+++ b/third_party/WebKit/Source/core/dom/ScriptRunner.h
@@ -31,7 +31,6 @@
 #include "wtf/Deque.h"
 #include "wtf/HashMap.h"
 #include "wtf/Noncopyable.h"
-#include "wtf/PassOwnPtr.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/dom/ScriptedAnimationController.h b/third_party/WebKit/Source/core/dom/ScriptedAnimationController.h
index fc3537f..c172e008 100644
--- a/third_party/WebKit/Source/core/dom/ScriptedAnimationController.h
+++ b/third_party/WebKit/Source/core/dom/ScriptedAnimationController.h
@@ -29,8 +29,6 @@
 #include "core/dom/FrameRequestCallbackCollection.h"
 #include "platform/heap/Handle.h"
 #include "wtf/ListHashSet.h"
-#include "wtf/RefCounted.h"
-#include "wtf/RefPtr.h"
 #include "wtf/Vector.h"
 #include "wtf/text/AtomicString.h"
 #include "wtf/text/StringImpl.h"
diff --git a/third_party/WebKit/Source/core/dom/ScriptedIdleTaskController.h b/third_party/WebKit/Source/core/dom/ScriptedIdleTaskController.h
index f1d710c2..9bf74f0 100644
--- a/third_party/WebKit/Source/core/dom/ScriptedIdleTaskController.h
+++ b/third_party/WebKit/Source/core/dom/ScriptedIdleTaskController.h
@@ -9,8 +9,6 @@
 #include "core/dom/IdleDeadline.h"
 #include "platform/Timer.h"
 #include "platform/heap/Handle.h"
-#include "wtf/RefCounted.h"
-#include "wtf/RefPtr.h"
 #include "wtf/Vector.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/dom/StaticNodeList.h b/third_party/WebKit/Source/core/dom/StaticNodeList.h
index 9c1db01d..5f76b0c1 100644
--- a/third_party/WebKit/Source/core/dom/StaticNodeList.h
+++ b/third_party/WebKit/Source/core/dom/StaticNodeList.h
@@ -30,8 +30,6 @@
 #define StaticNodeList_h
 
 #include "core/dom/NodeList.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefPtr.h"
 #include "wtf/Vector.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/dom/StyleChangeReason.h b/third_party/WebKit/Source/core/dom/StyleChangeReason.h
index 84e8003..c6a2d84 100644
--- a/third_party/WebKit/Source/core/dom/StyleChangeReason.h
+++ b/third_party/WebKit/Source/core/dom/StyleChangeReason.h
@@ -6,7 +6,6 @@
 #define StyleChangeReason_h
 
 #include "core/dom/QualifiedName.h"
-#include "wtf/PassRefPtr.h"
 #include "wtf/text/AtomicString.h"
 #include "wtf/text/WTFString.h"
 
diff --git a/third_party/WebKit/Source/core/dom/StyleEngine.h b/third_party/WebKit/Source/core/dom/StyleEngine.h
index 6d642547..9dac03a9 100644
--- a/third_party/WebKit/Source/core/dom/StyleEngine.h
+++ b/third_party/WebKit/Source/core/dom/StyleEngine.h
@@ -39,7 +39,6 @@
 #include "platform/heap/Handle.h"
 #include "wtf/Allocator.h"
 #include "wtf/ListHashSet.h"
-#include "wtf/RefPtr.h"
 #include "wtf/TemporaryChange.h"
 #include "wtf/Vector.h"
 #include "wtf/text/WTFString.h"
diff --git a/third_party/WebKit/Source/core/dom/StyleSheetCollection.h b/third_party/WebKit/Source/core/dom/StyleSheetCollection.h
index 5d80497..47d467d2 100644
--- a/third_party/WebKit/Source/core/dom/StyleSheetCollection.h
+++ b/third_party/WebKit/Source/core/dom/StyleSheetCollection.h
@@ -31,7 +31,6 @@
 #include "core/CoreExport.h"
 #include "platform/heap/Handle.h"
 #include "wtf/Allocator.h"
-#include "wtf/RefPtr.h"
 #include "wtf/Vector.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/dom/Touch.h b/third_party/WebKit/Source/core/dom/Touch.h
index 3efa1c3..5a72ea0 100644
--- a/third_party/WebKit/Source/core/dom/Touch.h
+++ b/third_party/WebKit/Source/core/dom/Touch.h
@@ -35,9 +35,6 @@
 #include "platform/geometry/FloatSize.h"
 #include "platform/geometry/LayoutPoint.h"
 #include "platform/heap/Handle.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
-#include "wtf/RefPtr.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.h b/third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.h
index fa954d3..46acaac 100644
--- a/third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.h
+++ b/third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.h
@@ -35,7 +35,6 @@
 #include "core/dom/TreeScope.h"
 #include "wtf/HashMap.h"
 #include "wtf/ListHashSet.h"
-#include "wtf/RefPtr.h"
 #include "wtf/Vector.h"
 #include "wtf/text/WTFString.h"
 
diff --git a/third_party/WebKit/Source/core/dom/TreeWalker.h b/third_party/WebKit/Source/core/dom/TreeWalker.h
index a9b4447..d2a20555 100644
--- a/third_party/WebKit/Source/core/dom/TreeWalker.h
+++ b/third_party/WebKit/Source/core/dom/TreeWalker.h
@@ -29,8 +29,6 @@
 #include "core/dom/NodeFilter.h"
 #include "core/dom/NodeIteratorBase.h"
 #include "platform/heap/Handle.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/dom/UserActionElementSet.h b/third_party/WebKit/Source/core/dom/UserActionElementSet.h
index 79d2a54..0db2395 100644
--- a/third_party/WebKit/Source/core/dom/UserActionElementSet.h
+++ b/third_party/WebKit/Source/core/dom/UserActionElementSet.h
@@ -29,8 +29,6 @@
 
 #include "platform/heap/Handle.h"
 #include "wtf/HashMap.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/RefPtr.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElement.h b/third_party/WebKit/Source/core/dom/custom/CustomElement.h
index c277ebea..0923fc5 100644
--- a/third_party/WebKit/Source/core/dom/custom/CustomElement.h
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElement.h
@@ -35,9 +35,6 @@
 #include "core/dom/custom/CustomElementDefinition.h"
 #include "wtf/Allocator.h"
 #include "wtf/HashMap.h"
-#include "wtf/Noncopyable.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefPtr.h"
 #include "wtf/Vector.h"
 #include "wtf/text/AtomicString.h"
 
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.h b/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.h
index ede43ec..cccf9ec 100644
--- a/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.h
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackInvocation.h
@@ -33,9 +33,6 @@
 
 #include "core/dom/custom/CustomElementLifecycleCallbacks.h"
 #include "core/dom/custom/CustomElementProcessingStep.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefPtr.h"
 #include "wtf/text/AtomicString.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.h b/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.h
index 45f1e0c3..2a0cc064 100644
--- a/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.h
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElementCallbackQueue.h
@@ -34,10 +34,6 @@
 #include "core/dom/Element.h"
 #include "core/dom/custom/CustomElementProcessingStep.h"
 #include "platform/heap/Handle.h"
-#include "wtf/OwnPtr.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefPtr.h"
 #include "wtf/Vector.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementDefinition.h b/third_party/WebKit/Source/core/dom/custom/CustomElementDefinition.h
index 3e6b25d..5fcf4899 100644
--- a/third_party/WebKit/Source/core/dom/custom/CustomElementDefinition.h
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElementDefinition.h
@@ -33,8 +33,6 @@
 
 #include "core/dom/custom/CustomElementDescriptor.h"
 #include "core/dom/custom/CustomElementLifecycleCallbacks.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementLifecycleCallbacks.h b/third_party/WebKit/Source/core/dom/custom/CustomElementLifecycleCallbacks.h
index b9b91e8..195d0f82 100644
--- a/third_party/WebKit/Source/core/dom/custom/CustomElementLifecycleCallbacks.h
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElementLifecycleCallbacks.h
@@ -32,7 +32,6 @@
 #define CustomElementLifecycleCallbacks_h
 
 #include "platform/heap/Handle.h"
-#include "wtf/RefCounted.h"
 #include "wtf/text/AtomicString.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskDispatcher.h b/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskDispatcher.h
index a81801b1..14c35431 100644
--- a/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskDispatcher.h
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskDispatcher.h
@@ -7,7 +7,6 @@
 
 #include "platform/heap/Handle.h"
 #include "wtf/Noncopyable.h"
-#include "wtf/PassOwnPtr.h"
 #include "wtf/Vector.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskImportStep.h b/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskImportStep.h
index 37d81b3..cebf67f 100644
--- a/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskImportStep.h
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskImportStep.h
@@ -33,10 +33,6 @@
 
 #include "core/dom/custom/CustomElementMicrotaskStep.h"
 #include "platform/heap/Handle.h"
-#include "wtf/Noncopyable.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefPtr.h"
 #include "wtf/WeakPtr.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskQueueBase.h b/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskQueueBase.h
index ccd87d5..b469261 100644
--- a/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskQueueBase.h
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskQueueBase.h
@@ -7,11 +7,6 @@
 
 #include "core/dom/custom/CustomElementMicrotaskStep.h"
 #include "platform/heap/Handle.h"
-#include "wtf/OwnPtr.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
-#include "wtf/RefPtr.h"
 #include "wtf/Vector.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskResolutionStep.h b/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskResolutionStep.h
index 626122f..e9d0378d 100644
--- a/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskResolutionStep.h
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskResolutionStep.h
@@ -34,9 +34,6 @@
 #include "core/dom/custom/CustomElementDescriptor.h"
 #include "core/dom/custom/CustomElementMicrotaskStep.h"
 #include "platform/heap/Handle.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefPtr.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskRunQueue.h b/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskRunQueue.h
index 0744dd2c..895a3d3 100644
--- a/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskRunQueue.h
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElementMicrotaskRunQueue.h
@@ -6,7 +6,6 @@
 #define CustomElementMicrotaskRunQueue_h
 
 #include "platform/heap/Handle.h"
-#include "wtf/RefCounted.h"
 #include "wtf/WeakPtr.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.cpp b/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.cpp
index 5b420127..c1b5798 100644
--- a/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.cpp
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.cpp
@@ -41,7 +41,6 @@
 #include "core/html/HTMLElement.h"
 #include "core/html/HTMLUnknownElement.h"
 #include "core/svg/SVGUnknownElement.h"
-#include "wtf/RefPtr.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.h b/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.h
index 04334f0..dbdc9964 100644
--- a/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.h
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElementRegistrationContext.h
@@ -36,9 +36,6 @@
 #include "core/dom/custom/CustomElementRegistry.h"
 #include "core/dom/custom/CustomElementUpgradeCandidateMap.h"
 #include "platform/heap/Handle.h"
-#include "wtf/HashMap.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/PassRefPtr.h"
 #include "wtf/text/AtomicString.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementRegistry.h b/third_party/WebKit/Source/core/dom/custom/CustomElementRegistry.h
index db80ca9..b1b8436 100644
--- a/third_party/WebKit/Source/core/dom/custom/CustomElementRegistry.h
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElementRegistry.h
@@ -37,7 +37,6 @@
 #include "core/dom/custom/CustomElementDescriptorHash.h"
 #include "wtf/HashMap.h"
 #include "wtf/HashSet.h"
-#include "wtf/RefPtr.h"
 #include "wtf/text/AtomicString.h"
 #include "wtf/text/AtomicStringHash.h"
 
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementScheduler.h b/third_party/WebKit/Source/core/dom/custom/CustomElementScheduler.h
index 1814b7b..a107ee38 100644
--- a/third_party/WebKit/Source/core/dom/custom/CustomElementScheduler.h
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElementScheduler.h
@@ -35,8 +35,6 @@
 #include "core/dom/custom/CustomElementLifecycleCallbacks.h"
 #include "platform/heap/Handle.h"
 #include "wtf/HashMap.h"
-#include "wtf/OwnPtr.h"
-#include "wtf/PassRefPtr.h"
 #include "wtf/text/AtomicString.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementsRegistry.cpp b/third_party/WebKit/Source/core/dom/custom/CustomElementsRegistry.cpp
new file mode 100644
index 0000000..f22190ce
--- /dev/null
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElementsRegistry.cpp
@@ -0,0 +1,29 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/dom/custom/CustomElementsRegistry.h"
+
+#include "bindings/core/v8/ExceptionState.h"
+#include "bindings/core/v8/ScriptState.h"
+#include "core/dom/ElementRegistrationOptions.h"
+
+namespace blink {
+
+CustomElementsRegistry::CustomElementsRegistry()
+{
+}
+
+void CustomElementsRegistry::define(ScriptState* scriptState,
+    const AtomicString& name, const ScriptValue& constructor,
+    const ElementRegistrationOptions& options, ExceptionState& exceptionState)
+{
+    // TODO(kojii): Element definition process not implemented yet.
+    // http://w3c.github.io/webcomponents/spec/custom/#dfn-element-definition
+}
+
+DEFINE_TRACE(CustomElementsRegistry)
+{
+}
+
+} // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementsRegistry.h b/third_party/WebKit/Source/core/dom/custom/CustomElementsRegistry.h
new file mode 100644
index 0000000..2d78fdf
--- /dev/null
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElementsRegistry.h
@@ -0,0 +1,40 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CustomElementsRegistry_h
+#define CustomElementsRegistry_h
+
+#include "bindings/core/v8/ScriptWrappable.h"
+#include "core/CoreExport.h"
+
+namespace blink {
+
+class ElementRegistrationOptions;
+class ExceptionState;
+class ScriptState;
+class ScriptValue;
+
+class CORE_EXPORT CustomElementsRegistry final
+    : public GarbageCollected<CustomElementsRegistry>
+    , public ScriptWrappable {
+    DEFINE_WRAPPERTYPEINFO();
+public:
+    static CustomElementsRegistry* create()
+    {
+        return new CustomElementsRegistry();
+    }
+
+    void define(ScriptState*, const AtomicString& name,
+        const ScriptValue& constructor, const ElementRegistrationOptions&,
+        ExceptionState&);
+
+    DECLARE_TRACE();
+
+private:
+    CustomElementsRegistry();
+};
+
+} // namespace blink
+
+#endif // CustomElementsRegistry_h
diff --git a/third_party/WebKit/Source/core/dom/custom/CustomElementsRegistry.idl b/third_party/WebKit/Source/core/dom/custom/CustomElementsRegistry.idl
new file mode 100644
index 0000000..60259667
--- /dev/null
+++ b/third_party/WebKit/Source/core/dom/custom/CustomElementsRegistry.idl
@@ -0,0 +1,10 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+    RuntimeEnabled=CustomElementsV1,
+    GarbageCollected,
+] interface CustomElementsRegistry {
+    [CallWith=ScriptState, CustomElementCallbacks, RaisesException] void define(DOMString name, Function constructor, optional ElementRegistrationOptions options);
+};
diff --git a/third_party/WebKit/Source/core/dom/shadow/ElementShadow.h b/third_party/WebKit/Source/core/dom/shadow/ElementShadow.h
index fb522ec..9454f36e 100644
--- a/third_party/WebKit/Source/core/dom/shadow/ElementShadow.h
+++ b/third_party/WebKit/Source/core/dom/shadow/ElementShadow.h
@@ -36,7 +36,6 @@
 #include "wtf/DoublyLinkedList.h"
 #include "wtf/HashMap.h"
 #include "wtf/Noncopyable.h"
-#include "wtf/PassOwnPtr.h"
 
 namespace blink {
 
diff --git a/third_party/WebKit/Source/core/dom/shadow/FlatTreeTraversalTest.cpp b/third_party/WebKit/Source/core/dom/shadow/FlatTreeTraversalTest.cpp
index 3584d0a2..52a35f2 100644
--- a/third_party/WebKit/Source/core/dom/shadow/FlatTreeTraversalTest.cpp
+++ b/third_party/WebKit/Source/core/dom/shadow/FlatTreeTraversalTest.cpp
@@ -18,8 +18,6 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "wtf/Compiler.h"
 #include "wtf/OwnPtr.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefPtr.h"
 #include "wtf/StdLibExtras.h"
 #include "wtf/Vector.h"
 
diff --git a/third_party/WebKit/Source/core/dom/shadow/ShadowRootRareData.h b/third_party/WebKit/Source/core/dom/shadow/ShadowRootRareData.h
index a01cc2ef..b92e81a3 100644
--- a/third_party/WebKit/Source/core/dom/shadow/ShadowRootRareData.h
+++ b/third_party/WebKit/Source/core/dom/shadow/ShadowRootRareData.h
@@ -33,7 +33,6 @@
 
 #include "core/dom/shadow/InsertionPoint.h"
 #include "core/html/HTMLSlotElement.h"
-#include "wtf/RefPtr.h"
 #include "wtf/Vector.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
index 1a7dc9d7..3fb0b51 100644
--- a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
+++ b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
@@ -569,7 +569,7 @@
     return current + machine.finalizeAndGetBoundaryOffset();
 }
 
-int uncheckedPreviousOffset(const Node* node, int current)
+int previousGraphemeBoundaryOf(const Node* node, int current)
 {
     if (!node->isTextNode())
         return current - 1;
@@ -583,7 +583,7 @@
     return result == TextBreakDone ? current - 1 : result;
 }
 
-static int uncheckedPreviousOffsetForBackwardDeletion(const Node* node, int current)
+static int previousBackwardDeletionOffsetOf(const Node* node, int current)
 {
     DCHECK_GE(current, 0);
     if (current <= 1)
@@ -596,7 +596,7 @@
     return findNextBoundaryOffset<BackspaceStateMachine>(text, current);
 }
 
-int uncheckedNextOffset(const Node* node, int current)
+int nextGraphemeBoundaryOf(const Node* node, int current)
 {
     if (!node->isTextNode())
         return current + 1;
@@ -635,9 +635,10 @@
         case PositionMoveType::CodeUnit:
             return PositionTemplate<Strategy>(node, offset - 1);
         case PositionMoveType::CodePoint:
-            return PositionTemplate<Strategy>(node, uncheckedPreviousOffset(node, offset));
+            // TODO(nona): Move to PositionMoveType::GraphemeBoundary case.
+            return PositionTemplate<Strategy>(node, previousGraphemeBoundaryOf(node, offset));
         case PositionMoveType::BackwardDeletion:
-            return PositionTemplate<Strategy>(node, uncheckedPreviousOffsetForBackwardDeletion(node, offset));
+            return PositionTemplate<Strategy>(node, previousBackwardDeletionOffsetOf(node, offset));
         }
     }
 
@@ -684,7 +685,9 @@
         //      is correct.
         //   2) The new offset is a bogus offset like (<br>, 1), and there is no
         //      child. Going from 0 to 1 is correct.
-        return PositionTemplate<Strategy>::editingPositionOf(node, (moveType == PositionMoveType::CodePoint) ? uncheckedNextOffset(node, offset) : offset + 1);
+        // TODO(nona): Call nextGraphemeBoundaryOf if
+        //             moveType == PositionMoveType::GraphemeBoundary
+        return PositionTemplate<Strategy>::editingPositionOf(node, (moveType == PositionMoveType::CodePoint) ? nextGraphemeBoundaryOf(node, offset) : offset + 1);
     }
 
     if (ContainerNode* parent = Strategy::parent(*node))
diff --git a/third_party/WebKit/Source/core/editing/EditingUtilities.h b/third_party/WebKit/Source/core/editing/EditingUtilities.h
index 51dd8c2..fd7071b 100644
--- a/third_party/WebKit/Source/core/editing/EditingUtilities.h
+++ b/third_party/WebKit/Source/core/editing/EditingUtilities.h
@@ -213,8 +213,8 @@
 CORE_EXPORT PositionInFlatTree previousPositionOf(const PositionInFlatTree&, PositionMoveType);
 CORE_EXPORT PositionInFlatTree nextPositionOf(const PositionInFlatTree&, PositionMoveType);
 
-CORE_EXPORT int uncheckedPreviousOffset(const Node*, int current);
-CORE_EXPORT int uncheckedNextOffset(const Node*, int current);
+CORE_EXPORT int previousGraphemeBoundaryOf(const Node*, int current);
+CORE_EXPORT int nextGraphemeBoundaryOf(const Node*, int current);
 
 // comparision functions on Position
 
diff --git a/third_party/WebKit/Source/core/editing/EditingUtilitiesTest.cpp b/third_party/WebKit/Source/core/editing/EditingUtilitiesTest.cpp
index 43b15b2..8de7431 100644
--- a/third_party/WebKit/Source/core/editing/EditingUtilitiesTest.cpp
+++ b/third_party/WebKit/Source/core/editing/EditingUtilitiesTest.cpp
@@ -204,42 +204,42 @@
 {
     setBodyContent("<style>p::first-letter {color:red;}</style><p id='target'>abc</p>");
     Node* node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(2, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(2, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(3, uncheckedNextOffset(node, 2));
+    EXPECT_EQ(2, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(2, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 2));
 
     updateLayoutAndStyleForPainting();
     EXPECT_NE(nullptr, node->layoutObject());
-    EXPECT_EQ(2, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(2, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(3, uncheckedNextOffset(node, 2));
+    EXPECT_EQ(2, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(2, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 2));
 }
 
 TEST_F(EditingUtilitiesTest, uncheckedPreviousNextOffset_textTransform)
 {
     setBodyContent("<style>p {text-transform:uppercase}</style><p id='target'>abc</p>");
     Node* node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(2, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(2, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(3, uncheckedNextOffset(node, 2));
+    EXPECT_EQ(2, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(2, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 2));
 
     updateLayoutAndStyleForPainting();
     EXPECT_NE(nullptr, node->layoutObject());
-    EXPECT_EQ(2, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(2, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(3, uncheckedNextOffset(node, 2));
+    EXPECT_EQ(2, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(2, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 2));
 }
 
 // Following breaking rules come from http://unicode.org/reports/tr29/
@@ -250,50 +250,50 @@
     // GB1: Break at the start of text.
     setBodyContent("<p id='target'>a</p>");
     Node* node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
 
     // GB2: Break at the end of text.
     setBodyContent("<p id='target'>a</p>");
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
 
     // GB3: Do not break between CR and LF.
     setBodyContent("<p id='target'>a&#x0D;&#x0A;b</p>");
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(3, uncheckedPreviousOffset(node, 4));
+    EXPECT_EQ(3, previousGraphemeBoundaryOf(node, 4));
     // TODO(nona) : Enable following expectation.
-    // EXPECT_EQ(1, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
+    // EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
     // TODO(nona) : Enable following expectation.
-    // EXPECT_EQ(3, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(4, uncheckedNextOffset(node, 3));
+    // EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(4, nextGraphemeBoundaryOf(node, 3));
 
     // GB4,GB5: Break before and after CR/LF/Control.
     setBodyContent("<p id='target'>a&#x0D;b</p>"); // CR
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(2, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(2, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(3, uncheckedNextOffset(node, 2));
+    EXPECT_EQ(2, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(2, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 2));
     setBodyContent("<p id='target'>a&#x0A;b</p>"); // LF
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(2, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(2, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(3, uncheckedNextOffset(node, 2));
+    EXPECT_EQ(2, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(2, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 2));
     setBodyContent("<p id='target'>a&#xAD;b</p>"); // U+00AD(SOFT HYPHEN) has Control property.
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(2, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(2, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(3, uncheckedNextOffset(node, 2));
+    EXPECT_EQ(2, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(2, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 2));
 
     // GB6: Don't break Hangul sequence.
     const std::string L = "&#x1100;"; // U+1100 (HANGUL CHOSEONG KIYEOK) has L property.
@@ -303,88 +303,88 @@
     const std::string T = "&#x11A8;"; // U+11A8 (HANGUL JONGSEONG KIYEOK) has T property.
     setBodyContent("<p id='target'>a" + L + L + "b</p>"); // L x L
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(3, uncheckedPreviousOffset(node, 4));
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(3, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(4, uncheckedNextOffset(node, 3));
+    EXPECT_EQ(3, previousGraphemeBoundaryOf(node, 4));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(4, nextGraphemeBoundaryOf(node, 3));
     setBodyContent("<p id='target'>a" + L + V +"b</p>"); // L x V
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(3, uncheckedPreviousOffset(node, 4));
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(3, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(4, uncheckedNextOffset(node, 3));
+    EXPECT_EQ(3, previousGraphemeBoundaryOf(node, 4));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(4, nextGraphemeBoundaryOf(node, 3));
     setBodyContent("<p id='target'>a" + L + LV + "b</p>"); // L x LV
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(3, uncheckedPreviousOffset(node, 4));
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(3, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(4, uncheckedNextOffset(node, 3));
+    EXPECT_EQ(3, previousGraphemeBoundaryOf(node, 4));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(4, nextGraphemeBoundaryOf(node, 3));
     setBodyContent("<p id='target'>a" + L + LVT + "b</p>"); // L x LVT
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(3, uncheckedPreviousOffset(node, 4));
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(3, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(4, uncheckedNextOffset(node, 3));
+    EXPECT_EQ(3, previousGraphemeBoundaryOf(node, 4));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(4, nextGraphemeBoundaryOf(node, 3));
 
     // GB7: Don't break Hangul sequence.
     setBodyContent("<p id='target'>a" + LV + V + "b</p>"); // LV x V
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(3, uncheckedPreviousOffset(node, 4));
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(3, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(4, uncheckedNextOffset(node, 3));
+    EXPECT_EQ(3, previousGraphemeBoundaryOf(node, 4));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(4, nextGraphemeBoundaryOf(node, 3));
     setBodyContent("<p id='target'>a" + LV + T + "b</p>"); // LV x T
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(3, uncheckedPreviousOffset(node, 4));
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(3, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(4, uncheckedNextOffset(node, 3));
+    EXPECT_EQ(3, previousGraphemeBoundaryOf(node, 4));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(4, nextGraphemeBoundaryOf(node, 3));
     setBodyContent("<p id='target'>a" + V + V + "b</p>"); // V x V
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(3, uncheckedPreviousOffset(node, 4));
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(3, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(4, uncheckedNextOffset(node, 3));
+    EXPECT_EQ(3, previousGraphemeBoundaryOf(node, 4));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(4, nextGraphemeBoundaryOf(node, 3));
     setBodyContent("<p id='target'>a" + V + T + "b</p>"); // V x T
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(3, uncheckedPreviousOffset(node, 4));
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(3, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(4, uncheckedNextOffset(node, 3));
+    EXPECT_EQ(3, previousGraphemeBoundaryOf(node, 4));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(4, nextGraphemeBoundaryOf(node, 3));
 
     // GB8: Don't break Hangul sequence.
     setBodyContent("<p id='target'>a" + LVT + T + "b</p>"); // LVT x T
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(3, uncheckedPreviousOffset(node, 4));
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(3, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(4, uncheckedNextOffset(node, 3));
+    EXPECT_EQ(3, previousGraphemeBoundaryOf(node, 4));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(4, nextGraphemeBoundaryOf(node, 3));
     setBodyContent("<p id='target'>a" + T + T + "b</p>"); // T x T
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(3, uncheckedPreviousOffset(node, 4));
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(3, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(4, uncheckedNextOffset(node, 3));
+    EXPECT_EQ(3, previousGraphemeBoundaryOf(node, 4));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(4, nextGraphemeBoundaryOf(node, 3));
 
     // Break other Hangul syllable combination. See test of GB999.
 
@@ -394,101 +394,101 @@
     const std::string flag = "&#x1F1FA;&#x1F1F8;"; // US flag.
     setBodyContent("<p id='target'>" + flag + flag + flag + flag + "a</p>"); // ^(RI RI)* RI x RI
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(16, uncheckedPreviousOffset(node, 17));
-    EXPECT_EQ(12, uncheckedPreviousOffset(node, 16));
+    EXPECT_EQ(16, previousGraphemeBoundaryOf(node, 17));
+    EXPECT_EQ(12, previousGraphemeBoundaryOf(node, 16));
     // TODO(nona): Enable following expectations.
-    // EXPECT_EQ(8, uncheckedPreviousOffset(node, 12));
-    // EXPECT_EQ(4, uncheckedPreviousOffset(node, 8));
-    // EXPECT_EQ(0, uncheckedPreviousOffset(node, 4));
-    // EXPECT_EQ(4, uncheckedNextOffset(node, 0));
-    // EXPECT_EQ(8, uncheckedNextOffset(node, 4));
-    EXPECT_EQ(12, uncheckedNextOffset(node, 8));
-    EXPECT_EQ(16, uncheckedNextOffset(node, 12));
-    EXPECT_EQ(17, uncheckedNextOffset(node, 16));
+    // EXPECT_EQ(8, previousGraphemeBoundaryOf(node, 12));
+    // EXPECT_EQ(4, previousGraphemeBoundaryOf(node, 8));
+    // EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 4));
+    // EXPECT_EQ(4, nextGraphemeBoundaryOf(node, 0));
+    // EXPECT_EQ(8, nextGraphemeBoundaryOf(node, 4));
+    EXPECT_EQ(12, nextGraphemeBoundaryOf(node, 8));
+    EXPECT_EQ(16, nextGraphemeBoundaryOf(node, 12));
+    EXPECT_EQ(17, nextGraphemeBoundaryOf(node, 16));
 
     // GB8c: Don't break between regional indicator if there are even numbered regional indicator symbols before.
     setBodyContent("<p id='target'>a" + flag + flag + flag + flag + "b</p>"); // [^RI] (RI RI)* RI x RI
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(17, uncheckedPreviousOffset(node, 18));
-    EXPECT_EQ(13, uncheckedPreviousOffset(node, 17));
+    EXPECT_EQ(17, previousGraphemeBoundaryOf(node, 18));
+    EXPECT_EQ(13, previousGraphemeBoundaryOf(node, 17));
     // TODO(nona): Enable following expectations.
-    // EXPECT_EQ(9, uncheckedPreviousOffset(node, 13));
-    // EXPECT_EQ(5, uncheckedPreviousOffset(node, 9));
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 5));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
+    // EXPECT_EQ(9, previousGraphemeBoundaryOf(node, 13));
+    // EXPECT_EQ(5, previousGraphemeBoundaryOf(node, 9));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 5));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
     // TODO(nona): Enable following expectations.
-    // EXPECT_EQ(5, uncheckedNextOffset(node, 1));
-    // EXPECT_EQ(9, uncheckedNextOffset(node, 5));
-    EXPECT_EQ(13, uncheckedNextOffset(node, 9));
-    EXPECT_EQ(17, uncheckedNextOffset(node, 13));
-    EXPECT_EQ(18, uncheckedNextOffset(node, 17));
+    // EXPECT_EQ(5, nextGraphemeBoundaryOf(node, 1));
+    // EXPECT_EQ(9, nextGraphemeBoundaryOf(node, 5));
+    EXPECT_EQ(13, nextGraphemeBoundaryOf(node, 9));
+    EXPECT_EQ(17, nextGraphemeBoundaryOf(node, 13));
+    EXPECT_EQ(18, nextGraphemeBoundaryOf(node, 17));
 
     // GB8c: Break if there is an odd number of regional indicator symbols before.
     setBodyContent("<p id='target'>a" + flag + flag + flag + flag + "&#x1F1F8;b</p>"); // RI ÷ RI
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(19, uncheckedPreviousOffset(node, 20));
+    EXPECT_EQ(19, previousGraphemeBoundaryOf(node, 20));
     // TODO(nona): Enable following expectations.
-    // EXPECT_EQ(17, uncheckedPreviousOffset(node, 19));
-    // EXPECT_EQ(13, uncheckedPreviousOffset(node, 17));
-    // EXPECT_EQ(9, uncheckedPreviousOffset(node, 13));
-    // EXPECT_EQ(5, uncheckedPreviousOffset(node, 9));
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 5));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
+    // EXPECT_EQ(17, previousGraphemeBoundaryOf(node, 19));
+    // EXPECT_EQ(13, previousGraphemeBoundaryOf(node, 17));
+    // EXPECT_EQ(9, previousGraphemeBoundaryOf(node, 13));
+    // EXPECT_EQ(5, previousGraphemeBoundaryOf(node, 9));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 5));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
     // TODO(nona): Enable following expectations.
-    // EXPECT_EQ(5, uncheckedNextOffset(node, 1));
-    // EXPECT_EQ(9, uncheckedNextOffset(node, 5));
-    // EXPECT_EQ(13, uncheckedNextOffset(node, 9));
-    EXPECT_EQ(17, uncheckedNextOffset(node, 13));
-    EXPECT_EQ(19, uncheckedNextOffset(node, 17));
-    EXPECT_EQ(20, uncheckedNextOffset(node, 19));
+    // EXPECT_EQ(5, nextGraphemeBoundaryOf(node, 1));
+    // EXPECT_EQ(9, nextGraphemeBoundaryOf(node, 5));
+    // EXPECT_EQ(13, nextGraphemeBoundaryOf(node, 9));
+    EXPECT_EQ(17, nextGraphemeBoundaryOf(node, 13));
+    EXPECT_EQ(19, nextGraphemeBoundaryOf(node, 17));
+    EXPECT_EQ(20, nextGraphemeBoundaryOf(node, 19));
 
     // GB9: Do not break before extending characters or ZWJ.
     // U+0300(COMBINING GRAVE ACCENT) has Extend property.
     setBodyContent("<p id='target'>a&#x0300;b</p>"); // x Extend
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(2, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(2, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(3, uncheckedNextOffset(node, 2));
+    EXPECT_EQ(2, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(2, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 2));
     // U+200D is ZERO WIDTH JOINER.
     setBodyContent("<p id='target'>a&#x200D;b</p>"); // x ZWJ
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(2, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(2, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(3, uncheckedNextOffset(node, 2));
+    EXPECT_EQ(2, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(2, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 2));
 
     // GB9a: Do not break before SpacingMarks.
     // U+0903(DEVANAGARI SIGN VISARGA) has SpacingMark property.
     setBodyContent("<p id='target'>a&#x0903;b</p>"); // x SpacingMark
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(2, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(2, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(3, uncheckedNextOffset(node, 2));
+    EXPECT_EQ(2, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(2, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 2));
 
     // GB9b: Do not break after Prepend but Blink breaks after Prepend char to address Bug 24342.
     // U+0600(ARABIC NUMBER SIGN) has Prepend property.
     setBodyContent("<p id='target'>a&#x0600;b</p>"); // Prepend x
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(2, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(2, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(3, uncheckedNextOffset(node, 2));
+    EXPECT_EQ(2, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(2, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 2));
 
     // Blink customization: Don't break before Japanese half-width katakana voiced marks.
     setBodyContent("<p id='target'>a&#xFF76;&#xFF9E;b</p>");
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(3, uncheckedPreviousOffset(node, 4));
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(3, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(4, uncheckedNextOffset(node, 3));
+    EXPECT_EQ(3, previousGraphemeBoundaryOf(node, 4));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(4, nextGraphemeBoundaryOf(node, 3));
 
     // Additional rule for Virama: Do not break after Virama except for Tamil.
     // See http://www.unicode.org/Public/9.0.0/ucd/IndicSyllabicCategory-9.0.0d2.txt
@@ -497,25 +497,25 @@
     // U+0915 is DEVANAGARI LETTER KA.
     setBodyContent("<p id='target'>a&#x0905;&#x094D;&#x0915;b</p>");
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(4, uncheckedPreviousOffset(node, 5));
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 4));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(4, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(5, uncheckedNextOffset(node, 4));
+    EXPECT_EQ(4, previousGraphemeBoundaryOf(node, 5));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 4));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(4, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(5, nextGraphemeBoundaryOf(node, 4));
     // U+0B85 is TAMIL LETTER A. This has Extend property.
     // U+0BCD is TAMIL SIGN VIRAMA. This has Virama property.
     // U+0B95 is TAMIL LETTER KA.
     setBodyContent("<p id='target'>a&#x0B85;&#x0BCD;&#x0B95;b</p>");
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(4, uncheckedPreviousOffset(node, 5));
-    EXPECT_EQ(3, uncheckedPreviousOffset(node, 4));
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(3, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(4, uncheckedNextOffset(node, 3));
-    EXPECT_EQ(5, uncheckedNextOffset(node, 4));
+    EXPECT_EQ(4, previousGraphemeBoundaryOf(node, 5));
+    EXPECT_EQ(3, previousGraphemeBoundaryOf(node, 4));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(4, nextGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(5, nextGraphemeBoundaryOf(node, 4));
     // TODO(nona): Consider to add Sinhala, Balinese, etc.
 
     // GB10: Do not break within emoji modifier.
@@ -523,123 +523,123 @@
     // U+1F3FB(EMOJI MODIFIER FITZPATRICK TYPE-1-2) has E_Modifier property.
     setBodyContent("<p id='target'>a&#x1F385;&#x1F3FB;b</p>"); // E_Base x E_Modifier
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(5, uncheckedPreviousOffset(node, 6));
+    EXPECT_EQ(5, previousGraphemeBoundaryOf(node, 6));
     // TODO(nona): Enable following expectation.
-    // EXPECT_EQ(1, uncheckedPreviousOffset(node, 5));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
+    // EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 5));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
     // TODO(nona): Enable following expectation.
-    // EXPECT_EQ(5, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(6, uncheckedNextOffset(node, 5));
+    // EXPECT_EQ(5, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(6, nextGraphemeBoundaryOf(node, 5));
     // U+1F466(BOY) has EBG property.
     setBodyContent("<p id='target'>a&#x1F466;&#x1F3FB;b</p>"); // EBG x E_Modifier
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(5, uncheckedPreviousOffset(node, 6));
+    EXPECT_EQ(5, previousGraphemeBoundaryOf(node, 6));
     // TODO(nona): Enable following expectation.
-    // EXPECT_EQ(1, uncheckedPreviousOffset(node, 5));
-    EXPECT_EQ(0, uncheckedPreviousOffset(node, 1));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
+    // EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 5));
+    EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
     // TODO(nona): Enable following expectation.
-    // EXPECT_EQ(5, uncheckedNextOffset(node, 1));
-    EXPECT_EQ(6, uncheckedNextOffset(node, 5));
+    // EXPECT_EQ(5, nextGraphemeBoundaryOf(node, 1));
+    EXPECT_EQ(6, nextGraphemeBoundaryOf(node, 5));
 
     // GB11: Do not break within ZWJ emoji sequence.
     // U+2764(HEAVY BLACK HEART) has Glue_After_Zwj property.
     setBodyContent("<p id='target'>a&#x200D;&#x2764;b</p>"); // ZWJ x Glue_After_Zwj
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(3, uncheckedPreviousOffset(node, 4));
+    EXPECT_EQ(3, previousGraphemeBoundaryOf(node, 4));
     // TODO(nona): Enable following expectation.
-    // EXPECT_EQ(0, uncheckedPreviousOffset(node, 3));
-    // EXPECT_EQ(3, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(4, uncheckedNextOffset(node, 3));
+    // EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 3));
+    // EXPECT_EQ(3, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(4, nextGraphemeBoundaryOf(node, 3));
     setBodyContent("<p id='target'>a&#x200D;&#x1F466;b</p>"); // ZWJ x EBG
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(4, uncheckedPreviousOffset(node, 5));
+    EXPECT_EQ(4, previousGraphemeBoundaryOf(node, 5));
     // TODO(nona): Enable following expectation.
-    // EXPECT_EQ(0, uncheckedPreviousOffset(node, 4));
-    // EXPECT_EQ(4, uncheckedNextOffset(node, 0));
-    EXPECT_EQ(5, uncheckedNextOffset(node, 4));
+    // EXPECT_EQ(0, previousGraphemeBoundaryOf(node, 4));
+    // EXPECT_EQ(4, nextGraphemeBoundaryOf(node, 0));
+    EXPECT_EQ(5, nextGraphemeBoundaryOf(node, 4));
 
     // GB999: Otherwise break everywhere.
     // Breaks between Hangul syllable except for GB6, GB7, GB8.
     setBodyContent("<p id='target'>" + L + T + "</p>");
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
     setBodyContent("<p id='target'>" + V + L + "</p>");
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
     setBodyContent("<p id='target'>" + V + LV + "</p>");
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
     setBodyContent("<p id='target'>" + V + LVT + "</p>");
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
     setBodyContent("<p id='target'>" + LV + L + "</p>");
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
     setBodyContent("<p id='target'>" + LV + LV + "</p>");
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
     setBodyContent("<p id='target'>" + LV + LVT + "</p>");
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
     setBodyContent("<p id='target'>" + LVT + L + "</p>");
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
     setBodyContent("<p id='target'>" + LVT + V + "</p>");
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
     setBodyContent("<p id='target'>" + LVT + LV + "</p>");
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
     setBodyContent("<p id='target'>" + LVT + LVT + "</p>");
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
     setBodyContent("<p id='target'>" + T + L + "</p>");
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
     setBodyContent("<p id='target'>" + T + V + "</p>");
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
     setBodyContent("<p id='target'>" + T + LV + "</p>");
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
     setBodyContent("<p id='target'>" + T + LVT + "</p>");
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 2));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 2));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
 
     // For GB10, if base emoji character is not E_Base or EBG, break happens before E_Modifier.
     setBodyContent("<p id='target'>a&#x1F3FB;</p>");
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
     // U+1F5FA(WORLD MAP) doesn't have either E_Base or EBG property.
     setBodyContent("<p id='target'>&#x1F5FA;&#x1F3FB;</p>");
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(2, uncheckedPreviousOffset(node, 4));
-    EXPECT_EQ(2, uncheckedNextOffset(node, 0));
+    EXPECT_EQ(2, previousGraphemeBoundaryOf(node, 4));
+    EXPECT_EQ(2, nextGraphemeBoundaryOf(node, 0));
 
     // For GB11, if trailing character is not Glue_After_Zwj or EBG, break happens after ZWJ.
     // U+1F5FA(WORLD MAP) doesn't have either Glue_After_Zwj or EBG.
     setBodyContent("<p id='target'>&#x200D;&#x1F5FA;</p>");
     node = document().getElementById("target")->firstChild();
-    EXPECT_EQ(1, uncheckedPreviousOffset(node, 3));
-    EXPECT_EQ(1, uncheckedNextOffset(node, 0));
+    EXPECT_EQ(1, previousGraphemeBoundaryOf(node, 3));
+    EXPECT_EQ(1, nextGraphemeBoundaryOf(node, 0));
 }
 
 TEST_F(EditingUtilitiesTest, previousPositionOf_Backspace)
diff --git a/third_party/WebKit/Source/core/editing/PositionIterator.cpp b/third_party/WebKit/Source/core/editing/PositionIterator.cpp
index 5846f39..bd2d654 100644
--- a/third_party/WebKit/Source/core/editing/PositionIterator.cpp
+++ b/third_party/WebKit/Source/core/editing/PositionIterator.cpp
@@ -158,7 +158,7 @@
         // In this case |anchor| is a leaf(E,F,C,G or H) and
         // |m_offsetInAnchor| is not on the end of |anchor|.
         // Then just increment |m_offsetInAnchor|.
-        m_offsetInAnchor = uncheckedNextOffset(m_anchorNode, m_offsetInAnchor);
+        m_offsetInAnchor = nextGraphemeBoundaryOf(m_anchorNode, m_offsetInAnchor);
     } else {
         // Case #3. This is the next of Case #2 or #3.
         // Position is the end of |anchor|.
@@ -264,7 +264,7 @@
             // In this case |anchor| is a leaf(E,F,C,G or H) and
             // |m_offsetInAnchor| is not on the beginning of |anchor|.
             // Then just decrement |m_offsetInAnchor|.
-            m_offsetInAnchor = uncheckedPreviousOffset(m_anchorNode, m_offsetInAnchor);
+            m_offsetInAnchor = previousGraphemeBoundaryOf(m_anchorNode, m_offsetInAnchor);
             return;
         } else {
             // Case #3-b. This is a reverse of increment()::Case#1.
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
index bd4bd7e9..dd704fa 100644
--- a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
+++ b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
@@ -2268,7 +2268,7 @@
         }
         if (box->containsCaretOffset(textOffset)) {
             // Return false for offsets inside composed characters.
-            return textOffset == 0 || textOffset == uncheckedNextOffset(anchorNode, uncheckedPreviousOffset(anchorNode, textOffset));
+            return textOffset == 0 || textOffset == nextGraphemeBoundaryOf(anchorNode, previousGraphemeBoundaryOf(anchorNode, textOffset));
         }
     }
 
@@ -2851,7 +2851,7 @@
                 continue;
             }
 
-            offset = box->isLeftToRightDirection() ? uncheckedPreviousOffset(lineLayoutItem.node(), offset) : uncheckedNextOffset(lineLayoutItem.node(), offset);
+            offset = box->isLeftToRightDirection() ? previousGraphemeBoundaryOf(lineLayoutItem.node(), offset) : nextGraphemeBoundaryOf(lineLayoutItem.node(), offset);
 
             int caretMinOffset = box->caretMinOffset();
             int caretMaxOffset = box->caretMaxOffset();
@@ -3026,7 +3026,7 @@
                 continue;
             }
 
-            offset = box->isLeftToRightDirection() ? uncheckedNextOffset(layoutObject->node(), offset) : uncheckedPreviousOffset(layoutObject->node(), offset);
+            offset = box->isLeftToRightDirection() ? nextGraphemeBoundaryOf(layoutObject->node(), offset) : previousGraphemeBoundaryOf(layoutObject->node(), offset);
 
             int caretMinOffset = box->caretMinOffset();
             int caretMaxOffset = box->caretMaxOffset();
diff --git a/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp b/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp
index abfda0f..0d69e8e 100644
--- a/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp
+++ b/third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp
@@ -42,8 +42,8 @@
 #include "platform/testing/UnitTestHelpers.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebURL.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
 #include "public/platform/WebURLResponse.h"
-#include "public/platform/WebUnitTestSupport.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace blink {
@@ -90,7 +90,7 @@
     ImageResource* cachedImage = ImageResource::create(ResourceRequest(testURL), nullptr);
     cachedImage->setIdentifier(createUniqueIdentifier());
     cachedImage->load(fetcher);
-    Platform::current()->unitTestSupport()->unregisterMockedURL(testURL);
+    Platform::current()->getURLLoaderMockFactory()->unregisterURL(testURL);
 
     MockImageResourceClient client(cachedImage);
     EXPECT_EQ(Resource::Pending, cachedImage->getStatus());
@@ -170,7 +170,7 @@
     EXPECT_EQ(Resource::LoadError, cachedImage->getStatus());
     EXPECT_EQ(reinterpret_cast<Resource*>(0), memoryCache()->resourceForURL(testURL));
 
-    Platform::current()->unitTestSupport()->unregisterMockedURL(testURL);
+    Platform::current()->getURLLoaderMockFactory()->unregisterURL(testURL);
 }
 
 TEST(ImageResourceTest, DecodedDataRemainsWhileHasClients)
diff --git a/third_party/WebKit/Source/core/fetch/RawResourceTest.cpp b/third_party/WebKit/Source/core/fetch/RawResourceTest.cpp
index edadd2d..9b3085d 100644
--- a/third_party/WebKit/Source/core/fetch/RawResourceTest.cpp
+++ b/third_party/WebKit/Source/core/fetch/RawResourceTest.cpp
@@ -37,7 +37,6 @@
 #include "public/platform/Platform.h"
 #include "public/platform/WebURL.h"
 #include "public/platform/WebURLResponse.h"
-#include "public/platform/WebUnitTestSupport.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp b/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp
index ed069f8..6d565e3 100644
--- a/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp
+++ b/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp
@@ -42,8 +42,8 @@
 #include "platform/testing/URLTestHelpers.h"
 #include "platform/weborigin/KURL.h"
 #include "public/platform/Platform.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
 #include "public/platform/WebURLResponse.h"
-#include "public/platform/WebUnitTestSupport.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace blink {
@@ -134,12 +134,12 @@
 
     ResourceFetcher* fetcher = ResourceFetcher::create(ResourceFetcherTestMockFetchContext::create());
     FetchRequest fetchRequest = FetchRequest(url, FetchInitiatorInfo());
-    Platform::current()->unitTestSupport()->registerMockedURL(url, WebURLResponse(), "");
+    Platform::current()->getURLLoaderMockFactory()->registerURL(url, WebURLResponse(), "");
     Resource* newResource = fetcher->requestResource(fetchRequest, TestResourceFactory());
     EXPECT_NE(resource, newResource);
     newResource->loader()->cancel();
     memoryCache()->remove(newResource);
-    Platform::current()->unitTestSupport()->unregisterMockedURL(url);
+    Platform::current()->getURLLoaderMockFactory()->unregisterURL(url);
 
     memoryCache()->remove(resource);
 }
@@ -184,7 +184,7 @@
     FetchRequest fetchRequestOriginal = FetchRequest(url, FetchInitiatorInfo());
     Resource* resource = fetcher->requestResource(fetchRequestOriginal, TestResourceFactory(Resource::Image));
     ASSERT_TRUE(resource);
-    Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
+    Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
     ASSERT_TRUE(resource->hasVaryHeader());
 
     FetchRequest fetchRequest = FetchRequest(url, FetchInitiatorInfo());
@@ -192,13 +192,13 @@
     EXPECT_EQ(resource, newResource);
 
     memoryCache()->remove(newResource);
-    Platform::current()->unitTestSupport()->unregisterMockedURL(url);
+    Platform::current()->getURLLoaderMockFactory()->unregisterURL(url);
 }
 
 TEST_F(ResourceFetcherTest, RevalidateWhileLoading)
 {
     KURL url(ParsedURLString, "http://127.0.0.1:8000/foo.html");
-    Platform::current()->unitTestSupport()->registerMockedURL(url, WebURLResponse(), "");
+    Platform::current()->getURLLoaderMockFactory()->registerURL(url, WebURLResponse(), "");
 
     ResourceFetcher* fetcher1 = ResourceFetcher::create(ResourceFetcherTestMockFetchContext::create());
     ResourceRequest request1(url);
@@ -222,7 +222,7 @@
 
     // Tidily(?) shut down the ResourceLoader.
     resource1->loader()->cancel();
-    Platform::current()->unitTestSupport()->unregisterMockedURL(url);
+    Platform::current()->getURLLoaderMockFactory()->unregisterURL(url);
 }
 
 TEST_F(ResourceFetcherTest, DontReuseMediaDataUrl)
@@ -242,7 +242,7 @@
 public:
     void notifyFinished(Resource*) override
     {
-        Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
+        Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
     }
 
     // No callbacks should be received except for the notifyFinished()
@@ -277,7 +277,7 @@
     ServeRequestsOnCompleteClient client;
     resource->addClient(&client);
     resource->loader()->cancel();
-    Platform::current()->unitTestSupport()->unregisterMockedURL(url);
+    Platform::current()->getURLLoaderMockFactory()->unregisterURL(url);
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/frame/DOMWindow.h b/third_party/WebKit/Source/core/frame/DOMWindow.h
index 7461a06..510cb97 100644
--- a/third_party/WebKit/Source/core/frame/DOMWindow.h
+++ b/third_party/WebKit/Source/core/frame/DOMWindow.h
@@ -21,6 +21,7 @@
 class CSSRuleList;
 class CSSStyleDeclaration;
 class Console;
+class CustomElementsRegistry;
 class DOMSelection;
 class DOMWindowCSS;
 class Document;
@@ -174,6 +175,9 @@
     virtual int requestIdleCallback(IdleRequestCallback*, const IdleRequestOptions&) = 0;
     virtual void cancelIdleCallback(int id) = 0;
 
+    // Custom elements
+    virtual CustomElementsRegistry* customElements() const = 0;
+
     void captureEvents() { }
     void releaseEvents() { }
 
diff --git a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
index 16262f8..3852f1b 100644
--- a/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
+++ b/third_party/WebKit/Source/core/frame/ImageBitmap.cpp
@@ -141,7 +141,7 @@
         return StaticBitmapImage::create(adoptRef(croppedSkImage));
     }
 
-    RefPtr<SkSurface> surface = adoptRef(SkSurface::NewRasterN32Premul(cropRect.width(), cropRect.height()));
+    sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(cropRect.width(), cropRect.height());
     if (!surface)
         return nullptr;
     if (srcRect.isEmpty())
diff --git a/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp b/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp
index 0a0da75d..925d505 100644
--- a/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp
+++ b/third_party/WebKit/Source/core/frame/ImageBitmapTest.cpp
@@ -53,11 +53,11 @@
 protected:
     virtual void SetUp()
     {
-        RefPtr<SkSurface> surface = adoptRef(SkSurface::NewRasterN32Premul(10, 10));
+        sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(10, 10);
         surface->getCanvas()->clear(0xFFFFFFFF);
         m_image = adoptRef(surface->newImageSnapshot());
 
-        RefPtr<SkSurface> surface2 = adoptRef(SkSurface::NewRasterN32Premul(5, 5));
+        sk_sp<SkSurface> surface2 = SkSurface::MakeRasterN32Premul(5, 5);
         surface2->getCanvas()->clear(0xAAAAAAAA);
         m_image2 = adoptRef(surface2->newImageSnapshot());
 
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
index f178a4be..ff6ada9 100644
--- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
+++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.cpp
@@ -39,6 +39,7 @@
 #include "core/dom/ExecutionContextTask.h"
 #include "core/dom/FrameRequestCallback.h"
 #include "core/dom/SandboxFlags.h"
+#include "core/dom/custom/CustomElementsRegistry.h"
 #include "core/editing/Editor.h"
 #include "core/events/DOMWindowEventQueue.h"
 #include "core/events/HashChangeEvent.h"
@@ -552,6 +553,7 @@
     m_console = nullptr;
     m_navigator = nullptr;
     m_media = nullptr;
+    m_customElements = nullptr;
     m_applicationCache = nullptr;
 #if ENABLE(ASSERT)
     m_hasBeenReset = true;
@@ -1308,6 +1310,13 @@
         document->cancelIdleCallback(id);
 }
 
+CustomElementsRegistry* LocalDOMWindow::customElements() const
+{
+    if (!m_customElements)
+        m_customElements = CustomElementsRegistry::create();
+    return m_customElements.get();
+}
+
 bool LocalDOMWindow::addEventListenerInternal(const AtomicString& eventType, EventListener* listener, const EventListenerOptions& options)
 {
     if (!EventTarget::addEventListenerInternal(eventType, listener, options))
@@ -1504,6 +1513,7 @@
     visitor->trace(m_console);
     visitor->trace(m_navigator);
     visitor->trace(m_media);
+    visitor->trace(m_customElements);
     visitor->trace(m_applicationCache);
     visitor->trace(m_eventQueue);
     visitor->trace(m_postMessageTimers);
diff --git a/third_party/WebKit/Source/core/frame/LocalDOMWindow.h b/third_party/WebKit/Source/core/frame/LocalDOMWindow.h
index d2b0e76..f45aa85 100644
--- a/third_party/WebKit/Source/core/frame/LocalDOMWindow.h
+++ b/third_party/WebKit/Source/core/frame/LocalDOMWindow.h
@@ -42,6 +42,7 @@
 
 namespace blink {
 
+class CustomElementsRegistry;
 class DOMWindowEventQueue;
 class DOMWindowProperty;
 class DocumentInit;
@@ -145,6 +146,7 @@
     void cancelAnimationFrame(int id) override;
     int requestIdleCallback(IdleRequestCallback*, const IdleRequestOptions&) override;
     void cancelIdleCallback(int id) override;
+    CustomElementsRegistry* customElements() const override;
     void schedulePostMessage(MessageEvent*, SecurityOrigin* target, PassRefPtr<ScriptCallStack>);
 
     void registerProperty(DOMWindowProperty*);
@@ -261,6 +263,7 @@
     mutable Member<Console> m_console;
     mutable Member<Navigator> m_navigator;
     mutable Member<StyleMedia> m_media;
+    mutable Member<CustomElementsRegistry> m_customElements;
 
     String m_status;
     String m_defaultStatus;
diff --git a/third_party/WebKit/Source/core/frame/RemoteDOMWindow.cpp b/third_party/WebKit/Source/core/frame/RemoteDOMWindow.cpp
index 2950999..f2b0563 100644
--- a/third_party/WebKit/Source/core/frame/RemoteDOMWindow.cpp
+++ b/third_party/WebKit/Source/core/frame/RemoteDOMWindow.cpp
@@ -333,6 +333,12 @@
     ASSERT_NOT_REACHED();
 }
 
+CustomElementsRegistry* RemoteDOMWindow::customElements() const
+{
+    ASSERT_NOT_REACHED();
+    return nullptr;
+}
+
 RemoteDOMWindow::RemoteDOMWindow(RemoteFrame& frame)
     : m_frame(&frame)
 {
diff --git a/third_party/WebKit/Source/core/frame/RemoteDOMWindow.h b/third_party/WebKit/Source/core/frame/RemoteDOMWindow.h
index d0cb65d..7019b47f 100644
--- a/third_party/WebKit/Source/core/frame/RemoteDOMWindow.h
+++ b/third_party/WebKit/Source/core/frame/RemoteDOMWindow.h
@@ -78,6 +78,7 @@
     void cancelAnimationFrame(int id) override;
     int requestIdleCallback(IdleRequestCallback*, const IdleRequestOptions&) override;
     void cancelIdleCallback(int id) override;
+    CustomElementsRegistry* customElements() const override;
 
     void frameDetached();
 
diff --git a/third_party/WebKit/Source/core/frame/Window.idl b/third_party/WebKit/Source/core/frame/Window.idl
index d769657..22de1d6 100644
--- a/third_party/WebKit/Source/core/frame/Window.idl
+++ b/third_party/WebKit/Source/core/frame/Window.idl
@@ -86,6 +86,10 @@
 
     [DoNotCheckSecurity, Custom, RaisesException] void postMessage(any message, DOMString targetOrigin, optional sequence<Transferable> transfer);
 
+    // Custom elements
+    // http://w3c.github.io/webcomponents/spec/custom/#custom-elements-api
+    [RuntimeEnabled=CustomElementsV1] readonly attribute CustomElementsRegistry customElements;
+
     // HTML obsolete features
     // https://html.spec.whatwg.org/#Window-partial
     [MeasureAs=WindowCaptureEvents] void captureEvents();
diff --git a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
index e9e1a28..03aed59 100644
--- a/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp
@@ -126,7 +126,7 @@
 PassRefPtr<Image> createTransparentImage(const IntSize& size)
 {
     ASSERT(canCreateImageBuffer(size));
-    RefPtr<SkSurface> surface = adoptRef(SkSurface::NewRasterN32Premul(size.width(), size.height()));
+    sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(size.width(), size.height());
     surface->getCanvas()->clear(SK_ColorTRANSPARENT);
     return StaticBitmapImage::create(adoptRef(surface->newImageSnapshot()));
 }
diff --git a/third_party/WebKit/Source/core/html/HTMLImageFallbackHelper.cpp b/third_party/WebKit/Source/core/html/HTMLImageFallbackHelper.cpp
index 5f7fc8a..6cb3a73 100644
--- a/third_party/WebKit/Source/core/html/HTMLImageFallbackHelper.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLImageFallbackHelper.cpp
@@ -44,6 +44,7 @@
     container->setInlineStyleProperty(CSSPropertyDisplay, CSSValueInlineBlock);
     container->setInlineStyleProperty(CSSPropertyBoxSizing, CSSValueBorderBox);
     container->setInlineStyleProperty(CSSPropertyPadding, 1, CSSPrimitiveValue::UnitType::Pixels);
+    container->setInlineStyleProperty(CSSPropertyBorderRadius, ("inherit"));
 
     RawPtr<HTMLImageElement> brokenImage = HTMLImageElement::create(element.document());
     container->appendChild(brokenImage);
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.h b/third_party/WebKit/Source/core/layout/LayoutBox.h
index 1cf0809..1b1cb84 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBox.h
+++ b/third_party/WebKit/Source/core/layout/LayoutBox.h
@@ -895,6 +895,8 @@
     void removeFromPercentHeightContainer();
     void clearPercentHeightDescendants();
 
+    bool hitTestClippedOutByRoundedBorder(const HitTestLocation& locationInContainer, const LayoutPoint& borderBoxLocation) const;
+
 protected:
     void willBeDestroyed() override;
 
@@ -923,8 +925,6 @@
     void addLayerHitTestRects(LayerHitTestRects&, const PaintLayer* currentCompositedLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const override;
     void computeSelfHitTestRects(Vector<LayoutRect>&, const LayoutPoint& layerOffset) const override;
 
-    bool hitTestClippedOutByRoundedBorder(const HitTestLocation& locationInContainer, const LayoutPoint& borderBoxLocation) const;
-
     PaintInvalidationReason getPaintInvalidationReason(const LayoutBoxModelObject& paintInvalidationContainer,
         const LayoutRect& oldBounds, const LayoutPoint& oldPositionFromPaintInvalidationContainer,
         const LayoutRect& newBounds, const LayoutPoint& newPositionFromPaintInvalidationContainer) const override;
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.h b/third_party/WebKit/Source/core/layout/LayoutObject.h
index c406435f1..2c3fd82 100644
--- a/third_party/WebKit/Source/core/layout/LayoutObject.h
+++ b/third_party/WebKit/Source/core/layout/LayoutObject.h
@@ -217,6 +217,7 @@
 // See the individual getters below for more details about what each width is.
 class CORE_EXPORT LayoutObject : public ImageResourceObserver, public DisplayItemClient {
     friend class LayoutObjectChildList;
+    friend class VisualRectMappingTest;
     WTF_MAKE_NONCOPYABLE(LayoutObject);
 public:
     // Anonymous objects should pass the document as their node, and they will then automatically be
diff --git a/third_party/WebKit/Source/core/layout/LayoutObjectTest.cpp b/third_party/WebKit/Source/core/layout/LayoutObjectTest.cpp
index c9d18017..747069d 100644
--- a/third_party/WebKit/Source/core/layout/LayoutObjectTest.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutObjectTest.cpp
@@ -109,274 +109,4 @@
     EXPECT_EQ(layoutObject->containingBlock(), bodyLayoutObject);
 }
 
-TEST_F(LayoutObjectTest, LayoutTextMapToVisualRectInAncestorSpace)
-{
-    setBodyInnerHTML(
-        "<style>body { margin: 0; }</style>"
-        "<div id='container' style='overflow: scroll; width: 50px; height: 50px'>"
-        "  <span><img style='width: 20px; height: 100px'></span>"
-        "  text text text text text text text"
-        "</div>");
-
-    LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container"));
-    LayoutText* text = toLayoutText(container->lastChild());
-
-    container->setScrollTop(LayoutUnit(50));
-    LayoutRect rect(0, 60, 20, 80);
-    EXPECT_TRUE(text->mapToVisualRectInAncestorSpace(container, rect));
-    EXPECT_EQ(rect, LayoutRect(0, 10, 20, 80));
-
-    rect = LayoutRect(0, 60, 80, 0);
-    EXPECT_TRUE(text->mapToVisualRectInAncestorSpace(container, rect, EdgeInclusive));
-    EXPECT_EQ(rect, LayoutRect(0, 10, 80, 0));
-}
-
-TEST_F(LayoutObjectTest, LayoutInlineMapToVisualRectInAncestorSpace)
-{
-    document().setBaseURLOverride(KURL(ParsedURLString, "http://test.com"));
-    setBodyInnerHTML(
-        "<style>body { margin: 0; }</style>"
-        "<div id='container' style='overflow: scroll; width: 50px; height: 50px'>"
-        "  <span><img style='width: 20px; height: 100px'></span>"
-        "  <span id=leaf></span></div>");
-
-    LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container"));
-    LayoutObject* leaf = container->lastChild();
-
-    container->setScrollTop(LayoutUnit(50));
-    LayoutRect rect(0, 60, 20, 80);
-    EXPECT_TRUE(leaf->mapToVisualRectInAncestorSpace(container, rect));
-    EXPECT_EQ(rect, LayoutRect(0, 10, 20, 80));
-
-    rect = LayoutRect(0, 60, 80, 0);
-    EXPECT_TRUE(leaf->mapToVisualRectInAncestorSpace(container, rect, EdgeInclusive));
-    EXPECT_EQ(rect, LayoutRect(0, 10, 80, 0));
-}
-
-TEST_F(LayoutObjectTest, LayoutViewMapToVisualRectInAncestorSpace)
-{
-    document().setBaseURLOverride(KURL(ParsedURLString, "http://test.com"));
-    setBodyInnerHTML(
-        "<style>body { margin: 0; }</style>"
-        "<div id=frameContainer>"
-        "  <iframe id=frame src='http://test.com' width='50' height='50' frameBorder='0'></iframe>"
-        "</div>");
-
-    Document& frameDocument = setupChildIframe("frame", "<style>body { margin: 0; }</style><span><img style='width: 20px; height: 100px'></span>text text text");
-    frameDocument.updateLayout();
-
-    LayoutBlock* frameContainer = toLayoutBlock(getLayoutObjectByElementId("frameContainer"));
-    LayoutBlock* frameBody = toLayoutBlock(frameDocument.body()->layoutObject());
-    LayoutText* frameText = toLayoutText(frameBody->lastChild());
-
-    // This case involves clipping: frame height is 50, y-coordinate of result rect is 13,
-    // so height should be clipped to (50 - 13) == 37.
-    frameDocument.view()->setScrollPosition(DoublePoint(0, 47), ProgrammaticScroll);
-    LayoutRect rect(4, 60, 20, 80);
-    EXPECT_TRUE(frameText->mapToVisualRectInAncestorSpace(frameContainer, rect));
-    EXPECT_EQ(rect, LayoutRect(4, 13, 20, 37));
-
-    rect = LayoutRect(4, 60, 0, 80);
-    EXPECT_TRUE(frameText->mapToVisualRectInAncestorSpace(frameContainer, rect, EdgeInclusive));
-    EXPECT_EQ(rect, LayoutRect(4, 13, 0, 37));
-}
-
-TEST_F(LayoutObjectTest, LayoutViewMapToVisualRectInAncestorSpaceSubpixelRounding)
-{
-    document().setBaseURLOverride(KURL(ParsedURLString, "http://test.com"));
-    setBodyInnerHTML(
-        "<style>body { margin: 0; }</style>"
-        "<div id=frameContainer style='position: relative; left: 0.5px'>"
-        "  <iframe id=frame style='position: relative; left: 0.5px' src='http://test.com' width='200' height='200' frameBorder='0'></iframe>"
-        "</div>");
-
-    Document& frameDocument = setupChildIframe(
-        "frame", "<style>body { margin: 0; }</style><div id='target' style='position: relative; width: 100px; height: 100px; left: 0.5px'>");
-    frameDocument.updateLayout();
-
-    LayoutBlock* frameContainer = toLayoutBlock(getLayoutObjectByElementId("frameContainer"));
-    LayoutObject* target = frameDocument.getElementById("target")->layoutObject();
-    LayoutRect rect(0, 0, 100, 100);
-    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(frameContainer, rect));
-    // When passing from the iframe to the parent frame, the rect of (0.5, 0, 100, 100) is expanded to (0, 0, 100, 100), and then offset by
-    // the 0.5 offset of frameContainer.
-    EXPECT_EQ(LayoutRect(LayoutPoint(DoublePoint(0.5, 0)), LayoutSize(101, 100)), rect);
-}
-
-TEST_F(LayoutObjectTest, OverflowRectMappingWithSelfFlippedWritingMode)
-{
-    setBodyInnerHTML(
-        "<div id='target' style='writing-mode: vertical-rl; box-shadow: 40px 20px black;"
-        "    width: 100px; height: 50px; position: absolute; top: 111px; left: 222px'>"
-        "</div>");
-
-    LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target"));
-    LayoutRect overflowRect = target->localOverflowRectForPaintInvalidation();
-    // -40 = -box_shadow_offset_x(40) (with target's top-right corner as the origin)
-    // 140 = width(100) + box_shadow_offset_x(40)
-    // 70 = height(50) + box_shadow_offset_y(20)
-    EXPECT_EQ(LayoutRect(-40, 0, 140, 70), overflowRect);
-
-    LayoutRect rect = overflowRect;
-    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect));
-    // This rect is in physical coordinates of target.
-    EXPECT_EQ(LayoutRect(0, 0, 140, 70), rect);
-
-    rect = overflowRect;
-    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect));
-    EXPECT_EQ(LayoutRect(222, 111, 140, 70), rect);
-}
-
-TEST_F(LayoutObjectTest, OverflowRectMappingWithContainerFlippedWritingMode)
-{
-    setBodyInnerHTML(
-        "<div id='container' style='writing-mode: vertical-rl; position: absolute; top: 111px; left: 222px'>"
-        "    <div id='target' style='box-shadow: 40px 20px black; width: 100px; height: 90px'></div>"
-        "    <div style='width: 100px; height: 100px'></div>"
-        "</div>");
-
-    LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target"));
-    LayoutRect targetOverflowRect = target->localOverflowRectForPaintInvalidation();
-    // -40 = -box_shadow_offset_x(40) (with target's top-right corner as the origin)
-    // 140 = width(100) + box_shadow_offset_x(40)
-    // 110 = height(90) + box_shadow_offset_y(20)
-    EXPECT_EQ(LayoutRect(-40, 0, 140, 110), targetOverflowRect);
-
-    LayoutRect rect = targetOverflowRect;
-    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect));
-    // This rect is in physical coordinates of target.
-    EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect);
-
-    LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container"));
-    rect = targetOverflowRect;
-    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(container, rect));
-    // 100 is the physical x location of target in container.
-    EXPECT_EQ(LayoutRect(100, 0, 140, 110), rect);
-    rect = targetOverflowRect;
-    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect));
-    EXPECT_EQ(LayoutRect(322, 111, 140, 110), rect);
-
-    LayoutRect containerOverflowRect = container->localOverflowRectForPaintInvalidation();
-    EXPECT_EQ(LayoutRect(-40, 0, 240, 110), containerOverflowRect);
-    rect = containerOverflowRect;
-    EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(container, rect));
-    EXPECT_EQ(LayoutRect(0, 0, 240, 110), rect);
-    rect = containerOverflowRect;
-    EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(&layoutView(), rect));
-    EXPECT_EQ(LayoutRect(222, 111, 240, 110), rect);
-}
-
-TEST_F(LayoutObjectTest, OverflowRectMappingWithContainerOverflowClip)
-{
-    setBodyInnerHTML(
-        "<div id='container' style='position: absolute; top: 111px; left: 222px;"
-        "    border: 10px solid red; overflow: hidden; width: 50px; height: 80px;'>"
-        "    <div id='target' style='box-shadow: 40px 20px black; width: 100px; height: 90px'></div>"
-        "</div>");
-
-    LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container"));
-    EXPECT_EQ(LayoutUnit(0), container->scrollTop());
-    EXPECT_EQ(LayoutUnit(0), container->scrollLeft());
-    container->setScrollTop(LayoutUnit(7));
-    container->setScrollLeft(LayoutUnit(8));
-
-    LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target"));
-    LayoutRect targetOverflowRect = target->localOverflowRectForPaintInvalidation();
-    // 140 = width(100) + box_shadow_offset_x(40)
-    // 110 = height(90) + box_shadow_offset_y(20)
-    EXPECT_EQ(LayoutRect(0, 0, 140, 110), targetOverflowRect);
-    LayoutRect rect = targetOverflowRect;
-    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect));
-    EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect);
-
-    rect = targetOverflowRect;
-    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(container, rect));
-    // 2 = target_x(0) + container_border_left(10) - scroll_left(8)
-    // 3 = target_y(0) + container_border_top(10) - scroll_top(7)
-    // Rect is not clipped by container's overflow clip.
-    EXPECT_EQ(LayoutRect(2, 3, 140, 110), rect);
-
-    rect = targetOverflowRect;
-    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect));
-    // (2, 3, 140, 100) is first clipped by container's overflow clip, to (10, 10, 50, 80),
-    // then is by added container's offset in LayoutView (111, 222).
-    EXPECT_EQ(LayoutRect(232, 121, 50, 80), rect);
-
-    LayoutRect containerOverflowRect = container->localOverflowRectForPaintInvalidation();
-    // Because container has overflow clip, its visual overflow doesn't include overflow from children.
-    // 70 = width(50) + border_left_width(10) + border_right_width(10)
-    // 100 = height(80) + border_top_width(10) + border_bottom_width(10)
-    EXPECT_EQ(LayoutRect(0, 0, 70, 100), containerOverflowRect);
-    rect = containerOverflowRect;
-    EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(container, rect));
-    // Container should not apply overflow clip on its own overflow rect.
-    EXPECT_EQ(LayoutRect(0, 0, 70, 100), rect);
-
-    rect = containerOverflowRect;
-    EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(&layoutView(), rect));
-    EXPECT_EQ(LayoutRect(222, 111, 70, 100), rect);
-}
-
-TEST_F(LayoutObjectTest, OverflowRectMappingWithContainerFlippedWritingModeAndOverflowClip)
-{
-    setBodyInnerHTML(
-        "<div id='container' style='writing-mode: vertical-rl; position: absolute; top: 111px; left: 222px;"
-        "    border: solid red; border-width: 10px 20px 30px 40px;"
-        "    overflow: hidden; width: 50px; height: 80px'>"
-        "    <div id='target' style='box-shadow: 40px 20px black; width: 100px; height: 90px'></div>"
-        "    <div style='width: 100px; height: 100px'></div>"
-        "</div>");
-
-    LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container"));
-    EXPECT_EQ(LayoutUnit(0), container->scrollTop());
-    // The initial scroll offset is to the left-most because of flipped blocks writing mode.
-    // 150 = total_layout_overflow(100 + 100) - width(50)
-    EXPECT_EQ(LayoutUnit(150), container->scrollLeft());
-    container->setScrollTop(LayoutUnit(7));
-    container->setScrollLeft(LayoutUnit(142)); // Scroll to the right by 8 pixels.
-
-    LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target"));
-    LayoutRect targetOverflowRect = target->localOverflowRectForPaintInvalidation();
-    // -40 = -box_shadow_offset_x(40) (with target's top-right corner as the origin)
-    // 140 = width(100) + box_shadow_offset_x(40)
-    // 110 = height(90) + box_shadow_offset_y(20)
-    EXPECT_EQ(LayoutRect(-40, 0, 140, 110), targetOverflowRect);
-
-    LayoutRect rect = targetOverflowRect;
-    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect));
-    // This rect is in physical coordinates of target.
-    EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect);
-
-    rect = targetOverflowRect;
-    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(container, rect));
-    // -2 = target_physical_x(100) + container_border_left(40) - scroll_left(142)
-    // 3 = target_y(0) + container_border_top(10) - scroll_top(7)
-    // Rect is not clipped by container's overflow clip.
-    EXPECT_EQ(LayoutRect(-2, 3, 140, 110), rect);
-
-    rect = targetOverflowRect;
-    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect));
-    // (-2, 3, 140, 100) is first clipped by container's overflow clip, to (40, 10, 50, 80),
-    // then is added by container's offset in LayoutView (111, 222).
-    // TODO(crbug.com/600039): rect.x() should be 262 (left + border-left), but is offset
-    // by extra horizontal border-widths because of layout error.
-    EXPECT_EQ(LayoutRect(322, 121, 50, 80), rect);
-
-    LayoutRect containerOverflowRect = container->localOverflowRectForPaintInvalidation();
-    // Because container has overflow clip, its visual overflow doesn't include overflow from children.
-    // 110 = width(50) + border_left_width(40) + border_right_width(20)
-    // 120 = height(80) + border_top_width(10) + border_bottom_width(30)
-    EXPECT_EQ(LayoutRect(0, 0, 110, 120), containerOverflowRect);
-
-    rect = containerOverflowRect;
-    EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(container, rect));
-    EXPECT_EQ(LayoutRect(0, 0, 110, 120), rect);
-
-    rect = containerOverflowRect;
-    EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(&layoutView(), rect));
-    // TODO(crbug.com/600039): rect.x() should be 222 (left), but is offset by extra horizontal
-    // border-widths because of layout error.
-    EXPECT_EQ(LayoutRect(282, 111, 110, 120), rect);
-}
-
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp b/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp
index 4ba7f63..2178eb5 100644
--- a/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp
+++ b/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp
@@ -134,19 +134,10 @@
 
     ASSERT(parentState.m_didUpdateForChildren);
 
-    EPosition position = currentObject.styleRef().position();
-
     if (currentObject.isPaintInvalidationContainer()) {
         m_paintInvalidationContainer = toLayoutBoxModelObject(&currentObject);
-        if (currentObject.styleRef().isStackingContext()) {
+        if (currentObject.styleRef().isStackingContext())
             m_paintInvalidationContainerForStackedContents = toLayoutBoxModelObject(&currentObject);
-            // Adjust cached offsets for absolute-position to be relative to this new paintInvalidationContainer.
-            if (m_cachedOffsetsForAbsolutePositionEnabled && m_cachedOffsetsEnabled) {
-                m_paintOffsetForAbsolutePosition -= m_paintOffset;
-                if (m_clippedForAbsolutePosition)
-                    m_clipRectForAbsolutePosition.move(-m_paintOffset);
-            }
-        }
     } else if (currentObject.isLayoutView()) {
         // m_paintInvalidationContainerForStackedContents is only for stacked descendants in its own frame,
         // because it doesn't establish stacking context for stacked contents in sub-frames.
@@ -194,31 +185,52 @@
         m_forcedSubtreeInvalidationWithinContainer = false;
         m_forcedSubtreeInvalidationRectUpdateWithinContainer = false;
 
+        if (currentObject == m_paintInvalidationContainerForStackedContents
+            && currentObject != m_containerForAbsolutePosition
+            && m_cachedOffsetsForAbsolutePositionEnabled
+            && m_cachedOffsetsEnabled) {
+            // The current object is the new paintInvalidationContainer for absolute-position descendants but is not their container.
+            // Call updateForCurrentObject() before resetting m_paintOffset to get paint offset of the current object
+            // from the original paintInvalidationContainerForStackingContents, then use this paint offset to adjust
+            // m_paintOffsetForAbsolutePosition.
+            updateForCurrentObject(parentState);
+            m_paintOffsetForAbsolutePosition -= m_paintOffset;
+            if (m_clippedForAbsolutePosition)
+                m_clipRectForAbsolutePosition.move(-m_paintOffset);
+        }
+
         m_clipped = false; // Will be updated in updateForChildren().
         m_paintOffset = LayoutSize();
         return;
     }
 
+    updateForCurrentObject(parentState);
+}
+
+void PaintInvalidationState::updateForCurrentObject(const PaintInvalidationState& parentState)
+{
     if (!m_cachedOffsetsEnabled)
         return;
 
-    if (currentObject.isLayoutView()) {
-        ASSERT(&parentState.m_currentObject == toLayoutView(currentObject).frame()->ownerLayoutObject());
+    if (m_currentObject.isLayoutView()) {
+        ASSERT(&parentState.m_currentObject == toLayoutView(m_currentObject).frame()->ownerLayoutObject());
         m_paintOffset += toLayoutBox(parentState.m_currentObject).contentBoxOffset();
         // a LayoutView paints with a defined size but a pixel-rounded offset.
         m_paintOffset = LayoutSize(roundedIntSize(m_paintOffset));
         return;
     }
 
+    EPosition position = m_currentObject.styleRef().position();
+
     if (position == FixedPosition) {
-        if (m_paintInvalidationContainer != currentObject.view() && m_paintInvalidationContainer->view() == currentObject.view()) {
+        if (m_paintInvalidationContainer != m_currentObject.view() && m_paintInvalidationContainer->view() == m_currentObject.view()) {
             // TODO(crbug.com/598762): localToAncestorPoint() is incorrect for fixed-position when paintInvalidationContainer
             // is under the containing LayoutView.
             m_cachedOffsetsEnabled = false;
             return;
         }
         // Use slow path to get the offset of the fixed-position, and enable fast path for descendants.
-        FloatPoint fixedOffset = currentObject.localToAncestorPoint(FloatPoint(), m_paintInvalidationContainer, TraverseDocumentBoundaries);
+        FloatPoint fixedOffset = m_currentObject.localToAncestorPoint(FloatPoint(), m_paintInvalidationContainer, TraverseDocumentBoundaries);
         m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y());
         // In the above way to get paint offset, we can't get accurate clip rect, so just assume no clip.
         // Clip on fixed-position is rare, in case that paintInvalidationContainer crosses frame boundary
@@ -242,11 +254,11 @@
             m_paintOffset += toLayoutInline(container).offsetForInFlowPositionedInline(toLayoutBox(m_currentObject));
     }
 
-    if (currentObject.isBox())
-        m_paintOffset += toLayoutBox(currentObject).locationOffset();
+    if (m_currentObject.isBox())
+        m_paintOffset += toLayoutBox(m_currentObject).locationOffset();
 
-    if (currentObject.isInFlowPositioned() && currentObject.hasLayer())
-        m_paintOffset += toLayoutBoxModelObject(currentObject).layer()->offsetForInFlowPosition();
+    if (m_currentObject.isInFlowPositioned() && m_currentObject.hasLayer())
+        m_paintOffset += toLayoutBoxModelObject(m_currentObject).layer()->offsetForInFlowPosition();
 }
 
 void PaintInvalidationState::updateForChildren()
@@ -399,7 +411,7 @@
     }
 }
 
-void PaintInvalidationState::mapLocalRectToPaintInvalidationBacking(LayoutRect& rect) const
+void PaintInvalidationState::mapLocalRectToPaintInvalidationContainer(LayoutRect& rect) const
 {
     ASSERT(!m_didUpdateForChildren);
 
@@ -420,6 +432,11 @@
     } else {
         slowMapToVisualRectInAncestorSpace(m_currentObject, *m_paintInvalidationContainer, rect);
     }
+}
+
+void PaintInvalidationState::mapLocalRectToPaintInvalidationBacking(LayoutRect& rect) const
+{
+    mapLocalRectToPaintInvalidationContainer(rect);
 
     if (m_paintInvalidationContainer->layer()->groupedMapping())
         PaintLayer::mapRectInPaintInvalidationContainerToBacking(*m_paintInvalidationContainer, rect);
diff --git a/third_party/WebKit/Source/core/layout/PaintInvalidationState.h b/third_party/WebKit/Source/core/layout/PaintInvalidationState.h
index 8852577..50e2c73 100644
--- a/third_party/WebKit/Source/core/layout/PaintInvalidationState.h
+++ b/third_party/WebKit/Source/core/layout/PaintInvalidationState.h
@@ -5,6 +5,7 @@
 #ifndef PaintInvalidationState_h
 #define PaintInvalidationState_h
 
+#include "core/CoreExport.h"
 #include "platform/geometry/LayoutRect.h"
 #include "platform/transforms/AffineTransform.h"
 #include "wtf/Allocator.h"
@@ -35,7 +36,7 @@
 //
 // See Source/core/paint/README.md ### PaintInvalidationState for more details.
 
-class PaintInvalidationState {
+class CORE_EXPORT PaintInvalidationState {
     DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
     WTF_MAKE_NONCOPYABLE(PaintInvalidationState);
 public:
@@ -81,14 +82,17 @@
 #endif
 
 private:
+    friend class VisualRectMappingTest;
+
+    void mapLocalRectToPaintInvalidationContainer(LayoutRect&) const;
+
+    void updateForCurrentObject(const PaintInvalidationState& parentState);
     void updateForNormalChildren();
 
     LayoutRect computePaintInvalidationRectInBackingForSVG() const;
 
     void addClipRectRelativeToPaintOffset(const LayoutRect& localClipRect);
 
-    friend class ForceHorriblySlowRectMapping;
-
     const LayoutObject& m_currentObject;
 
     bool m_forcedSubtreeInvalidationWithinContainer;
@@ -108,7 +112,7 @@
 
     // Whether m_paintOffset[XXX] and m_clipRect[XXX] are valid and can be used
     // to map a rect from space of the current object to space of paintInvalidationContainer.
-    mutable bool m_cachedOffsetsEnabled;
+    bool m_cachedOffsetsEnabled;
     bool m_cachedOffsetsForAbsolutePositionEnabled;
 
     // The following two fields are never null. Declare them as pointers because we need some
diff --git a/third_party/WebKit/Source/core/layout/VisualRectMappingTest.cpp b/third_party/WebKit/Source/core/layout/VisualRectMappingTest.cpp
new file mode 100644
index 0000000..07fc9d6
--- /dev/null
+++ b/third_party/WebKit/Source/core/layout/VisualRectMappingTest.cpp
@@ -0,0 +1,416 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/layout/LayoutTestHelper.h"
+#include "core/layout/LayoutView.h"
+#include "core/layout/PaintInvalidationState.h"
+#include "core/paint/PaintLayer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace blink {
+
+class VisualRectMappingTest : public RenderingTest {
+public:
+    VisualRectMappingTest()
+        : RenderingTest(SingleChildFrameLoaderClient::create()) {}
+protected:
+    LayoutView& layoutView() const { return *document().layoutView(); }
+
+    void checkPaintInvalidationStateRectMapping(const LayoutRect& expectedRect, const LayoutRect& rect, const LayoutObject& object, const LayoutView& layoutView, const LayoutObject& paintInvalidationContainer)
+    {
+        Vector<const LayoutObject*> ancestors;
+        for (const LayoutObject* ancestor = &object; ancestor != layoutView; ancestor = ancestor->parentCrossingFrameBoundaries())
+            ancestors.append(ancestor);
+
+        Vector<Optional<PaintInvalidationState>> paintInvalidationStates(ancestors.size() + 1);
+        Vector<LayoutObject*> pendingDelayedPaintInvalidations;
+        paintInvalidationStates[0].emplace(layoutView, pendingDelayedPaintInvalidations);
+        if (layoutView != object)
+            paintInvalidationStates[0]->updateForChildren();
+        for (size_t i = 1; i < paintInvalidationStates.size(); ++i) {
+            paintInvalidationStates[i].emplace(*paintInvalidationStates[i - 1], *ancestors[ancestors.size() - i]);
+            if (paintInvalidationStates[i]->m_currentObject != object)
+                paintInvalidationStates[i]->updateForChildren();
+        }
+
+        const PaintInvalidationState& paintInvalidationState = *paintInvalidationStates.last();
+        ASSERT_EQ(paintInvalidationState.m_currentObject, object);
+        ASSERT_EQ(&paintInvalidationState.paintInvalidationContainer(), &paintInvalidationContainer);
+
+        LayoutRect r = rect;
+        paintInvalidationState.mapLocalRectToPaintInvalidationContainer(r);
+        EXPECT_EQ(expectedRect, r);
+    }
+};
+
+TEST_F(VisualRectMappingTest, LayoutText)
+{
+    setBodyInnerHTML(
+        "<style>body { margin: 0; }</style>"
+        "<div id='container' style='overflow: scroll; width: 50px; height: 50px'>"
+        "  <span><img style='width: 20px; height: 100px'></span>"
+        "  text text text text text text text"
+        "</div>");
+
+    LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container"));
+    LayoutText* text = toLayoutText(container->lastChild());
+
+    container->setScrollTop(LayoutUnit(50));
+    LayoutRect originalRect(0, 60, 20, 80);
+    LayoutRect rect = originalRect;
+    EXPECT_TRUE(text->mapToVisualRectInAncestorSpace(container, rect));
+    EXPECT_EQ(rect, LayoutRect(0, 10, 20, 80));
+
+    rect = originalRect;
+    EXPECT_TRUE(text->mapToVisualRectInAncestorSpace(&layoutView(), rect));
+    EXPECT_EQ(rect, LayoutRect(0, 10, 20, 40));
+    checkPaintInvalidationStateRectMapping(rect, originalRect, *text, layoutView(), layoutView());
+
+    rect = LayoutRect(0, 60, 80, 0);
+    EXPECT_TRUE(text->mapToVisualRectInAncestorSpace(container, rect, EdgeInclusive));
+    EXPECT_EQ(rect, LayoutRect(0, 10, 80, 0));
+}
+
+TEST_F(VisualRectMappingTest, LayoutInline)
+{
+    document().setBaseURLOverride(KURL(ParsedURLString, "http://test.com"));
+    setBodyInnerHTML(
+        "<style>body { margin: 0; }</style>"
+        "<div id='container' style='overflow: scroll; width: 50px; height: 50px'>"
+        "  <span><img style='width: 20px; height: 100px'></span>"
+        "  <span id=leaf></span></div>");
+
+    LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container"));
+    LayoutObject* leaf = container->lastChild();
+
+    container->setScrollTop(LayoutUnit(50));
+    LayoutRect originalRect(0, 60, 20, 80);
+    LayoutRect rect = originalRect;
+    EXPECT_TRUE(leaf->mapToVisualRectInAncestorSpace(container, rect));
+    EXPECT_EQ(rect, LayoutRect(0, 10, 20, 80));
+
+    rect = originalRect;
+    EXPECT_TRUE(leaf->mapToVisualRectInAncestorSpace(&layoutView(), rect));
+    EXPECT_EQ(rect, LayoutRect(0, 10, 20, 40));
+    checkPaintInvalidationStateRectMapping(rect, originalRect, *leaf, layoutView(), layoutView());
+
+    rect = LayoutRect(0, 60, 80, 0);
+    EXPECT_TRUE(leaf->mapToVisualRectInAncestorSpace(container, rect, EdgeInclusive));
+    EXPECT_EQ(rect, LayoutRect(0, 10, 80, 0));
+}
+
+TEST_F(VisualRectMappingTest, LayoutView)
+{
+    document().setBaseURLOverride(KURL(ParsedURLString, "http://test.com"));
+    setBodyInnerHTML(
+        "<style>body { margin: 0; }</style>"
+        "<div id=frameContainer>"
+        "  <iframe id=frame src='http://test.com' width='50' height='50' frameBorder='0'></iframe>"
+        "</div>");
+
+    Document& frameDocument = setupChildIframe("frame", "<style>body { margin: 0; }</style><span><img style='width: 20px; height: 100px'></span>text text text");
+    document().view()->updateAllLifecyclePhases();
+
+    LayoutBlock* frameContainer = toLayoutBlock(getLayoutObjectByElementId("frameContainer"));
+    LayoutBlock* frameBody = toLayoutBlock(frameDocument.body()->layoutObject());
+    LayoutText* frameText = toLayoutText(frameBody->lastChild());
+
+    // This case involves clipping: frame height is 50, y-coordinate of result rect is 13,
+    // so height should be clipped to (50 - 13) == 37.
+    frameDocument.view()->setScrollPosition(DoublePoint(0, 47), ProgrammaticScroll);
+    LayoutRect originalRect(4, 60, 20, 80);
+    LayoutRect rect = originalRect;
+    EXPECT_TRUE(frameText->mapToVisualRectInAncestorSpace(frameContainer, rect));
+    EXPECT_EQ(rect, LayoutRect(4, 13, 20, 37));
+
+    rect = originalRect;
+    EXPECT_TRUE(frameText->mapToVisualRectInAncestorSpace(&layoutView(), rect));
+    EXPECT_EQ(rect, LayoutRect(4, 13, 20, 37));
+    checkPaintInvalidationStateRectMapping(rect, originalRect, *frameText, layoutView(), layoutView());
+
+    rect = LayoutRect(4, 60, 0, 80);
+    EXPECT_TRUE(frameText->mapToVisualRectInAncestorSpace(frameContainer, rect, EdgeInclusive));
+    EXPECT_EQ(rect, LayoutRect(4, 13, 0, 37));
+}
+
+TEST_F(VisualRectMappingTest, LayoutViewSubpixelRounding)
+{
+    document().setBaseURLOverride(KURL(ParsedURLString, "http://test.com"));
+    setBodyInnerHTML(
+        "<style>body { margin: 0; }</style>"
+        "<div id=frameContainer style='position: relative; left: 0.5px'>"
+        "  <iframe id=frame style='position: relative; left: 0.5px' src='http://test.com' width='200' height='200' frameBorder='0'></iframe>"
+        "</div>");
+
+    Document& frameDocument = setupChildIframe(
+        "frame", "<style>body { margin: 0; }</style><div id='target' style='position: relative; width: 100px; height: 100px; left: 0.5px'>");
+    document().view()->updateAllLifecyclePhases();
+
+    LayoutBlock* frameContainer = toLayoutBlock(getLayoutObjectByElementId("frameContainer"));
+    LayoutObject* target = frameDocument.getElementById("target")->layoutObject();
+    LayoutRect rect(0, 0, 100, 100);
+    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(frameContainer, rect));
+    // When passing from the iframe to the parent frame, the rect of (0.5, 0, 100, 100) is expanded to (0, 0, 100, 100), and then offset by
+    // the 0.5 offset of frameContainer.
+    EXPECT_EQ(LayoutRect(LayoutPoint(DoublePoint(0.5, 0)), LayoutSize(101, 100)), rect);
+}
+
+TEST_F(VisualRectMappingTest, SelfFlippedWritingMode)
+{
+    setBodyInnerHTML(
+        "<div id='target' style='writing-mode: vertical-rl; box-shadow: 40px 20px black;"
+        "    width: 100px; height: 50px; position: absolute; top: 111px; left: 222px'>"
+        "</div>");
+
+    LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target"));
+    LayoutRect overflowRect = target->localOverflowRectForPaintInvalidation();
+    // -40 = -box_shadow_offset_x(40) (with target's top-right corner as the origin)
+    // 140 = width(100) + box_shadow_offset_x(40)
+    // 70 = height(50) + box_shadow_offset_y(20)
+    EXPECT_EQ(LayoutRect(-40, 0, 140, 70), overflowRect);
+
+    LayoutRect rect = overflowRect;
+    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect));
+    // This rect is in physical coordinates of target.
+    EXPECT_EQ(LayoutRect(0, 0, 140, 70), rect);
+
+    rect = overflowRect;
+    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect));
+    EXPECT_EQ(LayoutRect(222, 111, 140, 70), rect);
+    checkPaintInvalidationStateRectMapping(rect, overflowRect, *target, layoutView(), layoutView());
+}
+
+TEST_F(VisualRectMappingTest, ContainerFlippedWritingMode)
+{
+    setBodyInnerHTML(
+        "<div id='container' style='writing-mode: vertical-rl; position: absolute; top: 111px; left: 222px'>"
+        "    <div id='target' style='box-shadow: 40px 20px black; width: 100px; height: 90px'></div>"
+        "    <div style='width: 100px; height: 100px'></div>"
+        "</div>");
+
+    LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target"));
+    LayoutRect targetOverflowRect = target->localOverflowRectForPaintInvalidation();
+    // -40 = -box_shadow_offset_x(40) (with target's top-right corner as the origin)
+    // 140 = width(100) + box_shadow_offset_x(40)
+    // 110 = height(90) + box_shadow_offset_y(20)
+    EXPECT_EQ(LayoutRect(-40, 0, 140, 110), targetOverflowRect);
+
+    LayoutRect rect = targetOverflowRect;
+    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect));
+    // This rect is in physical coordinates of target.
+    EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect);
+
+    LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container"));
+    rect = targetOverflowRect;
+    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(container, rect));
+    // 100 is the physical x location of target in container.
+    EXPECT_EQ(LayoutRect(100, 0, 140, 110), rect);
+    rect = targetOverflowRect;
+    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect));
+    EXPECT_EQ(LayoutRect(322, 111, 140, 110), rect);
+    checkPaintInvalidationStateRectMapping(rect, targetOverflowRect, *target, layoutView(), layoutView());
+
+    LayoutRect containerOverflowRect = container->localOverflowRectForPaintInvalidation();
+    EXPECT_EQ(LayoutRect(-40, 0, 240, 110), containerOverflowRect);
+    rect = containerOverflowRect;
+    EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(container, rect));
+    EXPECT_EQ(LayoutRect(0, 0, 240, 110), rect);
+    rect = containerOverflowRect;
+    EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(&layoutView(), rect));
+    EXPECT_EQ(LayoutRect(222, 111, 240, 110), rect);
+    checkPaintInvalidationStateRectMapping(rect, containerOverflowRect, *container, layoutView(), layoutView());
+}
+
+TEST_F(VisualRectMappingTest, ContainerOverflowClip)
+{
+    setBodyInnerHTML(
+        "<div id='container' style='position: absolute; top: 111px; left: 222px;"
+        "    border: 10px solid red; overflow: hidden; width: 50px; height: 80px;'>"
+        "    <div id='target' style='box-shadow: 40px 20px black; width: 100px; height: 90px'></div>"
+        "</div>");
+
+    LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container"));
+    EXPECT_EQ(LayoutUnit(0), container->scrollTop());
+    EXPECT_EQ(LayoutUnit(0), container->scrollLeft());
+    container->setScrollTop(LayoutUnit(7));
+    container->setScrollLeft(LayoutUnit(8));
+    document().view()->updateAllLifecyclePhases();
+
+    LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target"));
+    LayoutRect targetOverflowRect = target->localOverflowRectForPaintInvalidation();
+    // 140 = width(100) + box_shadow_offset_x(40)
+    // 110 = height(90) + box_shadow_offset_y(20)
+    EXPECT_EQ(LayoutRect(0, 0, 140, 110), targetOverflowRect);
+    LayoutRect rect = targetOverflowRect;
+    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect));
+    EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect);
+
+    rect = targetOverflowRect;
+    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(container, rect));
+    // 2 = target_x(0) + container_border_left(10) - scroll_left(8)
+    // 3 = target_y(0) + container_border_top(10) - scroll_top(7)
+    // Rect is not clipped by container's overflow clip.
+    EXPECT_EQ(LayoutRect(2, 3, 140, 110), rect);
+
+    rect = targetOverflowRect;
+    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect));
+    // (2, 3, 140, 100) is first clipped by container's overflow clip, to (10, 10, 50, 80),
+    // then is by added container's offset in LayoutView (111, 222).
+    EXPECT_EQ(LayoutRect(232, 121, 50, 80), rect);
+    checkPaintInvalidationStateRectMapping(rect, targetOverflowRect, *target, layoutView(), layoutView());
+
+    LayoutRect containerOverflowRect = container->localOverflowRectForPaintInvalidation();
+    // Because container has overflow clip, its visual overflow doesn't include overflow from children.
+    // 70 = width(50) + border_left_width(10) + border_right_width(10)
+    // 100 = height(80) + border_top_width(10) + border_bottom_width(10)
+    EXPECT_EQ(LayoutRect(0, 0, 70, 100), containerOverflowRect);
+    rect = containerOverflowRect;
+    EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(container, rect));
+    // Container should not apply overflow clip on its own overflow rect.
+    EXPECT_EQ(LayoutRect(0, 0, 70, 100), rect);
+
+    rect = containerOverflowRect;
+    EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(&layoutView(), rect));
+    EXPECT_EQ(LayoutRect(222, 111, 70, 100), rect);
+    checkPaintInvalidationStateRectMapping(rect, containerOverflowRect, *container, layoutView(), layoutView());
+}
+
+TEST_F(VisualRectMappingTest, ContainerFlippedWritingModeAndOverflowClip)
+{
+    setBodyInnerHTML(
+        "<div id='container' style='writing-mode: vertical-rl; position: absolute; top: 111px; left: 222px;"
+        "    border: solid red; border-width: 10px 20px 30px 40px;"
+        "    overflow: hidden; width: 50px; height: 80px'>"
+        "    <div id='target' style='box-shadow: 40px 20px black; width: 100px; height: 90px'></div>"
+        "    <div style='width: 100px; height: 100px'></div>"
+        "</div>");
+
+    LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container"));
+    EXPECT_EQ(LayoutUnit(0), container->scrollTop());
+    // The initial scroll offset is to the left-most because of flipped blocks writing mode.
+    // 150 = total_layout_overflow(100 + 100) - width(50)
+    EXPECT_EQ(LayoutUnit(150), container->scrollLeft());
+    container->setScrollTop(LayoutUnit(7));
+    container->setScrollLeft(LayoutUnit(142)); // Scroll to the right by 8 pixels.
+    document().view()->updateAllLifecyclePhases();
+
+    LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target"));
+    LayoutRect targetOverflowRect = target->localOverflowRectForPaintInvalidation();
+    // -40 = -box_shadow_offset_x(40) (with target's top-right corner as the origin)
+    // 140 = width(100) + box_shadow_offset_x(40)
+    // 110 = height(90) + box_shadow_offset_y(20)
+    EXPECT_EQ(LayoutRect(-40, 0, 140, 110), targetOverflowRect);
+
+    LayoutRect rect = targetOverflowRect;
+    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect));
+    // This rect is in physical coordinates of target.
+    EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect);
+
+    rect = targetOverflowRect;
+    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(container, rect));
+    // -2 = target_physical_x(100) + container_border_left(40) - scroll_left(142)
+    // 3 = target_y(0) + container_border_top(10) - scroll_top(7)
+    // Rect is not clipped by container's overflow clip.
+    EXPECT_EQ(LayoutRect(-2, 3, 140, 110), rect);
+
+    rect = targetOverflowRect;
+    EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect));
+    // (-2, 3, 140, 100) is first clipped by container's overflow clip, to (40, 10, 50, 80),
+    // then is added by container's offset in LayoutView (111, 222).
+    // TODO(crbug.com/600039): rect.x() should be 262 (left + border-left), but is offset
+    // by extra horizontal border-widths because of layout error.
+    EXPECT_EQ(LayoutRect(322, 121, 50, 80), rect);
+    checkPaintInvalidationStateRectMapping(rect, targetOverflowRect, *target, layoutView(), layoutView());
+
+    LayoutRect containerOverflowRect = container->localOverflowRectForPaintInvalidation();
+    // Because container has overflow clip, its visual overflow doesn't include overflow from children.
+    // 110 = width(50) + border_left_width(40) + border_right_width(20)
+    // 120 = height(80) + border_top_width(10) + border_bottom_width(30)
+    EXPECT_EQ(LayoutRect(0, 0, 110, 120), containerOverflowRect);
+
+    rect = containerOverflowRect;
+    EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(container, rect));
+    EXPECT_EQ(LayoutRect(0, 0, 110, 120), rect);
+
+    rect = containerOverflowRect;
+    EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(&layoutView(), rect));
+    // TODO(crbug.com/600039): rect.x() should be 222 (left), but is offset by extra horizontal
+    // border-widths because of layout error.
+    EXPECT_EQ(LayoutRect(282, 111, 110, 120), rect);
+    checkPaintInvalidationStateRectMapping(rect, containerOverflowRect, *container, layoutView(), layoutView());
+}
+
+TEST_F(VisualRectMappingTest, DifferentPaintInvalidaitionContainerForAbsolutePosition)
+{
+    enableCompositing();
+    document().frame()->settings()->setPreferCompositingToLCDTextEnabled(true);
+
+    setBodyInnerHTML(
+        "<div id='stacking-context' style='opacity: 0.9; background: blue; will-change: transform'>"
+        "    <div id='scroller' style='overflow: scroll; width: 80px; height: 80px'>"
+        "        <div id='absolute' style='position: absolute; top: 111px; left: 222px; width: 50px; height: 50px; background: green'></div>"
+        "        <div id='normal-flow' style='width: 2000px; height: 2000px; background: yellow'></div>"
+        "    </div>"
+        "</div>");
+
+    LayoutBlock* scroller = toLayoutBlock(getLayoutObjectByElementId("scroller"));
+    scroller->setScrollTop(LayoutUnit(77));
+    scroller->setScrollLeft(LayoutUnit(88));
+    document().view()->updateAllLifecyclePhases();
+
+    LayoutBlock* normalFlow = toLayoutBlock(getLayoutObjectByElementId("normal-flow"));
+    EXPECT_EQ(scroller, &normalFlow->containerForPaintInvalidation());
+
+    LayoutRect normalFlowOverflowRect = normalFlow->localOverflowRectForPaintInvalidation();
+    EXPECT_EQ(LayoutRect(0, 0, 2000, 2000), normalFlowOverflowRect);
+    LayoutRect rect = normalFlowOverflowRect;
+    EXPECT_TRUE(normalFlow->mapToVisualRectInAncestorSpace(scroller, rect));
+    EXPECT_EQ(LayoutRect(-88, -77, 2000, 2000), rect);
+    checkPaintInvalidationStateRectMapping(rect, normalFlowOverflowRect, *normalFlow, layoutView(), *scroller);
+
+    LayoutBlock* stackingContext = toLayoutBlock(getLayoutObjectByElementId("stacking-context"));
+    LayoutBlock* absolute = toLayoutBlock(getLayoutObjectByElementId("absolute"));
+    EXPECT_EQ(stackingContext, &absolute->containerForPaintInvalidation());
+    EXPECT_EQ(stackingContext, absolute->container());
+
+    LayoutRect absoluteOverflowRect = absolute->localOverflowRectForPaintInvalidation();
+    EXPECT_EQ(LayoutRect(0, 0, 50, 50), absoluteOverflowRect);
+    rect = absoluteOverflowRect;
+    EXPECT_TRUE(absolute->mapToVisualRectInAncestorSpace(stackingContext, rect));
+    EXPECT_EQ(LayoutRect(222, 111, 50, 50), rect);
+    checkPaintInvalidationStateRectMapping(rect, absoluteOverflowRect, *absolute, layoutView(), *stackingContext);
+}
+
+TEST_F(VisualRectMappingTest, ContainerOfAbsoluteAbovePaintInvalidationContainer)
+{
+    enableCompositing();
+    document().frame()->settings()->setPreferCompositingToLCDTextEnabled(true);
+
+    setBodyInnerHTML(
+        "<div id='container' style='position: absolute; top: 88px; left: 99px'>"
+        "    <div style='height: 222px'></div>"
+        // This div makes stacking-context composited.
+        "    <div style='position: absolute; width: 1px; height: 1px; background:yellow; will-change: transform'></div>"
+        // This stacking context is paintInvalidationContainer of the absolute child, but not a container of it.
+        "    <div id='stacking-context' style='opacity: 0.9'>"
+        "        <div id='absolute' style='position: absolute; top: 50px; left: 50px; width: 50px; height: 50px; background: green'></div>"
+        "    </div>"
+        "</div>");
+
+    LayoutBlock* stackingContext = toLayoutBlock(getLayoutObjectByElementId("stacking-context"));
+    LayoutBlock* absolute = toLayoutBlock(getLayoutObjectByElementId("absolute"));
+    LayoutBlock* container = toLayoutBlock(getLayoutObjectByElementId("container"));
+    EXPECT_EQ(stackingContext, &absolute->containerForPaintInvalidation());
+    EXPECT_EQ(container, absolute->container());
+
+    LayoutRect absoluteOverflowRect = absolute->localOverflowRectForPaintInvalidation();
+    EXPECT_EQ(LayoutRect(0, 0, 50, 50), absoluteOverflowRect);
+    LayoutRect rect = absoluteOverflowRect;
+    EXPECT_TRUE(absolute->mapToVisualRectInAncestorSpace(stackingContext, rect));
+    // -172 = top(50) - y_offset_of_stacking_context(222)
+    EXPECT_EQ(LayoutRect(50, -172, 50, 50), rect);
+    checkPaintInvalidationStateRectMapping(rect, absoluteOverflowRect, *absolute, layoutView(), *stackingContext);
+}
+
+} // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/line/InlineBox.cpp b/third_party/WebKit/Source/core/layout/line/InlineBox.cpp
index 031b572..f2b16d3 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineBox.cpp
+++ b/third_party/WebKit/Source/core/layout/line/InlineBox.cpp
@@ -228,14 +228,6 @@
     if (parent()->getLineLayoutItem().hasFlippedBlocksWritingMode()) // Faster than calling containingBlock().
         childPoint = getLineLayoutItem().containingBlock().flipForWritingModeForChild(LineLayoutBox(getLineLayoutItem()), childPoint);
 
-    if (getLineLayoutItem().style()->hasBorderRadius()) {
-        LayoutRect borderRect = logicalFrameRect();
-        borderRect.moveBy(accumulatedOffset);
-        FloatRoundedRect border = getLineLayoutItem().style()->getRoundedBorderFor(borderRect);
-        if (!locationInContainer.intersects(border))
-            return false;
-    }
-
     return getLineLayoutItem().hitTest(result, locationInContainer, childPoint);
 }
 
diff --git a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
index 4ebe373..7a1b4db 100644
--- a/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
+++ b/third_party/WebKit/Source/core/layout/line/InlineFlowBox.cpp
@@ -22,6 +22,7 @@
 #include "core/CSSPropertyNames.h"
 #include "core/dom/Document.h"
 #include "core/layout/HitTestResult.h"
+#include "core/layout/api/LineLayoutAPIShim.h"
 #include "core/layout/api/LineLayoutBlockFlow.h"
 #include "core/layout/api/LineLayoutBox.h"
 #include "core/layout/api/LineLayoutInline.h"
@@ -1028,6 +1029,10 @@
     }
 
     if (getLineLayoutItem().style()->hasBorderRadius()) {
+        LayoutPoint adjustedLocation = accumulatedOffset + overflowRect.location();
+        if (getLineLayoutItem().isBox() && toLayoutBox(LineLayoutAPIShim::layoutObjectFrom(getLineLayoutItem()))->hitTestClippedOutByRoundedBorder(locationInContainer, adjustedLocation))
+            return false;
+
         LayoutRect borderRect = logicalFrameRect();
         borderRect.moveBy(accumulatedOffset);
         FloatRoundedRect border = getLineLayoutItem().style()->getRoundedBorderFor(borderRect, includeLogicalLeftEdge(), includeLogicalRightEdge());
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
index b9f010c..143a8f5 100644
--- a/third_party/WebKit/Source/core/loader/FrameLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
@@ -1206,10 +1206,6 @@
 
 void FrameLoader::detach()
 {
-#if !ENABLE(OILPAN)
-    // The caller must protect a reference to m_frame.
-    ASSERT(m_frame->refCount() > 1);
-#endif
     detachDocumentLoader(m_documentLoader);
     detachDocumentLoader(m_provisionalDocumentLoader);
 
diff --git a/third_party/WebKit/Source/core/loader/HttpEquiv.cpp b/third_party/WebKit/Source/core/loader/HttpEquiv.cpp
index 14b2b1bd..d4ff0b76 100644
--- a/third_party/WebKit/Source/core/loader/HttpEquiv.cpp
+++ b/third_party/WebKit/Source/core/loader/HttpEquiv.cpp
@@ -5,6 +5,7 @@
 #include "core/loader/HttpEquiv.h"
 
 #include "core/dom/Document.h"
+#include "core/dom/ScriptableDocumentParser.h"
 #include "core/dom/StyleEngine.h"
 #include "core/fetch/ClientHintsPreferences.h"
 #include "core/frame/UseCounter.h"
@@ -12,6 +13,8 @@
 #include "core/html/HTMLDocument.h"
 #include "core/inspector/ConsoleMessage.h"
 #include "core/loader/DocumentLoader.h"
+#include "core/origin_trials/OriginTrialContext.h"
+#include "platform/HTTPNames.h"
 #include "platform/network/HTTPParsers.h"
 #include "platform/weborigin/KURL.h"
 
@@ -42,6 +45,9 @@
             document.contentSecurityPolicy()->reportMetaOutsideHead(content);
     } else if (equalIgnoringCase(equiv, "suborigin")) {
         document.addConsoleMessage(ConsoleMessage::create(SecurityMessageSource, ErrorMessageLevel, "Error with Suborigin header: Suborigin header with value '" + content + "' was delivered via a <meta> element and not an HTTP header, which is disallowed. The Suborigin has been ignored."));
+    } else if (equalIgnoringCase(equiv, HTTPNames::Origin_Trial)) {
+        if (inDocumentHeadElement)
+            OriginTrialContext::from(&document)->addToken(content);
     }
 }
 
diff --git a/third_party/WebKit/Source/core/loader/ImageLoader.cpp b/third_party/WebKit/Source/core/loader/ImageLoader.cpp
index 6c3dde2..c7e4591 100644
--- a/third_party/WebKit/Source/core/loader/ImageLoader.cpp
+++ b/third_party/WebKit/Source/core/loader/ImageLoader.cpp
@@ -157,16 +157,11 @@
     , m_suppressErrorEvents(false)
 {
     WTF_LOG(Timers, "new ImageLoader %p", this);
-#if ENABLE(OILPAN)
     ThreadState::current()->registerPreFinalizer(this);
-#endif
 }
 
 ImageLoader::~ImageLoader()
 {
-#if !ENABLE(OILPAN)
-    dispose();
-#endif
 }
 
 void ImageLoader::dispose()
@@ -174,26 +169,11 @@
     WTF_LOG(Timers, "~ImageLoader %p; m_hasPendingLoadEvent=%d, m_hasPendingErrorEvent=%d",
         this, m_hasPendingLoadEvent, m_hasPendingErrorEvent);
 
-#if !ENABLE(OILPAN)
-    if (m_pendingTask)
-        m_pendingTask->clearLoader();
-#endif
-
     if (m_image) {
         m_image->removeClient(this);
         m_image->removeObserver(this);
         m_image = nullptr;
     }
-
-#if !ENABLE(OILPAN)
-    ASSERT(m_hasPendingLoadEvent || !loadEventSender().hasPendingEvents(this));
-    if (m_hasPendingLoadEvent)
-        loadEventSender().cancelEvent(this);
-
-    ASSERT(m_hasPendingErrorEvent || !errorEventSender().hasPendingEvents(this));
-    if (m_hasPendingErrorEvent)
-        errorEventSender().cancelEvent(this);
-#endif
 }
 
 DEFINE_TRACE(ImageLoader)
diff --git a/third_party/WebKit/Source/core/loader/LinkLoaderTest.cpp b/third_party/WebKit/Source/core/loader/LinkLoaderTest.cpp
index 3d9789b..8921e669 100644
--- a/third_party/WebKit/Source/core/loader/LinkLoaderTest.cpp
+++ b/third_party/WebKit/Source/core/loader/LinkLoaderTest.cpp
@@ -15,7 +15,7 @@
 #include "platform/network/ResourceLoadPriority.h"
 #include "platform/testing/URLTestHelpers.h"
 #include "public/platform/Platform.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include <base/macros.h>
 
@@ -174,7 +174,7 @@
             dummyPageHolder->document().fetcher()->clearPreloads();
         }
         memoryCache()->evictResources();
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
     }
 }
 
diff --git a/third_party/WebKit/Source/core/loader/PrerenderHandle.cpp b/third_party/WebKit/Source/core/loader/PrerenderHandle.cpp
index 789c2fb..9efd6f9c 100644
--- a/third_party/WebKit/Source/core/loader/PrerenderHandle.cpp
+++ b/third_party/WebKit/Source/core/loader/PrerenderHandle.cpp
@@ -88,7 +88,6 @@
 
 void PrerenderHandle::documentWasDetached()
 {
-#if ENABLE(OILPAN)
     // In Oilpan, a PrerenderHandle is not removed from
     // LifecycleNotifier::m_observers until a next GC is triggered.
     // Thus documentWasDetached() can be called for a PrerenderHandle
@@ -96,9 +95,6 @@
     // we should not detach the PrerenderHandle again, so we need this check.
     if (!m_prerender)
         return;
-#else
-    ASSERT(m_prerender);
-#endif
     m_prerender->abandon();
     detach();
 }
diff --git a/third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp b/third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp
index 8301be5..810bf14 100644
--- a/third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp
+++ b/third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp
@@ -5,6 +5,7 @@
 #include "core/loader/ThreadableLoader.h"
 
 #include "core/dom/CrossThreadTask.h"
+#include "core/fetch/MemoryCache.h"
 #include "core/fetch/ResourceLoaderOptions.h"
 #include "core/loader/DocumentThreadableLoader.h"
 #include "core/loader/ThreadableLoaderClient.h"
@@ -24,8 +25,8 @@
 #include "platform/weborigin/SecurityOrigin.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebURLLoadTiming.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
 #include "public/platform/WebURLResponse.h"
-#include "public/platform/WebUnitTestSupport.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "wtf/Assertions.h"
@@ -343,7 +344,7 @@
     void serveRequests()
     {
         m_helper->onServeRequests();
-        Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
+        Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
     }
 
     void createLoader(CrossOriginRequestPolicy crossOriginRequestPolicy = AllowCrossOriginRequests)
@@ -368,7 +369,8 @@
     void TearDown() override
     {
         m_helper->onTearDown();
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        memoryCache()->evictResources();
         m_client.clear();
     }
 
diff --git a/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.h b/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.h
index dc74da4..b54927f 100644
--- a/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.h
+++ b/third_party/WebKit/Source/core/loader/appcache/ApplicationCache.h
@@ -50,9 +50,6 @@
     }
     ~ApplicationCache() override
     {
-#if !ENABLE(OILPAN)
-        ASSERT(!m_frame);
-#endif
     }
 
     void willDestroyGlobalObjectInFrame() override;
diff --git a/third_party/WebKit/Source/core/origin_trials/DocumentOriginTrialContext.cpp b/third_party/WebKit/Source/core/origin_trials/DocumentOriginTrialContext.cpp
deleted file mode 100644
index f43bceb..0000000
--- a/third_party/WebKit/Source/core/origin_trials/DocumentOriginTrialContext.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "core/origin_trials/DocumentOriginTrialContext.h"
-
-#include "core/dom/ElementTraversal.h"
-#include "core/html/HTMLHeadElement.h"
-#include "core/html/HTMLMetaElement.h"
-
-namespace blink {
-
-class Document;
-
-DocumentOriginTrialContext::DocumentOriginTrialContext(Document* document)
-    : m_parent(document)
-{
-}
-
-Vector<String> DocumentOriginTrialContext::getTokens()
-{
-    // When in a document, the tokens are provided in a meta tag
-    Vector<String> tokens;
-    HTMLHeadElement* head = m_parent->head();
-    if (head) {
-        for (HTMLMetaElement& metaElement : Traversal<HTMLMetaElement>::childrenOf(*head)) {
-            if (equalIgnoringCase(metaElement.httpEquiv(), kTrialHeaderName)) {
-                tokens.append(metaElement.content());
-            }
-        }
-    }
-    return tokens;
-}
-
-DEFINE_TRACE(DocumentOriginTrialContext)
-{
-    visitor->trace(m_parent);
-    OriginTrialContext::trace(visitor);
-}
-
-} // namespace blink
diff --git a/third_party/WebKit/Source/core/origin_trials/DocumentOriginTrialContext.h b/third_party/WebKit/Source/core/origin_trials/DocumentOriginTrialContext.h
deleted file mode 100644
index a45587c..0000000
--- a/third_party/WebKit/Source/core/origin_trials/DocumentOriginTrialContext.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef DocumentOriginTrialContext_h
-#define DocumentOriginTrialContext_h
-
-#include "core/CoreExport.h"
-#include "core/dom/Document.h"
-#include "core/origin_trials/OriginTrialContext.h"
-#include "platform/heap/Handle.h"
-#include "wtf/Forward.h"
-#include <utility>
-
-namespace blink {
-
-class WebApiKeyValidator;
-
-// DocumentOriginTrialContext is a specialization of OriginTrialContext for
-// the Document execution context. It enables and disables feature trials based
-// on the tokens found in <meta> tags in the document header.
-class CORE_EXPORT DocumentOriginTrialContext : public OriginTrialContext {
-public:
-    explicit DocumentOriginTrialContext(Document*);
-    ~DocumentOriginTrialContext() override = default;
-
-    ExecutionContext* getExecutionContext() override { return m_parent; }
-    Vector<String> getTokens() override;
-
-    DECLARE_VIRTUAL_TRACE();
-
-protected:
-    friend class DocumentOriginTrialContextTest;
-
-private:
-    Member<Document> m_parent;
-};
-
-} // namespace blink
-
-#endif // DocumentOriginTrialContext_h
diff --git a/third_party/WebKit/Source/core/origin_trials/DocumentOriginTrialContextTest.cpp b/third_party/WebKit/Source/core/origin_trials/DocumentOriginTrialContextTest.cpp
deleted file mode 100644
index 5f00329d2..0000000
--- a/third_party/WebKit/Source/core/origin_trials/DocumentOriginTrialContextTest.cpp
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "core/origin_trials/DocumentOriginTrialContext.h"
-
-#include "core/HTMLNames.h"
-#include "core/dom/DOMException.h"
-#include "core/dom/ExceptionCode.h"
-#include "core/frame/FrameView.h"
-#include "core/html/HTMLDocument.h"
-#include "core/html/HTMLHeadElement.h"
-#include "core/html/HTMLMetaElement.h"
-#include "core/testing/DummyPageHolder.h"
-#include "platform/weborigin/KURL.h"
-#include "platform/weborigin/SecurityOrigin.h"
-#include "public/platform/WebTrialTokenValidator.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace blink {
-
-using ::testing::UnorderedElementsAre;
-
-namespace {
-
-// API Key which will appear valid
-const char* kGoodTrialToken = "1|AnySignatureWillDo|https://www.example.com|Frobulate|2000000000";
-const char* kAnotherTrialToken = "1|AnySignatureWillDo|https://www.example.com|FrobulateV2|2000000000";
-
-} // namespace
-
-class DocumentOriginTrialContextTest : public ::testing::Test {
-protected:
-    DocumentOriginTrialContextTest()
-        : m_pageHolder(DummyPageHolder::create())
-        , m_frameworkWasEnabled(RuntimeEnabledFeatures::experimentalFrameworkEnabled())
-    {
-        RuntimeEnabledFeatures::setExperimentalFrameworkEnabled(true);
-    }
-
-    ~DocumentOriginTrialContextTest()
-    {
-        RuntimeEnabledFeatures::setExperimentalFrameworkEnabled(m_frameworkWasEnabled);
-        m_pageHolder.clear();
-    }
-
-    void SetUp() override
-    {
-        setInnerHTML(
-            "<html>"
-            "<head>"
-            "</head>"
-            "<body>"
-            "</body>"
-            "</html>");
-    }
-
-    Document& document() { return m_pageHolder->document(); }
-
-    void setPageOrigin(const String& origin)
-    {
-        KURL pageURL(ParsedURLString, origin);
-        RefPtr<SecurityOrigin> pageOrigin = SecurityOrigin::create(pageURL);
-        document().updateSecurityOrigin(pageOrigin);
-    }
-
-    void setInnerHTML(const char* htmlContent)
-    {
-        document().documentElement()->setInnerHTML(String::fromUTF8(htmlContent), ASSERT_NO_EXCEPTION);
-        document().view()->updateAllLifecyclePhases();
-    }
-
-    void addTrialToken(const AtomicString& token)
-    {
-        HTMLElement* head = document().head();
-        ASSERT_TRUE(head);
-
-        RawPtr<HTMLMetaElement> meta = HTMLMetaElement::create(document());
-        meta->setAttribute(HTMLNames::http_equivAttr, OriginTrialContext::kTrialHeaderName);
-        meta->setAttribute(HTMLNames::contentAttr, token);
-        head->appendChild(meta.release());
-    }
-
-    Vector<String> getTokens()
-    {
-        return document().createOriginTrialContext()->getTokens();
-    }
-
-private:
-    OwnPtr<DummyPageHolder> m_pageHolder;
-    const bool m_frameworkWasEnabled;
-};
-
-TEST_F(DocumentOriginTrialContextTest, DetectsZeroTokens)
-{
-    String errorMessage;
-    Vector<String> tokens = getTokens();
-    EXPECT_EQ(0UL, tokens.size());
-}
-
-TEST_F(DocumentOriginTrialContextTest, ExtractsSingleToken)
-{
-    addTrialToken(kGoodTrialToken);
-    Vector<String> tokens = getTokens();
-    EXPECT_EQ(1UL, tokens.size());
-    EXPECT_EQ(kGoodTrialToken, tokens[0]);
-}
-
-TEST_F(DocumentOriginTrialContextTest, ExtractsAllTokens)
-{
-    addTrialToken(kGoodTrialToken);
-    addTrialToken(kAnotherTrialToken);
-    EXPECT_THAT(getTokens(), UnorderedElementsAre(kGoodTrialToken, kAnotherTrialToken));
-}
-
-} // namespace blink
diff --git a/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.cpp b/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.cpp
index 6d3f81d..72f663ae 100644
--- a/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.cpp
+++ b/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.cpp
@@ -4,10 +4,7 @@
 
 #include "core/origin_trials/OriginTrialContext.h"
 
-#include "core/dom/ElementTraversal.h"
-#include "core/dom/ExceptionCode.h"
-#include "core/html/HTMLHeadElement.h"
-#include "core/html/HTMLMetaElement.h"
+#include "core/dom/ExecutionContext.h"
 #include "platform/RuntimeEnabledFeatures.h"
 #include "platform/weborigin/SecurityOrigin.h"
 #include "public/platform/Platform.h"
@@ -31,9 +28,31 @@
 
 } // namespace
 
-const char OriginTrialContext::kTrialHeaderName[] = "origin-trial";
+OriginTrialContext::OriginTrialContext(ExecutionContext* host) : m_host(host)
+{
+}
 
-OriginTrialContext::OriginTrialContext() {}
+// static
+const char* OriginTrialContext::supplementName()
+{
+    return "OriginTrialContext";
+}
+
+// static
+OriginTrialContext* OriginTrialContext::from(ExecutionContext* host)
+{
+    OriginTrialContext* originTrials = static_cast<OriginTrialContext*>(Supplement<ExecutionContext>::from(host, supplementName()));
+    if (!originTrials) {
+        originTrials = new OriginTrialContext(host);
+        Supplement<ExecutionContext>::provideTo(*host, supplementName(), originTrials);
+    }
+    return originTrials;
+}
+
+void OriginTrialContext::addToken(const String& token)
+{
+    m_tokens.append(token);
+}
 
 bool OriginTrialContext::isFeatureEnabled(const String& featureName, String* errorMessage, WebTrialTokenValidator* validator)
 {
@@ -45,8 +64,8 @@
 
     // Feature trials are only enabled for secure origins
     bool isSecure = errorMessage
-        ? getExecutionContext()->isSecureContext(*errorMessage)
-        : getExecutionContext()->isSecureContext();
+        ? m_host->isSecureContext(*errorMessage)
+        : m_host->isSecureContext();
     if (!isSecure) {
         // The execution context should always set a message here, if a valid
         // pointer was passed in. If it does not, then we should find out why
@@ -65,14 +84,9 @@
         }
     }
 
-    return hasValidToken(getTokens(), featureName, errorMessage, validator);
-}
 
-bool OriginTrialContext::hasValidToken(Vector<String> tokens, const String& featureName, String* errorMessage, WebTrialTokenValidator* validator)
-{
-    WebSecurityOrigin origin(getExecutionContext()->getSecurityOrigin());
-
-    for (const String& token : tokens) {
+    WebSecurityOrigin origin(m_host->getSecurityOrigin());
+    for (const String& token : m_tokens) {
         // Check with the validator service to verify the signature.
         if (validator->validateToken(token, origin, featureName)) {
             return true;
@@ -90,7 +104,7 @@
         return false;
     }
 
-    if (tokens.size()) {
+    if (m_tokens.size()) {
         *errorMessage = getInvalidTokenMessage(featureName);
     } else {
         *errorMessage = getDisabledMessage(featureName);
@@ -101,6 +115,7 @@
 
 DEFINE_TRACE(OriginTrialContext)
 {
+    visitor->trace(m_host);
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.h b/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.h
index d8e0629..df27b813 100644
--- a/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.h
+++ b/third_party/WebKit/Source/core/origin_trials/OriginTrialContext.h
@@ -6,8 +6,7 @@
 #define OriginTrialContext_h
 
 #include "core/CoreExport.h"
-#include "platform/heap/Handle.h"
-#include "wtf/Forward.h"
+#include "platform/Supplementable.h"
 #include "wtf/HashSet.h"
 #include "wtf/Vector.h"
 #include "wtf/text/WTFString.h"
@@ -21,7 +20,7 @@
 // features, on a per-origin basis (origin trials). This class provides the
 // implementation to check if the experimental feature should be enabled for the
 // current context.  This class is not for direct use by feature implementers.
-// Instead, the OriginTrials generated class provides a static method for each
+// Instead, the OriginTrials generated namespace provides a method for each
 // feature to check if it is enabled. Experimental features must be defined in
 // RuntimeEnabledFeatures.in, which is used to generate OriginTrials.h/cpp.
 //
@@ -30,26 +29,16 @@
 // feature names. Instead, the EF validates the name provided by the feature
 // implementation against any provided tokens.
 //
-// This class is abstract, and should be subclassed for each execution context
-// which supports origin trials.
-//
 // TODO(chasej): Link to documentation, or provide more detail on keys, .etc
-class CORE_EXPORT OriginTrialContext : public GarbageCollectedFinalized<OriginTrialContext> {
+class CORE_EXPORT OriginTrialContext final : public GarbageCollectedFinalized<OriginTrialContext>, public Supplement<ExecutionContext> {
+USING_GARBAGE_COLLECTED_MIXIN(OriginTrialContext)
 public:
-    static const char kTrialHeaderName[];
-    virtual ~OriginTrialContext() = default;
+    explicit OriginTrialContext(ExecutionContext*);
 
-    virtual ExecutionContext* getExecutionContext() = 0;
-    virtual Vector<String> getTokens() = 0;
+    static const char* supplementName();
+    static OriginTrialContext* from(ExecutionContext*);
 
-    DECLARE_VIRTUAL_TRACE();
-
-protected:
-    OriginTrialContext();
-
-private:
-    friend class OriginTrialContextTest;
-    friend class OriginTrials;
+    void addToken(const String& token);
 
     // Returns true if the feature should be considered enabled for the current
     // execution context. This method usually makes use of the token validator
@@ -57,7 +46,11 @@
     // is required (for testing, for instance).
     bool isFeatureEnabled(const String& featureName, String* errorMessage, WebTrialTokenValidator* = nullptr);
 
-    bool hasValidToken(Vector<String> tokens, const String& featureName, String* errorMessage, WebTrialTokenValidator*);
+    DECLARE_VIRTUAL_TRACE();
+
+private:
+    Member<ExecutionContext> m_host;
+    Vector<String> m_tokens;
 
     // Records whether an error message has been generated, for each feature
     // name. Since these messages are generally written to the console, this is
diff --git a/third_party/WebKit/Source/core/origin_trials/OriginTrialContextTest.cpp b/third_party/WebKit/Source/core/origin_trials/OriginTrialContextTest.cpp
index 843129e..64a24a3 100644
--- a/third_party/WebKit/Source/core/origin_trials/OriginTrialContextTest.cpp
+++ b/third_party/WebKit/Source/core/origin_trials/OriginTrialContextTest.cpp
@@ -68,60 +68,15 @@
     DISALLOW_COPY_AND_ASSIGN(MockTokenValidator);
 };
 
-// Concrete subclass of OriginTrialContext which simply maintains a vector of
-// token strings to use for tests.
-class TestOriginTrialContext : public OriginTrialContext {
-public:
-    TestOriginTrialContext()
-        : m_parent(new NullExecutionContext())
-    {
-    }
-
-    ~TestOriginTrialContext() override = default;
-
-    ExecutionContext* getExecutionContext() override { return m_parent.get(); }
-
-    void addToken(const String& token)
-    {
-        m_tokens.append(token);
-    }
-
-    void updateSecurityOrigin(const String& origin)
-    {
-        KURL pageURL(ParsedURLString, origin);
-        RefPtr<SecurityOrigin> pageOrigin = SecurityOrigin::create(pageURL);
-        m_parent->setSecurityOrigin(pageOrigin);
-        m_parent->setIsSecureContext(SecurityOrigin::isSecure(pageURL));
-    }
-
-    Vector<String> getTokens() override
-    {
-        Vector<String> tokens;
-        for (String token : m_tokens) {
-            tokens.append(token);
-        }
-        return tokens;
-    }
-
-    DEFINE_INLINE_VIRTUAL_TRACE()
-    {
-        visitor->trace(m_parent);
-        OriginTrialContext::trace(visitor);
-    }
-
-private:
-    Member<NullExecutionContext> m_parent;
-    Vector<String> m_tokens;
-};
-
 } // namespace
 
 class OriginTrialContextTest : public ::testing::Test {
 protected:
     OriginTrialContextTest()
         : m_frameworkWasEnabled(RuntimeEnabledFeatures::experimentalFrameworkEnabled())
+        , m_executionContext(new NullExecutionContext())
         , m_tokenValidator(adoptPtr(new MockTokenValidator()))
-        , m_originTrialContext(new TestOriginTrialContext)
+        , m_originTrialContext(new OriginTrialContext(m_executionContext.get()))
     {
         RuntimeEnabledFeatures::setExperimentalFrameworkEnabled(true);
     }
@@ -133,9 +88,17 @@
 
     MockTokenValidator* tokenValidator() { return m_tokenValidator.get(); }
 
+    void updateSecurityOrigin(const String& origin)
+    {
+        KURL pageURL(ParsedURLString, origin);
+        RefPtr<SecurityOrigin> pageOrigin = SecurityOrigin::create(pageURL);
+        m_executionContext->setSecurityOrigin(pageOrigin);
+        m_executionContext->setIsSecureContext(SecurityOrigin::isSecure(pageURL));
+    }
+
     bool isFeatureEnabled(const String& origin, const String& featureName, const String& token, String* errorMessage)
     {
-        m_originTrialContext->updateSecurityOrigin(origin);
+        updateSecurityOrigin(origin);
         m_originTrialContext->addToken(token);
         return m_originTrialContext->isFeatureEnabled(featureName, errorMessage, tokenValidator());
     }
@@ -147,8 +110,9 @@
 
 private:
     const bool m_frameworkWasEnabled;
+    Persistent<NullExecutionContext> m_executionContext;
     OwnPtr<MockTokenValidator> m_tokenValidator;
-    Persistent<TestOriginTrialContext> m_originTrialContext;
+    Persistent<OriginTrialContext> m_originTrialContext;
 };
 
 TEST_F(OriginTrialContextTest, EnabledNonExistingFeature)
diff --git a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
index ea59969c..69ef5d0 100644
--- a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.cpp
@@ -225,6 +225,9 @@
     // being carried out on the right thread. We therefore cannot clear
     // the thread field before all references to the worker global
     // scope are gone.
+    //
+    // TODO(haraken): It's nasty to keep a raw pointer to WorkerThread
+    // after disposing WorkerGlobalScope. m_thread should be cleared here.
 }
 
 void WorkerGlobalScope::didEvaluateWorkerScript()
diff --git a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
index c5b392e..4cfc430 100644
--- a/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
+++ b/third_party/WebKit/Source/core/workers/WorkerGlobalScope.h
@@ -162,11 +162,6 @@
     void removeURLFromMemoryCache(const KURL&) override;
 
 private:
-#if !ENABLE(OILPAN)
-    void refExecutionContext() final { ref(); }
-    void derefExecutionContext() final { deref(); }
-#endif
-
     const KURL& virtualURL() const final;
     KURL virtualCompleteURL(const String&) const final;
 
diff --git a/third_party/WebKit/Source/core/workers/WorkerThread.cpp b/third_party/WebKit/Source/core/workers/WorkerThread.cpp
index 5ae35a9..31b9f57b5 100644
--- a/third_party/WebKit/Source/core/workers/WorkerThread.cpp
+++ b/third_party/WebKit/Source/core/workers/WorkerThread.cpp
@@ -269,9 +269,6 @@
     // We cannot let any objects survive past thread exit, because no other thread will run GC or otherwise destroy them.
     // If Oilpan is enabled, we detach of the context/global scope, with the final heap cleanup below sweeping it out.
     m_workerGlobalScope->notifyContextDestroyed();
-#if !ENABLE(OILPAN)
-    ASSERT(m_workerGlobalScope->hasOneRef());
-#endif
     m_workerGlobalScope = nullptr;
 
     willDestroyIsolate();
diff --git a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp
index c95f88a..5b5c4195 100644
--- a/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp
+++ b/third_party/WebKit/Source/modules/canvas2d/CanvasRenderingContext2DTest.cpp
@@ -55,7 +55,7 @@
     : m_size(size)
     , m_isOpaque(opacity == OpaqueBitmap)
 {
-    SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterN32Premul(m_size.width(), m_size.height()));
+    sk_sp<SkSurface> surface(SkSurface::MakeRasterN32Premul(m_size.width(), m_size.height()));
     surface->getCanvas()->clear(opacity == OpaqueBitmap ? SK_ColorWHITE : SK_ColorTRANSPARENT);
     RefPtr<SkImage> image = adoptRef(surface->newImageSnapshot());
     m_image = StaticBitmapImage::create(image);
diff --git a/third_party/WebKit/Source/modules/credentialmanager/CredentialsContainer.cpp b/third_party/WebKit/Source/modules/credentialmanager/CredentialsContainer.cpp
index ea400dc..9612607 100644
--- a/third_party/WebKit/Source/modules/credentialmanager/CredentialsContainer.cpp
+++ b/third_party/WebKit/Source/modules/credentialmanager/CredentialsContainer.cpp
@@ -55,7 +55,7 @@
     void onSuccess() override
     {
         Frame* frame = toDocument(m_resolver->getScriptState()->getExecutionContext())->frame();
-        SECURITY_CHECK(frame == frame->tree().top());
+        SECURITY_CHECK(!frame || frame == frame->tree().top());
 
         m_resolver->resolve();
     }
@@ -78,10 +78,10 @@
     void onSuccess(WebPassOwnPtr<WebCredential> webCredential) override
     {
         Frame* frame = toDocument(m_resolver->getScriptState()->getExecutionContext())->frame();
-        SECURITY_CHECK(frame == frame->tree().top());
+        SECURITY_CHECK(!frame || frame == frame->tree().top());
 
         OwnPtr<WebCredential> credential = webCredential.release();
-        if (!credential) {
+        if (!credential || !frame) {
             m_resolver->resolve();
             return;
         }
diff --git a/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.cpp b/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.cpp
index 2943811..ae6b34b 100644
--- a/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.cpp
+++ b/third_party/WebKit/Source/modules/imagebitmap/ImageBitmapRenderingContext.cpp
@@ -34,7 +34,7 @@
     RefPtr<SkImage> skImage = m_image->imageForCurrentFrame();
     if (skImage->isTextureBacked()) {
         // TODO(junov): crbug.com/585607 Eliminate this readback and use an ExternalTextureLayer
-        RefPtr<SkSurface> surface = adoptRef(SkSurface::NewRasterN32Premul(skImage->width(), skImage->height()));
+        sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(skImage->width(), skImage->height());
         if (!surface) {
             // silent failure
             m_image.clear();
diff --git a/third_party/WebKit/Source/modules/mediastream/RTCDataChannelTest.cpp b/third_party/WebKit/Source/modules/mediastream/RTCDataChannelTest.cpp
index 771124dd..c8ca26e 100644
--- a/third_party/WebKit/Source/modules/mediastream/RTCDataChannelTest.cpp
+++ b/third_party/WebKit/Source/modules/mediastream/RTCDataChannelTest.cpp
@@ -11,7 +11,6 @@
 #include "core/events/Event.h"
 #include "platform/heap/Heap.h"
 #include "public/platform/WebRTCDataChannelHandler.h"
-#include "public/platform/WebUnitTestSupport.h"
 #include "public/platform/WebVector.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/modules/payments/PaymentDetailsTestHelper.cpp b/third_party/WebKit/Source/modules/payments/PaymentDetailsTestHelper.cpp
index be2f272..b5ace51 100644
--- a/third_party/WebKit/Source/modules/payments/PaymentDetailsTestHelper.cpp
+++ b/third_party/WebKit/Source/modules/payments/PaymentDetailsTestHelper.cpp
@@ -5,22 +5,20 @@
 #include "modules/payments/PaymentDetailsTestHelper.h"
 
 #include "modules/payments/CurrencyAmount.h"
-#include "modules/payments/PaymentItem.h"
-#include "modules/payments/ShippingOption.h"
 #include "platform/heap/HeapAllocator.h"
 
 namespace blink {
 
-PaymentDetails buildPaymentDetailsForTest(PaymentTestDetailToChange detail, PaymentTestDataToChange data, PaymentTestModificationType modificationType, const String& valueToUse)
+PaymentItem buildPaymentItemForTest(PaymentTestDataToChange data, PaymentTestModificationType modificationType, const String& valueToUse)
 {
     CurrencyAmount itemAmount;
-    if (detail == PaymentTestDetailItem && data == PaymentTestDataCurrencyCode) {
+    if (data == PaymentTestDataCurrencyCode) {
         if (modificationType == PaymentTestOverwriteValue)
             itemAmount.setCurrencyCode(valueToUse);
     } else {
         itemAmount.setCurrencyCode("USD");
     }
-    if (detail == PaymentTestDetailItem && data == PaymentTestDataAmount) {
+    if (data == PaymentTestDataAmount) {
         if (modificationType == PaymentTestOverwriteValue)
             itemAmount.setValue(valueToUse);
     } else {
@@ -29,27 +27,32 @@
 
     PaymentItem item;
     item.setAmount(itemAmount);
-    if (detail == PaymentTestDetailItem && data == PaymentTestDataId) {
+    if (data == PaymentTestDataId) {
         if (modificationType == PaymentTestOverwriteValue)
             item.setId(valueToUse);
     } else {
         item.setId("total");
     }
-    if (detail == PaymentTestDetailItem && data == PaymentTestDataLabel) {
+    if (data == PaymentTestDataLabel) {
         if (modificationType == PaymentTestOverwriteValue)
             item.setLabel(valueToUse);
     } else {
         item.setLabel("Total charge");
     }
 
+    return item;
+}
+
+ShippingOption buildShippingOptionForTest(PaymentTestDataToChange data, PaymentTestModificationType modificationType, const String& valueToUse)
+{
     CurrencyAmount shippingAmount;
-    if (detail == PaymentTestDetailShippingOption && data == PaymentTestDataCurrencyCode) {
+    if (data == PaymentTestDataCurrencyCode) {
         if (modificationType == PaymentTestOverwriteValue)
             shippingAmount.setCurrencyCode(valueToUse);
     } else {
         shippingAmount.setCurrencyCode("USD");
     }
-    if (detail == PaymentTestDetailShippingOption && data == PaymentTestDataAmount) {
+    if (data == PaymentTestDataAmount) {
         if (modificationType == PaymentTestOverwriteValue)
             shippingAmount.setValue(valueToUse);
     } else {
@@ -58,19 +61,37 @@
 
     ShippingOption shippingOption;
     shippingOption.setAmount(shippingAmount);
-    if (detail == PaymentTestDetailShippingOption && data == PaymentTestDataId) {
+    if (data == PaymentTestDataId) {
         if (modificationType == PaymentTestOverwriteValue)
             shippingOption.setId(valueToUse);
     } else {
         shippingOption.setId("standard");
     }
-    if (detail == PaymentTestDetailShippingOption && data == PaymentTestDataLabel) {
+    if (data == PaymentTestDataLabel) {
         if (modificationType == PaymentTestOverwriteValue)
             shippingOption.setLabel(valueToUse);
     } else {
         shippingOption.setLabel("Standard shipping");
     }
 
+    return shippingOption;
+}
+
+PaymentDetails buildPaymentDetailsForTest(PaymentTestDetailToChange detail, PaymentTestDataToChange data, PaymentTestModificationType modificationType, const String& valueToUse)
+{
+
+    PaymentItem item;
+    if (detail == PaymentTestDetailItem)
+        item = buildPaymentItemForTest(data, modificationType, valueToUse);
+    else
+        item = buildPaymentItemForTest();
+
+    ShippingOption shippingOption;
+    if (detail == PaymentTestDetailShippingOption)
+        shippingOption = buildShippingOptionForTest(data, modificationType, valueToUse);
+    else
+        shippingOption = buildShippingOptionForTest();
+
     PaymentDetails result;
     result.setItems(HeapVector<PaymentItem>(1, item));
     result.setShippingOptions(HeapVector<ShippingOption>(2, shippingOption));
diff --git a/third_party/WebKit/Source/modules/payments/PaymentDetailsTestHelper.h b/third_party/WebKit/Source/modules/payments/PaymentDetailsTestHelper.h
index 748f27f..786e6a7 100644
--- a/third_party/WebKit/Source/modules/payments/PaymentDetailsTestHelper.h
+++ b/third_party/WebKit/Source/modules/payments/PaymentDetailsTestHelper.h
@@ -6,6 +6,8 @@
 #define PaymentDetailsTestHelper_h
 
 #include "modules/payments/PaymentDetails.h"
+#include "modules/payments/PaymentItem.h"
+#include "modules/payments/ShippingOption.h"
 #include "wtf/text/WTFString.h"
 
 namespace blink {
@@ -29,6 +31,10 @@
     PaymentTestRemoveKey
 };
 
+PaymentItem buildPaymentItemForTest(PaymentTestDataToChange = PaymentTestDataNone, PaymentTestModificationType = PaymentTestOverwriteValue, const String& valueToUse = String());
+
+ShippingOption buildShippingOptionForTest(PaymentTestDataToChange = PaymentTestDataNone, PaymentTestModificationType = PaymentTestOverwriteValue, const String& valueToUse = String());
+
 PaymentDetails buildPaymentDetailsForTest(PaymentTestDetailToChange = PaymentTestDetailNone, PaymentTestDataToChange = PaymentTestDataNone, PaymentTestModificationType = PaymentTestOverwriteValue, const String& valueToUse = String());
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/modules/payments/PaymentRequestTest.cpp b/third_party/WebKit/Source/modules/payments/PaymentRequestTest.cpp
index 8cdb6102..985006d 100644
--- a/third_party/WebKit/Source/modules/payments/PaymentRequestTest.cpp
+++ b/third_party/WebKit/Source/modules/payments/PaymentRequestTest.cpp
@@ -78,10 +78,10 @@
 
 TEST_F(PaymentRequestTest, AtLeastOnePaymentDetailsItemRequired)
 {
-    PaymentDetails emptyItems;
-    emptyItems.setItems(HeapVector<PaymentItem>());
+    PaymentDetails details;
+    details.setShippingOptions(HeapVector<ShippingOption>(2, buildShippingOptionForTest()));
 
-    PaymentRequest::create(getScriptState(), Vector<String>(1, "foo"), emptyItems, getExceptionState());
+    PaymentRequest::create(getScriptState(), Vector<String>(1, "foo"), details, getExceptionState());
 
     EXPECT_TRUE(getExceptionState().hadException());
     EXPECT_EQ(V8TypeError, getExceptionState().code());
@@ -89,8 +89,8 @@
 
 TEST_F(PaymentRequestTest, NullShippingOptionWhenNoOptionsAvailable)
 {
-    PaymentDetails details = buildPaymentDetailsForTest();
-    details.setShippingOptions(HeapVector<ShippingOption>());
+    PaymentDetails details;
+    details.setItems(HeapVector<PaymentItem>(1, buildPaymentItemForTest()));
 
     PaymentRequest* request = PaymentRequest::create(getScriptState(), Vector<String>(1, "foo"), details, getExceptionState());
 
@@ -99,8 +99,9 @@
 
 TEST_F(PaymentRequestTest, NullShippingOptionWhenMultipleOptionsAvailable)
 {
-    PaymentDetails details = buildPaymentDetailsForTest();
-    EXPECT_LE(2U, details.shippingOptions().size());
+    PaymentDetails details;
+    details.setItems(HeapVector<PaymentItem>(1, buildPaymentItemForTest()));
+    details.setShippingOptions(HeapVector<ShippingOption>(2, buildShippingOptionForTest()));
 
     PaymentRequest* request = PaymentRequest::create(getScriptState(), Vector<String>(1, "foo"), details, getExceptionState());
 
@@ -109,15 +110,9 @@
 
 TEST_F(PaymentRequestTest, SelectSingleAvailableShippingOption)
 {
-    CurrencyAmount amount;
-    amount.setCurrencyCode("USD");
-    amount.setValue("10.00");
-    ShippingOption option;
-    option.setAmount(amount);
-    option.setId("standard");
-    option.setLabel("Standard shipping");
-    PaymentDetails details = buildPaymentDetailsForTest();
-    details.setShippingOptions(HeapVector<ShippingOption>(1, option));
+    PaymentDetails details;
+    details.setItems(HeapVector<PaymentItem>(1, buildPaymentItemForTest()));
+    details.setShippingOptions(HeapVector<ShippingOption>(1, buildShippingOptionForTest()));
 
     PaymentRequest* request = PaymentRequest::create(getScriptState(), Vector<String>(1, "foo"), details, getExceptionState());
 
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn
index bb54aff..5bba9f7 100644
--- a/third_party/WebKit/Source/platform/BUILD.gn
+++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -410,10 +410,6 @@
     sources -= [ "scroll/ScrollbarThemeAndroid.cpp" ]
   }
 
-  if (is_linux) {
-    public_deps += [ "//build/linux:fontconfig" ]
-  }
-
   if (!use_default_render_theme) {
     sources -= [
       "scroll/ScrollbarThemeAura.cpp",
diff --git a/third_party/WebKit/Source/platform/DragImage.cpp b/third_party/WebKit/Source/platform/DragImage.cpp
index de3a48e..192f354 100644
--- a/third_party/WebKit/Source/platform/DragImage.cpp
+++ b/third_party/WebKit/Source/platform/DragImage.cpp
@@ -96,7 +96,7 @@
         return image;
     }
 
-    RefPtr<SkSurface> surface = adoptRef(SkSurface::NewRasterN32Premul(size.width(), size.height()));
+    sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(size.width(), size.height());
     if (!surface)
         return nullptr;
 
diff --git a/third_party/WebKit/Source/platform/DragImageTest.cpp b/third_party/WebKit/Source/platform/DragImageTest.cpp
index 3257c25e..b4db5aa1 100644
--- a/third_party/WebKit/Source/platform/DragImageTest.cpp
+++ b/third_party/WebKit/Source/platform/DragImageTest.cpp
@@ -96,7 +96,7 @@
     explicit TestImage(IntSize size)
         : m_image(nullptr)
     {
-        RefPtr<SkSurface> surface = adoptRef(createSkSurface(size));
+        sk_sp<SkSurface> surface = createSkSurface(size);
         if (!surface)
             return;
 
@@ -104,9 +104,9 @@
         m_image = adoptRef(surface->newImageSnapshot());
     }
 
-    static SkSurface* createSkSurface(IntSize size)
+    static sk_sp<SkSurface> createSkSurface(IntSize size)
     {
-        return SkSurface::NewRaster(SkImageInfo::MakeN32(size.width(), size.height(), kPremul_SkAlphaType));
+        return SkSurface::MakeRaster(SkImageInfo::MakeN32(size.width(), size.height(), kPremul_SkAlphaType));
     }
 
     RefPtr<SkImage> m_image;
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
index b3d4608..3704501 100644
--- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
+++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
@@ -60,6 +60,7 @@
 CSSVariables status=stable
 CSSViewport status=experimental
 CSSScrollSnapPoints status=test
+CustomElementsV1 status=test
 CustomSchemeHandler depends_on=NavigatorContentUtils, status=experimental
 Database status=stable
 DecodeToYUV status=experimental
diff --git a/third_party/WebKit/Source/platform/blink_platform.gyp b/third_party/WebKit/Source/platform/blink_platform.gyp
index e840db1..efab638 100644
--- a/third_party/WebKit/Source/platform/blink_platform.gyp
+++ b/third_party/WebKit/Source/platform/blink_platform.gyp
@@ -343,14 +343,6 @@
           ['exclude', 'Android\\.cpp$'],
         ],
       }],
-      ['OS=="linux"', {
-        'dependencies': [
-          '<(DEPTH)/build/linux/system.gyp:fontconfig',
-        ],
-        'export_dependent_settings': [
-          '<(DEPTH)/build/linux/system.gyp:fontconfig',
-        ],
-      }],
       ['use_default_render_theme==0', {
         'sources/': [
           ['exclude', 'scroll/ScrollbarThemeAura\\.(cpp|h)'],
diff --git a/third_party/WebKit/Source/platform/blink_platform.gypi b/third_party/WebKit/Source/platform/blink_platform.gypi
index 3d64fac..8f77432 100644
--- a/third_party/WebKit/Source/platform/blink_platform.gypi
+++ b/third_party/WebKit/Source/platform/blink_platform.gypi
@@ -383,7 +383,6 @@
       'exported/WebURLResponsePrivate.h',
       'exported/WrappedResourceRequest.h',
       'exported/WrappedResourceResponse.h',
-      'exported/linux/WebFontInfo.cpp',
       'exported/linux/WebFontRenderStyle.cpp',
       'fonts/AcceptLanguagesResolver.cpp',
       'fonts/AcceptLanguagesResolver.h',
@@ -654,8 +653,6 @@
       'graphics/StaticBitmapImage.h',
       'graphics/StrokeData.cpp',
       'graphics/StrokeData.h',
-      'graphics/ThreadSafeDataTransport.cpp',
-      'graphics/ThreadSafeDataTransport.h',
       'graphics/UnacceleratedImageBufferSurface.cpp',
       'graphics/UnacceleratedImageBufferSurface.h',
       'graphics/compositing/PaintArtifactCompositor.cpp',
@@ -801,6 +798,8 @@
       'image-decoders/ImageDecoder.h',
       'image-decoders/ImageFrame.cpp',
       'image-decoders/ImageFrame.h',
+      'image-decoders/SegmentReader.cpp',
+      'image-decoders/SegmentReader.h',
       'image-decoders/bmp/BMPImageDecoder.cpp',
       'image-decoders/bmp/BMPImageDecoder.h',
       'image-decoders/bmp/BMPImageReader.cpp',
@@ -1176,7 +1175,6 @@
       'graphics/ContiguousContainerTest.cpp',
       'graphics/GraphicsContextTest.cpp',
       'graphics/RecordingImageBufferSurfaceTest.cpp',
-      'graphics/ThreadSafeDataTransportTest.cpp',
       'graphics/compositing/PaintArtifactCompositorTest.cpp',
       'graphics/filters/FilterOperationsTest.cpp',
       'graphics/filters/ImageFilterBuilderTest.cpp',
diff --git a/third_party/WebKit/Source/platform/exported/linux/WebFontInfo.cpp b/third_party/WebKit/Source/platform/exported/linux/WebFontInfo.cpp
deleted file mode 100644
index ea0c0b7f..0000000
--- a/third_party/WebKit/Source/platform/exported/linux/WebFontInfo.cpp
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "public/platform/linux/WebFontInfo.h"
-
-#include "public/platform/linux/WebFallbackFont.h"
-#include "wtf/Allocator.h"
-#include "wtf/HashMap.h"
-#include "wtf/Noncopyable.h"
-#include "wtf/OwnPtr.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/Vector.h"
-#include "wtf/text/AtomicString.h"
-#include "wtf/text/AtomicStringHash.h"
-#include <fontconfig/fontconfig.h>
-#include <string.h>
-
-namespace blink {
-
-class CachedFont {
-    DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
-public:
-    // Note: We pass the charset explicitly as callers
-    // should not create CachedFont entries without knowing
-    // that the FcPattern contains a valid charset.
-    CachedFont(FcPattern* pattern, FcCharSet* charSet)
-        : m_supportedCharacters(charSet)
-    {
-        ASSERT(pattern);
-        ASSERT(charSet);
-        m_fallbackFont.name = fontName(pattern);
-        m_fallbackFont.filename = fontFilename(pattern);
-        m_fallbackFont.ttcIndex = fontTtcIndex(pattern);
-        m_fallbackFont.isBold = fontIsBold(pattern);
-        m_fallbackFont.isItalic = fontIsItalic(pattern);
-    }
-    const WebFallbackFont& fallbackFont() const { return m_fallbackFont; }
-    bool hasGlyphForCharacter(WebUChar32 c)
-    {
-        return m_supportedCharacters && FcCharSetHasChar(m_supportedCharacters, c);
-    }
-
-private:
-    static WebCString fontName(FcPattern* pattern)
-    {
-        FcChar8* familyName = nullptr;
-        if (FcPatternGetString(pattern, FC_FAMILY, 0, &familyName) != FcResultMatch)
-            return WebCString();
-
-        // FCChar8 is unsigned char, so we cast to char for WebCString.
-        const char* charFamily = reinterpret_cast<char*>(familyName);
-        return WebCString(charFamily, strlen(charFamily));
-    }
-
-    static WebCString fontFilename(FcPattern* pattern)
-    {
-        FcChar8* cFilename = nullptr;
-        if (FcPatternGetString(pattern, FC_FILE, 0, &cFilename) != FcResultMatch)
-            return WebCString();
-        const char* fontFilename = reinterpret_cast<char*>(cFilename);
-        return WebCString(fontFilename, strlen(fontFilename));
-    }
-
-    static int fontTtcIndex(FcPattern* pattern)
-    {
-        int ttcIndex = -1;
-        if (FcPatternGetInteger(pattern, FC_INDEX, 0, &ttcIndex) != FcResultMatch || ttcIndex < 0)
-            return 0;
-        return ttcIndex;
-    }
-
-    static bool fontIsBold(FcPattern* pattern)
-    {
-        int weight = 0;
-        if (FcPatternGetInteger(pattern, FC_WEIGHT, 0, &weight) != FcResultMatch)
-            return false;
-        return weight >= FC_WEIGHT_BOLD;
-    }
-
-    static bool fontIsItalic(FcPattern* pattern)
-    {
-        int slant = 0;
-        if (FcPatternGetInteger(pattern, FC_SLANT, 0, &slant) != FcResultMatch)
-            return false;
-        return slant != FC_SLANT_ROMAN;
-    }
-
-    WebFallbackFont m_fallbackFont;
-    // m_supportedCharaters is owned by the parent
-    // FcFontSet and should never be freed.
-    FcCharSet* m_supportedCharacters;
-};
-
-
-class CachedFontSet {
-    WTF_MAKE_NONCOPYABLE(CachedFontSet);
-    USING_FAST_MALLOC(CachedFontSet);
-public:
-    // CachedFontSet takes ownership of the passed FcFontSet.
-    static PassOwnPtr<CachedFontSet> createForLocale(const char* locale)
-    {
-        FcFontSet* fontSet = createFcFontSetForLocale(locale);
-        return adoptPtr(new CachedFontSet(fontSet));
-    }
-
-    ~CachedFontSet()
-    {
-        m_fallbackList.clear();
-        FcFontSetDestroy(m_fontSet);
-    }
-
-    WebFallbackFont fallbackFontForChar(WebUChar32 c)
-    {
-        Vector<CachedFont>::iterator itr = m_fallbackList.begin();
-        for (; itr != m_fallbackList.end(); itr++) {
-            if (itr->hasGlyphForCharacter(c))
-                return itr->fallbackFont();
-        }
-        // The previous code just returned garbage if the user didn't
-        // have the necessary fonts, this seems better than garbage.
-        // Current callers happen to ignore any values with an empty family string.
-        return WebFallbackFont();
-    }
-
-private:
-    static FcFontSet* createFcFontSetForLocale(const char* locale)
-    {
-        FcPattern* pattern = FcPatternCreate();
-
-        if (locale) {
-            // FcChar* is unsigned char* so we have to cast.
-            FcPatternAddString(pattern, FC_LANG, reinterpret_cast<const FcChar8*>(locale));
-        }
-
-        FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
-
-        FcConfigSubstitute(0, pattern, FcMatchPattern);
-        FcDefaultSubstitute(pattern);
-
-        if (!locale)
-            FcPatternDel(pattern, FC_LANG);
-
-        // The result parameter returns if any fonts were found.
-        // We already handle 0 fonts correctly, so we ignore the param.
-        FcResult result;
-        FcFontSet* fontSet = FcFontSort(0, pattern, 0, 0, &result);
-        FcPatternDestroy(pattern);
-
-        // The caller will take ownership of this FcFontSet.
-        return fontSet;
-    }
-
-    CachedFontSet(FcFontSet* fontSet)
-        : m_fontSet(fontSet)
-    {
-        fillFallbackList();
-    }
-
-    void fillFallbackList()
-    {
-        ASSERT(m_fallbackList.isEmpty());
-        if (!m_fontSet)
-            return;
-
-        for (int i = 0; i < m_fontSet->nfont; ++i) {
-            FcPattern* pattern = m_fontSet->fonts[i];
-
-            // Ignore any bitmap fonts users may still have installed from last century.
-            FcBool isScalable;
-            if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &isScalable) != FcResultMatch || !isScalable)
-                continue;
-
-            // Ignore any fonts FontConfig knows about, but that we don't have permission to read.
-            FcChar8* cFilename;
-            if (FcPatternGetString(pattern, FC_FILE, 0, &cFilename) != FcResultMatch)
-                continue;
-            if (access(reinterpret_cast<char*>(cFilename), R_OK))
-                continue;
-
-            // Make sure this font can tell us what characters it has glyphs for.
-            FcCharSet* charSet;
-            if (FcPatternGetCharSet(pattern, FC_CHARSET, 0, &charSet) != FcResultMatch)
-                continue;
-
-            m_fallbackList.append(CachedFont(pattern, charSet));
-        }
-    }
-
-    FcFontSet* m_fontSet; // Owned by this object.
-    // CachedFont has a FcCharset* which points into the FcFontSet.
-    // If the FcFontSet is ever destroyed, the fallbackList
-    // must be cleared first.
-    Vector<CachedFont> m_fallbackList;
-};
-
-class FontSetCache {
-    WTF_MAKE_NONCOPYABLE(FontSetCache);
-    USING_FAST_MALLOC(FontSetCache);
-public:
-    static FontSetCache& shared()
-    {
-        DEFINE_STATIC_LOCAL(FontSetCache, cache, ());
-        return cache;
-    }
-
-    WebFallbackFont fallbackFontForCharInLocale(WebUChar32 c, const char* locale)
-    {
-        DEFINE_STATIC_LOCAL(AtomicString, noLocale, ("NO_LOCALE_SPECIFIED"));
-        AtomicString localeKey;
-        if (locale && strlen(locale)) {
-            localeKey = AtomicString(locale);
-        } else {
-            // String hash computation the m_setsByLocale map needs
-            // a non-empty string.
-            localeKey = noLocale;
-        }
-
-        LocaleToCachedFont::iterator itr = m_setsByLocale.find(localeKey);
-        if (itr == m_setsByLocale.end()) {
-            OwnPtr<CachedFontSet> newEntry = CachedFontSet::createForLocale(strlen(locale) ? locale : 0);
-            return m_setsByLocale.add(localeKey, newEntry.release()).storedValue->value->fallbackFontForChar(c);
-        }
-        return itr.get()->value->fallbackFontForChar(c);
-    }
-    // FIXME: We may wish to add a way to prune the cache at a later time.
-
-private:
-    FontSetCache() { }
-
-    // FIXME: This shouldn't need to be AtomicString, but
-    // currently HashTraits<const char*> isn't smart enough
-    // to hash the string (only does pointer compares).
-    typedef HashMap<AtomicString, OwnPtr<CachedFontSet>> LocaleToCachedFont;
-    LocaleToCachedFont m_setsByLocale;
-};
-
-void WebFontInfo::fallbackFontForChar(WebUChar32 c, const char* locale, WebFallbackFont* fallbackFont)
-{
-    *fallbackFont = FontSetCache::shared().fallbackFontForCharInLocale(c, locale);
-}
-
-} // namespace blink
diff --git a/third_party/WebKit/Source/platform/fonts/Character.h b/third_party/WebKit/Source/platform/fonts/Character.h
index 237f9582..12dbb655 100644
--- a/third_party/WebKit/Source/platform/fonts/Character.h
+++ b/third_party/WebKit/Source/platform/fonts/Character.h
@@ -63,6 +63,11 @@
     }
 
     static bool isCJKIdeographOrSymbol(UChar32);
+    static bool isCJKIdeographOrSymbolBase(UChar32 c)
+    {
+        return isCJKIdeographOrSymbol(c)
+            && !(U_GET_GC_MASK(c) & (U_GC_M_MASK | U_GC_LM_MASK | U_GC_SK_MASK));
+    }
 
     static unsigned expansionOpportunityCount(const LChar*, size_t length, TextDirection, bool& isAfterExpansion, const TextJustify);
     static unsigned expansionOpportunityCount(const UChar*, size_t length, TextDirection, bool& isAfterExpansion, const TextJustify);
diff --git a/third_party/WebKit/Source/platform/fonts/CharacterPropertyData.cpp b/third_party/WebKit/Source/platform/fonts/CharacterPropertyData.cpp
index 3086dc3..c8011971 100644
--- a/third_party/WebKit/Source/platform/fonts/CharacterPropertyData.cpp
+++ b/third_party/WebKit/Source/platform/fonts/CharacterPropertyData.cpp
@@ -592,7 +592,7 @@
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
     0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
     0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
-    0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
+    0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
     0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
     0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
     0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00,
diff --git a/third_party/WebKit/Source/platform/fonts/CharacterPropertyDataGenerator.h b/third_party/WebKit/Source/platform/fonts/CharacterPropertyDataGenerator.h
index 9f20428..3604bb1 100644
--- a/third_party/WebKit/Source/platform/fonts/CharacterPropertyDataGenerator.h
+++ b/third_party/WebKit/Source/platform/fonts/CharacterPropertyDataGenerator.h
@@ -73,9 +73,11 @@
     0x270A, 0x270D,
     // Ideographic Description Characters, with CJK Symbols and Punctuation,
     // excluding 0x3030.
+    // Exclude Hangul Tone Marks (0x302E .. 0x302F) because Hangul is not Han
+    // and no other Hangul are included.
     // Then Hiragana 0x3040 .. 0x309F, Katakana 0x30A0 .. 0x30FF, Bopomofo
     // 0x3100 .. 0x312F
-    0x2FF0, 0x302F,
+    0x2FF0, 0x302D,
     0x3031, 0x312F,
     // More Bopomofo and Bopomofo Extended 0x31A0 .. 0x31BF
     0x3190, 0x31BF,
diff --git a/third_party/WebKit/Source/platform/fonts/CharacterTest.cpp b/third_party/WebKit/Source/platform/fonts/CharacterTest.cpp
index a7833ca..b6de727 100644
--- a/third_party/WebKit/Source/platform/fonts/CharacterTest.cpp
+++ b/third_party/WebKit/Source/platform/fonts/CharacterTest.cpp
@@ -306,7 +306,7 @@
 
     EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2B1A));
 
-    TestSpecificUChar32RangeIdeographSymbol(0x2FF0, 0x302F);
+    TestSpecificUChar32RangeIdeographSymbol(0x2FF0, 0x302D);
     EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x3031));
     EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x312F));
     EXPECT_FALSE(Character::isCJKIdeographOrSymbol(0x3130));
diff --git a/third_party/WebKit/Source/platform/fonts/linux/FontCacheLinux.cpp b/third_party/WebKit/Source/platform/fonts/linux/FontCacheLinux.cpp
index d881c69..9402ede 100644
--- a/third_party/WebKit/Source/platform/fonts/linux/FontCacheLinux.cpp
+++ b/third_party/WebKit/Source/platform/fonts/linux/FontCacheLinux.cpp
@@ -27,9 +27,9 @@
 #include "platform/fonts/FontPlatformData.h"
 #include "platform/fonts/SimpleFontData.h"
 #include "public/platform/linux/WebFallbackFont.h"
-#include "public/platform/linux/WebFontInfo.h"
 #include "public/platform/linux/WebSandboxSupport.h"
 #include "public/platform/Platform.h"
+#include "ui/gfx/font_fallback_linux.h"
 #include "wtf/text/CString.h"
 
 namespace blink {
@@ -47,17 +47,25 @@
 
 void FontCache::getFontForCharacter(UChar32 c, const char* preferredLocale, FontCache::PlatformFallbackFont* fallbackFont)
 {
-    WebFallbackFont webFallbackFont;
-    if (Platform::current()->sandboxSupport())
+    if (Platform::current()->sandboxSupport()) {
+        WebFallbackFont webFallbackFont;
         Platform::current()->sandboxSupport()->getFallbackFontForCharacter(c, preferredLocale, &webFallbackFont);
-    else
-        WebFontInfo::fallbackFontForChar(c, preferredLocale, &webFallbackFont);
-    fallbackFont->name = String::fromUTF8(CString(webFallbackFont.name));
-    fallbackFont->filename = webFallbackFont.filename;
-    fallbackFont->fontconfigInterfaceId = webFallbackFont.fontconfigInterfaceId;
-    fallbackFont->ttcIndex = webFallbackFont.ttcIndex;
-    fallbackFont->isBold = webFallbackFont.isBold;
-    fallbackFont->isItalic = webFallbackFont.isItalic;
+        fallbackFont->name = String::fromUTF8(CString(webFallbackFont.name));
+        fallbackFont->filename = webFallbackFont.filename;
+        fallbackFont->fontconfigInterfaceId = webFallbackFont.fontconfigInterfaceId;
+        fallbackFont->ttcIndex = webFallbackFont.ttcIndex;
+        fallbackFont->isBold = webFallbackFont.isBold;
+        fallbackFont->isItalic = webFallbackFont.isItalic;
+    } else {
+        std::string locale = preferredLocale ? preferredLocale : std::string();
+        gfx::FallbackFontData fallbackData = gfx::GetFallbackFontForChar(c, locale);
+        fallbackFont->name = String::fromUTF8(fallbackData.name.data(), fallbackData.name.length());
+        fallbackFont->filename = CString(fallbackData.filename.data(), fallbackData.filename.length());
+        fallbackFont->fontconfigInterfaceId = 0;
+        fallbackFont->ttcIndex = fallbackData.ttc_index;
+        fallbackFont->isBold = fallbackData.is_bold;
+        fallbackFont->isItalic = fallbackData.is_italic;
+    }
 }
 
 #if !OS(ANDROID)
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShapeIterator.h b/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShapeIterator.h
index 2da5bef..6418ecf 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShapeIterator.h
+++ b/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShapeIterator.h
@@ -154,7 +154,7 @@
             if (!m_textRun.is8Bit()) {
                 UChar32 nextChar;
                 U16_GET(m_textRun.characters16(), 0, i, length, nextChar);
-                if (Character::isCJKIdeographOrSymbol(nextChar))
+                if (Character::isCJKIdeographOrSymbolBase(nextChar))
                     return i;
             }
         }
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaperTest.cpp b/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaperTest.cpp
index c3522a4..a8623c6 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaperTest.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/CachingWordShaperTest.cpp
@@ -463,6 +463,24 @@
     ASSERT_FALSE(iterator.next(&wordResult));
 }
 
+TEST_F(CachingWordShaperTest, SegmentHangulToneMark)
+{
+    const UChar str[] = {
+        0xC740, // HANGUL SYLLABLE EUN
+        0x302E, // HANGUL SINGLE DOT TONE MARK
+        0x0
+    };
+    TextRun textRun(str, 2);
+
+    RefPtr<ShapeResult> wordResult;
+    CachingWordShapeIterator iterator(cache.get(), textRun, &font);
+
+    ASSERT_TRUE(iterator.next(&wordResult));
+    EXPECT_EQ(2u, wordResult->numCharacters());
+
+    ASSERT_FALSE(iterator.next(&wordResult));
+}
+
 TEST_F(CachingWordShaperTest, TextOrientationFallbackShouldNotInFallbackList)
 {
     const UChar str[] = {
diff --git a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
index 8315809..b15b8f5 100644
--- a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
+++ b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
@@ -74,16 +74,16 @@
     SkAlphaType alphaType = (Opaque == opacityMode) ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
     SkImageInfo info = SkImageInfo::MakeN32(size.width(), size.height(), alphaType);
     SkSurfaceProps disableLCDProps(0, kUnknown_SkPixelGeometry);
-    RefPtr<SkSurface> surface;
+    sk_sp<SkSurface> surface;
 
     if (gr) {
         *surfaceIsAccelerated = true;
-        surface = adoptRef(SkSurface::NewRenderTarget(gr, SkBudgeted::kNo, info, msaaSampleCount, Opaque == opacityMode ? 0 : &disableLCDProps));
+        surface = SkSurface::MakeRenderTarget(gr, SkBudgeted::kNo, info, msaaSampleCount, Opaque == opacityMode ? 0 : &disableLCDProps);
     }
 
     if (!surface) {
         *surfaceIsAccelerated = false;
-        surface = adoptRef(SkSurface::NewRaster(info, Opaque == opacityMode ? 0 : &disableLCDProps));
+        surface = SkSurface::MakeRaster(info, Opaque == opacityMode ? 0 : &disableLCDProps);
     }
 
     if (surface) {
@@ -93,7 +93,7 @@
             surface->getCanvas()->clear(SK_ColorTRANSPARENT);
         }
     }
-    return surface;
+    return fromSkSp(surface);
 }
 
 PassRefPtr<Canvas2DLayerBridge> Canvas2DLayerBridge::create(const IntSize& size, int msaaSampleCount, OpacityMode opacityMode, AccelerationMode accelerationMode)
@@ -428,7 +428,7 @@
     }
 
     TRACE_EVENT0("cc", "Canvas2DLayerBridge::hibernate");
-    RefPtr<SkSurface> tempHibernationSurface = adoptRef(SkSurface::NewRasterN32Premul(m_size.width(), m_size.height()));
+    sk_sp<SkSurface> tempHibernationSurface = SkSurface::MakeRasterN32Premul(m_size.width(), m_size.height());
     if (!tempHibernationSurface) {
         m_logger->reportHibernationEvent(HibernationAbortedDueToAllocationFailure);
         return;
diff --git a/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.cpp b/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.cpp
index d857ae67..dbcf9c1 100644
--- a/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.cpp
+++ b/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.cpp
@@ -30,13 +30,16 @@
 #include "platform/TraceEvent.h"
 #include "platform/graphics/ImageFrameGenerator.h"
 #include "platform/image-decoders/ImageDecoder.h"
+#include "platform/image-decoders/SegmentReader.h"
 #include "third_party/skia/include/core/SkData.h"
 
 namespace blink {
 
-DecodingImageGenerator::DecodingImageGenerator(PassRefPtr<ImageFrameGenerator> frameGenerator, const SkImageInfo& info, size_t index)
+DecodingImageGenerator::DecodingImageGenerator(PassRefPtr<ImageFrameGenerator> frameGenerator, const SkImageInfo& info, PassRefPtr<SegmentReader> data, bool allDataReceived, size_t index)
     : SkImageGenerator(info)
     , m_frameGenerator(frameGenerator)
+    , m_data(data)
+    , m_allDataReceived(allDataReceived)
     , m_frameIndex(index)
     , m_generationId(0)
     , m_canYUVDecode(false)
@@ -51,7 +54,7 @@
 {
     TRACE_EVENT0("blink", "DecodingImageGenerator::refEncodedData");
 
-    return m_frameGenerator->refEncodedData();
+    return m_allDataReceived ? m_data->getAsSkData().leakRef() : nullptr;
 }
 
 bool DecodingImageGenerator::onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, SkPMColor table[], int* tableCount)
@@ -69,7 +72,7 @@
     }
 
     PlatformInstrumentation::willDecodeLazyPixelRef(m_generationId);
-    bool decoded = m_frameGenerator->decodeAndScale(m_frameIndex, getInfo(), pixels, rowBytes);
+    bool decoded = m_frameGenerator->decodeAndScale(m_data.get(), m_allDataReceived, m_frameIndex, getInfo(), pixels, rowBytes);
     PlatformInstrumentation::didDecodeLazyPixelRef();
 
     return decoded;
@@ -77,7 +80,8 @@
 
 bool DecodingImageGenerator::onQueryYUV8(SkYUVSizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const
 {
-    if (!m_canYUVDecode)
+    // YUV decoding does not currently support progressive decoding. See comment in ImageFrameGenerator.h.
+    if (!m_canYUVDecode || !m_allDataReceived)
         return false;
 
     TRACE_EVENT1("blink", "DecodingImageGenerator::queryYUV8", "sizes", static_cast<int>(m_frameIndex));
@@ -85,17 +89,18 @@
     if (colorSpace)
         *colorSpace = kJPEG_SkYUVColorSpace;
 
-    return m_frameGenerator->getYUVComponentSizes(sizeInfo);
+    return m_frameGenerator->getYUVComponentSizes(m_data.get(), sizeInfo);
 }
 
 bool DecodingImageGenerator::onGetYUV8Planes(const SkYUVSizeInfo& sizeInfo, void* planes[3])
 {
-    ASSERT(m_canYUVDecode);
+    // YUV decoding does not currently support progressive decoding. See comment in ImageFrameGenerator.h.
+    ASSERT(m_canYUVDecode && m_allDataReceived);
 
     TRACE_EVENT1("blink", "DecodingImageGenerator::getYUV8Planes", "frame index", static_cast<int>(m_frameIndex));
 
     PlatformInstrumentation::willDecodeLazyPixelRef(m_generationId);
-    bool decoded = m_frameGenerator->decodeToYUV(m_frameIndex, sizeInfo.fSizes, planes, sizeInfo.fWidthBytes);
+    bool decoded = m_frameGenerator->decodeToYUV(m_data.get(), m_frameIndex, sizeInfo.fSizes, planes, sizeInfo.fWidthBytes);
     PlatformInstrumentation::didDecodeLazyPixelRef();
 
     return decoded;
@@ -103,26 +108,26 @@
 
 SkImageGenerator* DecodingImageGenerator::create(SkData* data)
 {
-    RefPtr<SharedBuffer> buffer = SharedBuffer::create(data->bytes(), data->size());
-
     // We just need the size of the image, so we have to temporarily create an ImageDecoder. Since
     // we only need the size, it doesn't really matter about premul or not, or gamma settings.
-    OwnPtr<ImageDecoder> decoder = ImageDecoder::create(*buffer.get(), ImageDecoder::AlphaPremultiplied, ImageDecoder::GammaAndColorProfileApplied);
+    OwnPtr<ImageDecoder> decoder = ImageDecoder::create(static_cast<const char*>(data->data()), data->size(),
+        ImageDecoder::AlphaPremultiplied, ImageDecoder::GammaAndColorProfileApplied);
     if (!decoder)
         return 0;
 
-    decoder->setData(buffer.get(), true);
+    RefPtr<SegmentReader> segmentReader = SegmentReader::createFromSkData(data);
+    decoder->setData(segmentReader.get(), true);
     if (!decoder->isSizeAvailable())
         return 0;
 
     const IntSize size = decoder->size();
     const SkImageInfo info = SkImageInfo::MakeN32Premul(size.width(), size.height());
 
-    RefPtr<ImageFrameGenerator> frame = ImageFrameGenerator::create(SkISize::Make(size.width(), size.height()), buffer, true, false);
+    RefPtr<ImageFrameGenerator> frame = ImageFrameGenerator::create(SkISize::Make(size.width(), size.height()), false);
     if (!frame)
         return 0;
 
-    return new DecodingImageGenerator(frame, info, 0);
+    return new DecodingImageGenerator(frame, info, segmentReader.release(), true, 0);
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.h b/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.h
index 65407af..bc338d0 100644
--- a/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.h
+++ b/third_party/WebKit/Source/platform/graphics/DecodingImageGenerator.h
@@ -27,10 +27,12 @@
 #define DecodingImageGenerator_h
 
 #include "platform/PlatformExport.h"
+#include "platform/image-decoders/SegmentReader.h"
 #include "third_party/skia/include/core/SkImageGenerator.h"
 #include "third_party/skia/include/core/SkImageInfo.h"
 #include "wtf/Allocator.h"
 #include "wtf/Noncopyable.h"
+#include "wtf/PassRefPtr.h"
 #include "wtf/RefPtr.h"
 
 class SkData;
@@ -48,7 +50,7 @@
 public:
     static SkImageGenerator* create(SkData*);
 
-    DecodingImageGenerator(PassRefPtr<ImageFrameGenerator>, const SkImageInfo&, size_t index);
+    DecodingImageGenerator(PassRefPtr<ImageFrameGenerator>, const SkImageInfo&, PassRefPtr<SegmentReader>, bool allDataReceived, size_t index);
     ~DecodingImageGenerator() override;
 
     void setGenerationId(size_t id) { m_generationId = id; }
@@ -65,7 +67,9 @@
 
 private:
     RefPtr<ImageFrameGenerator> m_frameGenerator;
-    size_t m_frameIndex;
+    const RefPtr<SegmentReader> m_data; // Data source.
+    const bool m_allDataReceived;
+    const size_t m_frameIndex;
     size_t m_generationId;
     bool m_canYUVDecode;
 };
diff --git a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.cpp b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.cpp
index f1d76fd8..6cebd8a 100644
--- a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.cpp
+++ b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.cpp
@@ -26,10 +26,12 @@
 #include "platform/graphics/DeferredImageDecoder.h"
 
 #include "platform/RuntimeEnabledFeatures.h"
+#include "platform/SharedBuffer.h"
 #include "platform/graphics/DecodingImageGenerator.h"
 #include "platform/graphics/FrameData.h"
 #include "platform/graphics/ImageDecodingStore.h"
 #include "platform/graphics/ImageFrameGenerator.h"
+#include "platform/image-decoders/SegmentReader.h"
 #include "third_party/skia/include/core/SkImage.h"
 #include "wtf/PassOwnPtr.h"
 
@@ -54,7 +56,6 @@
 
 DeferredImageDecoder::DeferredImageDecoder(PassOwnPtr<ImageDecoder> actualDecoder)
     : m_allDataReceived(false)
-    , m_lastDataSize(0)
     , m_actualDecoder(std::move(actualDecoder))
     , m_repetitionCount(cAnimationNone)
     , m_hasColorProfile(false)
@@ -114,15 +115,20 @@
 void DeferredImageDecoder::setData(SharedBuffer& data, bool allDataReceived)
 {
     if (m_actualDecoder) {
-        m_data = RefPtr<SharedBuffer>(data);
-        m_lastDataSize = data.size();
         m_allDataReceived = allDataReceived;
         m_actualDecoder->setData(&data, allDataReceived);
         prepareLazyDecodedFrames();
     }
 
-    if (m_frameGenerator)
-        m_frameGenerator->setData(&data, allDataReceived);
+    if (m_frameGenerator) {
+        if (!m_rwBuffer)
+            m_rwBuffer = adoptPtr(new SkRWBuffer(data.size()));
+
+        const char* segment = 0;
+        for (size_t length = data.getSomeData(segment, m_rwBuffer->size());
+            length; length = data.getSomeData(segment, m_rwBuffer->size()))
+            m_rwBuffer->append(segment, length);
+    }
 }
 
 bool DeferredImageDecoder::isSizeAvailable()
@@ -230,7 +236,8 @@
     m_hasColorProfile = m_actualDecoder->hasColorProfile();
 
     const bool isSingleFrame = m_actualDecoder->repetitionCount() == cAnimationNone || (m_allDataReceived && m_actualDecoder->frameCount() == 1u);
-    m_frameGenerator = ImageFrameGenerator::create(SkISize::Make(m_actualDecoder->decodedSize().width(), m_actualDecoder->decodedSize().height()), m_data, m_allDataReceived, !isSingleFrame);
+    const SkISize decodedSize = SkISize::Make(m_actualDecoder->decodedSize().width(), m_actualDecoder->decodedSize().height());
+    m_frameGenerator = ImageFrameGenerator::create(decodedSize, !isSingleFrame);
 }
 
 void DeferredImageDecoder::prepareLazyDecodedFrames()
@@ -267,7 +274,7 @@
     if (m_allDataReceived) {
         m_repetitionCount = m_actualDecoder->repetitionCount();
         m_actualDecoder.clear();
-        m_data = nullptr;
+        // Hold on to m_rwBuffer, which is still needed by createFrameAtIndex.
     }
 }
 
@@ -282,7 +289,9 @@
     ASSERT(decodedSize.width() > 0);
     ASSERT(decodedSize.height() > 0);
 
-    DecodingImageGenerator* generator = new DecodingImageGenerator(m_frameGenerator, imageInfoFrom(decodedSize, knownToBeOpaque), index);
+    RefPtr<SkROBuffer> roBuffer = adoptRef(m_rwBuffer->newRBufferSnapshot());
+    RefPtr<SegmentReader> segmentReader = SegmentReader::createFromSkROBuffer(roBuffer.release());
+    DecodingImageGenerator* generator = new DecodingImageGenerator(m_frameGenerator, imageInfoFrom(decodedSize, knownToBeOpaque), segmentReader.release(), m_allDataReceived, index);
     RefPtr<SkImage> image = adoptRef(SkImage::NewFromGenerator(generator)); // SkImage takes ownership of the generator.
     if (!image)
         return nullptr;
diff --git a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.h b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.h
index 3338d4a..d6084c91 100644
--- a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.h
+++ b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.h
@@ -31,6 +31,7 @@
 #include "platform/image-decoders/ImageDecoder.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkPixelRef.h"
+#include "third_party/skia/include/core/SkRWBuffer.h"
 #include "wtf/Allocator.h"
 #include "wtf/Forward.h"
 #include "wtf/OwnPtr.h"
@@ -88,9 +89,10 @@
 
     PassRefPtr<SkImage> createFrameImageAtIndex(size_t index, bool knownToBeOpaque) const;
 
-    RefPtr<SharedBuffer> m_data;
+    // Copy of the data that is passed in, used by deferred decoding.
+    // Allows creating readonly snapshots that may be read in another thread.
+    OwnPtr<SkRWBuffer> m_rwBuffer;
     bool m_allDataReceived;
-    unsigned m_lastDataSize;
     OwnPtr<ImageDecoder> m_actualDecoder;
 
     String m_filenameExtension;
diff --git a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp
index 9edd5595..bf6e341 100644
--- a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoderTest.cpp
@@ -104,7 +104,7 @@
         m_actualDecoder = decoder.get();
         m_actualDecoder->setSize(1, 1);
         m_lazyDecoder = DeferredImageDecoder::createForTesting(decoder.release());
-        m_surface.reset(SkSurface::NewRasterN32Premul(100, 100));
+        m_surface = SkSurface::MakeRasterN32Premul(100, 100);
         ASSERT_TRUE(m_surface.get());
         m_decodeRequestCount = 0;
         m_repetitionCount = cAnimationNone;
@@ -162,7 +162,7 @@
     // Don't own this but saves the pointer to query states.
     MockImageDecoder* m_actualDecoder;
     OwnPtr<DeferredImageDecoder> m_lazyDecoder;
-    SkAutoTUnref<SkSurface> m_surface;
+    sk_sp<SkSurface> m_surface;
     int m_decodeRequestCount;
     RefPtr<SharedBuffer> m_data;
     size_t m_frameCount;
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp
index fcb02d1..624db43 100644
--- a/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayerTest.cpp
@@ -42,7 +42,6 @@
 #include "public/platform/WebGraphicsContext3D.h"
 #include "public/platform/WebLayer.h"
 #include "public/platform/WebLayerTreeView.h"
-#include "public/platform/WebUnitTestSupport.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "wtf/PassOwnPtr.h"
 
diff --git a/third_party/WebKit/Source/platform/graphics/ImageDecodingStoreTest.cpp b/third_party/WebKit/Source/platform/graphics/ImageDecodingStoreTest.cpp
index bfea0da..1fa2cce 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageDecodingStoreTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ImageDecodingStoreTest.cpp
@@ -25,7 +25,6 @@
 
 #include "platform/graphics/ImageDecodingStore.h"
 
-#include "platform/SharedBuffer.h"
 #include "platform/graphics/ImageFrameGenerator.h"
 #include "platform/graphics/test/MockImageDecoder.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -37,8 +36,7 @@
     void SetUp() override
     {
         ImageDecodingStore::instance().setCacheLimitInBytes(1024 * 1024);
-        m_data = SharedBuffer::create();
-        m_generator = ImageFrameGenerator::create(SkISize::Make(100, 100), m_data, true);
+        m_generator = ImageFrameGenerator::create(SkISize::Make(100, 100), true);
         m_decodersDestroyed = 0;
     }
 
@@ -77,7 +75,6 @@
             ImageDecodingStore::instance().setCacheLimitInBytes(0);
     }
 
-    RefPtr<SharedBuffer> m_data;
     RefPtr<ImageFrameGenerator> m_generator;
     int m_decodersDestroyed;
 };
diff --git a/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp b/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp
index 312dba24..1decd0f7 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.cpp
@@ -26,7 +26,6 @@
 #include "platform/graphics/ImageFrameGenerator.h"
 
 #include "SkData.h"
-#include "platform/SharedBuffer.h"
 #include "platform/TraceEvent.h"
 #include "platform/graphics/ImageDecodingStore.h"
 #include "platform/image-decoders/ImageDecoder.h"
@@ -52,7 +51,7 @@
 
 // Creates a SkPixelRef such that the memory for pixels is given by an external body.
 // This is used to write directly to the memory given by Skia during decoding.
-class ImageFrameGenerator::ExternalMemoryAllocator final : public SkBitmap::Allocator {
+class ExternalMemoryAllocator final : public SkBitmap::Allocator {
     USING_FAST_MALLOC(ExternalMemoryAllocator);
     WTF_MAKE_NONCOPYABLE(ExternalMemoryAllocator);
 public:
@@ -101,105 +100,39 @@
     return true;
 }
 
-ImageFrameGenerator::ImageFrameGenerator(const SkISize& fullSize, PassRefPtr<SharedBuffer> data, bool allDataReceived, bool isMultiFrame)
+ImageFrameGenerator::ImageFrameGenerator(const SkISize& fullSize, bool isMultiFrame)
     : m_fullSize(fullSize)
-    , m_data(adoptRef(new ThreadSafeDataTransport()))
     , m_isMultiFrame(isMultiFrame)
     , m_decodeFailed(false)
     , m_yuvDecodingFailed(false)
     , m_frameCount(0)
-    , m_encodedData(nullptr)
 {
-    setData(data.get(), allDataReceived);
 }
 
 ImageFrameGenerator::~ImageFrameGenerator()
 {
-    if (m_encodedData)
-        m_encodedData->unref();
     ImageDecodingStore::instance().removeCacheIndexedByGenerator(this);
 }
 
-void ImageFrameGenerator::setData(PassRefPtr<SharedBuffer> data, bool allDataReceived)
+bool ImageFrameGenerator::decodeAndScale(SegmentReader* data, bool allDataReceived, size_t index, const SkImageInfo& info, void* pixels, size_t rowBytes)
 {
-    m_data->setData(data.get(), allDataReceived);
-}
-
-static void sharedSkDataReleaseCallback(const void* address, void* context)
-{
-    // This gets called when m_encodedData reference count becomes 0 - and it could happen in
-    // ImageFrameGenerator destructor or later when m_encodedData gets dereferenced.
-    // In this method, we deref ThreadSafeDataTransport, as ThreadSafeDataTransport is the owner
-    // of data returned via refEncodedData.
-
-    ThreadSafeDataTransport* dataTransport = static_cast<ThreadSafeDataTransport*>(context);
-#if ENABLE(ASSERT)
-    ASSERT(dataTransport);
-    SharedBuffer* buffer = 0;
-    bool allDataReceived = false;
-    dataTransport->data(&buffer, &allDataReceived);
-    ASSERT(allDataReceived && buffer && buffer->data() == address);
-#endif
-    // Dereference m_data now.
-    dataTransport->deref();
-}
-
-SkData* ImageFrameGenerator::refEncodedData()
-{
-    // SkData is returned only when full image (encoded) data is received. This is important
-    // since DeferredImageDecoder::setData is called only once with allDataReceived set to true,
-    // and after that m_data->m_readBuffer.data() is not changed. See also RELEASE_ASSERT used in
-    // ThreadSafeDataTransport::data().
-    SharedBuffer* buffer = 0;
-    bool allDataReceived = false;
-    m_data->data(&buffer, &allDataReceived);
-    if (!allDataReceived)
-        return nullptr;
-
-    {
-        // Prevents concurrent access to m_encodedData creation.
-        MutexLocker lock(m_decodeMutex);
-        if (m_encodedData) {
-            m_encodedData->ref();
-            return m_encodedData;
-        }
-        // m_encodedData is created with initial reference count == 1. ImageFrameGenerator always holds one
-        // reference to m_encodedData, as it prevents write access in SkData::writable_data.
-        m_encodedData = SkData::NewWithProc(buffer->data(), buffer->size(), sharedSkDataReleaseCallback, m_data.get());
-        // While m_encodedData is referenced, prevent disposing m_data and its content.
-        // it is dereferenced in sharedSkDataReleaseCallback, called when m_encodedData gets dereferenced.
-        m_data->ref();
-    }
-    // Increase the reference, caller must decrease it. One reference is always kept by ImageFrameGenerator and released
-    // in destructor.
-    m_encodedData->ref();
-    return m_encodedData;
-}
-
-bool ImageFrameGenerator::decodeAndScale(size_t index, const SkImageInfo& info, void* pixels, size_t rowBytes)
-{
-    // Prevent concurrent decode or scale operations on the same image data.
-    MutexLocker lock(m_decodeMutex);
-
     if (m_decodeFailed)
         return false;
 
     TRACE_EVENT1("blink", "ImageFrameGenerator::decodeAndScale", "frame index", static_cast<int>(index));
 
-    m_externalAllocator = adoptPtr(new ExternalMemoryAllocator(info, pixels, rowBytes));
+    RefPtr<ExternalMemoryAllocator> externalAllocator = adoptRef(new ExternalMemoryAllocator(info, pixels, rowBytes));
 
     // This implementation does not support scaling so check the requested size.
     SkISize scaledSize = SkISize::Make(info.width(), info.height());
     ASSERT(m_fullSize == scaledSize);
 
-    SkBitmap bitmap = tryToResumeDecode(index, scaledSize);
+    // TODO (scroggo): Convert tryToResumeDecode() and decode() to take a
+    // PassRefPtr<SkBitmap::Allocator> instead of a bare pointer.
+    SkBitmap bitmap = tryToResumeDecode(data, allDataReceived, index, scaledSize, externalAllocator.get());
     if (bitmap.isNull())
         return false;
 
-    // Don't keep the allocator because it contains a pointer to memory
-    // that we do not own.
-    m_externalAllocator.clear();
-
     // Check to see if the decoder has written directly to the pixel memory
     // provided. If not, make a copy.
     ASSERT(bitmap.width() == scaledSize.width());
@@ -210,11 +143,10 @@
     return true;
 }
 
-bool ImageFrameGenerator::decodeToYUV(size_t index, const SkISize componentSizes[3], void* planes[3], const size_t rowBytes[3])
+bool ImageFrameGenerator::decodeToYUV(SegmentReader* data, size_t index, const SkISize componentSizes[3], void* planes[3], const size_t rowBytes[3])
 {
-    // Prevent concurrent decode or scale operations on the same image data.
-    MutexLocker lock(m_decodeMutex);
-
+    // TODO (scroggo): The only interesting thing this uses from the ImageFrameGenerator is m_decodeFailed.
+    // Move this into DecodingImageGenerator, which is the only class that calls it.
     if (m_decodeFailed)
         return false;
 
@@ -225,18 +157,11 @@
         return false;
     }
 
-    SharedBuffer* data = 0;
-    bool allDataReceived = false;
-    m_data->data(&data, &allDataReceived);
-
-    // FIXME: YUV decoding does not currently support progressive decoding.
-    ASSERT(allDataReceived);
-
     OwnPtr<ImageDecoder> decoder = ImageDecoder::create(*data, ImageDecoder::AlphaPremultiplied, ImageDecoder::GammaAndColorProfileApplied);
-    if (!decoder)
-        return false;
+    // getYUVComponentSizes was already called and was successful, so ImageDecoder::create must succeed.
+    ASSERT(decoder);
 
-    decoder->setData(data, allDataReceived);
+    decoder->setData(data, true);
 
     OwnPtr<ImagePlanes> imagePlanes = adoptPtr(new ImagePlanes(planes, rowBytes));
     decoder->setImagePlanes(imagePlanes.release());
@@ -253,16 +178,19 @@
     return false;
 }
 
-SkBitmap ImageFrameGenerator::tryToResumeDecode(size_t index, const SkISize& scaledSize)
+SkBitmap ImageFrameGenerator::tryToResumeDecode(SegmentReader* data, bool allDataReceived, size_t index, const SkISize& scaledSize, SkBitmap::Allocator* allocator)
 {
     TRACE_EVENT1("blink", "ImageFrameGenerator::tryToResumeDecode", "frame index", static_cast<int>(index));
 
     ImageDecoder* decoder = 0;
+
+    // Lock the mutex, so only one thread can use the decoder at once.
+    MutexLocker lock(m_decodeMutex);
     const bool resumeDecoding = ImageDecodingStore::instance().lockDecoder(this, m_fullSize, &decoder);
     ASSERT(!resumeDecoding || decoder);
 
     SkBitmap fullSizeImage;
-    bool complete = decode(index, &decoder, &fullSizeImage);
+    bool complete = decode(data, allDataReceived, index, &decoder, &fullSizeImage, allocator);
 
     if (!decoder)
         return SkBitmap();
@@ -322,14 +250,11 @@
     m_hasAlpha[index] = hasAlpha;
 }
 
-bool ImageFrameGenerator::decode(size_t index, ImageDecoder** decoder, SkBitmap* bitmap)
+bool ImageFrameGenerator::decode(SegmentReader* data, bool allDataReceived, size_t index, ImageDecoder** decoder, SkBitmap* bitmap, SkBitmap::Allocator* allocator)
 {
+    ASSERT(m_decodeMutex.locked());
     TRACE_EVENT2("blink", "ImageFrameGenerator::decode", "width", m_fullSize.width(), "height", m_fullSize.height());
 
-    SharedBuffer* data = 0;
-    bool allDataReceived = false;
-    m_data->data(&data, &allDataReceived);
-
     // Try to create an ImageDecoder if we are not given one.
     ASSERT(decoder);
     bool newDecoder = false;
@@ -348,8 +273,8 @@
     if (!m_isMultiFrame && newDecoder && allDataReceived) {
         // If we're using an external memory allocator that means we're decoding
         // directly into the output memory and we can save one memcpy.
-        ASSERT(m_externalAllocator.get());
-        (*decoder)->setMemoryAllocator(m_externalAllocator.get());
+        ASSERT(allocator);
+        (*decoder)->setMemoryAllocator(allocator);
     }
 
     (*decoder)->setData(data, allDataReceived);
@@ -362,7 +287,7 @@
     if (allDataReceived)
         m_frameCount = (*decoder)->frameCount();
 
-    (*decoder)->setData(0, false); // Unref SharedBuffer from ImageDecoder.
+    (*decoder)->setData(PassRefPtr<SegmentReader>(nullptr), false); // Unref SegmentReader from ImageDecoder.
     (*decoder)->clearCacheExceptFrame(index);
     (*decoder)->setMemoryAllocator(0);
 
@@ -392,27 +317,19 @@
     return true;
 }
 
-bool ImageFrameGenerator::getYUVComponentSizes(SkYUVSizeInfo* sizeInfo)
+bool ImageFrameGenerator::getYUVComponentSizes(SegmentReader* data, SkYUVSizeInfo* sizeInfo)
 {
     TRACE_EVENT2("blink", "ImageFrameGenerator::getYUVComponentSizes", "width", m_fullSize.width(), "height", m_fullSize.height());
 
     if (m_yuvDecodingFailed)
         return false;
 
-    SharedBuffer* data = 0;
-    bool allDataReceived = false;
-    m_data->data(&data, &allDataReceived);
-
-    // FIXME: YUV decoding does not currently support progressive decoding.
-    if (!allDataReceived)
-        return false;
-
     OwnPtr<ImageDecoder> decoder = ImageDecoder::create(*data, ImageDecoder::AlphaPremultiplied, ImageDecoder::GammaAndColorProfileApplied);
     if (!decoder)
         return false;
 
     // Setting a dummy ImagePlanes object signals to the decoder that we want to do YUV decoding.
-    decoder->setData(data, allDataReceived);
+    decoder->setData(data, true);
     OwnPtr<ImagePlanes> dummyImagePlanes = adoptPtr(new ImagePlanes);
     decoder->setImagePlanes(dummyImagePlanes.release());
 
diff --git a/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.h b/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.h
index 73ac628..4b31634 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.h
+++ b/third_party/WebKit/Source/platform/graphics/ImageFrameGenerator.h
@@ -27,7 +27,7 @@
 #define ImageFrameGenerator_h
 
 #include "platform/PlatformExport.h"
-#include "platform/graphics/ThreadSafeDataTransport.h"
+#include "platform/image-decoders/SegmentReader.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkSize.h"
 #include "third_party/skia/include/core/SkTypes.h"
@@ -47,7 +47,6 @@
 namespace blink {
 
 class ImageDecoder;
-class SharedBuffer;
 
 class PLATFORM_EXPORT ImageDecoderFactory {
     USING_FAST_MALLOC(ImageDecoderFactory);
@@ -61,27 +60,23 @@
 class PLATFORM_EXPORT ImageFrameGenerator final : public ThreadSafeRefCounted<ImageFrameGenerator> {
     WTF_MAKE_NONCOPYABLE(ImageFrameGenerator);
 public:
-    static PassRefPtr<ImageFrameGenerator> create(const SkISize& fullSize, PassRefPtr<SharedBuffer> data, bool allDataReceived, bool isMultiFrame = false)
+    static PassRefPtr<ImageFrameGenerator> create(const SkISize& fullSize, bool isMultiFrame = false)
     {
-        return adoptRef(new ImageFrameGenerator(fullSize, data, allDataReceived, isMultiFrame));
+        return adoptRef(new ImageFrameGenerator(fullSize, isMultiFrame));
     }
 
     ~ImageFrameGenerator();
 
-    void setData(PassRefPtr<SharedBuffer>, bool allDataReceived);
-
-    // Return our encoded image data. Caller takes ownership and must unref the data
-    // according to the contract SkImageGenerator::refEncodedData. Returns null if
-    // the data is has not been fully received.
-    SkData* refEncodedData();
-
     // Decodes and scales the specified frame at |index|. The dimensions and output
     // format are given in SkImageInfo. Decoded pixels are written into |pixels| with
     // a stride of |rowBytes|. Returns true if decoding was successful.
-    bool decodeAndScale(size_t index, const SkImageInfo&, void* pixels, size_t rowBytes);
+    bool decodeAndScale(SegmentReader*, bool allDataReceived, size_t index, const SkImageInfo&, void* pixels, size_t rowBytes);
 
     // Decodes YUV components directly into the provided memory planes.
-    bool decodeToYUV(size_t index, const SkISize componentSizes[3], void* planes[3], const size_t rowBytes[3]);
+    // Must not be called unless getYUVComponentSizes has been called and returned true.
+    // YUV decoding does not currently support progressive decoding. In order to support it, ImageDecoder needs something
+    // analagous to its ImageFrame cache to hold partial planes, and the GPU code needs to handle them.
+    bool decodeToYUV(SegmentReader*, size_t index, const SkISize componentSizes[3], void* planes[3], const size_t rowBytes[3]);
 
     const SkISize& getFullSize() const { return m_fullSize; }
 
@@ -90,10 +85,12 @@
 
     bool hasAlpha(size_t index);
 
-    bool getYUVComponentSizes(SkYUVSizeInfo*);
+    // Must not be called unless the SkROBuffer has all the data.
+    // YUV decoding does not currently support progressive decoding. See comment above on decodeToYUV.
+    bool getYUVComponentSizes(SegmentReader*, SkYUVSizeInfo*);
 
 private:
-    ImageFrameGenerator(const SkISize& fullSize, PassRefPtr<SharedBuffer>, bool allDataReceived, bool isMultiFrame);
+    ImageFrameGenerator(const SkISize& fullSize, bool isMultiFrame);
 
     friend class ImageFrameGeneratorTest;
     friend class DeferredImageDecoderTest;
@@ -102,26 +99,18 @@
 
     void setHasAlpha(size_t index, bool hasAlpha);
 
-    // These methods are called while m_decodeMutex is locked.
-    SkBitmap tryToResumeDecode(size_t index, const SkISize& scaledSize);
-    bool decode(size_t index, ImageDecoder**, SkBitmap*);
+    SkBitmap tryToResumeDecode(SegmentReader*, bool allDataReceived, size_t index, const SkISize& scaledSize, SkBitmap::Allocator*);
+    // This method should only be called while m_decodeMutex is locked.
+    bool decode(SegmentReader*, bool allDataReceived, size_t index, ImageDecoder**, SkBitmap*, SkBitmap::Allocator*);
 
-    SkISize m_fullSize;
+    const SkISize m_fullSize;
 
-    // ThreadSafeDataTransport is referenced by this class and m_encodedData.
-    // In case that ImageFrameGenerator get's deleted before m_encodedData,
-    // m_encodedData would hold the reference to it (and underlying data).
-    RefPtr<ThreadSafeDataTransport> m_data;
-
-    bool m_isMultiFrame;
+    const bool m_isMultiFrame;
     bool m_decodeFailed;
     bool m_yuvDecodingFailed;
     size_t m_frameCount;
     Vector<bool> m_hasAlpha;
 
-    class ExternalMemoryAllocator;
-    OwnPtr<ExternalMemoryAllocator> m_externalAllocator;
-
     OwnPtr<ImageDecoderFactory> m_imageDecoderFactory;
 
     // Prevents multiple decode operations on the same data.
@@ -129,13 +118,6 @@
 
     // Protect concurrent access to m_hasAlpha.
     Mutex m_alphaMutex;
-
-    // Our encoded image data returned in refEncodedData.
-    SkData* m_encodedData;
-
-#if COMPILER(MSVC)
-    friend struct ::WTF::OwnedPtrDeleter<ExternalMemoryAllocator>;
-#endif
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/ImageFrameGeneratorTest.cpp b/third_party/WebKit/Source/platform/graphics/ImageFrameGeneratorTest.cpp
index aef5863c..4b9d1b7 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageFrameGeneratorTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ImageFrameGeneratorTest.cpp
@@ -29,6 +29,7 @@
 #include "platform/ThreadSafeFunctional.h"
 #include "platform/graphics/ImageDecodingStore.h"
 #include "platform/graphics/test/MockImageDecoder.h"
+#include "platform/image-decoders/SegmentReader.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebTaskRunner.h"
 #include "public/platform/WebThread.h"
@@ -54,8 +55,9 @@
     void SetUp() override
     {
         ImageDecodingStore::instance().setCacheLimitInBytes(1024 * 1024);
+        m_generator = ImageFrameGenerator::create(fullSize(), false);
         m_data = SharedBuffer::create();
-        m_generator = ImageFrameGenerator::create(fullSize(), m_data, false);
+        m_segmentReader = SegmentReader::createFromSharedBuffer(m_data);
         useMockImageDecoderFactory();
         m_decodersDestroyed = 0;
         m_decodeRequestCount = 0;
@@ -101,10 +103,9 @@
         m_generator->setImageDecoderFactory(MockImageDecoderFactory::create(this, fullSize()));
     }
 
-    void addNewData(bool allDataReceived = false)
+    void addNewData()
     {
         m_data->append("g", 1u);
-        m_generator->setData(m_data, allDataReceived);
     }
 
     void setFrameStatus(ImageFrame::Status status)  { m_status = m_nextFrameStatus = status; }
@@ -114,12 +115,13 @@
         m_frameCount = count;
         if (count > 1) {
             m_generator.clear();
-            m_generator = ImageFrameGenerator::create(fullSize(), m_data, true, true);
+            m_generator = ImageFrameGenerator::create(fullSize(), true);
             useMockImageDecoderFactory();
         }
     }
 
     RefPtr<SharedBuffer> m_data;
+    RefPtr<SegmentReader> m_segmentReader;
     RefPtr<ImageFrameGenerator> m_generator;
     int m_decodersDestroyed;
     int m_decodeRequestCount;
@@ -134,11 +136,11 @@
     setFrameStatus(ImageFrame::FramePartial);
 
     char buffer[100 * 100 * 4];
-    m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
+    m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), buffer, 100 * 4);
     EXPECT_EQ(1, m_decodeRequestCount);
 
     addNewData();
-    m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
+    m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), buffer, 100 * 4);
     EXPECT_EQ(2, m_decodeRequestCount);
     EXPECT_EQ(0, m_decodersDestroyed);
 }
@@ -148,35 +150,26 @@
     setFrameStatus(ImageFrame::FramePartial);
 
     char buffer[100 * 100 * 4];
-    m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
+    m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), buffer, 100 * 4);
     EXPECT_EQ(1, m_decodeRequestCount);
     EXPECT_EQ(0, m_decodersDestroyed);
 
     setFrameStatus(ImageFrame::FrameComplete);
     addNewData();
 
-    m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
+    m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), buffer, 100 * 4);
     EXPECT_EQ(2, m_decodeRequestCount);
     EXPECT_EQ(1, m_decodersDestroyed);
 
     // Decoder created again.
-    m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
+    m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), buffer, 100 * 4);
     EXPECT_EQ(3, m_decodeRequestCount);
 }
 
-static void decodeThreadMain(ImageFrameGenerator* generator)
+static void decodeThreadMain(ImageFrameGenerator* generator, SegmentReader* segmentReader)
 {
     char buffer[100 * 100 * 4];
-    generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
-}
-
-static void decodeThreadWithRefEncodedMain(ImageFrameGenerator* generator)
-{
-    // Image must be complete - refEncodedData otherwise returns null.
-    char buffer[100 * 100 * 4];
-    SkData* data = generator->refEncodedData();
-    generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
-    data->unref();
+    generator->decodeAndScale(segmentReader, false, 0, imageInfo(), buffer, 100 * 4);
 }
 
 TEST_F(ImageFrameGeneratorTest, incompleteDecodeBecomesCompleteMultiThreaded)
@@ -184,52 +177,27 @@
     setFrameStatus(ImageFrame::FramePartial);
 
     char buffer[100 * 100 * 4];
-    m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
+    m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), buffer, 100 * 4);
     EXPECT_EQ(1, m_decodeRequestCount);
     EXPECT_EQ(0, m_decodersDestroyed);
-    SkData* data = m_generator->refEncodedData();
-    EXPECT_EQ(nullptr, data);
 
     // LocalFrame can now be decoded completely.
     setFrameStatus(ImageFrame::FrameComplete);
     addNewData();
-    // addNewData is calling m_generator->setData with allDataReceived == false, which means that
-    // refEncodedData should return null.
-    data = m_generator->refEncodedData();
-    EXPECT_EQ(nullptr, data);
     OwnPtr<WebThread> thread = adoptPtr(Platform::current()->createThread("DecodeThread"));
-    thread->getWebTaskRunner()->postTask(BLINK_FROM_HERE, threadSafeBind(&decodeThreadMain, AllowCrossThreadAccess(m_generator.get())));
+    thread->getWebTaskRunner()->postTask(BLINK_FROM_HERE, threadSafeBind(&decodeThreadMain, AllowCrossThreadAccess(m_generator.get()), AllowCrossThreadAccess(m_segmentReader.get())));
     thread.clear();
     EXPECT_EQ(2, m_decodeRequestCount);
     EXPECT_EQ(1, m_decodersDestroyed);
 
     // Decoder created again.
-    m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
+    m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), buffer, 100 * 4);
     EXPECT_EQ(3, m_decodeRequestCount);
 
-    addNewData(true);
-    data = m_generator->refEncodedData();
-    ASSERT_TRUE(data);
-    // To prevent data writting, SkData::unique() should be false.
-    ASSERT_TRUE(!data->unique());
+    addNewData();
 
-    // Thread will also ref and unref the data.
-    thread = adoptPtr(Platform::current()->createThread("RefEncodedDataThread"));
-    thread->getWebTaskRunner()->postTask(BLINK_FROM_HERE, threadSafeBind(&decodeThreadWithRefEncodedMain, AllowCrossThreadAccess(m_generator.get())));
-    thread.clear();
-    EXPECT_EQ(4, m_decodeRequestCount);
-
-    data->unref();
-    // m_generator is holding the only reference to SkData now.
-    ASSERT_TRUE(data->unique());
-
-    data = m_generator->refEncodedData();
-    ASSERT_TRUE(data && !data->unique());
-
-    // Delete generator, and SkData should have the only reference.
+    // Delete generator.
     m_generator = nullptr;
-    ASSERT_TRUE(data->unique());
-    data->unref();
 }
 
 TEST_F(ImageFrameGeneratorTest, frameHasAlpha)
@@ -237,7 +205,7 @@
     setFrameStatus(ImageFrame::FramePartial);
 
     char buffer[100 * 100 * 4];
-    m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
+    m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), buffer, 100 * 4);
     EXPECT_TRUE(m_generator->hasAlpha(0));
     EXPECT_EQ(1, m_decodeRequestCount);
 
@@ -249,7 +217,7 @@
     EXPECT_EQ(2, m_decodeRequestCount);
 
     setFrameStatus(ImageFrame::FrameComplete);
-    m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
+    m_generator->decodeAndScale(m_segmentReader.get(), false, 0, imageInfo(), buffer, 100 * 4);
     EXPECT_EQ(3, m_decodeRequestCount);
     EXPECT_FALSE(m_generator->hasAlpha(0));
 }
@@ -260,14 +228,14 @@
     setFrameStatus(ImageFrame::FrameComplete);
 
     char buffer[100 * 100 * 4];
-    m_generator->decodeAndScale(0, imageInfo(), buffer, 100 * 4);
+    m_generator->decodeAndScale(m_segmentReader.get(), true, 0, imageInfo(), buffer, 100 * 4);
     EXPECT_EQ(1, m_decodeRequestCount);
     EXPECT_EQ(0, m_decodersDestroyed);
     EXPECT_EQ(0U, m_requestedClearExceptFrame);
 
     setFrameStatus(ImageFrame::FrameComplete);
 
-    m_generator->decodeAndScale(1, imageInfo(), buffer, 100 * 4);
+    m_generator->decodeAndScale(m_segmentReader.get(), true, 1, imageInfo(), buffer, 100 * 4);
     EXPECT_EQ(2, m_decodeRequestCount);
     EXPECT_EQ(0, m_decodersDestroyed);
     EXPECT_EQ(1U, m_requestedClearExceptFrame);
@@ -277,7 +245,7 @@
     // Decoding the last frame of a multi-frame images should trigger clearing
     // all the frame data, but not destroying the decoder.  See comments in
     // ImageFrameGenerator::tryToResumeDecode().
-    m_generator->decodeAndScale(2, imageInfo(), buffer, 100 * 4);
+    m_generator->decodeAndScale(m_segmentReader.get(), true, 2, imageInfo(), buffer, 100 * 4);
     EXPECT_EQ(3, m_decodeRequestCount);
     EXPECT_EQ(0, m_decodersDestroyed);
     EXPECT_EQ(kNotFound, m_requestedClearExceptFrame);
diff --git a/third_party/WebKit/Source/platform/graphics/ImageLayerChromiumTest.cpp b/third_party/WebKit/Source/platform/graphics/ImageLayerChromiumTest.cpp
index a112fec..d9a0fa50 100644
--- a/third_party/WebKit/Source/platform/graphics/ImageLayerChromiumTest.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ImageLayerChromiumTest.cpp
@@ -73,7 +73,7 @@
         : Image(0)
         , m_size(size)
     {
-        RefPtr<SkSurface> surface = adoptRef(createSkSurface(size, opaque));
+        sk_sp<SkSurface> surface = createSkSurface(size, opaque);
         if (!surface)
             return;
 
@@ -81,9 +81,9 @@
         m_image = adoptRef(surface->newImageSnapshot());
     }
 
-    static SkSurface* createSkSurface(IntSize size, bool opaque)
+    static sk_sp<SkSurface> createSkSurface(IntSize size, bool opaque)
     {
-        return SkSurface::NewRaster(SkImageInfo::MakeN32(size.width(), size.height(), opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType));
+        return SkSurface::MakeRaster(SkImageInfo::MakeN32(size.width(), size.height(), opaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType));
     }
 
     IntSize m_size;
diff --git a/third_party/WebKit/Source/platform/graphics/ImagePattern.cpp b/third_party/WebKit/Source/platform/graphics/ImagePattern.cpp
index 1e0b2b9..287fd12 100644
--- a/third_party/WebKit/Source/platform/graphics/ImagePattern.cpp
+++ b/third_party/WebKit/Source/platform/graphics/ImagePattern.cpp
@@ -57,8 +57,8 @@
     // Create a transparent image 1 pixel wider and/or taller than the
     // original, then copy the orignal into it.
     // FIXME: Is there a better way to pad (not scale) an image in skia?
-    RefPtr<SkSurface> surface = adoptRef(SkSurface::NewRasterN32Premul(
-        m_tileImage->width() + expandW, m_tileImage->height() + expandH));
+    sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(
+        m_tileImage->width() + expandW, m_tileImage->height() + expandH);
     if (!surface)
         return SkShader::MakeColorShader(SK_ColorTRANSPARENT);
 
diff --git a/third_party/WebKit/Source/platform/graphics/PictureSnapshot.cpp b/third_party/WebKit/Source/platform/graphics/PictureSnapshot.cpp
index e5ff225..5a4d008 100644
--- a/third_party/WebKit/Source/platform/graphics/PictureSnapshot.cpp
+++ b/third_party/WebKit/Source/platform/graphics/PictureSnapshot.cpp
@@ -38,7 +38,9 @@
 #include "platform/graphics/skia/ImagePixelLocker.h"
 #include "platform/image-decoders/ImageDecoder.h"
 #include "platform/image-decoders/ImageFrame.h"
+#include "platform/image-decoders/SegmentReader.h"
 #include "platform/image-encoders/skia/PNGImageEncoder.h"
+#include "third_party/skia/include/core/SkData.h"
 #include "third_party/skia/include/core/SkImage.h"
 #include "third_party/skia/include/core/SkPictureRecorder.h"
 #include "third_party/skia/include/core/SkStream.h"
@@ -56,11 +58,14 @@
 
 static bool decodeBitmap(const void* data, size_t length, SkBitmap* result)
 {
-    RefPtr<SharedBuffer> buffer = SharedBuffer::create(static_cast<const char*>(data), length);
-    OwnPtr<ImageDecoder> imageDecoder = ImageDecoder::create(*buffer, ImageDecoder::AlphaPremultiplied, ImageDecoder::GammaAndColorProfileIgnored);
+    OwnPtr<ImageDecoder> imageDecoder = ImageDecoder::create(static_cast<const char*>(data), length,
+        ImageDecoder::AlphaPremultiplied, ImageDecoder::GammaAndColorProfileIgnored);
     if (!imageDecoder)
         return false;
-    imageDecoder->setData(buffer.get(), true);
+
+    // No need to copy the data; this decodes immediately.
+    RefPtr<SegmentReader> segmentReader = SegmentReader::createFromSkData(adoptRef(SkData::NewWithoutCopy(data, length)));
+    imageDecoder->setData(segmentReader.release(), true);
     ImageFrame* frame = imageDecoder->frameBufferAtIndex(0);
     if (!frame)
         return true;
diff --git a/third_party/WebKit/Source/platform/graphics/ThreadSafeDataTransport.cpp b/third_party/WebKit/Source/platform/graphics/ThreadSafeDataTransport.cpp
deleted file mode 100644
index f191017a..0000000
--- a/third_party/WebKit/Source/platform/graphics/ThreadSafeDataTransport.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "platform/graphics/ThreadSafeDataTransport.h"
-
-#include "platform/SharedBuffer.h"
-
-namespace blink {
-
-ThreadSafeDataTransport::ThreadSafeDataTransport()
-    : m_readBuffer(SharedBuffer::create())
-    , m_allDataReceived(false)
-    , m_readPosition(0)
-{
-}
-
-ThreadSafeDataTransport::~ThreadSafeDataTransport()
-{
-}
-
-void ThreadSafeDataTransport::setData(SharedBuffer* buffer, bool allDataReceived)
-{
-    ASSERT(buffer->size() >= m_readPosition);
-    Vector<RefPtr<SharedBuffer>> newBufferQueue;
-
-    const char* segment = 0;
-    while (size_t length = buffer->getSomeData(segment, m_readPosition)) {
-        m_readPosition += length;
-        newBufferQueue.append(SharedBuffer::create(segment, length));
-    }
-
-    MutexLocker locker(m_mutex);
-
-    // If all data was previously received, don't append more to it.
-    RELEASE_ASSERT(!(m_allDataReceived && newBufferQueue.size()));
-
-    m_newBufferQueue.appendVector(newBufferQueue);
-    newBufferQueue.clear();
-    m_allDataReceived = allDataReceived;
-}
-
-void ThreadSafeDataTransport::data(SharedBuffer** buffer, bool* allDataReceived)
-{
-    ASSERT(buffer);
-    ASSERT(allDataReceived);
-    Vector<RefPtr<SharedBuffer>> newBufferQueue;
-    {
-        MutexLocker lock(m_mutex);
-        m_newBufferQueue.swap(newBufferQueue);
-        *allDataReceived = m_allDataReceived;
-    }
-    for (size_t i = 0; i < newBufferQueue.size(); ++i)
-        m_readBuffer->append(newBufferQueue[i].get());
-    *buffer = m_readBuffer.get();
-}
-
-bool ThreadSafeDataTransport::hasNewData()
-{
-    MutexLocker lock(m_mutex);
-    return !m_newBufferQueue.isEmpty();
-}
-
-} // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/ThreadSafeDataTransport.h b/third_party/WebKit/Source/platform/graphics/ThreadSafeDataTransport.h
deleted file mode 100644
index 3aae947..0000000
--- a/third_party/WebKit/Source/platform/graphics/ThreadSafeDataTransport.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ThreadSafeDataTransport_h
-#define ThreadSafeDataTransport_h
-
-#include "platform/PlatformExport.h"
-#include "wtf/Allocator.h"
-#include "wtf/Noncopyable.h"
-#include "wtf/OwnPtr.h"
-#include "wtf/PassOwnPtr.h"
-#include "wtf/RefPtr.h"
-#include "wtf/ThreadSafeRefCounted.h"
-#include "wtf/ThreadingPrimitives.h"
-#include "wtf/Vector.h"
-
-namespace blink {
-
-class SharedBuffer;
-
-// The purpose of this class is to allow the transfer of data stored in
-// SharedBuffer in a thread-safe manner, and to minimize memory copies
-// and thread contention.
-//
-// This class is designed such that there is only one producer and
-// one consumer.
-
-class PLATFORM_EXPORT ThreadSafeDataTransport final : public ThreadSafeRefCounted<ThreadSafeDataTransport> {
-    WTF_MAKE_NONCOPYABLE(ThreadSafeDataTransport);
-public:
-    ThreadSafeDataTransport();
-    ~ThreadSafeDataTransport();
-
-    // This method is being called subsequently with an expanding
-    // SharedBuffer.
-    void setData(SharedBuffer*, bool allDataReceived);
-
-    // Get the data submitted to this class so far.
-    void data(SharedBuffer**, bool* allDataReceived);
-
-    // Return true of there is new data submitted to this class
-    // since last time data() was called.
-    bool hasNewData();
-
-private:
-    Mutex m_mutex;
-
-    Vector<RefPtr<SharedBuffer>> m_newBufferQueue;
-    RefPtr<SharedBuffer> m_readBuffer;
-    bool m_allDataReceived;
-    size_t m_readPosition;
-};
-
-} // namespace blink
-
-#endif
diff --git a/third_party/WebKit/Source/platform/graphics/ThreadSafeDataTransportTest.cpp b/third_party/WebKit/Source/platform/graphics/ThreadSafeDataTransportTest.cpp
deleted file mode 100644
index 69462ec..0000000
--- a/third_party/WebKit/Source/platform/graphics/ThreadSafeDataTransportTest.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "platform/graphics/ThreadSafeDataTransport.h"
-
-#include "platform/SharedBuffer.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace blink {
-
-TEST(ThreadSafeDataTransportTest, hasNewData)
-{
-    ThreadSafeDataTransport transport;
-
-    const char testString[] = "123456789";
-    RefPtr<SharedBuffer> buffer = SharedBuffer::create(testString, sizeof(testString));
-
-    transport.setData(buffer.get(), false);
-    EXPECT_TRUE(transport.hasNewData());
-
-    SharedBuffer* tempBuffer = 0;
-    bool allDataReceived = false;
-    transport.data(&tempBuffer, &allDataReceived);
-    EXPECT_FALSE(transport.hasNewData());
-
-    transport.setData(buffer.get(), false);
-    EXPECT_FALSE(transport.hasNewData());
-}
-
-TEST(ThreadSafeDataTransportTest, setData)
-{
-    ThreadSafeDataTransport transport;
-
-    const char testString1[] = "123";
-    RefPtr<SharedBuffer> buffer1 = SharedBuffer::create(testString1, sizeof(testString1) - 1);
-    const char testString2[] = "12345";
-    RefPtr<SharedBuffer> buffer2 = SharedBuffer::create(testString2, sizeof(testString2) - 1);
-    const char testString3[] = "1234567890";
-    RefPtr<SharedBuffer> buffer3 = SharedBuffer::create(testString3, sizeof(testString3) - 1);
-
-    transport.setData(buffer1.get(), false);
-    transport.setData(buffer2.get(), false);
-    transport.setData(buffer3.get(), true);
-    EXPECT_TRUE(transport.hasNewData());
-
-    SharedBuffer* tempBuffer = 0;
-    bool allDataReceived = false;
-    transport.data(&tempBuffer, &allDataReceived);
-    EXPECT_TRUE(allDataReceived);
-    EXPECT_FALSE(memcmp(testString3, tempBuffer->data(), tempBuffer->size()));
-}
-
-} // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.cpp b/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.cpp
index 9f74e5d..7e45a59 100644
--- a/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.cpp
+++ b/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.cpp
@@ -43,7 +43,7 @@
     SkAlphaType alphaType = (Opaque == opacityMode) ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
     SkImageInfo info = SkImageInfo::MakeN32(size.width(), size.height(), alphaType);
     SkSurfaceProps disableLCDProps(0, kUnknown_SkPixelGeometry);
-    m_surface = adoptRef(SkSurface::NewRaster(info, Opaque == opacityMode ? 0 : &disableLCDProps));
+    m_surface = SkSurface::MakeRaster(info, Opaque == opacityMode ? 0 : &disableLCDProps);
 
     if (initializationMode == InitializeImagePixels) {
         if (m_surface)
diff --git a/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.h b/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.h
index 6452fd6..04469c0b 100644
--- a/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.h
+++ b/third_party/WebKit/Source/platform/graphics/UnacceleratedImageBufferSurface.h
@@ -49,7 +49,7 @@
 
     PassRefPtr<SkImage> newImageSnapshot(AccelerationHint, SnapshotReason) override;
 private:
-    RefPtr<SkSurface> m_surface;
+    sk_sp<SkSurface> m_surface;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/graphics/filters/FEBoxReflect.cpp b/third_party/WebKit/Source/platform/graphics/filters/FEBoxReflect.cpp
index 9cf8318..bd73ca8750 100644
--- a/third_party/WebKit/Source/platform/graphics/filters/FEBoxReflect.cpp
+++ b/third_party/WebKit/Source/platform/graphics/filters/FEBoxReflect.cpp
@@ -28,12 +28,10 @@
 
 FloatRect FEBoxReflect::mapRect(const FloatRect& rect, bool forward) const
 {
+    // Reflection about any line is self-inverse, so this matrix works for both
+    // forward and reverse mapping.
     SkMatrix flipMatrix = SkiaImageFilterBuilder().matrixForBoxReflectFilter(
         m_reflectionDirection, m_offset);
-    if (!forward) {
-        bool inverted = flipMatrix.invert(&flipMatrix);
-        DCHECK(inverted) << "box reflect matrix must be invertible";
-    }
 
     SkRect reflection(rect);
     flipMatrix.mapRect(&reflection);
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.cpp b/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.cpp
index fd8ffbe..20a72f6e 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.cpp
+++ b/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.cpp
@@ -52,8 +52,8 @@
     SkAlphaType alphaType = (Opaque == opacityMode) ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
     SkImageInfo info = SkImageInfo::MakeN32(size.width(), size.height(), alphaType);
     SkSurfaceProps disableLCDProps(0, kUnknown_SkPixelGeometry);
-    m_surface = adoptPtr(SkSurface::NewRenderTarget(grContext, SkBudgeted::kYes, info, 0 /* sampleCount */,
-        Opaque == opacityMode ? nullptr : &disableLCDProps));
+    m_surface = SkSurface::MakeRenderTarget(grContext, SkBudgeted::kYes, info, 0 /* sampleCount */,
+        Opaque == opacityMode ? nullptr : &disableLCDProps);
     if (!m_surface.get())
         return;
     clear();
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.h b/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.h
index 2fbea2f..5fd2e07 100644
--- a/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.h
+++ b/third_party/WebKit/Source/platform/graphics/gpu/AcceleratedImageBufferSurface.h
@@ -52,7 +52,7 @@
 
 private:
     OwnPtr<WebGraphicsContext3DProvider> m_contextProvider;
-    OwnPtr<SkSurface> m_surface; // Uses m_contextProvider.
+    sk_sp<SkSurface> m_surface; // Uses m_contextProvider.
 };
 
 
diff --git a/third_party/WebKit/Source/platform/image-decoders/FastSharedBufferReader.cpp b/third_party/WebKit/Source/platform/image-decoders/FastSharedBufferReader.cpp
index 63a380a..ba2f2390 100644
--- a/third_party/WebKit/Source/platform/image-decoders/FastSharedBufferReader.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/FastSharedBufferReader.cpp
@@ -32,7 +32,7 @@
 
 namespace blink {
 
-FastSharedBufferReader::FastSharedBufferReader(PassRefPtr<SharedBuffer> data)
+FastSharedBufferReader::FastSharedBufferReader(PassRefPtr<SegmentReader> data)
     : m_data(data)
     , m_segment(0)
     , m_segmentLength(0)
@@ -40,7 +40,7 @@
 {
 }
 
-void FastSharedBufferReader::setData(PassRefPtr<SharedBuffer> data)
+void FastSharedBufferReader::setData(PassRefPtr<SegmentReader> data)
 {
     if (data == m_data)
         return;
diff --git a/third_party/WebKit/Source/platform/image-decoders/FastSharedBufferReader.h b/third_party/WebKit/Source/platform/image-decoders/FastSharedBufferReader.h
index c1bf3f91..e82beaa 100644
--- a/third_party/WebKit/Source/platform/image-decoders/FastSharedBufferReader.h
+++ b/third_party/WebKit/Source/platform/image-decoders/FastSharedBufferReader.h
@@ -32,7 +32,7 @@
 #define FastSharedBufferReader_h
 
 #include "platform/PlatformExport.h"
-#include "platform/SharedBuffer.h"
+#include "platform/image-decoders/SegmentReader.h"
 #include "wtf/Allocator.h"
 #include "wtf/Noncopyable.h"
 #include "wtf/PassRefPtr.h"
@@ -48,9 +48,9 @@
     DISALLOW_NEW();
     WTF_MAKE_NONCOPYABLE(FastSharedBufferReader);
 public:
-    FastSharedBufferReader(PassRefPtr<SharedBuffer> data);
+    FastSharedBufferReader(PassRefPtr<SegmentReader> data);
 
-    void setData(PassRefPtr<SharedBuffer>);
+    void setData(PassRefPtr<SegmentReader>);
 
     // Returns a consecutive buffer that carries the data starting
     // at |dataPosition| with |length| bytes.
@@ -60,7 +60,7 @@
     // Caller must ensure there are enough bytes in |m_data| and |buffer|.
     const char* getConsecutiveData(size_t dataPosition, size_t length, char* buffer) const;
 
-    // Wraps SharedBuffer::getSomeData().
+    // Wraps SegmentReader::getSomeData().
     size_t getSomeData(const char*& someData, size_t dataPosition) const;
 
     // Returns a byte at |dataPosition|.
@@ -76,14 +76,14 @@
     }
 
     // This class caches the last access for faster subsequent reads. This
-    // method clears that cache in case the SharedBuffer has been modified
-    // (i.e. with mergeSegmentsIntoBuffer).
+    // method clears that cache in case the SegmentReader has been modified
+    // (e.g. with mergeSegmentsIntoBuffer on a wrapped SharedBuffer).
     void clearCache();
 
 private:
     void getSomeDataInternal(size_t dataPosition) const;
 
-    RefPtr<SharedBuffer> m_data;
+    RefPtr<SegmentReader> m_data;
 
     // Caches the last segment of |m_data| accessed, since subsequent reads are
     // likely to re-access it.
diff --git a/third_party/WebKit/Source/platform/image-decoders/FastSharedBufferReaderTest.cpp b/third_party/WebKit/Source/platform/image-decoders/FastSharedBufferReaderTest.cpp
index 3ea9aa0..2e74a89 100644
--- a/third_party/WebKit/Source/platform/image-decoders/FastSharedBufferReaderTest.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/FastSharedBufferReaderTest.cpp
@@ -29,6 +29,7 @@
  */
 
 #include "platform/image-decoders/FastSharedBufferReader.h"
+#include "platform/image-decoders/SegmentReader.h"
 
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -44,6 +45,34 @@
         buffer[i] = static_cast<char>(i);
 }
 
+PassRefPtr<SegmentReader> copyToROBufferSegmentReader(PassRefPtr<SegmentReader> input)
+{
+    SkRWBuffer rwBuffer;
+    const char* segment = 0;
+    size_t position = 0;
+    while (size_t length = input->getSomeData(segment, position)) {
+        rwBuffer.append(segment, length);
+        position += length;
+    }
+    return SegmentReader::createFromSkROBuffer(adoptRef(rwBuffer.newRBufferSnapshot()));
+}
+
+PassRefPtr<SegmentReader> copyToDataSegmentReader(PassRefPtr<SegmentReader> input)
+{
+    return SegmentReader::createFromSkData(input->getAsSkData());
+}
+
+struct SegmentReaders {
+    RefPtr<SegmentReader> segmentReaders[3];
+
+    SegmentReaders(PassRefPtr<SharedBuffer> input)
+    {
+        segmentReaders[0] = SegmentReader::createFromSharedBuffer(input);
+        segmentReaders[1] = copyToROBufferSegmentReader(segmentReaders[0]);
+        segmentReaders[2] = copyToDataSegmentReader(segmentReaders[0]);
+    }
+};
+
 } // namespace
 
 TEST(FastSharedBufferReaderTest, nonSequentialReads)
@@ -53,15 +82,17 @@
     RefPtr<SharedBuffer> data = SharedBuffer::create();
     data->append(referenceData, sizeof(referenceData));
 
-    FastSharedBufferReader reader(data);
-
-    // Read size is prime such there will be a segment-spanning
-    // read eventually.
-    char tempBuffer[17];
-    for (size_t dataPosition = 0; dataPosition + sizeof(tempBuffer) < sizeof(referenceData); dataPosition += sizeof(tempBuffer)) {
-        const char* block = reader.getConsecutiveData(
-            dataPosition, sizeof(tempBuffer), tempBuffer);
-        ASSERT_FALSE(memcmp(block, referenceData + dataPosition, sizeof(tempBuffer)));
+    SegmentReaders readerStruct(data);
+    for (auto segmentReader : readerStruct.segmentReaders) {
+        FastSharedBufferReader reader(segmentReader);
+        // Read size is prime such there will be a segment-spanning
+        // read eventually.
+        char tempBuffer[17];
+        for (size_t dataPosition = 0; dataPosition + sizeof(tempBuffer) < sizeof(referenceData); dataPosition += sizeof(tempBuffer)) {
+            const char* block = reader.getConsecutiveData(
+                dataPosition, sizeof(tempBuffer), tempBuffer);
+            ASSERT_FALSE(memcmp(block, referenceData + dataPosition, sizeof(tempBuffer)));
+        }
     }
 }
 
@@ -72,15 +103,17 @@
     RefPtr<SharedBuffer> data = SharedBuffer::create();
     data->append(referenceData, sizeof(referenceData));
 
-    FastSharedBufferReader reader(data);
-
-    // Read size is prime such there will be a segment-spanning
-    // read eventually.
-    char tempBuffer[17];
-    for (size_t dataOffset = sizeof(tempBuffer); dataOffset < sizeof(referenceData); dataOffset += sizeof(tempBuffer)) {
-        const char* block = reader.getConsecutiveData(
-            sizeof(referenceData) - dataOffset, sizeof(tempBuffer), tempBuffer);
-        ASSERT_FALSE(memcmp(block, referenceData + sizeof(referenceData) - dataOffset, sizeof(tempBuffer)));
+    SegmentReaders readerStruct(data);
+    for (auto segmentReader : readerStruct.segmentReaders) {
+        FastSharedBufferReader reader(segmentReader);
+        // Read size is prime such there will be a segment-spanning
+        // read eventually.
+        char tempBuffer[17];
+        for (size_t dataOffset = sizeof(tempBuffer); dataOffset < sizeof(referenceData); dataOffset += sizeof(tempBuffer)) {
+            const char* block = reader.getConsecutiveData(
+                sizeof(referenceData) - dataOffset, sizeof(tempBuffer), tempBuffer);
+            ASSERT_FALSE(memcmp(block, referenceData + sizeof(referenceData) - dataOffset, sizeof(tempBuffer)));
+        }
     }
 }
 
@@ -91,9 +124,12 @@
     RefPtr<SharedBuffer> data = SharedBuffer::create();
     data->append(referenceData, sizeof(referenceData));
 
-    FastSharedBufferReader reader(data);
-    for (size_t i = 0; i < sizeof(referenceData); ++i) {
-        ASSERT_EQ(referenceData[i], reader.getOneByte(i));
+    SegmentReaders readerStruct(data);
+    for (auto segmentReader : readerStruct.segmentReaders) {
+        FastSharedBufferReader reader(segmentReader);
+        for (size_t i = 0; i < sizeof(referenceData); ++i) {
+            ASSERT_EQ(referenceData[i], reader.getOneByte(i));
+        }
     }
 }
 
@@ -107,11 +143,97 @@
     RefPtr<SharedBuffer> data = SharedBuffer::create();
     data->append(referenceData, dataSize);
 
-    char buffer[dataSize];
-    FastSharedBufferReader reader(data);
-    reader.getConsecutiveData(0, dataSize, buffer);
+    SegmentReaders readerStruct(data);
+    for (auto segmentReader : readerStruct.segmentReaders) {
+        FastSharedBufferReader reader(segmentReader);
+        char buffer[dataSize];
+        reader.getConsecutiveData(0, dataSize, buffer);
+        ASSERT_FALSE(memcmp(buffer, referenceData, dataSize));
+    }
+}
 
-    ASSERT_FALSE(memcmp(buffer, referenceData, dataSize));
+// Verify that reading past the end of the buffer does not break future reads.
+TEST(SegmentReaderTest, readPastEndThenRead)
+{
+    const unsigned dataSize = 2 * SharedBuffer::kSegmentSize;
+    char referenceData[dataSize];
+    prepareReferenceData(referenceData, dataSize);
+    RefPtr<SharedBuffer> data = SharedBuffer::create();
+    data->append(referenceData, dataSize);
+
+    SegmentReaders readerStruct(data);
+    for (auto segmentReader : readerStruct.segmentReaders) {
+        const char* contents;
+        size_t length = segmentReader->getSomeData(contents, dataSize);
+        EXPECT_EQ(0u, length);
+
+        length = segmentReader->getSomeData(contents, 0);
+        EXPECT_LE(SharedBuffer::kSegmentSize, length);
+    }
+}
+
+TEST(SegmentReaderTest, getAsSkData)
+{
+    const unsigned dataSize = 4 * SharedBuffer::kSegmentSize;
+    char referenceData[dataSize];
+    prepareReferenceData(referenceData, dataSize);
+    RefPtr<SharedBuffer> data = SharedBuffer::create();
+    data->append(referenceData, dataSize);
+
+    SegmentReaders readerStruct(data);
+    for (auto segmentReader : readerStruct.segmentReaders) {
+        RefPtr<SkData> skdata = segmentReader->getAsSkData();
+        EXPECT_EQ(data->size(), skdata->size());
+
+        const char* segment;
+        size_t position = 0;
+        for (size_t length = segmentReader->getSomeData(segment, position);
+            length; length = segmentReader->getSomeData(segment, position)) {
+            ASSERT_FALSE(memcmp(segment, skdata->bytes() + position, length));
+            position += length;
+        }
+        EXPECT_EQ(position, dataSize);
+    }
+}
+
+TEST(SegmentReaderTest, variableSegments)
+{
+    const size_t dataSize = 3.5 * SharedBuffer::kSegmentSize;
+    char referenceData[dataSize];
+    prepareReferenceData(referenceData, dataSize);
+
+    RefPtr<SegmentReader> segmentReader;
+    {
+        // Create a SegmentReader with difference sized segments, to test that
+        // the SkROBuffer implementation works when two consecutive segments
+        // are not the same size. This test relies on knowledge of the
+        // internals of SkRWBuffer: it ensures that each segment is at least
+        // 4096 (though the actual data may be smaller, if it has not been
+        // written to yet), but when appending a larger amount it may create a
+        // larger segment.
+        SkRWBuffer rwBuffer;
+        rwBuffer.append(referenceData, SharedBuffer::kSegmentSize);
+        rwBuffer.append(referenceData + SharedBuffer::kSegmentSize, 2 * SharedBuffer::kSegmentSize);
+        rwBuffer.append(referenceData + 3 * SharedBuffer::kSegmentSize, .5 * SharedBuffer::kSegmentSize);
+
+        segmentReader = SegmentReader::createFromSkROBuffer(adoptRef(rwBuffer.newRBufferSnapshot()));
+    }
+
+    const char* segment;
+    size_t position = 0;
+    size_t lastLength = 0;
+    for (size_t length = segmentReader->getSomeData(segment, position);
+        length; length = segmentReader->getSomeData(segment, position)) {
+        // It is not a bug to have consecutive segments of the same length, but
+        // it does mean that the following test does not actually test what it
+        // is intended to test.
+        ASSERT_NE(length, lastLength);
+        lastLength = length;
+
+        ASSERT_FALSE(memcmp(segment, referenceData + position, length));
+        position += length;
+    }
+    EXPECT_EQ(position, dataSize);
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp
index 663f0d5d..c008c4b 100644
--- a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp
@@ -32,67 +32,51 @@
 
 namespace blink {
 
-static size_t copyFromSharedBuffer(char* buffer, size_t bufferLength, const SharedBuffer& sharedBuffer, size_t offset)
-{
-    size_t bytesExtracted = 0;
-    const char* moreData;
-    while (size_t moreDataLength = sharedBuffer.getSomeData(moreData, offset)) {
-        size_t bytesToCopy = std::min(bufferLength - bytesExtracted, moreDataLength);
-        memcpy(buffer + bytesExtracted, moreData, bytesToCopy);
-        bytesExtracted += bytesToCopy;
-        if (bytesExtracted == bufferLength)
-            break;
-        offset += bytesToCopy;
-    }
-    return bytesExtracted;
-}
-
-inline bool matchesJPEGSignature(char* contents)
+inline bool matchesJPEGSignature(const char* contents)
 {
     return !memcmp(contents, "\xFF\xD8\xFF", 3);
 }
 
-inline bool matchesPNGSignature(char* contents)
+inline bool matchesPNGSignature(const char* contents)
 {
     return !memcmp(contents, "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", 8);
 }
 
-inline bool matchesGIFSignature(char* contents)
+inline bool matchesGIFSignature(const char* contents)
 {
     return !memcmp(contents, "GIF87a", 6) || !memcmp(contents, "GIF89a", 6);
 }
 
-inline bool matchesWebPSignature(char* contents)
+inline bool matchesWebPSignature(const char* contents)
 {
     return !memcmp(contents, "RIFF", 4) && !memcmp(contents + 8, "WEBPVP", 6);
 }
 
-inline bool matchesICOSignature(char* contents)
+inline bool matchesICOSignature(const char* contents)
 {
     return !memcmp(contents, "\x00\x00\x01\x00", 4);
 }
 
-inline bool matchesCURSignature(char* contents)
+inline bool matchesCURSignature(const char* contents)
 {
     return !memcmp(contents, "\x00\x00\x02\x00", 4);
 }
 
-inline bool matchesBMPSignature(char* contents)
+inline bool matchesBMPSignature(const char* contents)
 {
     return !memcmp(contents, "BM", 2);
 }
 
-PassOwnPtr<ImageDecoder> ImageDecoder::create(const SharedBuffer& data, AlphaOption alphaOption, GammaAndColorProfileOption colorOptions)
+PassOwnPtr<ImageDecoder> ImageDecoder::create(const char* contents, size_t length, AlphaOption alphaOption, GammaAndColorProfileOption colorOptions)
 {
     const size_t longestSignatureLength = sizeof("RIFF????WEBPVP") - 1;
     ASSERT(longestSignatureLength == 14);
 
-    size_t maxDecodedBytes = Platform::current() ? Platform::current()->maxDecodedImageBytes() : noDecodedImageByteLimit;
-
-    char contents[longestSignatureLength];
-    if (copyFromSharedBuffer(contents, longestSignatureLength, data, 0) < longestSignatureLength)
+    if (length < longestSignatureLength)
         return nullptr;
 
+    size_t maxDecodedBytes = Platform::current() ? Platform::current()->maxDecodedImageBytes() : noDecodedImageByteLimit;
+
     if (matchesJPEGSignature(contents))
         return adoptPtr(new JPEGImageDecoder(alphaOption, colorOptions, maxDecodedBytes));
 
@@ -114,6 +98,20 @@
     return nullptr;
 }
 
+PassOwnPtr<ImageDecoder> ImageDecoder::create(const SharedBuffer& data, AlphaOption alphaOption, GammaAndColorProfileOption colorOptions)
+{
+    const char* contents;
+    const size_t length = data.getSomeData<size_t>(contents);
+    return create(contents, length, alphaOption, colorOptions);
+}
+
+PassOwnPtr<ImageDecoder> ImageDecoder::create(const SegmentReader& data, AlphaOption alphaOption, GammaAndColorProfileOption colorOptions)
+{
+    const char* contents;
+    const size_t length = data.getSomeData(contents, 0);
+    return create(contents, length, alphaOption, colorOptions);
+}
+
 size_t ImageDecoder::frameCount()
 {
     const size_t oldSize = m_frameBufferCache.size();
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h
index 55eec65..7da3b9b 100644
--- a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h
+++ b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.h
@@ -33,6 +33,7 @@
 #include "platform/graphics/ImageOrientation.h"
 #include "platform/image-decoders/ImageAnimation.h"
 #include "platform/image-decoders/ImageFrame.h"
+#include "platform/image-decoders/SegmentReader.h"
 #include "public/platform/Platform.h"
 #include "wtf/Assertions.h"
 #include "wtf/PassOwnPtr.h"
@@ -122,22 +123,29 @@
     // we can't sniff a supported type from the provided data (possibly
     // because there isn't enough data yet).
     // Sets m_maxDecodedBytes to Platform::maxImageDecodedBytes().
-    static PassOwnPtr<ImageDecoder> create(const SharedBuffer& data, AlphaOption, GammaAndColorProfileOption);
+    static PassOwnPtr<ImageDecoder> create(const char* data, size_t length, AlphaOption, GammaAndColorProfileOption);
+    static PassOwnPtr<ImageDecoder> create(const SharedBuffer&, AlphaOption, GammaAndColorProfileOption);
+    static PassOwnPtr<ImageDecoder> create(const SegmentReader&, AlphaOption, GammaAndColorProfileOption);
 
     virtual String filenameExtension() const = 0;
 
     bool isAllDataReceived() const { return m_isAllDataReceived; }
 
-    void setData(SharedBuffer* data, bool allDataReceived)
+    void setData(PassRefPtr<SegmentReader> data, bool allDataReceived)
     {
         if (m_failed)
             return;
         m_data = data;
         m_isAllDataReceived = allDataReceived;
-        onSetData(data);
+        onSetData(m_data.get());
     }
 
-    virtual void onSetData(SharedBuffer* data) { }
+    void setData(PassRefPtr<SharedBuffer> data, bool allDataReceived)
+    {
+        setData(SegmentReader::createFromSharedBuffer(data), allDataReceived);
+    }
+
+    virtual void onSetData(SegmentReader* data) { }
 
     bool isSizeAvailable()
     {
@@ -310,7 +318,7 @@
     // Decodes the requested frame.
     virtual void decode(size_t) = 0;
 
-    RefPtr<SharedBuffer> m_data; // The encoded data.
+    RefPtr<SegmentReader> m_data; // The encoded data.
     Vector<ImageFrame, 1> m_frameBufferCache;
     bool m_premultiplyAlpha;
     bool m_ignoreGammaAndColorProfile;
diff --git a/third_party/WebKit/Source/platform/image-decoders/SegmentReader.cpp b/third_party/WebKit/Source/platform/image-decoders/SegmentReader.cpp
new file mode 100644
index 0000000..e412952
--- /dev/null
+++ b/third_party/WebKit/Source/platform/image-decoders/SegmentReader.cpp
@@ -0,0 +1,182 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "platform/image-decoders/SegmentReader.h"
+
+#include "platform/SharedBuffer.h"
+#include "third_party/skia/include/core/SkData.h"
+#include "wtf/Assertions.h"
+#include "wtf/Noncopyable.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefPtr.h"
+
+namespace blink {
+
+// SharedBufferSegmentReader ---------------------------------------------------
+
+// Interface for ImageDecoder to read a SharedBuffer.
+class SharedBufferSegmentReader final : public SegmentReader {
+    WTF_MAKE_NONCOPYABLE(SharedBufferSegmentReader);
+public:
+    SharedBufferSegmentReader(PassRefPtr<SharedBuffer>);
+    size_t size() const override;
+    size_t getSomeData(const char*& data, size_t position) const override;
+    PassRefPtr<SkData> getAsSkData() const override;
+private:
+    RefPtr<SharedBuffer> m_sharedBuffer;
+};
+
+SharedBufferSegmentReader::SharedBufferSegmentReader(PassRefPtr<SharedBuffer> buffer)
+    : m_sharedBuffer(buffer) {}
+
+size_t SharedBufferSegmentReader::size() const
+{
+    return m_sharedBuffer->size();
+}
+
+size_t SharedBufferSegmentReader::getSomeData(const char*& data, size_t position) const
+{
+    return m_sharedBuffer->getSomeData(data, position);
+}
+
+PassRefPtr<SkData> SharedBufferSegmentReader::getAsSkData() const
+{
+    return m_sharedBuffer->getAsSkData();
+}
+
+// DataSegmentReader -----------------------------------------------------------
+
+// Interface for ImageDecoder to read an SkData.
+class DataSegmentReader final : public SegmentReader {
+    WTF_MAKE_NONCOPYABLE(DataSegmentReader);
+public:
+    DataSegmentReader(PassRefPtr<SkData>);
+    size_t size() const override;
+    size_t getSomeData(const char*& data, size_t position) const override;
+    PassRefPtr<SkData> getAsSkData() const override;
+private:
+    RefPtr<SkData> m_data;
+};
+
+DataSegmentReader::DataSegmentReader(PassRefPtr<SkData> data)
+    : m_data(data) {}
+
+size_t DataSegmentReader::size() const
+{
+    return m_data->size();
+}
+
+size_t DataSegmentReader::getSomeData(const char*& data, size_t position) const
+{
+    if (position >= m_data->size())
+        return 0;
+
+    data = reinterpret_cast<const char*>(m_data->bytes() + position);
+    return m_data->size() - position;
+}
+
+PassRefPtr<SkData> DataSegmentReader::getAsSkData() const
+{
+    return m_data.get();
+}
+
+// ROBufferSegmentReader -------------------------------------------------------
+
+class ROBufferSegmentReader final : public SegmentReader {
+    WTF_MAKE_NONCOPYABLE(ROBufferSegmentReader);
+public:
+    ROBufferSegmentReader(PassRefPtr<SkROBuffer>);
+
+    size_t size() const override;
+    size_t getSomeData(const char*& data, size_t position) const override;
+    PassRefPtr<SkData> getAsSkData() const override;
+
+private:
+    RefPtr<SkROBuffer> m_roBuffer;
+};
+
+ROBufferSegmentReader::ROBufferSegmentReader(PassRefPtr<SkROBuffer> buffer)
+    : m_roBuffer(buffer)
+    {}
+
+size_t ROBufferSegmentReader::size() const
+{
+    return m_roBuffer ? m_roBuffer->size() : 0;
+}
+
+size_t ROBufferSegmentReader::getSomeData(const char*& data, size_t position) const
+{
+    if (!m_roBuffer)
+        return 0;
+
+    SkROBuffer::Iter iter(m_roBuffer.get());
+    for (size_t sizeOfBlock = iter.size(), positionOfBlock = 0; sizeOfBlock != 0; positionOfBlock += sizeOfBlock, sizeOfBlock = iter.size()) {
+        ASSERT(positionOfBlock <= position);
+
+        if (positionOfBlock + sizeOfBlock > position) {
+            // |position| is in this block.
+            const size_t positionInBlock = position - positionOfBlock;
+            data = static_cast<const char*>(iter.data()) + positionInBlock;
+            return sizeOfBlock - positionInBlock;
+        }
+
+        // Move to next block.
+        if (!iter.next()) {
+            return 0;
+        }
+    }
+
+    return 0;
+}
+
+static void unrefROBuffer(const void* ptr, void* context)
+{
+    static_cast<SkROBuffer*>(context)->unref();
+}
+
+PassRefPtr<SkData> ROBufferSegmentReader::getAsSkData() const
+{
+    if (!m_roBuffer)
+        return nullptr;
+
+    // Check to see if the data is already contiguous.
+    SkROBuffer::Iter iter(m_roBuffer.get());
+    const bool multipleBlocks = iter.next();
+    iter.reset(m_roBuffer.get());
+
+    if (!multipleBlocks) {
+        // Contiguous data. No need to copy.
+        m_roBuffer->ref();
+        return adoptRef(SkData::NewWithProc(iter.data(), iter.size(), &unrefROBuffer, m_roBuffer.get()));
+    }
+
+    RefPtr<SkData> data = adoptRef(SkData::NewUninitialized(m_roBuffer->size()));
+    char* dst = static_cast<char*>(data->writable_data());
+    do {
+        size_t size = iter.size();
+        memcpy(dst, iter.data(), size);
+        dst += size;
+    } while (iter.next());
+    return data.release();
+}
+
+// SegmentReader ---------------------------------------------------------------
+
+PassRefPtr<SegmentReader> SegmentReader::createFromSharedBuffer(PassRefPtr<SharedBuffer> buffer)
+{
+    return adoptRef(new SharedBufferSegmentReader(buffer));
+}
+
+PassRefPtr<SegmentReader> SegmentReader::createFromSkData(PassRefPtr<SkData> data)
+{
+    return adoptRef(new DataSegmentReader(data));
+}
+
+PassRefPtr<SegmentReader> SegmentReader::createFromSkROBuffer(PassRefPtr<SkROBuffer> buffer)
+{
+    return adoptRef(new ROBufferSegmentReader(buffer));
+}
+
+} // namespace blink
+
diff --git a/third_party/WebKit/Source/platform/image-decoders/SegmentReader.h b/third_party/WebKit/Source/platform/image-decoders/SegmentReader.h
new file mode 100644
index 0000000..13c28ce
--- /dev/null
+++ b/third_party/WebKit/Source/platform/image-decoders/SegmentReader.h
@@ -0,0 +1,48 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SegmentReader_h
+#define SegmentReader_h
+
+#include "platform/SharedBuffer.h"
+#include "third_party/skia/include/core/SkData.h"
+#include "third_party/skia/include/core/SkRWBuffer.h"
+#include "wtf/Noncopyable.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/ThreadSafeRefCounted.h"
+
+namespace blink {
+
+// Interface that looks like SharedBuffer. Used by ImageDecoders to use various
+// sources of input including:
+// - SharedBuffer
+//   - for when the caller already has a SharedBuffer
+// - SkData
+//   - for when the caller already has an SkData
+// - SkROBuffer
+//   - for when the caller wants to read/write in different threads
+//
+// Unlike SharedBuffer, this is a read-only interface. There is no way to
+// modify the underlying data source.
+class PLATFORM_EXPORT SegmentReader : public ThreadSafeRefCounted<SegmentReader> {
+    WTF_MAKE_NONCOPYABLE(SegmentReader);
+public:
+    // This version is thread-safe so long as no thread is modifying the
+    // underlying SharedBuffer. This class does not modify it, so that would
+    // mean modifying it in another way.
+    static PassRefPtr<SegmentReader> createFromSharedBuffer(PassRefPtr<SharedBuffer>);
+
+    // These versions use thread-safe input, so they are always thread-safe.
+    static PassRefPtr<SegmentReader> createFromSkData(PassRefPtr<SkData>);
+    static PassRefPtr<SegmentReader> createFromSkROBuffer(PassRefPtr<SkROBuffer>);
+
+    SegmentReader() {}
+    virtual ~SegmentReader() {}
+    virtual size_t size() const = 0;
+    virtual size_t getSomeData(const char*& data, size_t position) const = 0;
+    virtual PassRefPtr<SkData> getAsSkData() const = 0;
+};
+
+} // namespace blink
+#endif // SegmentReader_h
diff --git a/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageDecoder.cpp
index 998faac6..01815ab 100644
--- a/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageDecoder.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageDecoder.cpp
@@ -46,7 +46,7 @@
 {
 }
 
-void BMPImageDecoder::onSetData(SharedBuffer* data)
+void BMPImageDecoder::onSetData(SegmentReader* data)
 {
     if (m_reader)
         m_reader->setData(data);
diff --git a/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageDecoder.h b/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageDecoder.h
index c2053a5..e4a6bd1 100644
--- a/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageDecoder.h
+++ b/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageDecoder.h
@@ -43,7 +43,7 @@
 
     // ImageDecoder:
     String filenameExtension() const override { return "bmp"; }
-    void onSetData(SharedBuffer*) override;
+    void onSetData(SegmentReader*) override;
     // CAUTION: setFailed() deletes |m_reader|.  Be careful to avoid
     // accessing deleted memory, especially when calling this from inside
     // BMPImageReader!
diff --git a/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageReader.h b/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageReader.h
index 7bfa563..d150a56 100644
--- a/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageReader.h
+++ b/third_party/WebKit/Source/platform/image-decoders/bmp/BMPImageReader.h
@@ -65,7 +65,7 @@
     BMPImageReader(ImageDecoder* parent, size_t decodedAndHeaderOffset, size_t imgDataOffset, bool isInICO);
 
     void setBuffer(ImageFrame* buffer) { m_buffer = buffer; }
-    void setData(SharedBuffer* data)
+    void setData(SegmentReader* data)
     {
         m_data = data;
         m_fastReader.setData(data);
@@ -290,7 +290,7 @@
     ImageFrame* m_buffer;
 
     // The file to decode.
-    RefPtr<SharedBuffer> m_data;
+    RefPtr<SegmentReader> m_data;
     FastSharedBufferReader m_fastReader;
 
     // An index into |m_data| representing how much we've already decoded.
diff --git a/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.cpp
index 824764c5..457666d2 100644
--- a/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.cpp
@@ -42,7 +42,7 @@
 {
 }
 
-void GIFImageDecoder::onSetData(SharedBuffer* data)
+void GIFImageDecoder::onSetData(SegmentReader* data)
 {
     if (m_reader)
         m_reader->setData(data);
diff --git a/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.h b/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.h
index f9aa02c4..98941e68 100644
--- a/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.h
+++ b/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageDecoder.h
@@ -47,7 +47,7 @@
 
     // ImageDecoder:
     String filenameExtension() const override { return "gif"; }
-    void onSetData(SharedBuffer* data) override;
+    void onSetData(SegmentReader* data) override;
     int repetitionCount() const override;
     bool frameIsCompleteAtIndex(size_t) const override;
     float frameDurationAtIndex(size_t) const override;
diff --git a/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageReader.h b/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageReader.h
index 6172377..bfa9897 100644
--- a/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageReader.h
+++ b/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageReader.h
@@ -40,7 +40,6 @@
 
 // Define ourselves as the clientPtr.  Mozilla just hacked their C++ callback class into this old C decoder,
 // so we will too.
-#include "platform/SharedBuffer.h"
 #include "platform/image-decoders/FastSharedBufferReader.h"
 #include "platform/image-decoders/gif/GIFImageDecoder.h"
 #include "wtf/Allocator.h"
@@ -299,7 +298,7 @@
     {
     }
 
-    void setData(PassRefPtr<blink::SharedBuffer> data) { m_data = data; }
+    void setData(PassRefPtr<blink::SegmentReader> data) { m_data = data; }
     bool parse(blink::GIFImageDecoder::GIFParseQuery);
     bool decode(size_t frameIndex);
 
@@ -356,7 +355,7 @@
 
     Vector<OwnPtr<GIFFrameContext>> m_frames;
 
-    RefPtr<blink::SharedBuffer> m_data;
+    RefPtr<blink::SegmentReader> m_data;
     bool m_parseCompleted;
 };
 
diff --git a/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.cpp
index 592eb96..a189f81 100644
--- a/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.cpp
@@ -54,7 +54,7 @@
 {
 }
 
-void ICOImageDecoder::onSetData(SharedBuffer* data)
+void ICOImageDecoder::onSetData(SegmentReader* data)
 {
     m_fastReader.setData(data);
 
diff --git a/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.h b/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.h
index 73759ba..3df9ba1 100644
--- a/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.h
+++ b/third_party/WebKit/Source/platform/image-decoders/ico/ICOImageDecoder.h
@@ -46,7 +46,7 @@
 
     // ImageDecoder:
     String filenameExtension() const override { return "ico"; }
-    void onSetData(SharedBuffer*) override;
+    void onSetData(SegmentReader*) override;
     IntSize size() const override;
     IntSize frameSizeAtIndex(size_t) const override;
     bool setSize(unsigned width, unsigned height) override;
diff --git a/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
index a89c388..09cc8af 100644
--- a/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
@@ -362,19 +362,19 @@
         return true;
     }
 
-    void setData(SharedBuffer* data)
+    void setData(SegmentReader* data)
     {
         if (m_data.get() == data)
             return;
 
         m_data = data;
 
-        // If a restart is needed, the next call to fillBuffer will read from the new SharedBuffer.
+        // If a restart is needed, the next call to fillBuffer will read from the new SegmentReader.
         if (m_needsRestart)
             return;
 
         // Otherwise, empty the buffer, and leave the position the same, so fillBuffer continues
-        // reading from the same position in the new SharedBuffer.
+        // reading from the same position in the new SegmentReader.
         m_nextReadPosition -= m_info.src->bytes_in_buffer;
         clearBuffer();
     }
@@ -638,7 +638,7 @@
         m_lastSetByte = nullptr;
     }
 
-    RefPtr<SharedBuffer> m_data;
+    RefPtr<SegmentReader> m_data;
     JPEGImageDecoder* m_decoder;
 
     // Input reading: True if we need to back up to m_restartPosition.
@@ -724,7 +724,7 @@
     return true;
 }
 
-void JPEGImageDecoder::onSetData(SharedBuffer* data)
+void JPEGImageDecoder::onSetData(SegmentReader* data)
 {
     if (m_reader)
         m_reader->setData(data);
diff --git a/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.h b/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.h
index 704a7cca..74a0681 100644
--- a/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.h
+++ b/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.h
@@ -40,7 +40,7 @@
 
     // ImageDecoder:
     String filenameExtension() const override { return "jpg"; }
-    void onSetData(SharedBuffer* data) override;
+    void onSetData(SegmentReader* data) override;
     IntSize decodedSize() const override { return m_decodedSize; }
     bool setSize(unsigned width, unsigned height) override;
     IntSize decodedYUVSize(int component) const override;
diff --git a/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.cpp
index bff97c2..5f787b5 100644
--- a/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/png/PNGImageDecoder.cpp
@@ -110,7 +110,7 @@
         m_readOffset = 0;
     }
 
-    bool decode(const SharedBuffer& data, bool sizeOnly)
+    bool decode(const SegmentReader& data, bool sizeOnly)
     {
         m_decodingSizeOnly = sizeOnly;
 
diff --git a/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.cpp
index 2672862d..fae908a7 100644
--- a/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.cpp
@@ -144,6 +144,7 @@
 {
     WebPDemuxDelete(m_demux);
     m_demux = 0;
+    m_consolidatedData.clear();
     clearDecoder();
 }
 
@@ -155,7 +156,7 @@
     m_frameBackgroundHasAlpha = false;
 }
 
-void WEBPImageDecoder::onSetData(SharedBuffer*)
+void WEBPImageDecoder::onSetData(SegmentReader*)
 {
     m_haveAlreadyParsedThisData = false;
 }
@@ -195,10 +196,14 @@
         return false; // Await VP8X header so WebPDemuxPartial succeeds.
 
     WebPDemuxDelete(m_demux);
-    WebPData inputData = { reinterpret_cast<const uint8_t*>(m_data->data()), m_data->size() };
+    m_consolidatedData = m_data->getAsSkData();
+    WebPData inputData = { reinterpret_cast<const uint8_t*>(m_consolidatedData->data()), m_consolidatedData->size() };
     m_demux = WebPDemuxPartial(&inputData, &m_demuxState);
-    if (!m_demux || (isAllDataReceived() && m_demuxState != WEBP_DEMUX_DONE))
+    if (!m_demux || (isAllDataReceived() && m_demuxState != WEBP_DEMUX_DONE)) {
+        if (!m_demux)
+            m_consolidatedData.clear();
         return setFailed();
+    }
 
     ASSERT(m_demuxState > WEBP_DEMUX_PARSING_HEADER);
     if (!WebPDemuxGetI(m_demux, WEBP_FF_FRAME_COUNT))
diff --git a/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.h b/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.h
index c991671..718ae30 100644
--- a/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.h
+++ b/third_party/WebKit/Source/platform/image-decoders/webp/WEBPImageDecoder.h
@@ -30,8 +30,10 @@
 #define WEBPImageDecoder_h
 
 #include "platform/image-decoders/ImageDecoder.h"
+#include "third_party/skia/include/core/SkData.h"
 #include "webp/decode.h"
 #include "webp/demux.h"
+#include "wtf/RefPtr.h"
 
 namespace blink {
 
@@ -43,7 +45,7 @@
 
     // ImageDecoder:
     String filenameExtension() const override { return "webp"; }
-    void onSetData(SharedBuffer* data) override;
+    void onSetData(SegmentReader* data) override;
     int repetitionCount() const override;
     bool frameIsCompleteAtIndex(size_t) const override;
     float frameDurationAtIndex(size_t) const override;
@@ -83,6 +85,9 @@
 
     void clear();
     void clearDecoder();
+
+    // FIXME: Update libwebp's API so it does not require copying the data on each update.
+    RefPtr<SkData> m_consolidatedData;
 };
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/platform/network/HTTPNames.in b/third_party/WebKit/Source/platform/network/HTTPNames.in
index 031f96a..1034ae3b 100644
--- a/third_party/WebKit/Source/platform/network/HTTPNames.in
+++ b/third_party/WebKit/Source/platform/network/HTTPNames.in
@@ -34,6 +34,7 @@
 Link
 Location
 Origin
+Origin-Trial
 Ping-From
 Ping-To
 Pragma
diff --git a/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.cpp b/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.cpp
index a81538a..e8c7fbcf8 100644
--- a/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.cpp
+++ b/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.cpp
@@ -65,11 +65,6 @@
     return m_oldPlatform ? m_oldPlatform->currentThread() : nullptr;
 }
 
-WebUnitTestSupport* TestingPlatformSupport::unitTestSupport()
-{
-    return m_oldPlatform ? m_oldPlatform->unitTestSupport() : nullptr;
-}
-
 class TestingPlatformMockWebTaskRunner : public WebTaskRunner {
     WTF_MAKE_NONCOPYABLE(TestingPlatformMockWebTaskRunner);
 public:
diff --git a/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h b/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h
index ba689f9c..793d003 100644
--- a/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h
+++ b/third_party/WebKit/Source/platform/testing/TestingPlatformSupport.h
@@ -94,7 +94,6 @@
     WebString defaultLocale() override;
     WebCompositorSupport* compositorSupport() override;
     WebThread* currentThread() override;
-    WebUnitTestSupport* unitTestSupport() override;
     void registerMemoryDumpProvider(blink::WebMemoryDumpProvider*, const char* name) override {}
     void unregisterMemoryDumpProvider(blink::WebMemoryDumpProvider*) override {}
 
diff --git a/third_party/WebKit/Source/platform/testing/URLTestHelpers.cpp b/third_party/WebKit/Source/platform/testing/URLTestHelpers.cpp
index db2fcaf..4462fdde 100644
--- a/third_party/WebKit/Source/platform/testing/URLTestHelpers.cpp
+++ b/third_party/WebKit/Source/platform/testing/URLTestHelpers.cpp
@@ -35,8 +35,8 @@
 #include "public/platform/WebURL.h"
 #include "public/platform/WebURLError.h"
 #include "public/platform/WebURLLoadTiming.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
 #include "public/platform/WebURLResponse.h"
-#include "public/platform/WebUnitTestSupport.h"
 
 namespace blink {
 namespace URLTestHelpers {
@@ -79,7 +79,7 @@
 
     WebURLError error;
     error.reason = 404;
-    Platform::current()->unitTestSupport()->registerMockedErrorURL(fullURL, response, error);
+    Platform::current()->getURLLoaderMockFactory()->registerErrorURL(fullURL, response, error);
 }
 
 void registerMockedURLLoadWithCustomResponse(const WebURL& fullURL, const WebString& fileName, const WebString& relativeBaseDirectory, WebURLResponse response)
@@ -90,7 +90,7 @@
     filePath.append(relativeBaseDirectory);
     filePath.append(fileName);
 
-    Platform::current()->unitTestSupport()->registerMockedURL(fullURL, response, filePath);
+    Platform::current()->getURLLoaderMockFactory()->registerURL(fullURL, response, filePath);
 }
 
 } // namespace URLTestHelpers
diff --git a/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp b/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp
index fd991ac..4c4909b 100644
--- a/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp
+++ b/third_party/WebKit/Source/platform/testing/UnitTestHelpers.cpp
@@ -37,7 +37,6 @@
 #include "public/platform/WebTaskRunner.h"
 #include "public/platform/WebThread.h"
 #include "public/platform/WebTraceLocation.h"
-#include "public/platform/WebUnitTestSupport.h"
 #include "wtf/text/StringUTF8Adaptor.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/platform/testing/weburl_loader_mock.cc b/third_party/WebKit/Source/platform/testing/weburl_loader_mock.cc
index ab0f8e9..bf961a0 100644
--- a/third_party/WebKit/Source/platform/testing/weburl_loader_mock.cc
+++ b/third_party/WebKit/Source/platform/testing/weburl_loader_mock.cc
@@ -9,7 +9,6 @@
 #include "public/platform/WebData.h"
 #include "public/platform/WebURLError.h"
 #include "public/platform/WebURLLoaderClient.h"
-#include "public/platform/WebUnitTestSupport.h"
 #include "wtf/PassOwnPtr.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/web/AssociatedURLLoaderTest.cpp b/third_party/WebKit/Source/web/AssociatedURLLoaderTest.cpp
index f178fb7..1bbdd6d 100644
--- a/third_party/WebKit/Source/web/AssociatedURLLoaderTest.cpp
+++ b/third_party/WebKit/Source/web/AssociatedURLLoaderTest.cpp
@@ -36,9 +36,10 @@
 #include "public/platform/WebURL.h"
 #include "public/platform/WebURLLoader.h"
 #include "public/platform/WebURLLoaderClient.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
 #include "public/platform/WebURLRequest.h"
 #include "public/platform/WebURLResponse.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/web/WebCache.h"
 #include "public/web/WebFrame.h"
 #include "public/web/WebURLLoaderOptions.h"
 #include "public/web/WebView.h"
@@ -79,7 +80,7 @@
         WTF::String localPath = m_baseFilePath;
         localPath.append(filename);
         KURL url = toKURL(urlRoot + filename.utf8().data());
-        Platform::current()->unitTestSupport()->registerMockedURL(url, response, localPath);
+        Platform::current()->getURLLoaderMockFactory()->registerURL(url, response, localPath);
         return url;
     }
 
@@ -100,17 +101,18 @@
 
         FrameTestHelpers::loadFrame(mainFrame(), url.getString().utf8().data());
 
-        Platform::current()->unitTestSupport()->unregisterMockedURL(url);
+        Platform::current()->getURLLoaderMockFactory()->unregisterURL(url);
     }
 
     void TearDown() override
     {
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        WebCache::clear();
     }
 
     void serveRequests()
     {
-        Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
+        Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
     }
 
     PassOwnPtr<WebURLLoader> createAssociatedURLLoader(const WebURLLoaderOptions options = WebURLLoaderOptions())
@@ -244,7 +246,7 @@
         if (exposed)
             m_expectedResponse.addHTTPHeaderField("access-control-expose-headers", headerNameString);
         m_expectedResponse.addHTTPHeaderField(headerNameString, "foo");
-        Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedResponse, m_frameFilePath);
+        Platform::current()->getURLLoaderMockFactory()->registerURL(url, m_expectedResponse, m_frameFilePath);
 
         WebURLLoaderOptions options;
         options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
@@ -293,7 +295,7 @@
     m_expectedResponse.initialize();
     m_expectedResponse.setMIMEType("text/html");
     m_expectedResponse.setHTTPStatusCode(200);
-    Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedResponse, m_frameFilePath);
+    Platform::current()->getURLLoaderMockFactory()->registerURL(url, m_expectedResponse, m_frameFilePath);
 
     m_expectedLoader = createAssociatedURLLoader();
     EXPECT_TRUE(m_expectedLoader);
@@ -328,7 +330,7 @@
     m_expectedResponse.initialize();
     m_expectedResponse.setMIMEType("text/html");
     m_expectedResponse.setHTTPStatusCode(200);
-    Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedResponse, m_frameFilePath);
+    Platform::current()->getURLLoaderMockFactory()->registerURL(url, m_expectedResponse, m_frameFilePath);
 
     WebURLLoaderOptions options;
     options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyAllow;
@@ -355,7 +357,7 @@
     m_expectedResponse.setMIMEType("text/html");
     m_expectedResponse.setHTTPStatusCode(200);
     m_expectedResponse.addHTTPHeaderField("access-control-allow-origin", "*");
-    Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedResponse, m_frameFilePath);
+    Platform::current()->getURLLoaderMockFactory()->registerURL(url, m_expectedResponse, m_frameFilePath);
 
     WebURLLoaderOptions options;
     options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
@@ -382,7 +384,7 @@
     m_expectedResponse.setMIMEType("text/html");
     m_expectedResponse.setHTTPStatusCode(200);
     m_expectedResponse.addHTTPHeaderField("access-control-allow-origin", "*");
-    Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedResponse, m_frameFilePath);
+    Platform::current()->getURLLoaderMockFactory()->registerURL(url, m_expectedResponse, m_frameFilePath);
 
     WebURLLoaderOptions options;
     // Send credentials. This will cause the CORS checks to fail, because credentials can't be
@@ -415,7 +417,7 @@
     m_expectedResponse.setMIMEType("text/html");
     m_expectedResponse.setHTTPStatusCode(0);
     m_expectedResponse.addHTTPHeaderField("access-control-allow-origin", "*");
-    Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedResponse, m_frameFilePath);
+    Platform::current()->getURLLoaderMockFactory()->registerURL(url, m_expectedResponse, m_frameFilePath);
 
     WebURLLoaderOptions options;
     options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
@@ -447,7 +449,7 @@
     m_expectedRedirectResponse.setMIMEType("text/html");
     m_expectedRedirectResponse.setHTTPStatusCode(301);
     m_expectedRedirectResponse.setHTTPHeaderField("Location", redirect);
-    Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedRedirectResponse, m_frameFilePath);
+    Platform::current()->getURLLoaderMockFactory()->registerURL(url, m_expectedRedirectResponse, m_frameFilePath);
 
     m_expectedNewRequest = WebURLRequest();
     m_expectedNewRequest.initialize();
@@ -457,7 +459,7 @@
     m_expectedResponse.initialize();
     m_expectedResponse.setMIMEType("text/html");
     m_expectedResponse.setHTTPStatusCode(200);
-    Platform::current()->unitTestSupport()->registerMockedURL(redirectURL, m_expectedResponse, m_frameFilePath);
+    Platform::current()->getURLLoaderMockFactory()->registerURL(redirectURL, m_expectedResponse, m_frameFilePath);
 
     m_expectedLoader = createAssociatedURLLoader();
     EXPECT_TRUE(m_expectedLoader);
@@ -485,7 +487,7 @@
     m_expectedRedirectResponse.setMIMEType("text/html");
     m_expectedRedirectResponse.setHTTPStatusCode(301);
     m_expectedRedirectResponse.setHTTPHeaderField("Location", redirect);
-    Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedRedirectResponse, m_frameFilePath);
+    Platform::current()->getURLLoaderMockFactory()->registerURL(url, m_expectedRedirectResponse, m_frameFilePath);
 
     m_expectedNewRequest = WebURLRequest();
     m_expectedNewRequest.initialize();
@@ -495,7 +497,7 @@
     m_expectedResponse.initialize();
     m_expectedResponse.setMIMEType("text/html");
     m_expectedResponse.setHTTPStatusCode(200);
-    Platform::current()->unitTestSupport()->registerMockedURL(redirectURL, m_expectedResponse, m_frameFilePath);
+    Platform::current()->getURLLoaderMockFactory()->registerURL(redirectURL, m_expectedResponse, m_frameFilePath);
 
     m_expectedLoader = createAssociatedURLLoader();
     EXPECT_TRUE(m_expectedLoader);
@@ -524,7 +526,7 @@
     m_expectedRedirectResponse.setMIMEType("text/html");
     m_expectedRedirectResponse.setHTTPStatusCode(301);
     m_expectedRedirectResponse.setHTTPHeaderField("Location", redirect);
-    Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedRedirectResponse, m_frameFilePath);
+    Platform::current()->getURLLoaderMockFactory()->registerURL(url, m_expectedRedirectResponse, m_frameFilePath);
 
     m_expectedNewRequest = WebURLRequest();
     m_expectedNewRequest.initialize();
@@ -534,7 +536,7 @@
     m_expectedResponse.initialize();
     m_expectedResponse.setMIMEType("text/html");
     m_expectedResponse.setHTTPStatusCode(200);
-    Platform::current()->unitTestSupport()->registerMockedURL(redirectURL, m_expectedResponse, m_frameFilePath);
+    Platform::current()->getURLLoaderMockFactory()->registerURL(redirectURL, m_expectedResponse, m_frameFilePath);
 
     WebURLLoaderOptions options;
     options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
@@ -570,7 +572,7 @@
     m_expectedRedirectResponse.setHTTPStatusCode(301);
     m_expectedRedirectResponse.setHTTPHeaderField("Location", redirect);
     m_expectedRedirectResponse.addHTTPHeaderField("access-control-allow-origin", "*");
-    Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedRedirectResponse, m_frameFilePath);
+    Platform::current()->getURLLoaderMockFactory()->registerURL(url, m_expectedRedirectResponse, m_frameFilePath);
 
     m_expectedNewRequest = WebURLRequest();
     m_expectedNewRequest.initialize();
@@ -582,7 +584,7 @@
     m_expectedResponse.setMIMEType("text/html");
     m_expectedResponse.setHTTPStatusCode(200);
     m_expectedResponse.addHTTPHeaderField("access-control-allow-origin", "*");
-    Platform::current()->unitTestSupport()->registerMockedURL(redirectURL, m_expectedResponse, m_frameFilePath);
+    Platform::current()->getURLLoaderMockFactory()->registerURL(redirectURL, m_expectedResponse, m_frameFilePath);
 
     WebURLLoaderOptions options;
     options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
@@ -697,7 +699,7 @@
     m_expectedResponse.setHTTPStatusCode(200);
     m_expectedResponse.addHTTPHeaderField("Access-Control-Allow-Origin", "*");
     m_expectedResponse.addHTTPHeaderField(headerNameString, "foo");
-    Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedResponse, m_frameFilePath);
+    Platform::current()->getURLLoaderMockFactory()->registerURL(url, m_expectedResponse, m_frameFilePath);
 
     WebURLLoaderOptions options;
     options.exposeAllResponseHeaders = true; // This turns off response whitelisting.
diff --git a/third_party/WebKit/Source/web/ExternalPopupMenuTest.cpp b/third_party/WebKit/Source/web/ExternalPopupMenuTest.cpp
index ff9d3aa..1bd8877c 100644
--- a/third_party/WebKit/Source/web/ExternalPopupMenuTest.cpp
+++ b/third_party/WebKit/Source/web/ExternalPopupMenuTest.cpp
@@ -15,7 +15,8 @@
 #include "platform/PopupMenu.h"
 #include "platform/testing/URLTestHelpers.h"
 #include "public/platform/Platform.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
+#include "public/web/WebCache.h"
 #include "public/web/WebExternalPopupMenu.h"
 #include "public/web/WebPopupMenuInfo.h"
 #include "public/web/WebSettings.h"
@@ -107,7 +108,8 @@
     }
     void TearDown() override
     {
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        WebCache::clear();
     }
 
     void registerMockedURLLoad(const std::string& fileName)
diff --git a/third_party/WebKit/Source/web/LinkHighlightImplTest.cpp b/third_party/WebKit/Source/web/LinkHighlightImplTest.cpp
index 565f132..f440be6 100644
--- a/third_party/WebKit/Source/web/LinkHighlightImplTest.cpp
+++ b/third_party/WebKit/Source/web/LinkHighlightImplTest.cpp
@@ -36,7 +36,8 @@
 #include "public/platform/WebContentLayer.h"
 #include "public/platform/WebFloatPoint.h"
 #include "public/platform/WebSize.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
+#include "public/web/WebCache.h"
 #include "public/web/WebFrame.h"
 #include "public/web/WebFrameClient.h"
 #include "public/web/WebInputEvent.h"
@@ -104,7 +105,8 @@
     webViewImpl->enableTapHighlightAtPoint(getTargetedEvent(webViewImpl, touchEvent));
     ASSERT_EQ(0U, webViewImpl->numLinkHighlights());
 
-    Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+    Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+    WebCache::clear();
 }
 
 namespace {
@@ -161,7 +163,8 @@
     webViewImpl->updateAllLifecyclePhases();
     ASSERT_EQ(0U, highlightLayer->numLinkHighlights());
 
-    Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+    Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+    WebCache::clear();
 }
 
 // A lifetime test: delete LayerTreeView while running LinkHighlights.
@@ -202,7 +205,8 @@
     webViewImpl->willCloseLayerTreeView();
     webViewHelper.reset();
 
-    Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+    Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+    WebCache::clear();
 }
 
 TEST(LinkHighlightImplTest, multipleHighlights)
@@ -233,7 +237,8 @@
     webViewImpl->enableTapHighlights(highlightNodes);
     EXPECT_EQ(2U, webViewImpl->numLinkHighlights());
 
-    Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+    Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+    WebCache::clear();
 }
 
 } // namespace blink
diff --git a/third_party/WebKit/Source/web/WebEmbeddedWorkerImplTest.cpp b/third_party/WebKit/Source/web/WebEmbeddedWorkerImplTest.cpp
index 80db122d..7c34de63 100644
--- a/third_party/WebKit/Source/web/WebEmbeddedWorkerImplTest.cpp
+++ b/third_party/WebKit/Source/web/WebEmbeddedWorkerImplTest.cpp
@@ -7,9 +7,10 @@
 #include "platform/testing/URLTestHelpers.h"
 #include "platform/testing/UnitTestHelpers.h"
 #include "public/platform/Platform.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
 #include "public/platform/WebURLResponse.h"
-#include "public/platform/WebUnitTestSupport.h"
 #include "public/platform/modules/serviceworker/WebServiceWorkerProvider.h"
+#include "public/web/WebCache.h"
 #include "public/web/WebEmbeddedWorkerStartData.h"
 #include "public/web/WebSettings.h"
 #include "public/web/modules/serviceworker/WebServiceWorkerContextClient.h"
@@ -43,7 +44,7 @@
         response.initialize();
         response.setMIMEType("text/javascript");
         response.setHTTPStatusCode(200);
-        Platform::current()->unitTestSupport()->registerMockedURL(scriptURL, response, "");
+        Platform::current()->getURLLoaderMockFactory()->registerURL(scriptURL, response, "");
 
         m_startData.scriptURL = scriptURL;
         m_startData.userAgent = WebString("dummy user agent");
@@ -54,7 +55,8 @@
 
     void TearDown() override
     {
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        WebCache::clear();
     }
 
     WebEmbeddedWorkerStartData m_startData;
@@ -95,7 +97,7 @@
 
     // Load the shadow page.
     EXPECT_CALL(*m_mockClient, createServiceWorkerNetworkProvider(::testing::_)).WillOnce(::testing::Return(nullptr));
-    Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
+    Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
     ::testing::Mock::VerifyAndClearExpectations(m_mockClient);
 
     // Terminate before loading the script.
@@ -115,7 +117,7 @@
     // Load the shadow page.
     EXPECT_CALL(*m_mockClient, createServiceWorkerNetworkProvider(::testing::_))
         .WillOnce(::testing::Return(nullptr));
-    Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
+    Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
     ::testing::Mock::VerifyAndClearExpectations(m_mockClient);
 
     // Load the script.
@@ -123,7 +125,7 @@
         .Times(1);
     EXPECT_CALL(*m_mockClient, createServiceWorkerProvider())
         .Times(0);
-    Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
+    Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
     ::testing::Mock::VerifyAndClearExpectations(m_mockClient);
 
     // Terminate before resuming after download.
@@ -145,7 +147,7 @@
     WebURLError error;
     error.reason = 1010;
     error.domain = "WebEmbeddedWorkerImplTest";
-    Platform::current()->unitTestSupport()->registerMockedErrorURL(scriptURL, response, error);
+    Platform::current()->getURLLoaderMockFactory()->registerErrorURL(scriptURL, response, error);
     m_startData.scriptURL = scriptURL;
 
     EXPECT_CALL(*m_mockClient, workerReadyForInspection())
@@ -156,7 +158,7 @@
     // Load the shadow page.
     EXPECT_CALL(*m_mockClient, createServiceWorkerNetworkProvider(::testing::_))
         .WillOnce(::testing::Return(nullptr));
-    Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
+    Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
     ::testing::Mock::VerifyAndClearExpectations(m_mockClient);
 
     // Load the script.
@@ -166,7 +168,7 @@
         .Times(0);
     EXPECT_CALL(*m_mockClient, workerContextFailedToStart())
         .Times(1);
-    Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
+    Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
     ::testing::Mock::VerifyAndClearExpectations(m_mockClient);
 }
 
@@ -187,7 +189,7 @@
     // Load the shadow page.
     EXPECT_CALL(*m_mockClient, createServiceWorkerNetworkProvider(::testing::_))
         .WillOnce(::testing::Return(nullptr));
-    Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
+    Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
     ::testing::Mock::VerifyAndClearExpectations(m_mockClient);
 
     // Load the script.
@@ -195,7 +197,7 @@
         .Times(1);
     EXPECT_CALL(*m_mockClient, createServiceWorkerProvider())
         .WillOnce(::testing::Return(nullptr));
-    Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
+    Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
     ::testing::Mock::VerifyAndClearExpectations(m_mockClient);
 }
 
@@ -217,7 +219,7 @@
     // Load the shadow page.
     EXPECT_CALL(*m_mockClient, createServiceWorkerNetworkProvider(::testing::_))
         .WillOnce(::testing::Return(nullptr));
-    Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
+    Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
     ::testing::Mock::VerifyAndClearExpectations(m_mockClient);
 
     // Load the script.
@@ -225,7 +227,7 @@
         .Times(1);
     EXPECT_CALL(*m_mockClient, createServiceWorkerProvider())
         .Times(0);
-    Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
+    Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
     ::testing::Mock::VerifyAndClearExpectations(m_mockClient);
 
     // Resume after download.
diff --git a/third_party/WebKit/Source/web/tests/CompositorWorkerTest.cpp b/third_party/WebKit/Source/web/tests/CompositorWorkerTest.cpp
index 57d9a5b..d3764ad 100644
--- a/third_party/WebKit/Source/web/tests/CompositorWorkerTest.cpp
+++ b/third_party/WebKit/Source/web/tests/CompositorWorkerTest.cpp
@@ -13,7 +13,8 @@
 #include "public/platform/Platform.h"
 #include "public/platform/WebLayer.h"
 #include "public/platform/WebLayerTreeView.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
+#include "public/web/WebCache.h"
 #include "public/web/WebSettings.h"
 #include "public/web/WebViewClient.h"
 #include "web/WebLocalFrameImpl.h"
@@ -35,7 +36,8 @@
 
     ~CompositorWorkerTest() override
     {
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        WebCache::clear();
     }
 
     void navigateTo(const String& url)
diff --git a/third_party/WebKit/Source/web/tests/DocumentLoaderTest.cpp b/third_party/WebKit/Source/web/tests/DocumentLoaderTest.cpp
index c10dfa0..d360759 100644
--- a/third_party/WebKit/Source/web/tests/DocumentLoaderTest.cpp
+++ b/third_party/WebKit/Source/web/tests/DocumentLoaderTest.cpp
@@ -5,7 +5,8 @@
 #include "platform/testing/URLTestHelpers.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebURLLoaderClient.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
+#include "public/web/WebCache.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "web/WebLocalFrameImpl.h"
 #include "web/tests/FrameTestHelpers.h"
@@ -27,7 +28,8 @@
 
     void TearDown() override
     {
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        WebCache::clear();
     }
 
     WebLocalFrameImpl* mainFrame()
@@ -49,9 +51,9 @@
         }
     } delegate;
 
-    Platform::current()->unitTestSupport()->setLoaderDelegate(&delegate);
+    Platform::current()->getURLLoaderMockFactory()->setLoaderDelegate(&delegate);
     FrameTestHelpers::loadFrame(mainFrame(), "https://example.com/foo.html");
-    Platform::current()->unitTestSupport()->setLoaderDelegate(nullptr);
+    Platform::current()->getURLLoaderMockFactory()->setLoaderDelegate(nullptr);
 
     // TODO(dcheng): How should the test verify that the original callback is
     // invoked? The test currently still passes even if the test delegate
@@ -73,9 +75,9 @@
         }
     } delegate;
 
-    Platform::current()->unitTestSupport()->setLoaderDelegate(&delegate);
+    Platform::current()->getURLLoaderMockFactory()->setLoaderDelegate(&delegate);
     FrameTestHelpers::loadFrame(mainFrame(), "https://example.com/foo.html");
-    Platform::current()->unitTestSupport()->setLoaderDelegate(nullptr);
+    Platform::current()->getURLLoaderMockFactory()->setLoaderDelegate(nullptr);
 }
 
 // Finally, test reentrant callbacks to DocumentLoader::dataReceived().
@@ -154,9 +156,9 @@
     // setup a situation where didReceiveData() can be invoked reentrantly.
     FrameTestHelpers::loadHTMLString(mainFrame(), "<iframe></iframe>", URLTestHelpers::toKURL("about:blank"));
 
-    Platform::current()->unitTestSupport()->setLoaderDelegate(&delegate);
+    Platform::current()->getURLLoaderMockFactory()->setLoaderDelegate(&delegate);
     FrameTestHelpers::loadFrame(mainFrame(), "https://example.com/foo.html");
-    Platform::current()->unitTestSupport()->setLoaderDelegate(nullptr);
+    Platform::current()->getURLLoaderMockFactory()->setLoaderDelegate(nullptr);
 
     EXPECT_TRUE(delegate.servedReentrantly());
 
diff --git a/third_party/WebKit/Source/web/tests/FrameSerializerTest.cpp b/third_party/WebKit/Source/web/tests/FrameSerializerTest.cpp
index cd01112d..d3aa43a 100644
--- a/third_party/WebKit/Source/web/tests/FrameSerializerTest.cpp
+++ b/third_party/WebKit/Source/web/tests/FrameSerializerTest.cpp
@@ -38,9 +38,10 @@
 #include "public/platform/WebString.h"
 #include "public/platform/WebThread.h"
 #include "public/platform/WebURL.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
 #include "public/platform/WebURLRequest.h"
 #include "public/platform/WebURLResponse.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/web/WebCache.h"
 #include "public/web/WebSettings.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "web/WebLocalFrameImpl.h"
@@ -73,7 +74,8 @@
 
     void TearDown() override
     {
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        WebCache::clear();
     }
 
     void setBaseFolder(const char* folder)
@@ -107,7 +109,7 @@
         response.setMIMEType("text/html");
         response.setHTTPStatusCode(statusCode);
 
-        Platform::current()->unitTestSupport()->registerMockedErrorURL(KURL(m_baseUrl, file), response, error);
+        Platform::current()->getURLLoaderMockFactory()->registerErrorURL(KURL(m_baseUrl, file), response, error);
     }
 
     void registerRewriteURL(const char* fromURL, const char* toURL)
diff --git a/third_party/WebKit/Source/web/tests/FrameTestHelpers.cpp b/third_party/WebKit/Source/web/tests/FrameTestHelpers.cpp
index 58d42216..cb240a1 100644
--- a/third_party/WebKit/Source/web/tests/FrameTestHelpers.cpp
+++ b/third_party/WebKit/Source/web/tests/FrameTestHelpers.cpp
@@ -37,9 +37,9 @@
 #include "public/platform/WebData.h"
 #include "public/platform/WebString.h"
 #include "public/platform/WebThread.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
 #include "public/platform/WebURLRequest.h"
 #include "public/platform/WebURLResponse.h"
-#include "public/platform/WebUnitTestSupport.h"
 #include "public/web/WebFrameWidget.h"
 #include "public/web/WebRemoteFrame.h"
 #include "public/web/WebSettings.h"
@@ -78,7 +78,7 @@
 
 void runServeAsyncRequestsTask(TestWebFrameClient* client)
 {
-    Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
+    Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
     if (client->isLoading())
         Platform::current()->currentThread()->getWebTaskRunner()->postTask(BLINK_FROM_HERE, bind(&runServeAsyncRequestsTask, client));
     else
diff --git a/third_party/WebKit/Source/web/tests/ImeOnFocusTest.cpp b/third_party/WebKit/Source/web/tests/ImeOnFocusTest.cpp
index 426a761..9f0bb929 100644
--- a/third_party/WebKit/Source/web/tests/ImeOnFocusTest.cpp
+++ b/third_party/WebKit/Source/web/tests/ImeOnFocusTest.cpp
@@ -9,7 +9,8 @@
 #include "platform/testing/URLTestHelpers.h"
 #include "platform/testing/UnitTestHelpers.h"
 #include "public/platform/Platform.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
+#include "public/web/WebCache.h"
 #include "public/web/WebDocument.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "web/WebLocalFrameImpl.h"
@@ -58,7 +59,8 @@
 
     void TearDown() override
     {
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        WebCache::clear();
     }
 
 protected:
diff --git a/third_party/WebKit/Source/web/tests/LayoutGeometryMapTest.cpp b/third_party/WebKit/Source/web/tests/LayoutGeometryMapTest.cpp
index ae98a6e..ff19c0a 100644
--- a/third_party/WebKit/Source/web/tests/LayoutGeometryMapTest.cpp
+++ b/third_party/WebKit/Source/web/tests/LayoutGeometryMapTest.cpp
@@ -35,7 +35,8 @@
 #include "core/paint/PaintLayer.h"
 #include "platform/testing/URLTestHelpers.h"
 #include "public/platform/Platform.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
+#include "public/web/WebCache.h"
 #include "public/web/WebFrameClient.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "web/WebLocalFrameImpl.h"
@@ -55,7 +56,8 @@
 
     void TearDown() override
     {
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        WebCache::clear();
     }
 
 protected:
diff --git a/third_party/WebKit/Source/web/tests/ListenerLeakTest.cpp b/third_party/WebKit/Source/web/tests/ListenerLeakTest.cpp
index 8b69f26..38b78be 100644
--- a/third_party/WebKit/Source/web/tests/ListenerLeakTest.cpp
+++ b/third_party/WebKit/Source/web/tests/ListenerLeakTest.cpp
@@ -30,7 +30,8 @@
 
 #include "platform/testing/URLTestHelpers.h"
 #include "public/platform/Platform.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
+#include "public/web/WebCache.h"
 #include "public/web/WebView.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "web/tests/FrameTestHelpers.h"
@@ -94,7 +95,8 @@
 
     void TearDown() override
     {
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        WebCache::clear();
     }
 
 protected:
diff --git a/third_party/WebKit/Source/web/tests/MHTMLTest.cpp b/third_party/WebKit/Source/web/tests/MHTMLTest.cpp
index 5bf20f29..dc285d2 100644
--- a/third_party/WebKit/Source/web/tests/MHTMLTest.cpp
+++ b/third_party/WebKit/Source/web/tests/MHTMLTest.cpp
@@ -42,9 +42,10 @@
 #include "public/platform/Platform.h"
 #include "public/platform/WebString.h"
 #include "public/platform/WebURL.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
 #include "public/platform/WebURLRequest.h"
 #include "public/platform/WebURLResponse.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/web/WebCache.h"
 #include "public/web/WebDocument.h"
 #include "public/web/WebFrame.h"
 #include "public/web/WebView.h"
@@ -97,7 +98,8 @@
 
     void TearDown() override
     {
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        WebCache::clear();
     }
 
     void registerMockedURLLoad(const std::string& url, const WebString& fileName)
diff --git a/third_party/WebKit/Source/web/tests/PrerenderingTest.cpp b/third_party/WebKit/Source/web/tests/PrerenderingTest.cpp
index 8e99e2c8..67f8091 100644
--- a/third_party/WebKit/Source/web/tests/PrerenderingTest.cpp
+++ b/third_party/WebKit/Source/web/tests/PrerenderingTest.cpp
@@ -34,7 +34,7 @@
 #include "public/platform/WebPrerender.h"
 #include "public/platform/WebPrerenderingSupport.h"
 #include "public/platform/WebString.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
 #include "public/web/WebCache.h"
 #include "public/web/WebFrame.h"
 #include "public/web/WebPrerendererClient.h"
@@ -169,7 +169,8 @@
 public:
     ~PrerenderingTest() override
     {
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        WebCache::clear();
     }
 
     void initialize(const char* baseURL, const char* fileName)
diff --git a/third_party/WebKit/Source/web/tests/ProgrammaticScrollTest.cpp b/third_party/WebKit/Source/web/tests/ProgrammaticScrollTest.cpp
index c1c93c6..a82edee 100644
--- a/third_party/WebKit/Source/web/tests/ProgrammaticScrollTest.cpp
+++ b/third_party/WebKit/Source/web/tests/ProgrammaticScrollTest.cpp
@@ -4,7 +4,8 @@
 #include "core/loader/FrameLoader.h"
 #include "platform/testing/URLTestHelpers.h"
 #include "public/platform/Platform.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
+#include "public/web/WebCache.h"
 #include "public/web/WebFrame.h"
 #include "public/web/WebFrameClient.h"
 #include "public/web/WebHistoryItem.h"
@@ -31,7 +32,8 @@
 
     void TearDown() override
     {
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        WebCache::clear();
     }
 
 protected:
diff --git a/third_party/WebKit/Source/web/tests/ScreenWakeLockTest.cpp b/third_party/WebKit/Source/web/tests/ScreenWakeLockTest.cpp
index 0ecebcffcd..6d770ec 100644
--- a/third_party/WebKit/Source/web/tests/ScreenWakeLockTest.cpp
+++ b/third_party/WebKit/Source/web/tests/ScreenWakeLockTest.cpp
@@ -12,8 +12,9 @@
 #include "platform/testing/URLTestHelpers.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebPageVisibilityState.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
 #include "public/platform/modules/wake_lock/WebWakeLockClient.h"
+#include "public/web/WebCache.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "web/WebLocalFrameImpl.h"
 #include "web/tests/FrameTestHelpers.h"
@@ -67,7 +68,8 @@
 
     void TearDown() override
     {
-        blink::Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        blink::Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        blink::WebCache::clear();
     }
 
     void loadFrame()
diff --git a/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp b/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp
index 2c94083..30d90e7 100644
--- a/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp
+++ b/third_party/WebKit/Source/web/tests/ScrollingCoordinatorTest.cpp
@@ -36,7 +36,8 @@
 #include "public/platform/WebLayer.h"
 #include "public/platform/WebLayerPositionConstraint.h"
 #include "public/platform/WebLayerTreeView.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
+#include "public/web/WebCache.h"
 #include "public/web/WebSettings.h"
 #include "public/web/WebViewClient.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -63,7 +64,8 @@
 
     ~ScrollingCoordinatorTest() override
     {
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        WebCache::clear();
     }
 
     void navigateTo(const std::string& url)
diff --git a/third_party/WebKit/Source/web/tests/TopControlsTest.cpp b/third_party/WebKit/Source/web/tests/TopControlsTest.cpp
index a4de2cf..74e8b07 100644
--- a/third_party/WebKit/Source/web/tests/TopControlsTest.cpp
+++ b/third_party/WebKit/Source/web/tests/TopControlsTest.cpp
@@ -37,7 +37,8 @@
 #include "core/page/Page.h"
 #include "platform/testing/URLTestHelpers.h"
 #include "public/platform/Platform.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
+#include "public/web/WebCache.h"
 #include "public/web/WebElement.h"
 #include "public/web/WebSettings.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -67,7 +68,8 @@
 
     ~TopControlsTest() override
     {
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        WebCache::clear();
     }
 
     WebViewImpl* initialize(const std::string& pageName = "large-div.html")
diff --git a/third_party/WebKit/Source/web/tests/TouchActionTest.cpp b/third_party/WebKit/Source/web/tests/TouchActionTest.cpp
index 26d8ccd..3b792ff 100644
--- a/third_party/WebKit/Source/web/tests/TouchActionTest.cpp
+++ b/third_party/WebKit/Source/web/tests/TouchActionTest.cpp
@@ -43,7 +43,8 @@
 #include "platform/testing/URLTestHelpers.h"
 #include "platform/testing/UnitTestHelpers.h"
 #include "public/platform/Platform.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
+#include "public/web/WebCache.h"
 #include "public/web/WebDocument.h"
 #include "public/web/WebFrame.h"
 #include "public/web/WebHitTestResult.h"
@@ -112,7 +113,8 @@
 
     void TearDown() override
     {
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        WebCache::clear();
     }
 
 protected:
diff --git a/third_party/WebKit/Source/web/tests/ViewportTest.cpp b/third_party/WebKit/Source/web/tests/ViewportTest.cpp
index 042a282..e30a7834 100644
--- a/third_party/WebKit/Source/web/tests/ViewportTest.cpp
+++ b/third_party/WebKit/Source/web/tests/ViewportTest.cpp
@@ -41,7 +41,8 @@
 #include "platform/testing/URLTestHelpers.h"
 #include "platform/testing/UnitTestHelpers.h"
 #include "public/platform/Platform.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
+#include "public/web/WebCache.h"
 #include "public/web/WebConsoleMessage.h"
 #include "public/web/WebFrame.h"
 #include "public/web/WebScriptSource.h"
@@ -64,7 +65,8 @@
 
     ~ViewportTest() override
     {
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        WebCache::clear();
     }
 
     void registerMockedHttpURLLoad(const std::string& fileName)
diff --git a/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp b/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp
index b400edc..98c7e08 100644
--- a/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp
+++ b/third_party/WebKit/Source/web/tests/VisualViewportTest.cpp
@@ -12,7 +12,7 @@
 #include "core/html/HTMLElement.h"
 #include "core/input/EventHandler.h"
 #include "core/layout/LayoutObject.h"
-#include "core/layout/LayoutView.h"
+#include "core/layout/api/LayoutViewItem.h"
 #include "core/layout/compositing/PaintLayerCompositor.h"
 #include "core/page/Page.h"
 #include "platform/PlatformGestureEvent.h"
@@ -21,7 +21,8 @@
 #include "platform/testing/URLTestHelpers.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebLayerTreeView.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
+#include "public/web/WebCache.h"
 #include "public/web/WebContextMenuData.h"
 #include "public/web/WebDocument.h"
 #include "public/web/WebFrameClient.h"
@@ -130,7 +131,8 @@
 
     ~VisualViewportTest() override
     {
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        WebCache::clear();
     }
 
     void navigateTo(const std::string& url)
@@ -150,7 +152,7 @@
 
     WebLayer* getRootScrollLayer()
     {
-        PaintLayerCompositor* compositor = frame()->contentLayoutObject()->compositor();
+        PaintLayerCompositor* compositor = frame()->contentLayoutItem().compositor();
         DCHECK(compositor);
         DCHECK(compositor->scrollLayer());
 
diff --git a/third_party/WebKit/Source/web/tests/WebFrameSerializerTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameSerializerTest.cpp
index 85f9a1f..4091750 100644
--- a/third_party/WebKit/Source/web/tests/WebFrameSerializerTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebFrameSerializerTest.cpp
@@ -36,7 +36,8 @@
 #include "public/platform/WebCString.h"
 #include "public/platform/WebString.h"
 #include "public/platform/WebURL.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
+#include "public/web/WebCache.h"
 #include "public/web/WebFrameSerializerClient.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "web/WebLocalFrameImpl.h"
@@ -71,7 +72,8 @@
 
     ~WebFrameSerializerTest() override
     {
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        WebCache::clear();
     }
 
     void registerMockedImageURL(const String& url)
diff --git a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
index 168d35e..c261603 100644
--- a/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebFrameTest.cpp
@@ -65,7 +65,7 @@
 #include "core/input/EventHandler.h"
 #include "core/layout/HitTestResult.h"
 #include "core/layout/LayoutFullScreen.h"
-#include "core/layout/LayoutView.h"
+#include "core/layout/api/LayoutViewItem.h"
 #include "core/layout/compositing/PaintLayerCompositor.h"
 #include "core/loader/DocumentLoader.h"
 #include "core/loader/DocumentThreadableLoader.h"
@@ -93,8 +93,8 @@
 #include "public/platform/WebSecurityOrigin.h"
 #include "public/platform/WebThread.h"
 #include "public/platform/WebURL.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
 #include "public/platform/WebURLResponse.h"
-#include "public/platform/WebUnitTestSupport.h"
 #include "public/web/WebCache.h"
 #include "public/web/WebConsoleMessage.h"
 #include "public/web/WebDataSource.h"
@@ -184,7 +184,8 @@
 
     ~WebFrameTest() override
     {
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        WebCache::clear();
     }
 
     void registerMockedHttpURLLoad(const std::string& fileName)
@@ -2007,7 +2008,7 @@
 
     webViewHelper.webView()->setPageScaleFactor(2);
 
-    EXPECT_EQ(980, toLocalFrame(webViewHelper.webViewImpl()->page()->mainFrame())->contentLayoutObject()->documentRect().width());
+    EXPECT_EQ(980, toLocalFrame(webViewHelper.webViewImpl()->page()->mainFrame())->contentLayoutItem().documentRect().width());
     EXPECT_EQ(980, webViewHelper.webViewImpl()->mainFrameImpl()->frameView()->contentsSize().width());
 }
 
@@ -5120,7 +5121,7 @@
     WebHistoryItem errorHistoryItem;
     errorHistoryItem.initialize();
     errorHistoryItem.setURLString(WebString::fromUTF8(errorURL.c_str(), errorURL.length()));
-    Platform::current()->unitTestSupport()->registerMockedErrorURL(URLTestHelpers::toKURL(errorURL), response, error);
+    Platform::current()->getURLLoaderMockFactory()->registerErrorURL(URLTestHelpers::toKURL(errorURL), response, error);
     FrameTestHelpers::loadHistoryItem(frame, errorHistoryItem, WebHistoryDifferentDocumentLoad, WebURLRequest::UseProtocolCachePolicy);
     WebString text = WebFrameContentDumper::dumpWebViewAsText(webViewHelper.webView(), std::numeric_limits<size_t>::max());
     EXPECT_EQ("This should appear", text.utf8());
@@ -5763,12 +5764,12 @@
     redirectResponse.setMIMEType("text/html");
     redirectResponse.setHTTPStatusCode(302);
     redirectResponse.setHTTPHeaderField("Location", redirect);
-    Platform::current()->unitTestSupport()->registerMockedURL(testURL, redirectResponse, filePath);
+    Platform::current()->getURLLoaderMockFactory()->registerURL(testURL, redirectResponse, filePath);
 
     WebURLResponse finalResponse;
     finalResponse.initialize();
     finalResponse.setMIMEType("text/html");
-    Platform::current()->unitTestSupport()->registerMockedURL(redirectURL, finalResponse, filePath);
+    Platform::current()->getURLLoaderMockFactory()->registerURL(redirectURL, finalResponse, filePath);
 
     FrameTestHelpers::WebViewHelper webViewHelper(this);
     webViewHelper.initializeAndLoad(m_baseURL + "first_party_redirect.html", true);
diff --git a/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp b/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp
index 4f86d07..f0b37d4f 100644
--- a/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp
@@ -49,7 +49,8 @@
 #include "public/platform/WebCompositorSupport.h"
 #include "public/platform/WebLayer.h"
 #include "public/platform/WebThread.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
+#include "public/web/WebCache.h"
 #include "public/web/WebDocument.h"
 #include "public/web/WebElement.h"
 #include "public/web/WebFrame.h"
@@ -79,7 +80,8 @@
 
     void TearDown() override
     {
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        WebCache::clear();
     }
 
     void calculateGeometry(WebPluginContainerImpl* pluginContainerImpl, IntRect& windowRect, IntRect& clipRect, IntRect& unobscuredRect, Vector<IntRect>& cutOutRects)
diff --git a/third_party/WebKit/Source/web/tests/WebSearchableFormDataTest.cpp b/third_party/WebKit/Source/web/tests/WebSearchableFormDataTest.cpp
index 5d0154c..4346eb2 100644
--- a/third_party/WebKit/Source/web/tests/WebSearchableFormDataTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebSearchableFormDataTest.cpp
@@ -32,7 +32,8 @@
 
 #include "platform/testing/URLTestHelpers.h"
 #include "public/platform/Platform.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
+#include "public/web/WebCache.h"
 #include "public/web/WebDocument.h"
 #include "public/web/WebFrame.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -50,7 +51,8 @@
 
     ~WebSearchableFormDataTest() override
     {
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        WebCache::clear();
     }
 
     FrameTestHelpers::WebViewHelper m_webViewHelper;
diff --git a/third_party/WebKit/Source/web/tests/WebSelectorTest.cpp b/third_party/WebKit/Source/web/tests/WebSelectorTest.cpp
index fd3da16..65ff5a4 100644
--- a/third_party/WebKit/Source/web/tests/WebSelectorTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebSelectorTest.cpp
@@ -31,7 +31,6 @@
 #include "public/web/WebSelector.h"
 
 #include "public/platform/WebString.h"
-#include "public/platform/WebUnitTestSupport.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace blink {
diff --git a/third_party/WebKit/Source/web/tests/WebViewTest.cpp b/third_party/WebKit/Source/web/tests/WebViewTest.cpp
index e4287f8..0c14dbd 100644
--- a/third_party/WebKit/Source/web/tests/WebViewTest.cpp
+++ b/third_party/WebKit/Source/web/tests/WebViewTest.cpp
@@ -69,8 +69,9 @@
 #include "public/platform/WebDragData.h"
 #include "public/platform/WebSize.h"
 #include "public/platform/WebThread.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
 #include "public/web/WebAutofillClient.h"
+#include "public/web/WebCache.h"
 #include "public/web/WebContentDetectionResult.h"
 #include "public/web/WebDateTimeChooserCompletion.h"
 #include "public/web/WebDeviceEmulationParams.h"
@@ -229,7 +230,8 @@
 
     void TearDown() override
     {
-        Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+        Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
+        WebCache::clear();
     }
 
 protected:
diff --git a/third_party/WebKit/Source/web/tests/sim/SimNetwork.cpp b/third_party/WebKit/Source/web/tests/sim/SimNetwork.cpp
index 919bf3f..b3c79ac0 100644
--- a/third_party/WebKit/Source/web/tests/sim/SimNetwork.cpp
+++ b/third_party/WebKit/Source/web/tests/sim/SimNetwork.cpp
@@ -8,8 +8,8 @@
 #include "public/platform/WebURLError.h"
 #include "public/platform/WebURLLoader.h"
 #include "public/platform/WebURLLoaderClient.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
 #include "public/platform/WebURLResponse.h"
-#include "public/platform/WebUnitTestSupport.h"
 #include "web/tests/sim/SimRequest.h"
 
 namespace blink {
@@ -19,15 +19,15 @@
 SimNetwork::SimNetwork()
     : m_currentRequest(nullptr)
 {
-    Platform::current()->unitTestSupport()->setLoaderDelegate(this);
-    DCHECK(!s_network);
+    Platform::current()->getURLLoaderMockFactory()->setLoaderDelegate(this);
+    ASSERT(!s_network);
     s_network = this;
 }
 
 SimNetwork::~SimNetwork()
 {
-    Platform::current()->unitTestSupport()->setLoaderDelegate(nullptr);
-    Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+    Platform::current()->getURLLoaderMockFactory()->setLoaderDelegate(nullptr);
+    Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
     s_network = nullptr;
 }
 
@@ -39,7 +39,7 @@
 
 void SimNetwork::servePendingRequests()
 {
-    Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
+    Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
 }
 
 void SimNetwork::didReceiveResponse(WebURLLoaderClient* client, WebURLLoader* loader, const WebURLResponse& response)
diff --git a/third_party/WebKit/Source/web/tests/sim/SimRequest.cpp b/third_party/WebKit/Source/web/tests/sim/SimRequest.cpp
index 9aacb90..31b07f3 100644
--- a/third_party/WebKit/Source/web/tests/sim/SimRequest.cpp
+++ b/third_party/WebKit/Source/web/tests/sim/SimRequest.cpp
@@ -7,7 +7,7 @@
 #include "platform/weborigin/KURL.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebURLLoaderClient.h"
-#include "public/platform/WebUnitTestSupport.h"
+#include "public/platform/WebURLLoaderMockFactory.h"
 #include "web/tests/sim/SimNetwork.h"
 
 namespace blink {
@@ -23,7 +23,7 @@
     WebURLResponse response(fullUrl);
     response.setMIMEType(mimeType);
     response.setHTTPStatusCode(200);
-    Platform::current()->unitTestSupport()->registerMockedURL(fullUrl, response, "");
+    Platform::current()->getURLLoaderMockFactory()->registerURL(fullUrl, response, "");
     SimNetwork::current().addRequest(*this);
 }
 
diff --git a/third_party/WebKit/Source/web/tests/sim/SimTest.cpp b/third_party/WebKit/Source/web/tests/sim/SimTest.cpp
index 9bacb1d..95c4bdfd 100644
--- a/third_party/WebKit/Source/web/tests/sim/SimTest.cpp
+++ b/third_party/WebKit/Source/web/tests/sim/SimTest.cpp
@@ -7,6 +7,7 @@
 #include "core/dom/Document.h"
 #include "platform/LayoutTestSupport.h"
 #include "platform/scroll/ScrollbarTheme.h"
+#include "public/web/WebCache.h"
 #include "web/WebLocalFrameImpl.h"
 #include "web/WebViewImpl.h"
 
@@ -33,6 +34,7 @@
     Document::setThreadedParsingEnabledForTesting(true);
     LayoutTestSupport::setMockThemeEnabledForTest(false);
     ScrollbarTheme::setMockScrollbarsEnabled(false);
+    WebCache::clear();
 }
 
 void SimTest::loadURL(const String& url)
diff --git a/third_party/WebKit/public/blink_headers.gypi b/third_party/WebKit/public/blink_headers.gypi
index f61e41e..1361a43 100644
--- a/third_party/WebKit/public/blink_headers.gypi
+++ b/third_party/WebKit/public/blink_headers.gypi
@@ -215,12 +215,11 @@
       "platform/WebURLLoadTiming.h",
       "platform/WebURLLoader.h",
       "platform/WebURLLoaderClient.h",
+      "platform/WebURLLoaderMockFactory.h",
       "platform/WebURLRequest.h",
       "platform/WebURLResponse.h",
-      "platform/WebUnitTestSupport.h",
       "platform/WebVector.h",
       "platform/linux/WebFallbackFont.h",
-      "platform/linux/WebFontInfo.h",
       "platform/linux/WebFontRenderStyle.h",
       "platform/linux/WebSandboxSupport.h",
       "platform/mac/WebSandboxSupport.h",
diff --git a/third_party/WebKit/public/platform/Platform.h b/third_party/WebKit/public/platform/Platform.h
index 69a8832d..35354833d 100644
--- a/third_party/WebKit/public/platform/Platform.h
+++ b/third_party/WebKit/public/platform/Platform.h
@@ -113,11 +113,10 @@
 class WebThemeEngine;
 class WebThread;
 class WebTrialTokenValidator;
-class WebURL;
 class WebURLLoader;
+class WebURLLoaderMockFactory;
 class WebURLResponse;
-class WebUnitTestSupport;
-struct WebLocalizedString;
+class WebURLResponse;
 struct WebSize;
 
 class BLINK_PLATFORM_EXPORT Platform {
@@ -412,8 +411,8 @@
 
     // Testing -------------------------------------------------------------
 
-    // Get a pointer to testing support interfaces. Will not be available in production builds.
-    virtual WebUnitTestSupport* unitTestSupport() { return nullptr; }
+    // Gets a pointer to URLLoaderMockFactory for testing. Will not be available in production builds.
+    virtual WebURLLoaderMockFactory* getURLLoaderMockFactory() { return nullptr; }
 
     // Record to a RAPPOR privacy-preserving metric, see: https://www.chromium.org/developers/design-documents/rappor.
     // recordRappor records a sample string, while recordRapporURL records the domain and registry of a url.
diff --git a/third_party/WebKit/public/platform/WebUnitTestSupport.h b/third_party/WebKit/public/platform/WebUnitTestSupport.h
deleted file mode 100644
index 9be7da9..0000000
--- a/third_party/WebKit/public/platform/WebUnitTestSupport.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WebUnitTestSupport_h
-#define WebUnitTestSupport_h
-
-#include "WebCommon.h"
-#include "WebData.h"
-#include "WebString.h"
-#include "WebURLLoaderTestDelegate.h"
-
-namespace blink {
-
-class WebLayerTreeView;
-class WebURL;
-class WebURLResponse;
-struct WebURLError;
-
-// TODO(kinuko): Deprecate this.
-class WebUnitTestSupport {
-public:
-    virtual void registerMockedURL(const WebURL&, const WebURLResponse&, const WebString& filePath) { }
-
-    // Registers the error to be returned when |url| is requested.
-    virtual void registerMockedErrorURL(const WebURL&, const WebURLResponse&, const WebURLError&) { }
-
-    // Unregisters URLs so they are no longer mocked.
-    virtual void unregisterMockedURL(const WebURL&) { }
-    virtual void unregisterAllMockedURLs() { }
-
-    // Causes all pending asynchronous requests to be served. When this method
-    // returns all the pending requests have been processed.
-    // Note: this may not work as expected if more requests could be made
-    // asynchronously from different threads (e.g. when HTML parser thread
-    // is being involved).
-    // DO NOT USE THIS for Frame loading; always use methods defined in
-    // FrameTestHelpers instead.
-    virtual void serveAsynchronousMockedRequests() { }
-
-    // Set a delegate that allows callbacks for all WebURLLoaderClients to be intercepted.
-    virtual void setLoaderDelegate(WebURLLoaderTestDelegate*) { }
-};
-
-}
-
-#endif // WebUnitTestSupport_h
diff --git a/third_party/WebKit/public/platform/linux/WebFontInfo.h b/third_party/WebKit/public/platform/linux/WebFontInfo.h
deleted file mode 100644
index bfd7372b..0000000
--- a/third_party/WebKit/public/platform/linux/WebFontInfo.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef WebFontInfo_h
-#define WebFontInfo_h
-
-#include "WebFallbackFont.h"
-
-#include <string.h>
-#include <unistd.h>
-
-namespace blink {
-
-class WebFontInfo {
-public:
-    // Return a font family which provides a glyph for the Unicode code point
-    // specified by character.
-    //   character: a UTF-32 code point
-    //   preferredLocale: preferred locale identifier for the |characters|
-    //                    (e.g. "en", "ja", "zh-CN")
-    //
-    // Returns: the font family or an empty string if the request could not be satisfied.
-    // Returns: the font family instance. The instance has an empty font name if the request could not be satisfied.
-    BLINK_EXPORT static void fallbackFontForChar(const WebUChar32 character, const char* preferredLocale, WebFallbackFont*);
-};
-
-} // namespace blink
-
-#endif
diff --git a/third_party/harfbuzz-ng/BUILD.gn b/third_party/harfbuzz-ng/BUILD.gn
index 4824a4f8..81d4f65a9d 100644
--- a/third_party/harfbuzz-ng/BUILD.gn
+++ b/third_party/harfbuzz-ng/BUILD.gn
@@ -6,26 +6,13 @@
 import("//build/config/linux/pkg_config.gni")
 import("//build/config/ui.gni")
 
-# The GYP build supports system harfbuzz for non-official builds when using
-# pangoft2 1.31.0 or greater (which pulls it in).
-# TODO(brettw) we can consider doing this as well, although the benefit is
-# unclear and requires shelling out to a script to check the version.
-#
-# ChromeOS uses an up-to-date system one that we have control over, so we
-# don't want to bloat the binary more by including another copy.
-
 declare_args() {
-  # Since version 1.31.0, pangoft2 which we depend on pulls in harfbuzz
-  # anyways. However, we want to have control of the version of harfbuzz
-  # we use, so don't use system harfbuzz unless we are building for
-  # chrome os, where we have the system harfbuzz under control.
-  use_system_harfbuzz =
-      is_linux && is_chromeos && exec_script(pkg_config_script,
-                                             pkg_config_args + [
-                                                   "--atleast-version=1.31.0",
-                                                   "pangoft2",
-                                                 ],
-                                             "value")
+  # Blink uses a cutting-edge version of Harfbuzz; most Linux distros do not
+  # contain a new enough version of the code to work correctly. However,
+  # ChromeOS chroots (i.e, real ChromeOS builds for devices) do contain a
+  # new enough version of the library, and so this variable exists so that
+  # ChromeOS can build against the system lib and keep binary sizes smaller.
+  use_system_harfbuzz = false
 }
 
 if (use_system_harfbuzz) {
diff --git a/third_party/harfbuzz-ng/harfbuzz.gyp b/third_party/harfbuzz-ng/harfbuzz.gyp
index b9be8ae..2064a26c 100644
--- a/third_party/harfbuzz-ng/harfbuzz.gyp
+++ b/third_party/harfbuzz-ng/harfbuzz.gyp
@@ -7,17 +7,12 @@
     '../../build/win_precompile.gypi',
   ],
   'variables': {
-    'conditions': [
-      ['OS=="linux" and chromeos==1', {
-        # Since version 1.31.0, pangoft2 which we depend on pulls in harfbuzz
-        # anyways. However, we want to have control of the version of harfbuzz
-        # we use, so don't use system harfbuzz unless we are building for
-        # chrome os, where we have the system harfbuzz under control.
-        'use_system_harfbuzz%': '<!(python ../../build/check_return_value.py <(pkg-config) --atleast-version=1.31.0 pangoft2)',
-      }, {
-        'use_system_harfbuzz': 0,
-      }],
-    ],
+    # Blink uses a cutting-edge version of Harfbuzz; most Linux distros do not
+    # contain a new enough version of the code to work correctly. However,
+    # ChromeOS chroots (i.e, real ChromeOS builds for devices) do contain a
+    # new enough version of the library, and so this variable exists so that
+    # ChromeOS can build against the system lib and keep binary sizes smaller.
+    'use_system_harfbuzz%': 0,
   },
   'conditions': [
     ['use_system_harfbuzz==0', {
diff --git a/tools/android/loading/common_util.py b/tools/android/loading/common_util.py
index 5b62ce0..9384df0 100644
--- a/tools/android/loading/common_util.py
+++ b/tools/android/loading/common_util.py
@@ -24,3 +24,40 @@
     if result:
       return result
     time.sleep(interval)
+
+
+def SerializeAttributesToJsonDict(json_dict, instance, attributes):
+  """Adds the |attributes| from |instance| to a |json_dict|.
+
+  Args:
+    json_dict: (dict) Dict to update.
+    instance: (object) instance to take the values from.
+    attributes: ([str]) List of attributes to serialize.
+
+  Returns:
+    json_dict
+  """
+  json_dict.update({attr: getattr(instance, attr) for attr in attributes})
+  return json_dict
+
+
+def DeserializeAttributesFromJsonDict(json_dict, instance, attributes):
+  """Sets a list of |attributes| in |instance| according to their value in
+    |json_dict|.
+
+  Args:
+    json_dict: (dict) Dict containing values dumped by
+               SerializeAttributesToJsonDict.
+    instance: (object) instance to modify.
+    attributes: ([str]) List of attributes to set.
+
+  Raises:
+    AttributeError if one of the attribute doesn't exist in |instance|.
+
+  Returns:
+    instance
+  """
+  for attr in attributes:
+    getattr(instance, attr) # To raise AttributeError if attr doesn't exist.
+    setattr(instance, attr, json_dict[attr])
+  return instance
diff --git a/tools/android/loading/common_util_unittest.py b/tools/android/loading/common_util_unittest.py
new file mode 100644
index 0000000..8984881
--- /dev/null
+++ b/tools/android/loading/common_util_unittest.py
@@ -0,0 +1,51 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import unittest
+
+import common_util
+
+
+class SerializeAttributesTestCase(unittest.TestCase):
+  class Foo(object):
+    def __init__(self, foo_fighters, whisky_bar):
+      # Pylint doesn't like foo and bar, but I guess musical references are OK.
+      self.foo_fighters = foo_fighters
+      self.whisky_bar = whisky_bar
+
+  def testSerialization(self):
+    foo_fighters = self.Foo('1', 2)
+    json_dict = common_util.SerializeAttributesToJsonDict(
+        {}, foo_fighters, ['foo_fighters', 'whisky_bar'])
+    self.assertDictEqual({'foo_fighters': '1', 'whisky_bar': 2}, json_dict)
+    # Partial update
+    json_dict = common_util.SerializeAttributesToJsonDict(
+        {'baz': 42}, foo_fighters, ['whisky_bar'])
+    self.assertDictEqual({'baz': 42, 'whisky_bar': 2}, json_dict)
+    # Non-existing attribute.
+    with self.assertRaises(AttributeError):
+      json_dict = common_util.SerializeAttributesToJsonDict(
+          {}, foo_fighters, ['foo_fighters', 'whisky_bar', 'baz'])
+
+  def testDeserialization(self):
+    foo_fighters = self.Foo('hello', 'world')
+    json_dict = {'foo_fighters': 12, 'whisky_bar': 42}
+    # Partial.
+    foo_fighters = common_util.DeserializeAttributesFromJsonDict(
+        json_dict, foo_fighters, ['foo_fighters'])
+    self.assertEqual(12, foo_fighters.foo_fighters)
+    self.assertEqual('world', foo_fighters.whisky_bar)
+    # Complete.
+    foo_fighters = common_util.DeserializeAttributesFromJsonDict(
+        json_dict, foo_fighters, ['foo_fighters', 'whisky_bar'])
+    self.assertEqual(42, foo_fighters.whisky_bar)
+    # Non-existing attribute.
+    with self.assertRaises(AttributeError):
+      json_dict['baz'] = 'bad'
+      foo_fighters = common_util.DeserializeAttributesFromJsonDict(
+          json_dict, foo_fighters, ['foo_fighters', 'whisky_bar', 'baz'])
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/tools/android/loading/controller.py b/tools/android/loading/controller.py
index 053e062..b6616f94 100644
--- a/tools/android/loading/controller.py
+++ b/tools/android/loading/controller.py
@@ -299,8 +299,9 @@
     self._headless = headless
 
   @contextlib.contextmanager
-  def Open(self):
-    """Override for connection context."""
+  def OpenWithRedirection(self, stdout, stderr):
+    """Override for connection context. stdout and stderr are passed to the
+       child processes used to run Chrome and XVFB."""
     chrome_cmd = [OPTIONS.local_binary]
     chrome_cmd.extend(self._GetChromeArguments())
     chrome_cmd.append('--user-data-dir=%s' % self._profile_dir)
@@ -309,16 +310,16 @@
     #   - To find the correct target descriptor at devtool connection;
     #   - To avoid cache and WPR pollution by the NTP.
     chrome_cmd.append('about:blank')
-    chrome_out = None if OPTIONS.local_noisy else file('/dev/null', 'w')
     environment = os.environ.copy()
     if self._headless:
       environment['DISPLAY'] = 'localhost:99'
       xvfb_process = subprocess.Popen(
           ['Xvfb', ':99', '-screen', '0', '1600x1200x24'], shell=False,
-          stderr=chrome_out)
+          stdout=stdout, stderr=stderr)
     logging.debug(subprocess.list2cmdline(chrome_cmd))
     chrome_process = subprocess.Popen(chrome_cmd, shell=False,
-                                      stderr=chrome_out, env=environment)
+                                      stdout=stdout, stderr=stderr,
+                                      env=environment)
     connection = None
     try:
       time.sleep(10)
@@ -340,6 +341,13 @@
       if self._headless:
         xvfb_process.kill()
 
+  def Open(self):
+    """Wrapper around the more-specialized version of Open() above that sets
+    the value of stdout/stderr based on the value of OPTIONS.local_noisy."""
+    stdout = None if OPTIONS.local_noisy else file('/dev/null', 'w')
+    stderr = stdout
+    return self.OpenWithRedirection(self, stdout, stderr)
+
   def PushBrowserCache(self, cache_path):
     """Override for chrome cache pushing."""
     self._EnsureProfileDirectory()
diff --git a/tools/android/loading/dependency_graph.py b/tools/android/loading/dependency_graph.py
index 955177c..da55ad2 100644
--- a/tools/android/loading/dependency_graph.py
+++ b/tools/android/loading/dependency_graph.py
@@ -7,25 +7,54 @@
 import logging
 import sys
 
+import common_util
 import graph
 import request_track
 
 
 class RequestNode(graph.Node):
-  def __init__(self, request):
+  def __init__(self, request=None):
     super(RequestNode, self).__init__()
     self.request = request
-    self.cost = request.Cost()
+    self.cost = request.Cost() if request else None # Deserialization.
+
+  def ToJsonDict(self):
+    json_dict = super(RequestNode, self).ToJsonDict()
+    json_dict.update({'request': self.request.ToJsonDict()})
+    return json_dict
+
+  @classmethod
+  def FromJsonDict(cls, json_dict):
+    result = super(RequestNode, cls).FromJsonDict(json_dict)
+    result.request = request_track.Request.FromJsonDict(json_dict['request'])
+    return common_util.DeserializeAttributesFromJsonDict(
+        json_dict, result, ['cost'])
 
 
 class Edge(graph.Edge):
-  def __init__(self, from_node, to_node, reason):
+  def __init__(self, from_node, to_node, reason=None):
     super(Edge, self).__init__(from_node, to_node)
     self.reason = reason
+    self.cost = None
+    self.is_timing = None
+    if from_node is None: # Deserialization.
+      return
+    self.reason = reason
     self.cost = request_track.TimeBetween(
         self.from_node.request, self.to_node.request, self.reason)
     self.is_timing = False
 
+  def ToJsonDict(self):
+    result = {}
+    return common_util.SerializeAttributesToJsonDict(
+        result, self, ['reason', 'cost', 'is_timing'])
+
+  @classmethod
+  def FromJsonDict(cls, json_dict):
+    result = cls(None, None, None)
+    return common_util.DeserializeAttributesFromJsonDict(
+        json_dict, result, ['reason', 'cost', 'is_timing'])
+
 
 class RequestDependencyGraph(object):
   """Request dependency graph."""
@@ -45,6 +74,12 @@
       node_class: (subclass of RequestNode)
       edge_class: (subclass of Edge)
     """
+    self._requests = None
+    self._first_request_node = None
+    self._deps_graph = None
+    self._nodes_by_id = None
+    if requests is None: # Deserialization.
+      return
     assert issubclass(node_class, RequestNode)
     assert issubclass(edge_class, Edge)
     self._requests = requests
@@ -175,3 +210,22 @@
         self._deps_graph.UpdateEdge(
             current, edges_by_end_time[end_mark].to_node,
             current.to_node)
+
+  def ToJsonDict(self):
+    result = {'graph': self.graph.ToJsonDict()}
+    result['requests'] = [r.ToJsonDict() for r in self._requests]
+    return result
+
+  @classmethod
+  def FromJsonDict(cls, json_dict, node_class, edge_class):
+    result = cls(None, None)
+    graph_dict = json_dict['graph']
+    g = graph.DirectedGraph.FromJsonDict(graph_dict, node_class, edge_class)
+    result._requests = [request_track.Request.FromJsonDict(r)
+                        for r in json_dict['requests']]
+    result._nodes_by_id = {node.request.request_id: node
+                           for node in g.Nodes()}
+    result._first_request_node = result._nodes_by_id[
+        result._requests[0].request_id]
+    result._deps_graph = g
+    return result
diff --git a/tools/android/loading/dependency_graph_unittest.py b/tools/android/loading/dependency_graph_unittest.py
index 4f60995..68433f5 100644
--- a/tools/android/loading/dependency_graph_unittest.py
+++ b/tools/android/loading/dependency_graph_unittest.py
@@ -16,13 +16,15 @@
     super(RequestDependencyGraphTestCase, self).setUp()
     self.trace = TestRequests.CreateLoadingTrace()
 
-  def testUpdateRequestCost(self):
+  def testUpdateRequestCost(self, serialize=False):
     requests = self.trace.request_track.GetEvents()
     requests[0].timing = request_track.TimingFromDict(
         {'requestTime': 12, 'loadingFinished': 10})
     dependencies_lens = request_dependencies_lens.RequestDependencyLens(
         self.trace)
     g = dependency_graph.RequestDependencyGraph(requests, dependencies_lens)
+    if serialize:
+      g = self._SerializeDeserialize(g)
     self.assertEqual(10, g.Cost())
     request_id = requests[0].request_id
     g.UpdateRequestsCost({request_id: 100})
@@ -30,7 +32,7 @@
     g.UpdateRequestsCost({'unrelated_id': 1000})
     self.assertEqual(100, g.Cost())
 
-  def testCost(self):
+  def testCost(self, serialize=False):
     requests = self.trace.request_track.GetEvents()
     for (index, request) in enumerate(requests):
       request.timing = request_track.TimingFromDict(
@@ -39,6 +41,8 @@
     dependencies_lens = request_dependencies_lens.RequestDependencyLens(
         self.trace)
     g = dependency_graph.RequestDependencyGraph(requests, dependencies_lens)
+    if serialize:
+      g = self._SerializeDeserialize(g)
     # First redirect -> Second redirect -> Redirected Request -> Request ->
     # JS Request 2
     self.assertEqual(7010, g.Cost())
@@ -50,7 +54,7 @@
     g.UpdateRequestsCost({TestRequests.SECOND_REDIRECT_REQUEST.request_id: 0})
     self.assertEqual(6990, g.Cost())
 
-  def testHandleTimingDependencies(self):
+  def testHandleTimingDependencies(self, serialize=False):
     # Timing adds node 1 as a parent to 2 but not 3.
     requests = [
         test_utils.MakeRequest(0, 'null', 100, 110, 110,
@@ -65,6 +69,8 @@
         test_utils.MakeRequest(5, 2, 122, 126, 126)]
 
     g = self._GraphFromRequests(requests)
+    if serialize:
+      g = self._SerializeDeserialize(g)
     self.assertSetEqual(
         self._Successors(g, requests[0]), set([requests[1], requests[3]]))
     self.assertSetEqual(
@@ -106,7 +112,7 @@
     self.assertSetEqual(self._Successors(g, requests[5]), set())
     self.assertSetEqual(self._Successors(g, requests[6]), set([requests[3]]))
 
-  def testHandleTimingDependenciesImages(self):
+  def testHandleTimingDependenciesImages(self, serialize=False):
     # If we're all image types, then we shouldn't split by timing.
     requests = [test_utils.MakeRequest(0, 'null', 100, 110, 110),
                 test_utils.MakeRequest(1, 0, 115, 120, 120),
@@ -117,6 +123,8 @@
     for r in requests:
       r.response_headers['Content-Type'] = 'image/gif'
     g = self._GraphFromRequests(requests)
+    if serialize:
+      g = self._SerializeDeserialize(g)
     self.assertSetEqual(self._Successors(g, requests[0]),
                         set([requests[1], requests[2], requests[3]]))
     self.assertSetEqual(self._Successors(g, requests[1]), set())
@@ -126,6 +134,19 @@
     self.assertSetEqual(self._Successors(g, requests[4]), set())
     self.assertSetEqual(self._Successors(g, requests[5]), set())
 
+  def testSerializeDeserialize(self):
+    # Redo the tests, with a graph that has been serialized / deserialized.
+    self.testUpdateRequestCost(True)
+    self.testCost(True)
+    self.testHandleTimingDependencies(True)
+    self.testHandleTimingDependenciesImages(True)
+
+  @classmethod
+  def _SerializeDeserialize(cls, g):
+    json_dict = g.ToJsonDict()
+    return dependency_graph.RequestDependencyGraph.FromJsonDict(
+        json_dict, dependency_graph.RequestNode, dependency_graph.Edge)
+
   @classmethod
   def _GraphFromRequests(cls, requests):
     trace = test_utils.LoadingTraceFromEvents(requests)
diff --git a/tools/android/loading/gce/main.py b/tools/android/loading/gce/main.py
index 86d24a64..c20f0ae 100644
--- a/tools/android/loading/gce/main.py
+++ b/tools/android/loading/gce/main.py
@@ -8,11 +8,22 @@
 import threading
 import time
 import subprocess
+import sys
 
 from gcloud import storage
 from gcloud.exceptions import NotFound
 from oauth2client.client import GoogleCredentials
 
+# NOTE: The parent directory needs to be first in sys.path to avoid conflicts
+# with catapult modules that have colliding names, as catapult inserts itself
+# into the path as the second element. This is an ugly and fragile hack.
+sys.path.insert(0,
+    os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir))
+import controller
+import loading_trace
+import options
+
+
 class ServerApp(object):
   """Simple web server application, collecting traces and writing them in
   Google Cloud Storage.
@@ -45,9 +56,11 @@
          if not self._base_path_in_bucket.endswith('/'):
            self._base_path_in_bucket += '/'
 
-       self._chrome_path = config['chrome_path']
        self._src_path = config['src_path']
 
+    # Initialize the global options that will be used during trace generation.
+    options.OPTIONS.ParseArgs([])
+    options.OPTIONS.local_binary = config['chrome_path']
 
   def _GetStorageClient(self):
     return storage.Client(project = self._project_name,
@@ -91,8 +104,7 @@
 
   def _GenerateTrace(self, url, emulate_device, emulate_network, filename,
                      log_filename):
-    """ Generates a trace using analyze.py
-    Runs on _thread.
+    """ Generates a trace on _thread.
 
     Args:
       url: URL as a string.
@@ -108,18 +120,43 @@
       os.remove(filename)  # Remove any existing trace for this URL.
     except OSError:
       pass  # Nothing to remove.
-    analyze_path = self._src_path + '/tools/android/loading/analyze.py'
-    command_line = ['python', analyze_path, 'log_requests', '--local_noisy',
-        '--clear_cache', '--local', '--headless', '--local_binary',
-        self._chrome_path, '--url', url, '--output', filename]
-    if len(emulate_device):
-      command_line += ['--emulate_device', emulate_device]
-    if len(emulate_network):
-      command_line += ['--emulate_network', emulate_network]
-    with open(log_filename, 'w') as log_file:
-      ret = subprocess.call(command_line , stderr = subprocess.STDOUT,
-                            stdout = log_file)
-    return ret == 0
+
+    if not url.startswith('http') and not url.startswith('file'):
+      url = 'http://' + url
+
+    old_stdout = sys.stdout
+    old_stderr = sys.stderr
+
+    succeeded = True
+    try:
+      with open(log_filename, 'w') as sys.stdout:
+        sys.stderr = sys.stdout
+
+        # Set up the controller.
+        chrome_ctl = controller.LocalChromeController()
+        chrome_ctl.SetHeadless(True)
+        if emulate_device:
+          chrome_ctl.SetDeviceEmulation(emulate_device)
+        if emulate_network:
+          chrome_ctl.SetNetworkEmulation(emulate_network)
+
+        # Record and write the trace.
+        with chrome_ctl.OpenWithRedirection(sys.stdout,
+                                            sys.stderr) as connection:
+          connection.ClearCache()
+          trace = loading_trace.LoadingTrace.RecordUrlNavigation(
+              url, connection, chrome_ctl.ChromeMetadata())
+    except Exception as e:
+      succeeded = False
+      sys.stderr.write(e)
+
+    sys.stdout = old_stdout
+    sys.stderr = old_stderr
+
+    with open(filename, 'w') as f:
+      json.dump(trace.ToJsonDict(), f, sort_keys=True, indent=2)
+
+    return succeeded
 
   def _GetCurrentTaskCount(self):
     """Returns the number of remaining tasks. Thread safe."""
@@ -129,9 +166,8 @@
     return task_count
 
   def _ProcessTasks(self, tasks, repeat_count, emulate_device, emulate_network):
-    """Iterates over _tasks and runs analyze.py on each of them. Uploads the
-    resulting traces to Google Cloud Storage.
-    Runs on _thread.
+    """Iterates over _task, generating a trace for each of them. Uploads the
+    resulting traces to Google Cloud Storage.  Runs on _thread.
 
     Args:
       tasks: The list of URLs to process.
@@ -146,6 +182,8 @@
     self._tasks_lock.release()
     failures_dir = self._base_path_in_bucket + 'failures/'
     traces_dir = self._base_path_in_bucket + 'traces/'
+
+    # TODO(blundell): Fix this up.
     logs_dir = self._base_path_in_bucket + 'analyze_logs/'
     log_filename = 'analyze.log'
     # Avoid special characters in storage object names
@@ -161,13 +199,13 @@
           print 'Uploading: %s' % remote_filename
           self._UploadFile(local_filename, traces_dir + remote_filename)
         else:
-          print 'analyze.py failed for URL: %s' % url
+          print 'Trace generation failed for URL: %s' % url
           self._tasks_lock.acquire()
           self._failed_tasks.append({ "url": url, "repeat": repeat})
           self._tasks_lock.release()
           if os.path.isfile(local_filename):
             self._UploadFile(local_filename, failures_dir + remote_filename)
-        print 'Uploading analyze log'
+        print 'Uploading log'
         self._UploadFile(log_filename, logs_dir + remote_filename)
       # Pop once task is finished, for accurate status tracking.
       self._tasks_lock.acquire()
diff --git a/tools/android/loading/graph.py b/tools/android/loading/graph.py
index d051d58..7c2d275 100644
--- a/tools/android/loading/graph.py
+++ b/tools/android/loading/graph.py
@@ -6,6 +6,8 @@
 
 import collections
 
+import common_util
+
 
 class Node(object):
   """A node in a Graph.
@@ -16,6 +18,14 @@
     """Create a new node."""
     self.cost = 0
 
+  def ToJsonDict(self):
+    return common_util.SerializeAttributesToJsonDict({}, self, ['cost'])
+
+  @classmethod
+  def FromJsonDict(cls, json_dict):
+    return common_util.DeserializeAttributesFromJsonDict(
+        json_dict, cls(), ['cost'])
+
 
 class Edge(object):
   """Represents an edge in a graph."""
@@ -30,6 +40,16 @@
     self.to_node = to_node
     self.cost = 0
 
+  def ToJsonDict(self):
+    return common_util.SerializeAttributesToJsonDict(
+        {}, self, ['from_node', 'to_node', 'cost'])
+
+  @classmethod
+  def FromJsonDict(cls, json_dict):
+    result = cls(None, None)
+    return common_util.DeserializeAttributesFromJsonDict(
+        json_dict, result, ['from_node', 'to_node', 'cost'])
+
 
 class DirectedGraph(object):
   """Directed graph.
@@ -37,6 +57,10 @@
   A graph is identified by a list of nodes and a list of edges. It does not need
   to be acyclic, but then some methods will fail.
   """
+  __GRAPH_NODE_INDEX = '__graph_node_index'
+  __TO_NODE_INDEX = '__to_node_index'
+  __FROM_NODE_INDEX = '__from_node_index'
+
   def __init__(self, nodes, edges):
     """Builds a graph from a set of node and edges.
 
@@ -185,3 +209,40 @@
             else costliest_node, predecessors)
         path_list.insert(0, node)
     return max_cost
+
+  def ToJsonDict(self):
+    node_dicts = []
+    node_to_index = {node: index for (index, node) in enumerate(self._nodes)}
+    for (node, index) in node_to_index.items():
+      node_dict = node.ToJsonDict()
+      assert self.__GRAPH_NODE_INDEX not in node_dict
+      node_dict.update({self.__GRAPH_NODE_INDEX: index})
+      node_dicts.append(node_dict)
+    edge_dicts = []
+    for edge in self._edges:
+      edge_dict = edge.ToJsonDict()
+      assert self.__TO_NODE_INDEX not in edge_dict
+      assert self.__FROM_NODE_INDEX not in edge_dict
+      edge_dict.update({self.__TO_NODE_INDEX: node_to_index[edge.to_node],
+                        self.__FROM_NODE_INDEX: node_to_index[edge.from_node]})
+      edge_dicts.append(edge_dict)
+    return {'nodes': node_dicts, 'edges': edge_dicts}
+
+  @classmethod
+  def FromJsonDict(cls, json_dict, node_class, edge_class):
+    """Returns an instance from a dict.
+
+    Note that the classes of the nodes and edges need to be specified here.
+    This is done to reduce the likelihood of error.
+    """
+    index_to_node = {
+        node_dict[cls.__GRAPH_NODE_INDEX]: node_class.FromJsonDict(node_dict)
+        for node_dict in json_dict['nodes']}
+    edges = []
+    for edge_dict in json_dict['edges']:
+      edge = edge_class.FromJsonDict(edge_dict)
+      edge.from_node = index_to_node[edge_dict[cls.__FROM_NODE_INDEX]]
+      edge.to_node = index_to_node[edge_dict[cls.__TO_NODE_INDEX]]
+      edges.append(edge)
+    result = DirectedGraph(index_to_node.values(), edges)
+    return result
diff --git a/tools/android/loading/graph_unittest.py b/tools/android/loading/graph_unittest.py
index e8ef761b..e0e5f5b9 100644
--- a/tools/android/loading/graph_unittest.py
+++ b/tools/android/loading/graph_unittest.py
@@ -7,42 +7,61 @@
 import sys
 import unittest
 
+import common_util
 import graph
 
 
 class _IndexedNode(graph.Node):
-  def __init__(self, index):
+  def __init__(self, index=None):
     super(_IndexedNode, self).__init__()
     self.index = index
 
+  def ToJsonDict(self):
+    return common_util.SerializeAttributesToJsonDict(
+        super(_IndexedNode, self).ToJsonDict(), self, ['index'])
+
+  @classmethod
+  def FromJsonDict(cls, json_dict):
+    result = super(_IndexedNode, cls).FromJsonDict(json_dict)
+    return common_util.DeserializeAttributesFromJsonDict(
+        json_dict, result, ['index'])
+
 
 class GraphTestCase(unittest.TestCase):
   @classmethod
-  def MakeGraph(cls, count, edge_tuples):
+  def MakeGraph(cls, count, edge_tuples, serialize=False):
     """Makes a graph from a list of edges.
 
     Args:
       count: Number of nodes.
       edge_tuples: (from_index, to_index). Both indices must be in [0, count),
-                   and uniquely identify a node.
+                   and uniquely identify a node. Must be sorted
+                   lexicographically by node indices.
     """
     nodes = [_IndexedNode(i) for i in xrange(count)]
     edges = [graph.Edge(nodes[from_index], nodes[to_index])
              for (from_index, to_index) in edge_tuples]
-    return (nodes, edges, graph.DirectedGraph(nodes, edges))
+    g = graph.DirectedGraph(nodes, edges)
+    if serialize:
+      g = graph.DirectedGraph.FromJsonDict(
+          g.ToJsonDict(), _IndexedNode, graph.Edge)
+      nodes = sorted(g.Nodes(), key=operator.attrgetter('index'))
+      edges = sorted(g.Edges(), key=operator.attrgetter(
+          'from_node.index', 'to_node.index'))
+    return (nodes, edges, g)
 
   @classmethod
   def _NodesIndices(cls, g):
     return map(operator.attrgetter('index'), g.Nodes())
 
-  def testBuildGraph(self):
+  def testBuildGraph(self, serialize=False):
     (nodes, edges, g) = self.MakeGraph(
         7,
         [(0, 1),
          (0, 2),
          (1, 3),
          (3, 4),
-         (5, 6)])
+         (5, 6)], serialize)
     self.assertListEqual(range(7), sorted(self._NodesIndices(g)))
     self.assertSetEqual(set(edges), set(g.Edges()))
 
@@ -72,14 +91,14 @@
     self.assertListEqual(range(7), sorted(self._NodesIndices(g)))
     self.assertEqual(5, len(g.Edges()))
 
-  def testUpdateEdge(self):
+  def testUpdateEdge(self, serialize=False):
     (nodes, edges, g) = self.MakeGraph(
         7,
         [(0, 1),
          (0, 2),
          (1, 3),
          (3, 4),
-         (5, 6)])
+         (5, 6)], serialize)
     edge = edges[1]
     self.assertTrue(edge in g.OutEdges(nodes[0]))
     self.assertTrue(edge in g.InEdges(nodes[2]))
@@ -89,28 +108,28 @@
     self.assertTrue(edge in g.OutEdges(nodes[2]))
     self.assertTrue(edge in g.InEdges(nodes[3]))
 
-  def testTopologicalSort(self):
+  def testTopologicalSort(self, serialize=False):
     (_, edges, g) = self.MakeGraph(
         7,
         [(0, 1),
          (0, 2),
          (1, 3),
          (3, 4),
-         (5, 6)])
+         (5, 6)], serialize)
     sorted_nodes = g.TopologicalSort()
     node_to_sorted_index = dict(zip(sorted_nodes, xrange(len(sorted_nodes))))
     for e in edges:
       self.assertTrue(
           node_to_sorted_index[e.from_node] < node_to_sorted_index[e.to_node])
 
-  def testReachableNodes(self):
+  def testReachableNodes(self, serialize=False):
     (nodes, _, g) = self.MakeGraph(
         7,
         [(0, 1),
          (0, 2),
          (1, 3),
          (3, 4),
-         (5, 6)])
+         (5, 6)], serialize)
     self.assertSetEqual(
         set([0, 1, 2, 3, 4]),
         set(n.index for n in g.ReachableNodes([nodes[0]])))
@@ -124,14 +143,14 @@
         set([6]),
         set(n.index for n in g.ReachableNodes([nodes[6]])))
 
-  def testCost(self):
+  def testCost(self, serialize=False):
     (nodes, edges, g) = self.MakeGraph(
         7,
         [(0, 1),
          (0, 2),
          (1, 3),
          (3, 4),
-         (5, 6)])
+         (5, 6)], serialize)
     for (i, node) in enumerate(nodes):
       node.cost = i + 1
     nodes[6].cost = 6
@@ -146,14 +165,14 @@
     g.Cost(path_list=path_list)
     self.assertListEqual([nodes[i] for i in (5, 6)], path_list)
 
-  def testCostWithRoots(self):
+  def testCostWithRoots(self, serialize=False):
     (nodes, edges, g) = self.MakeGraph(
         7,
         [(0, 1),
          (0, 2),
          (1, 3),
          (3, 4),
-         (5, 6)])
+         (5, 6)], serialize)
     for (i, node) in enumerate(nodes):
       node.cost = i + 1
     nodes[6].cost = 9
@@ -165,6 +184,15 @@
     self.assertEqual(15, g.Cost(roots=[nodes[0]], path_list=path_list))
     self.assertListEqual([nodes[i] for i in (0, 1, 3, 4)], path_list)
 
+  def testSerialize(self):
+    # Re-do tests with a deserialized graph.
+    self.testBuildGraph(True)
+    self.testUpdateEdge(True)
+    self.testTopologicalSort(True)
+    self.testReachableNodes(True)
+    self.testCost(True)
+    self.testCostWithRoots(True)
+
 
 if __name__ == '__main__':
   unittest.main()
diff --git a/tools/android/loading/prefetch_view.py b/tools/android/loading/prefetch_view.py
index 8a172bd..85dd48d 100644
--- a/tools/android/loading/prefetch_view.py
+++ b/tools/android/loading/prefetch_view.py
@@ -8,47 +8,103 @@
 (https://goo.gl/B3nRUR).
 
 When executed as a script, takes a trace as a command-line arguments and shows
-how many requests were prefetched.
+statistics about it.
 """
 
 import itertools
 import operator
 
+import common_util
 import dependency_graph
+import graph
 import loading_trace
 import user_satisfied_lens
 import request_dependencies_lens
 import request_track
 
 
-class PrefetchSimulationView(object):
+class RequestNode(dependency_graph.RequestNode):
   """Simulates the effect of prefetching resources discoverable by the preload
   scanner.
   """
+  _ATTRS = ['preloaded', 'before']
+  def __init__(self, request=None):
+    super(RequestNode, self).__init__(request)
+    self.preloaded = False
+    self.before = False
+
+  def ToJsonDict(self):
+    result = super(RequestNode, self).ToJsonDict()
+    return common_util.SerializeAttributesToJsonDict(result, self, self._ATTRS)
+
+  @classmethod
+  def FromJsonDict(cls, json_dict):
+    result = super(RequestNode, cls).FromJsonDict(json_dict)
+    return common_util.DeserializeAttributesFromJsonDict(
+        json_dict, result, cls._ATTRS)
+
+
+class PrefetchSimulationView(object):
+  """Simulates the effect of prefetch."""
   def __init__(self, trace, dependencies_lens, user_lens):
-    """Initializes an instance of PrefetchSimulationView.
+    self.postload_msec = None
+    self.graph = None
+    if trace is None:
+      return
+    requests = trace.request_track.GetEvents()
+    critical_requests_ids = user_lens.CriticalRequests()
+    self.postload_msec = user_lens.PostloadTimeMsec()
+    self.graph = dependency_graph.RequestDependencyGraph(
+        requests, dependencies_lens, node_class=RequestNode)
+    preloaded_requests = [r.request_id for r in self._PreloadedRequests(
+        requests[0], dependencies_lens, trace)]
+    self._AnnotateNodes(self.graph.graph.Nodes(), preloaded_requests,
+                        critical_requests_ids)
+
+  def Cost(self):
+    """Returns the cost of the graph, restricted to the critical requests."""
+    pruned_graph = self._PrunedGraph()
+    return pruned_graph.Cost() + self.postload_msec
+
+  def UpdateNodeCosts(self, node_to_cost):
+    """Updates the cost of nodes, according to |node_to_cost|.
 
     Args:
-      trace: (LoadingTrace) a loading trace.
-      dependencies_lens: (RequestDependencyLens) request dependencies.
-      user_lens: (UserSatisfiedLens) Lens used to compute costs.
+      node_to_cost: (Callable) RequestNode -> float. Callable returning the cost
+                    of a node.
     """
-    self.trace = trace
-    self.dependencies_lens = dependencies_lens
-    self._resource_events = self.trace.tracing_track.Filter(
-        categories=set([u'blink.net']))
-    assert len(self._resource_events.GetEvents()) > 0,\
-            'Was the "blink.net" category enabled at trace collection time?"'
-    self._user_lens = user_lens
-    request_ids = self._user_lens.CriticalRequests()
-    all_requests = self.trace.request_track.GetEvents()
-    self._first_request_node = all_requests[0].request_id
-    requests = [r for r in all_requests if r.request_id in request_ids]
-    self.graph = dependency_graph.RequestDependencyGraph(
-        requests, self.dependencies_lens)
+    pruned_graph = self._PrunedGraph()
+    for node in pruned_graph.Nodes():
+      node.cost = node_to_cost(node)
 
-  def ParserDiscoverableRequests(self, request, recurse=False):
-    """Returns a list of requests discovered by the parser from a given request.
+  def ToJsonDict(self):
+    """Returns a dict representing this instance."""
+    result = {'graph': self.graph.ToJsonDict()}
+    return common_util.SerializeAttributesToJsonDict(
+        result, self, ['postload_msec'])
+
+  @classmethod
+  def FromJsonDict(cls, json_dict):
+    """Returns an instance of PrefetchSimulationView from a dict dumped by
+    ToJSonDict().
+    """
+    result = cls(None, None, None)
+    result.graph = dependency_graph.RequestDependencyGraph.FromJsonDict(
+        json_dict['graph'], RequestNode, dependency_graph.Edge)
+    return common_util.DeserializeAttributesFromJsonDict(
+        json_dict, result, ['postload_msec'])
+
+  @classmethod
+  def _AnnotateNodes(cls, nodes, preloaded_requests_ids,
+                     critical_requests_ids,):
+    for node in nodes:
+      node.preloaded = node.request.request_id in preloaded_requests_ids
+      node.before = node.request.request_id in critical_requests_ids
+
+  @classmethod
+  def _ParserDiscoverableRequests(
+      cls, dependencies_lens, request, recurse=False):
+    """Returns a list of requests IDs dicovered by the parser.
 
     Args:
       request: (Request) Root request.
@@ -59,18 +115,20 @@
     # TODO(lizeb): handle the recursive case.
     assert not recurse
     discoverable_requests = [request]
-    first_request = self.dependencies_lens.GetRedirectChain(request)[-1]
-    deps = self.dependencies_lens.GetRequestDependencies()
+    first_request = dependencies_lens.GetRedirectChain(request)[-1]
+    deps = dependencies_lens.GetRequestDependencies()
     for (first, second, reason) in deps:
       if first.request_id == first_request.request_id and reason == 'parser':
         discoverable_requests.append(second)
     return discoverable_requests
 
-  def ExpandRedirectChains(self, requests):
+  @classmethod
+  def _ExpandRedirectChains(cls, requests, dependencies_lens):
     return list(itertools.chain.from_iterable(
-        [self.dependencies_lens.GetRedirectChain(r) for r in requests]))
+        [dependencies_lens.GetRedirectChain(r) for r in requests]))
 
-  def PreloadedRequests(self, request):
+  @classmethod
+  def _PreloadedRequests(cls, request, dependencies_lens, trace):
     """Returns the requests that have been preloaded from a given request.
 
     This list is the set of request that are:
@@ -84,51 +142,48 @@
 
     Returns:
       A list of Request. Does not include the root request. This list is a
-      subset of the one returned by ParserDiscoverableRequests().
+      subset of the one returned by _ParserDiscoverableRequests().
     """
     # Preload step events are emitted in ResourceFetcher::preloadStarted().
+    resource_events = trace.tracing_track.Filter(
+        categories=set([u'blink.net']))
     preload_step_events = filter(
         lambda e:  e.args.get('step') == 'Preload',
-        self._resource_events.GetEvents())
+        resource_events.GetEvents())
     preloaded_urls = set()
     for preload_step_event in preload_step_events:
-      preload_event = self._resource_events.EventFromStep(preload_step_event)
+      preload_event = resource_events.EventFromStep(preload_step_event)
       if preload_event:
         preloaded_urls.add(preload_event.args['url'])
-    parser_requests = self.ParserDiscoverableRequests(request)
+    parser_requests = cls._ParserDiscoverableRequests(
+        dependencies_lens, request)
     preloaded_root_requests = filter(
         lambda r: r.url in preloaded_urls, parser_requests)
     # We can actually fetch the whole redirect chain.
     return [request] + list(itertools.chain.from_iterable(
-        [self.dependencies_lens.GetRedirectChain(r)
+        [dependencies_lens.GetRedirectChain(r)
          for r in preloaded_root_requests]))
 
+  def _PrunedGraph(self):
+    roots = self.graph.graph.RootNodes()
+    nodes = self.graph.graph.ReachableNodes(
+        roots, should_stop=lambda n: not n.before)
+    return graph.DirectedGraph(nodes, self.graph.graph.Edges())
 
-def _PrintSummary(prefetch_view, user_lens):
-  requests = prefetch_view.trace.request_track.GetEvents()
-  first_request = prefetch_view.trace.request_track.GetEvents()[0]
-  parser_requests = prefetch_view.ExpandRedirectChains(
-      prefetch_view.ParserDiscoverableRequests(first_request))
-  preloaded_requests = prefetch_view.ExpandRedirectChains(
-      prefetch_view.PreloadedRequests(first_request))
-  print '%d requests, %d parser from the main request, %d preloaded' % (
-      len(requests), len(parser_requests), len(preloaded_requests))
-  print 'Time to user satisfaction: %.02fms' % (
-      prefetch_view.graph.Cost() + user_lens.PostloadTimeMsec())
 
-  print 'With 0-cost prefetched resources...'
-  new_costs = {r.request_id: 0. for r in preloaded_requests}
-  prefetch_view.graph.UpdateRequestsCost(new_costs)
-  print 'Time to user satisfaction: %.02fms' % (
-      prefetch_view.graph.Cost() + user_lens.PostloadTimeMsec())
+def _PrintSumamry(trace, dependencies_lens, user_lens):
+  prefetch_view = PrefetchSimulationView(trace, dependencies_lens, user_lens)
+  print 'Time to First Contentful Paint = %.02fms' % prefetch_view.Cost()
+  print 'Set costs of prefetched requests to 0.'
+  prefetch_view.UpdateNodeCosts(lambda n: 0 if n.preloaded else n.cost)
+  print 'Time to First Contentful Paint = %.02fms' % prefetch_view.Cost()
 
 
 def main(filename):
   trace = loading_trace.LoadingTrace.FromJsonFile(filename)
   dependencies_lens = request_dependencies_lens.RequestDependencyLens(trace)
   user_lens = user_satisfied_lens.FirstContentfulPaintLens(trace)
-  prefetch_view = PrefetchSimulationView(trace, dependencies_lens, user_lens)
-  _PrintSummary(prefetch_view, user_lens)
+  _PrintSumamry(trace, dependencies_lens, user_lens)
 
 
 if __name__ == '__main__':
diff --git a/tools/android/loading/prefetch_view_unittest.py b/tools/android/loading/prefetch_view_unittest.py
index ca8897d2..e222bf5 100644
--- a/tools/android/loading/prefetch_view_unittest.py
+++ b/tools/android/loading/prefetch_view_unittest.py
@@ -4,7 +4,7 @@
 
 import unittest
 
-import prefetch_view
+from prefetch_view import PrefetchSimulationView
 import request_dependencies_lens
 from request_dependencies_lens_unittest import TestRequests
 import request_track
@@ -20,13 +20,13 @@
     self.assertListEqual(
         [TestRequests.FIRST_REDIRECT_REQUEST,
          TestRequests.SECOND_REDIRECT_REQUEST, TestRequests.REDIRECTED_REQUEST],
-        self.prefetch_view.ExpandRedirectChains(
-            [TestRequests.FIRST_REDIRECT_REQUEST]))
+        PrefetchSimulationView._ExpandRedirectChains(
+            [TestRequests.FIRST_REDIRECT_REQUEST], self.dependencies_lens))
 
   def testParserDiscoverableRequests(self):
     first_request = TestRequests.FIRST_REDIRECT_REQUEST
-    discovered_requests = self.prefetch_view.ParserDiscoverableRequests(
-        first_request)
+    discovered_requests = PrefetchSimulationView._ParserDiscoverableRequests(
+        self.dependencies_lens, first_request)
     self.assertListEqual(
         [TestRequests.FIRST_REDIRECT_REQUEST,
          TestRequests.JS_REQUEST, TestRequests.JS_REQUEST_OTHER_FRAME,
@@ -34,7 +34,8 @@
 
   def testPreloadedRequests(self):
     first_request = TestRequests.FIRST_REDIRECT_REQUEST
-    preloaded_requests = self.prefetch_view.PreloadedRequests(first_request)
+    preloaded_requests = PrefetchSimulationView._PreloadedRequests(
+        first_request, self.dependencies_lens, self.trace)
     self.assertListEqual([first_request], preloaded_requests)
     self._SetUp(
         [{'args': {'url': 'http://bla.com/nyancat.js'},
@@ -43,22 +44,51 @@
          {'args': {'step': 'Preload'}, 'cat': 'blink.net',
           'id': '0xaf9f14fa9dd6c314', 'name': 'Resource', 'ph': 'T',
           'ts': 12, 'pid': 12, 'tid': 12}])
-    preloaded_requests = self.prefetch_view.PreloadedRequests(first_request)
+    preloaded_requests = PrefetchSimulationView._PreloadedRequests(
+        first_request, self.dependencies_lens, self.trace)
     self.assertListEqual([TestRequests.FIRST_REDIRECT_REQUEST,
          TestRequests.JS_REQUEST, TestRequests.JS_REQUEST_OTHER_FRAME,
          TestRequests.JS_REQUEST_UNRELATED_FRAME], preloaded_requests)
 
+  def testCost(self):
+    self.assertEqual(40 + 12, self.prefetch_view.Cost())
+
+  def testUpdateNodeCosts(self):
+    self.prefetch_view.UpdateNodeCosts(lambda _: 100)
+    self.assertEqual(500 + 40 + 12, self.prefetch_view.Cost())
+
+  def testUpdateNodeCostsPartial(self):
+    self.prefetch_view.UpdateNodeCosts(
+        lambda n: 100 if (n.request.request_id
+                          == TestRequests.REDIRECTED_REQUEST.request_id) else 0)
+    self.assertEqual(100 + 40 + 12, self.prefetch_view.Cost())
+
+  def testToFromJsonDict(self):
+    self.assertEqual(40 + 12, self.prefetch_view.Cost())
+    json_dict = self.prefetch_view.ToJsonDict()
+    new_view = PrefetchSimulationView.FromJsonDict(json_dict)
+    self.assertEqual(40 + 12, new_view.Cost())
+    # Updated Costs.
+    self.prefetch_view.UpdateNodeCosts(lambda _: 100)
+    self.assertEqual(500 + 40 + 12, self.prefetch_view.Cost())
+    json_dict = self.prefetch_view.ToJsonDict()
+    new_view = PrefetchSimulationView.FromJsonDict(json_dict)
+    self.assertEqual(500 + 40 + 12, new_view.Cost())
+
   def _SetUp(self, added_trace_events=None):
     trace_events = [
         {'ts': 5, 'ph': 'X', 'dur': 10, 'pid': 2, 'tid': 1, 'cat': 'blink.net'}]
     if added_trace_events is not None:
       trace_events += added_trace_events
     self.trace = TestRequests.CreateLoadingTrace(trace_events)
-    dependencies_lens = request_dependencies_lens.RequestDependencyLens(
+    self.dependencies_lens = request_dependencies_lens.RequestDependencyLens(
         self.trace)
     self.user_satisfied_lens = test_utils.MockUserSatisfiedLens(self.trace)
-    self.prefetch_view = prefetch_view.PrefetchSimulationView(
-        self.trace, dependencies_lens, self.user_satisfied_lens)
+    self.user_satisfied_lens._postload_msec = 12
+    self.prefetch_view = PrefetchSimulationView(
+        self.trace, self.dependencies_lens, self.user_satisfied_lens)
+    for e in self.prefetch_view.graph.graph.Edges():
+      e.cost = 10
 
 
 if __name__ == '__main__':
diff --git a/tools/android/loading/user_satisfied_lens.py b/tools/android/loading/user_satisfied_lens.py
index 0115f8cd..89ce7a1 100644
--- a/tools/android/loading/user_satisfied_lens.py
+++ b/tools/android/loading/user_satisfied_lens.py
@@ -10,6 +10,8 @@
 import logging
 import operator
 
+import common_util
+
 
 class _UserSatisfiedLens(object):
   """A base class for all user satisfaction metrics.
@@ -19,6 +21,9 @@
   event. Subclasses need only provide the time computation. The base class will
   use that to construct the request ids.
   """
+  _ATTRS = ['_satisfied_msec', '_event_msec', '_postload_msec',
+            '_critical_request_ids']
+
   def __init__(self, trace):
     """Initialize the lens.
 
@@ -27,6 +32,10 @@
     """
     self._satisfied_msec = None
     self._event_msec = None
+    self._postload_msec = None
+    self._critical_request_ids = None
+    if trace is None:
+      return
     self._CalculateTimes(trace.tracing_track)
     critical_requests = self._RequestsBefore(
         trace.request_track, self._satisfied_msec)
@@ -57,6 +66,15 @@
     """
     return self._postload_msec
 
+  def ToJsonDict(self):
+    return common_util.SerializeAttributesToJsonDict({}, self, self._ATTRS)
+
+  @classmethod
+  def FromJsonDict(cls, json_dict):
+    result = cls(None)
+    return common_util.DeserializeAttributesFromJsonDict(
+        json_dict, result, cls._ATTRS)
+
   def _CalculateTimes(self, tracing_track):
     """Subclasses should implement to set _satisfied_msec and _event_msec."""
     raise NotImplementedError
diff --git a/tools/clang/plugins/CMakeLists.txt b/tools/clang/plugins/CMakeLists.txt
index 04de853e..6be8b2eb 100644
--- a/tools/clang/plugins/CMakeLists.txt
+++ b/tools/clang/plugins/CMakeLists.txt
@@ -1,7 +1,8 @@
 set(plugin_sources
   ChromeClassTester.cpp
   FindBadConstructsAction.cpp
-  FindBadConstructsConsumer.cpp)
+  FindBadConstructsConsumer.cpp
+  CheckIPCVisitor.cpp)
 
 if(WIN32)
   # Clang doesn't support loadable modules on Windows. Unfortunately, building
diff --git a/tools/clang/plugins/CheckIPCVisitor.cpp b/tools/clang/plugins/CheckIPCVisitor.cpp
new file mode 100644
index 0000000..b123b01
--- /dev/null
+++ b/tools/clang/plugins/CheckIPCVisitor.cpp
@@ -0,0 +1,288 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "CheckIPCVisitor.h"
+
+using namespace clang;
+
+namespace chrome_checker {
+
+namespace {
+
+const char kWriteParamBadType[] =
+    "[chromium-ipc] IPC::WriteParam() is called on blacklisted type '%0'%1.";
+
+const char kTupleBadType[] =
+    "[chromium-ipc] IPC tuple references banned type '%0'%1.";
+
+const char kWriteParamBadSignature[] =
+    "[chromium-ipc] IPC::WriteParam() is expected to have two arguments.";
+
+const char kNoteSeeHere[] =
+    "see here";
+
+}  // namespace
+
+CheckIPCVisitor::CheckIPCVisitor(CompilerInstance& compiler)
+  : compiler_(compiler), context_(nullptr) {
+  auto& diagnostics = compiler_.getDiagnostics();
+  error_write_param_bad_type_ = diagnostics.getCustomDiagID(
+      DiagnosticsEngine::Error, kWriteParamBadType);
+  error_tuple_bad_type_ = diagnostics.getCustomDiagID(
+      DiagnosticsEngine::Error, kTupleBadType);
+  error_write_param_bad_signature_ = diagnostics.getCustomDiagID(
+      DiagnosticsEngine::Error, kWriteParamBadSignature);
+  note_see_here_ = diagnostics.getCustomDiagID(
+      DiagnosticsEngine::Note, kNoteSeeHere);
+
+  blacklisted_typedefs_ = llvm::StringSet<>({
+      "intmax_t",
+      "uintmax_t",
+      "intptr_t",
+      "uintptr_t",
+      "wint_t",
+      "size_t",
+      "rsize_t",
+      "ssize_t",
+      "ptrdiff_t",
+      "dev_t",
+      "off_t",
+      "clock_t",
+      "time_t",
+      "suseconds_t"
+  });
+}
+
+void CheckIPCVisitor::BeginDecl(Decl* decl) {
+  decl_stack_.push_back(decl);
+}
+
+void CheckIPCVisitor::EndDecl() {
+  decl_stack_.pop_back();
+}
+
+void CheckIPCVisitor::VisitTemplateSpecializationType(
+    TemplateSpecializationType* spec) {
+  ValidateCheckedTuple(spec);
+}
+
+void CheckIPCVisitor::VisitCallExpr(CallExpr* call_expr) {
+  ValidateWriteParam(call_expr);
+}
+
+bool CheckIPCVisitor::ValidateWriteParam(const CallExpr* call_expr) {
+  const FunctionDecl* callee_decl = call_expr->getDirectCallee();
+  if (!callee_decl ||
+      callee_decl->getQualifiedNameAsString() != "IPC::WriteParam") {
+    return true;
+  }
+
+  return ValidateWriteParamSignature(call_expr) &&
+      ValidateWriteParamArgument(call_expr->getArg(1));
+}
+
+// Checks that IPC::WriteParam() has expected signature.
+bool CheckIPCVisitor::ValidateWriteParamSignature(
+    const CallExpr* call_expr) {
+  if (call_expr->getNumArgs() != 2) {
+    compiler_.getDiagnostics().Report(
+        call_expr->getExprLoc(), error_write_param_bad_signature_);
+    return false;
+  }
+  return true;
+}
+
+// Checks that IPC::WriteParam() argument type is allowed.
+// See CheckType() for specifics.
+bool CheckIPCVisitor::ValidateWriteParamArgument(const Expr* arg_expr) {
+  if (auto* parent_fn_decl = GetParentDecl<FunctionDecl>()) {
+    auto template_kind = parent_fn_decl->getTemplatedKind();
+    if (template_kind != FunctionDecl::TK_NonTemplate &&
+        template_kind != FunctionDecl::TK_FunctionTemplate) {
+      // Skip all specializations - we don't check WriteParam() on dependent
+      // types (typedef info gets lost), and we checked all non-dependent uses
+      // earlier (when we checked the template itself).
+      return true;
+    }
+  }
+
+  QualType arg_type;
+
+  arg_expr = arg_expr->IgnoreImplicit();
+  if (auto* cast_expr = dyn_cast<ExplicitCastExpr>(arg_expr)) {
+    arg_type = cast_expr->getTypeAsWritten();
+  } else {
+    arg_type = arg_expr->getType();
+  }
+
+  CheckDetails details;
+  if (CheckType(arg_type, &details)) {
+    return true;
+  }
+
+  ReportCheckError(details,
+                   arg_expr->getExprLoc(),
+                   error_write_param_bad_type_);
+
+  return false;
+}
+
+// Checks that IPC::CheckedTuple<> is specialized with allowed types.
+// See CheckType() above for specifics.
+bool CheckIPCVisitor::ValidateCheckedTuple(
+    const TemplateSpecializationType* spec) {
+  TemplateDecl* decl = spec->getTemplateName().getAsTemplateDecl();
+  if (!decl || decl->getQualifiedNameAsString() != "IPC::CheckedTuple") {
+    return true;
+  }
+
+  bool valid = true;
+  for (unsigned i = 0; i != spec->getNumArgs(); ++i) {
+    const TemplateArgument& arg = spec->getArg(i);
+    CheckDetails details;
+    if (CheckTemplateArgument(arg, &details)) {
+      continue;
+    }
+
+    valid = false;
+
+    auto* parent_decl = GetParentDecl<Decl>();
+    ReportCheckError(
+        details,
+        parent_decl ? parent_decl->getLocStart() : SourceLocation(),
+        error_tuple_bad_type_);
+  }
+
+  return valid;
+}
+
+template <typename T>
+const T* CheckIPCVisitor::GetParentDecl() const {
+  for (auto i = decl_stack_.rbegin(); i != decl_stack_.rend(); ++i) {
+    if (auto* parent = dyn_cast_or_null<T>(*i)) {
+      return parent;
+    }
+  }
+  return nullptr;
+}
+
+
+bool CheckIPCVisitor::IsBlacklistedType(QualType type) const {
+  return context_->hasSameUnqualifiedType(type, context_->LongTy) ||
+      context_->hasSameUnqualifiedType(type, context_->UnsignedLongTy);
+}
+
+bool CheckIPCVisitor::IsBlacklistedTypedef(const TypedefNameDecl* tdef) const {
+  return blacklisted_typedefs_.find(tdef->getName()) !=
+      blacklisted_typedefs_.end();
+}
+
+// Checks that integer type is allowed (not blacklisted).
+bool CheckIPCVisitor::CheckIntegerType(QualType type,
+                                       CheckDetails* details) const {
+  bool seen_typedef = false;
+  while (true) {
+    details->exit_type = type;
+
+    if (auto* tdef = dyn_cast<TypedefType>(type)) {
+      if (IsBlacklistedTypedef(tdef->getDecl())) {
+        return false;
+      }
+      details->typedefs.push_back(tdef);
+      seen_typedef = true;
+    }
+
+    QualType desugared_type =
+        type->getLocallyUnqualifiedSingleStepDesugaredType();
+    if (desugared_type == type) {
+      break;
+    }
+
+    type = desugared_type;
+  }
+
+  return seen_typedef || !IsBlacklistedType(type);
+}
+
+// Checks that |type| is allowed (not blacklisted), recursively visiting
+// template specializations.
+bool CheckIPCVisitor::CheckType(QualType type, CheckDetails* details) const {
+  if (type->isReferenceType()) {
+    type = type->getPointeeType();
+  }
+  type = type.getLocalUnqualifiedType();
+
+  if (details->entry_type.isNull()) {
+    details->entry_type = type;
+  }
+
+  if (type->isIntegerType()) {
+    return CheckIntegerType(type, details);
+  }
+
+  while (true) {
+    if (auto* spec = dyn_cast<TemplateSpecializationType>(type)) {
+      for (const TemplateArgument& arg: *spec) {
+        if (!CheckTemplateArgument(arg, details)) {
+          return false;
+        }
+      }
+      return true;
+    }
+
+    if (auto* record = dyn_cast<RecordType>(type)) {
+      if (auto* spec = dyn_cast<ClassTemplateSpecializationDecl>(
+              record->getDecl())) {
+        const TemplateArgumentList& args = spec->getTemplateArgs();
+        for (unsigned i = 0; i != args.size(); ++i) {
+          if (!CheckTemplateArgument(args[i], details)) {
+            return false;
+          }
+        }
+      }
+      return true;
+    }
+
+    if (auto* tdef = dyn_cast<TypedefType>(type)) {
+      details->typedefs.push_back(tdef);
+    }
+
+    QualType desugared_type =
+        type->getLocallyUnqualifiedSingleStepDesugaredType();
+    if (desugared_type == type) {
+      break;
+    }
+
+    type = desugared_type;
+  }
+
+  return true;
+}
+
+bool CheckIPCVisitor::CheckTemplateArgument(const TemplateArgument& arg,
+                                            CheckDetails* details) const {
+  return arg.getKind() != TemplateArgument::Type ||
+      CheckType(arg.getAsType(), details);
+}
+
+void CheckIPCVisitor::ReportCheckError(const CheckDetails& details,
+                                       SourceLocation loc,
+                                       unsigned error) {
+  DiagnosticsEngine& diagnostics = compiler_.getDiagnostics();
+
+  std::string entry_type = details.entry_type.getAsString();
+  std::string exit_type = details.exit_type.getAsString();
+
+  std::string via;
+  if (entry_type != exit_type) {
+    via = " via '" + entry_type + "'";
+  }
+  diagnostics.Report(loc, error) << exit_type << via;
+
+  for (const TypedefType* tdef: details.typedefs) {
+    diagnostics.Report(tdef->getDecl()->getLocation(), note_see_here_);
+  }
+}
+
+}  // namespace chrome_checker
diff --git a/tools/clang/plugins/CheckIPCVisitor.h b/tools/clang/plugins/CheckIPCVisitor.h
new file mode 100644
index 0000000..2d88e6b
--- /dev/null
+++ b/tools/clang/plugins/CheckIPCVisitor.h
@@ -0,0 +1,99 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This check ensures that 32/64-bit unstable types are not used in IPC.
+//
+// A type (or typedef) is unstable if it changes size between 32/ 64-bit
+// platforms. However, it's impossible to accurately identify unstable
+// typedefs, because their definitions rely on the preprocessor. For
+// example uintptr_t is either unsigned int or unsigned long.
+//
+// So we're not trying to be accurate, and just blacklisting some types
+// that are known to be unstable:
+// 1. Types: long / unsigned long (but not typedefs to)
+// 2. Typedefs: intmax_t, uintmax_t, intptr_t, uintptr_t, wint_t,
+//    size_t, rsize_t, ssize_t, ptrdiff_t, dev_t, off_t, clock_t,
+//    time_t, suseconds_t (including typedefs to)
+//
+// Additionally, templates referencing blacklisted types (e.g. vector<long>)
+// are also blacklisted.
+//
+// Blacklisted types are checked in:
+// 1. IPC::WriteParam() calls
+// 2. IPC::CheckedTuple<> specializations
+//
+
+#ifndef TOOLS_CLANG_PLUGINS_CHECKIPC_VISITOR_H_
+#define TOOLS_CLANG_PLUGINS_CHECKIPC_VISITOR_H_
+
+#include <vector>
+
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "llvm/ADT/StringSet.h"
+
+namespace chrome_checker {
+
+class CheckIPCVisitor {
+ public:
+  explicit CheckIPCVisitor(clang::CompilerInstance& compiler);
+
+  void set_context(clang::ASTContext* context) { context_ = context; }
+
+  void BeginDecl(clang::Decl* decl);
+  void EndDecl();
+  void VisitTemplateSpecializationType(
+      clang::TemplateSpecializationType* spec);
+  void VisitCallExpr(clang::CallExpr* call_expr);
+
+ private:
+  // ValidateXXX functions return false if validation failed and diagnostic
+  // was reported. They return true otherwise (not applicable / validation
+  // succeeded).
+
+  bool ValidateWriteParam(const clang::CallExpr* call_expr);
+  bool ValidateWriteParamSignature(const clang::CallExpr* call_expr);
+  bool ValidateWriteParamArgument(const clang::Expr* arg_expr);
+  bool ValidateCheckedTuple(
+      const clang::TemplateSpecializationType* spec);
+
+  template <typename T>
+  const T* GetParentDecl() const;
+
+  bool IsBlacklistedType(clang::QualType type) const;
+  bool IsBlacklistedTypedef(const clang::TypedefNameDecl* tdef) const;
+
+  struct CheckDetails {
+    clang::QualType entry_type;
+    clang::QualType exit_type;
+    llvm::SmallVector<const clang::TypedefType*, 5> typedefs;
+  };
+
+  bool CheckType(clang::QualType type, CheckDetails* details) const;
+  bool CheckIntegerType(clang::QualType type, CheckDetails* details) const;
+  bool CheckTemplateArgument(const clang::TemplateArgument& arg,
+                             CheckDetails* details) const;
+
+  void ReportCheckError(const CheckDetails& details,
+                        clang::SourceLocation loc,
+                        unsigned error);
+
+  clang::CompilerInstance& compiler_;
+  clang::ASTContext* context_;
+
+  unsigned error_write_param_bad_type_;
+  unsigned error_tuple_bad_type_;
+  unsigned error_write_param_bad_signature_;
+  unsigned note_see_here_;
+
+  std::vector<const clang::Decl*> decl_stack_;
+
+  llvm::StringSet<> blacklisted_typedefs_;
+};
+
+}  // namespace chrome_checker
+
+#endif  // TOOLS_CLANG_PLUGINS_CHECKIPC_VISITOR_H_
diff --git a/tools/clang/plugins/FindBadConstructsAction.cpp b/tools/clang/plugins/FindBadConstructsAction.cpp
index ad9fc55..f857ac2b 100644
--- a/tools/clang/plugins/FindBadConstructsAction.cpp
+++ b/tools/clang/plugins/FindBadConstructsAction.cpp
@@ -21,7 +21,7 @@
       : visitor_(*instance, options) {}
 
   void HandleTranslationUnit(clang::ASTContext& context) override {
-    visitor_.TraverseDecl(context.getTranslationUnitDecl());
+    visitor_.Traverse(context);
   }
 
  private:
@@ -63,6 +63,8 @@
       options_.check_implicit_copy_ctors = true;
     } else if (args[i] == "no-realpath") {
       options_.no_realpath = true;
+    } else if (args[i] == "check-ipc") {
+      options_.check_ipc = true;
     } else {
       parsed = false;
       llvm::errs() << "Unknown clang plugin argument: " << args[i] << "\n";
diff --git a/tools/clang/plugins/FindBadConstructsConsumer.cpp b/tools/clang/plugins/FindBadConstructsConsumer.cpp
index 649a7a5..6c33f75d 100644
--- a/tools/clang/plugins/FindBadConstructsConsumer.cpp
+++ b/tools/clang/plugins/FindBadConstructsConsumer.cpp
@@ -7,6 +7,7 @@
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/AST/Attr.h"
 #include "clang/Lex/Lexer.h"
+#include "clang/Sema/Sema.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace clang;
@@ -91,11 +92,32 @@
          record.isDependentType();
 }
 
+// Use a local RAV implementation to simply collect all FunctionDecls marked for
+// late template parsing. This happens with the flag -fdelayed-template-parsing,
+// which is on by default in MSVC-compatible mode.
+std::set<FunctionDecl*> GetLateParsedFunctionDecls(TranslationUnitDecl* decl) {
+  struct Visitor : public RecursiveASTVisitor<Visitor> {
+    bool VisitFunctionDecl(FunctionDecl* function_decl) {
+      if (function_decl->isLateTemplateParsed())
+        late_parsed_decls.insert(function_decl);
+      return true;
+    }
+
+    std::set<FunctionDecl*> late_parsed_decls;
+  } v;
+  v.TraverseDecl(decl);
+  return v.late_parsed_decls;
+}
+
 }  // namespace
 
 FindBadConstructsConsumer::FindBadConstructsConsumer(CompilerInstance& instance,
                                                      const Options& options)
     : ChromeClassTester(instance, options) {
+  if (options.check_ipc) {
+    ipc_visitor_.reset(new CheckIPCVisitor(instance));
+  }
+
   // Messages for virtual method specifiers.
   diag_method_requires_override_ =
       diagnostic().getCustomDiagID(getErrorLevel(), kMethodRequiresOverride);
@@ -129,6 +151,22 @@
       DiagnosticsEngine::Note, kNoteProtectedNonVirtualDtor);
 }
 
+void FindBadConstructsConsumer::Traverse(ASTContext& context) {
+  if (ipc_visitor_) {
+    ipc_visitor_->set_context(&context);
+    ParseFunctionTemplates(context.getTranslationUnitDecl());
+  }
+  RecursiveASTVisitor::TraverseDecl(context.getTranslationUnitDecl());
+  if (ipc_visitor_) ipc_visitor_->set_context(nullptr);
+}
+
+bool FindBadConstructsConsumer::TraverseDecl(Decl* decl) {
+  if (ipc_visitor_) ipc_visitor_->BeginDecl(decl);
+  bool result = RecursiveASTVisitor::TraverseDecl(decl);
+  if (ipc_visitor_) ipc_visitor_->EndDecl();
+  return result;
+}
+
 bool FindBadConstructsConsumer::VisitDecl(clang::Decl* decl) {
   clang::TagDecl* tag_decl = dyn_cast<clang::TagDecl>(decl);
   if (tag_decl && tag_decl->isCompleteDefinition())
@@ -136,6 +174,17 @@
   return true;
 }
 
+bool FindBadConstructsConsumer::VisitTemplateSpecializationType(
+    TemplateSpecializationType* spec) {
+  if (ipc_visitor_) ipc_visitor_->VisitTemplateSpecializationType(spec);
+  return true;
+}
+
+bool FindBadConstructsConsumer::VisitCallExpr(CallExpr* call_expr) {
+  if (ipc_visitor_) ipc_visitor_->VisitCallExpr(call_expr);
+  return true;
+}
+
 void FindBadConstructsConsumer::CheckChromeClass(SourceLocation record_location,
                                                  CXXRecordDecl* record) {
   // By default, the clang checker doesn't check some types (templates, etc).
@@ -878,4 +927,26 @@
   }
 }
 
+// Copied from BlinkGCPlugin, see crrev.com/1135333007
+void FindBadConstructsConsumer::ParseFunctionTemplates(
+    TranslationUnitDecl* decl) {
+  if (!instance().getLangOpts().DelayedTemplateParsing)
+    return;  // Nothing to do.
+
+  std::set<FunctionDecl*> late_parsed_decls = GetLateParsedFunctionDecls(decl);
+  clang::Sema& sema = instance().getSema();
+
+  for (const FunctionDecl* fd : late_parsed_decls) {
+    assert(fd->isLateTemplateParsed());
+
+    if (instance().getSourceManager().isInSystemHeader(
+            instance().getSourceManager().getSpellingLoc(fd->getLocation())))
+      continue;
+
+    // Parse and build AST for yet-uninstantiated template functions.
+    clang::LateParsedTemplate* lpt = sema.LateParsedTemplateMap[fd];
+    sema.LateTemplateParser(sema.OpaqueParser, *lpt);
+  }
+}
+
 }  // namespace chrome_checker
diff --git a/tools/clang/plugins/FindBadConstructsConsumer.h b/tools/clang/plugins/FindBadConstructsConsumer.h
index 8f8fc87..62bf9cf0 100644
--- a/tools/clang/plugins/FindBadConstructsConsumer.h
+++ b/tools/clang/plugins/FindBadConstructsConsumer.h
@@ -20,6 +20,8 @@
 #ifndef TOOLS_CLANG_PLUGINS_FINDBADCONSTRUCTSCONSUMER_H_
 #define TOOLS_CLANG_PLUGINS_FINDBADCONSTRUCTSCONSUMER_H_
 
+#include <memory>
+
 #include "clang/AST/AST.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/Attr.h"
@@ -29,6 +31,7 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/SourceLocation.h"
 
+#include "CheckIPCVisitor.h"
 #include "ChromeClassTester.h"
 #include "Options.h"
 #include "SuppressibleDiagnosticBuilder.h"
@@ -43,8 +46,13 @@
   FindBadConstructsConsumer(clang::CompilerInstance& instance,
                             const Options& options);
 
+  void Traverse(clang::ASTContext& context);
+
   // RecursiveASTVisitor:
+  bool TraverseDecl(clang::Decl* decl);
   bool VisitDecl(clang::Decl* decl);
+  bool VisitTemplateSpecializationType(clang::TemplateSpecializationType* spec);
+  bool VisitCallExpr(clang::CallExpr* call_expr);
 
   // ChromeClassTester overrides:
   void CheckChromeClass(clang::SourceLocation record_location,
@@ -98,6 +106,8 @@
   void CheckWeakPtrFactoryMembers(clang::SourceLocation record_location,
                                   clang::CXXRecordDecl* record);
 
+  void ParseFunctionTemplates(clang::TranslationUnitDecl* decl);
+
   unsigned diag_method_requires_override_;
   unsigned diag_redundant_virtual_specifier_;
   unsigned diag_base_method_virtual_and_final_;
@@ -110,6 +120,8 @@
   unsigned diag_note_implicit_dtor_;
   unsigned diag_note_public_dtor_;
   unsigned diag_note_protected_non_virtual_dtor_;
+
+  std::unique_ptr<CheckIPCVisitor> ipc_visitor_;
 };
 
 }  // namespace chrome_checker
diff --git a/tools/clang/plugins/Options.h b/tools/clang/plugins/Options.h
index e56084e..684dab52b 100644
--- a/tools/clang/plugins/Options.h
+++ b/tools/clang/plugins/Options.h
@@ -17,10 +17,10 @@
   // This is needed during the migration from ASTConsumer approach to the
   // RecursiveASTVisitor approach. See https://crbug.com/436357 for details.
   bool check_implicit_copy_ctors = false;
-
   // This is needed for some distributed build-sytems to respect banned
   // paths. See https://crbug.com/583454 for details.
   bool no_realpath = false;
+  bool check_ipc = false;
 };
 
 }  // namespace chrome_checker
diff --git a/tools/clang/plugins/tests/ipc.cpp b/tools/clang/plugins/tests/ipc.cpp
new file mode 100644
index 0000000..d2bcef1
--- /dev/null
+++ b/tools/clang/plugins/tests/ipc.cpp
@@ -0,0 +1,353 @@
+// Copyright (c) 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Blacklisted typedefs
+typedef __INTMAX_TYPE__ intmax_t;
+typedef __UINTMAX_TYPE__ uintmax_t;
+typedef int intptr_t;
+typedef unsigned int uintptr_t;
+typedef __WINT_TYPE__ wint_t;
+typedef __SIZE_TYPE__ size_t;
+typedef __SIZE_TYPE__ rsize_t;
+typedef long ssize_t;
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+typedef unsigned int dev_t;
+typedef int off_t;
+typedef long clock_t;
+typedef int time_t;
+typedef long suseconds_t;
+
+// Other typedefs
+typedef int int32_t;
+typedef unsigned int uint32_t;
+typedef long int64_t;
+typedef unsigned long uint64_t;
+
+namespace std {
+
+template <class T>
+struct allocator {};
+
+template <class T, class A = allocator<T>>
+struct vector {};
+
+template <class F, class S>
+struct pair {};
+
+}  // namespace std
+
+namespace base {
+
+class Pickle {};
+
+template <class T, class... Ts>
+struct Tuple {
+  T value;
+};
+
+}  // namespace base
+
+namespace IPC {
+
+template <class... T>
+struct CheckedTuple {
+  typedef base::Tuple<T...> Tuple;
+};
+
+template <class T>
+struct ParamTraits {
+  static void Write(base::Pickle*, const T&) {}
+};
+
+template <class T>
+void WriteParam(base::Pickle* pickle, const T& value) {
+  ParamTraits<T>::Write(pickle, value);
+}
+
+}  // namespace IPC
+
+
+/* Test IPC::WriteParam() usage in templates. ERRORS: 6 */
+
+struct Data {
+  uint32_t value;
+  size_t size;
+};
+
+template <>
+struct IPC::ParamTraits<Data> {
+  static void Write(base::Pickle* pickle, const Data& p) {
+    // OK: WriteParam() called in explicit specialization
+    WriteParam(pickle, p.value); // OK
+    WriteParam(pickle, p.size); // ERROR
+  }
+};
+
+template <class T>
+struct Container {
+  T value;
+};
+
+template <class T>
+struct IPC::ParamTraits<Container<T>> {
+  static void Write(base::Pickle* pickle, const Container<T>& container) {
+    // NOT CHECKED: T is not explicitly referenced
+    IPC::WriteParam(pickle, container.value); // NOT CHECKED
+    WriteParam(pickle, container.value); // NOT CHECKED
+
+    // NOT CHECKED: T explicitly referenced
+    IPC::WriteParam<T>(pickle, container.value); // NOT CHECKED
+    WriteParam<T>(pickle, container.value); // NOT CHECKED
+
+    // OK: explicit cast to non-dependent allowed type
+    WriteParam(pickle, static_cast<uint32_t>(container.value)); // OK
+
+    // ERROR: explicit cast to non-dependent banned type
+    WriteParam(pickle, static_cast<long>(container.value)); // ERROR
+  }
+};
+
+template <class T, class... Ts>
+struct MultiContainer {
+  T value;
+};
+
+template <class T, class... Ts>
+struct IPC::ParamTraits<MultiContainer<T, Ts...>> {
+  static void Write(base::Pickle* pickle,
+                    const MultiContainer<T, Ts...>& container) {
+    // NOT CHECKED: template argument explicitly referenced
+    bool helper[] = {
+        (WriteParam<Ts>(pickle, container.value), true)... // NOT CHECKED
+    };
+    (void)helper;
+  }
+};
+
+template <class T>
+struct SomeClass {
+  static void Write(base::Pickle* pickle) {
+    // NOT CHECKED: WriteParam() calls on dependent types
+    IPC::WriteParam(pickle, T(0)); // NOT CHECKED
+
+    // Non-dependent types are checked
+    IPC::WriteParam(pickle, size_t(0)); // ERROR
+    IPC::WriteParam(pickle, uint64_t(0)); // OK
+  }
+
+  template <class U>
+  static void WriteEx(base::Pickle* pickle) {
+    // NOT CHECKED: WriteParam() calls on dependent types
+    IPC::WriteParam(pickle, U(0)); // NOT CHECKED
+
+    // Non-dependent types are checked
+    IPC::WriteParam(pickle, time_t(0)); // ERROR
+    IPC::WriteParam(pickle, uint32_t(0)); // OK
+  }
+};
+
+template <class T>
+void SomeWriteFunction(base::Pickle* pickle) {
+  // NOT CHECKED: WriteParam() calls on dependent types
+  IPC::WriteParam(pickle, T(0)); // NOT CHECKED
+
+  // Non-dependent types are checked
+  IPC::WriteParam(pickle, long(0)); // ERROR
+  IPC::WriteParam(pickle, char(0)); // OK
+
+  [&](){
+    IPC::WriteParam(pickle, T(0)); // NOT CHECKED
+
+    IPC::WriteParam(pickle, clock_t(0)); // ERROR
+    IPC::WriteParam(pickle, int64_t(0)); // OK
+  }();
+}
+
+void TestWriteParamInTemplates() {
+  // These specializations call WriteParam() on various banned types, either
+  // because they were specified directly (long) or because non-blacklisted
+  // typedef (uint64_t) was stripped down to its underlying type, which is
+  // blacklisted when used as is (unsigned long).
+  // However, since it's hard (if not impossible) to check specializations
+  // properly, we're simply not checking them.
+  SomeClass<long>::Write(nullptr);
+  SomeClass<long>::WriteEx<uint64_t>(nullptr);
+  SomeWriteFunction<uint64_t>(nullptr);
+}
+
+
+/* Test IPC::CheckedTuple. ERRORS: 5 */
+
+#define IPC_TUPLE(...) IPC::CheckedTuple<__VA_ARGS__>::Tuple
+
+#define IPC_MESSAGE_DECL(name, id, in_tuple) \
+  struct name ## Meta_ ## id { \
+    using InTuple = in_tuple; \
+  };
+
+#define IPC_TEST_MESSAGE(id, in) \
+  IPC_MESSAGE_DECL(TestMessage, id, IPC_TUPLE in)
+
+struct Empty {};
+
+IPC_TEST_MESSAGE(__COUNTER__, (bool, size_t, Empty, long)) // 2 ERRORs
+
+typedef std::vector<long> long1D;
+typedef std::vector<long1D> long2D;
+IPC_TEST_MESSAGE(__COUNTER__, (bool, long2D)) // ERROR
+
+IPC_TEST_MESSAGE(__COUNTER__, (char, short, std::pair<size_t, bool>)) // ERROR
+
+IPC_TEST_MESSAGE(__COUNTER__, (std::vector<std::vector<long&>&>&)) // ERROR
+
+
+/* Check IPC::WriteParam() arguments. ERRORS: 30 */
+
+// ERRORS: 21
+void TestWriteParamArgument() {
+  #define CALL_WRITEPARAM(Type) \
+    { \
+      Type p; \
+      IPC::WriteParam(nullptr, p); \
+    }
+
+  // ERROR: blacklisted types / typedefs
+  CALL_WRITEPARAM(long) // ERROR
+  CALL_WRITEPARAM(unsigned long) // ERROR
+  CALL_WRITEPARAM(intmax_t) // ERROR
+  CALL_WRITEPARAM(uintmax_t) // ERROR
+  CALL_WRITEPARAM(intptr_t) // ERROR
+  CALL_WRITEPARAM(uintptr_t) // ERROR
+  CALL_WRITEPARAM(wint_t) // ERROR
+  CALL_WRITEPARAM(size_t) // ERROR
+  CALL_WRITEPARAM(rsize_t) // ERROR
+  CALL_WRITEPARAM(ssize_t) // ERROR
+  CALL_WRITEPARAM(ptrdiff_t) // ERROR
+  CALL_WRITEPARAM(dev_t) // ERROR
+  CALL_WRITEPARAM(off_t) // ERROR
+  CALL_WRITEPARAM(clock_t) // ERROR
+  CALL_WRITEPARAM(time_t) // ERROR
+  CALL_WRITEPARAM(suseconds_t) // ERROR
+
+  // ERROR: typedef to blacklisted typedef
+  typedef size_t my_size;
+  CALL_WRITEPARAM(my_size) // ERROR
+
+  // ERROR: expression ends up with type "unsigned long"
+  {
+    uint64_t p = 0;
+    IPC::WriteParam(nullptr, p + 1); // ERROR
+  }
+
+  // ERROR: long chain of typedefs, ends up with blacklisted typedef
+  {
+    typedef size_t my_size_base;
+    typedef const my_size_base my_size;
+    typedef my_size& my_size_ref;
+    my_size_ref p = 0;
+    IPC::WriteParam(nullptr, p); // ERROR
+  }
+
+  // ERROR: template specialization references blacklisted type
+  CALL_WRITEPARAM(std::vector<long>) // ERROR
+  CALL_WRITEPARAM(std::vector<size_t>) // ERROR
+
+  // OK: typedef to blacklisted type
+  typedef long my_long;
+  CALL_WRITEPARAM(my_long) // OK
+
+  // OK: other types / typedefs
+  CALL_WRITEPARAM(char) // OK
+  CALL_WRITEPARAM(int) // OK
+  CALL_WRITEPARAM(uint32_t) // OK
+  CALL_WRITEPARAM(int64_t) // OK
+
+  // OK: long chain of typedefs, ends up with non-blacklisted typedef
+  {
+    typedef uint32_t my_int_base;
+    typedef const my_int_base my_int;
+    typedef my_int& my_int_ref;
+    my_int_ref p = 0;
+    IPC::WriteParam(nullptr, p); // OK
+  }
+
+  // OK: template specialization references non-blacklisted type
+  CALL_WRITEPARAM(std::vector<char>) // OK
+  CALL_WRITEPARAM(std::vector<my_long>) // OK
+
+  #undef CALL_WRITEPARAM
+}
+
+struct Provider {
+  typedef unsigned int flags;
+
+  short get_short() const { return 0; }
+  uint64_t get_uint64() const { return 0; }
+  long get_long() const { return 0; }
+  unsigned int get_uint() const { return 0; }
+  flags get_flags() const { return 0; }
+  size_t get_size() const { return 0; }
+
+  const std::vector<size_t>& get_sizes() const { return sizes_data; }
+  const std::vector<uint64_t>& get_uint64s() const { return uint64s_data; }
+
+  template <class T>
+  T get() const { return T(); }
+
+  short short_data;
+  unsigned int uint_data;
+  flags flags_data;
+  long long_data;
+  size_t size_data;
+  uint64_t uint64_data;
+  std::vector<size_t> sizes_data;
+  std::vector<uint64_t> uint64s_data;
+};
+
+// ERRORS: 9
+void TestWriteParamMemberArgument() {
+  Provider p;
+
+  IPC::WriteParam(nullptr, p.get<short>()); // OK
+  IPC::WriteParam(nullptr, p.get_short()); // OK
+  IPC::WriteParam(nullptr, p.short_data); // OK
+
+  IPC::WriteParam(nullptr, p.get<unsigned int>()); // OK
+  IPC::WriteParam(nullptr, p.get_uint()); // OK
+  IPC::WriteParam(nullptr, p.uint_data); // OK
+
+  IPC::WriteParam(nullptr, p.get<Provider::flags>()); // OK
+  IPC::WriteParam(nullptr, p.get_flags()); // OK
+  IPC::WriteParam(nullptr, p.flags_data); // OK
+
+  IPC::WriteParam(nullptr, p.get<long>()); // ERROR
+  IPC::WriteParam(nullptr, p.get_long()); // ERROR
+  IPC::WriteParam(nullptr, p.long_data); // ERROR
+
+  // This one is flaky and depends on whether size_t is typedefed to a
+  // blacklisted type (unsigned long).
+  //IPC::WriteParam(nullptr, p.get<size_t>()); // ERROR
+  IPC::WriteParam(nullptr, p.get_size()); // ERROR
+  IPC::WriteParam(nullptr, p.size_data); // ERROR
+
+  // Information about uint64_t gets lost, and plugin sees WriteParam()
+  // call on unsigned long, which is blacklisted.
+  IPC::WriteParam(nullptr, p.get<uint64_t>()); // ERROR
+  IPC::WriteParam(nullptr, p.get_uint64()); // OK
+  IPC::WriteParam(nullptr, p.uint64_data); // OK
+
+  // Same thing here, WriteParam() sees vector<unsigned long>, and denies it.
+  IPC::WriteParam(nullptr, p.get<std::vector<uint64_t>>()); // ERROR
+  IPC::WriteParam(nullptr, p.get_uint64s()); // OK
+  IPC::WriteParam(nullptr, p.uint64s_data); // OK
+
+  // This one is flaky and depends on whether size_t is typedefed to a
+  // blacklisted type (unsigned long).
+  //IPC::WriteParam(nullptr, p.get<std::vector<size_t>>());
+  IPC::WriteParam(nullptr, p.get_sizes()); // ERROR
+  IPC::WriteParam(nullptr, p.sizes_data); // ERROR
+}
+
+
+/* ERRORS: 41 */
diff --git a/tools/clang/plugins/tests/ipc.flags b/tools/clang/plugins/tests/ipc.flags
new file mode 100644
index 0000000..49716d6
--- /dev/null
+++ b/tools/clang/plugins/tests/ipc.flags
@@ -0,0 +1 @@
+-ferror-limit=0 -Xclang -plugin-arg-find-bad-constructs -Xclang check-ipc
\ No newline at end of file
diff --git a/tools/clang/plugins/tests/ipc.txt b/tools/clang/plugins/tests/ipc.txt
new file mode 100644
index 0000000..fbca40b
--- /dev/null
+++ b/tools/clang/plugins/tests/ipc.txt
@@ -0,0 +1,224 @@
+ipc.cpp:83:26: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'size_t'.
+    WriteParam(pickle, p.size); // ERROR
+                         ^
+ipc.cpp:107:24: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'long'.
+    WriteParam(pickle, static_cast<long>(container.value)); // ERROR
+                       ^
+ipc.cpp:135:29: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'size_t'.
+    IPC::WriteParam(pickle, size_t(0)); // ERROR
+                            ^
+ipc.cpp:145:29: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'time_t'.
+    IPC::WriteParam(pickle, time_t(0)); // ERROR
+                            ^
+ipc.cpp:156:27: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'long'.
+  IPC::WriteParam(pickle, long(0)); // ERROR
+                          ^
+ipc.cpp:162:29: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'clock_t'.
+    IPC::WriteParam(pickle, clock_t(0)); // ERROR
+                            ^
+ipc.cpp:194:1: error: [chromium-ipc] IPC tuple references banned type 'size_t'.
+IPC_TEST_MESSAGE(__COUNTER__, (bool, size_t, Empty, long)) // 2 ERRORs
+^
+ipc.cpp:190:3: note: expanded from macro 'IPC_TEST_MESSAGE'
+  IPC_MESSAGE_DECL(TestMessage, id, IPC_TUPLE in)
+  ^
+ipc.cpp:186:5: note: expanded from macro 'IPC_MESSAGE_DECL'
+    using InTuple = in_tuple; \
+    ^
+ipc.cpp:194:1: error: [chromium-ipc] IPC tuple references banned type 'long'.
+ipc.cpp:190:3: note: expanded from macro 'IPC_TEST_MESSAGE'
+  IPC_MESSAGE_DECL(TestMessage, id, IPC_TUPLE in)
+  ^
+ipc.cpp:186:5: note: expanded from macro 'IPC_MESSAGE_DECL'
+    using InTuple = in_tuple; \
+    ^
+ipc.cpp:198:1: error: [chromium-ipc] IPC tuple references banned type 'long' via 'long2D'.
+IPC_TEST_MESSAGE(__COUNTER__, (bool, long2D)) // ERROR
+^
+ipc.cpp:190:3: note: expanded from macro 'IPC_TEST_MESSAGE'
+  IPC_MESSAGE_DECL(TestMessage, id, IPC_TUPLE in)
+  ^
+ipc.cpp:186:5: note: expanded from macro 'IPC_MESSAGE_DECL'
+    using InTuple = in_tuple; \
+    ^
+ipc.cpp:197:29: note: see here
+typedef std::vector<long1D> long2D;
+                            ^
+ipc.cpp:196:27: note: see here
+typedef std::vector<long> long1D;
+                          ^
+ipc.cpp:200:1: error: [chromium-ipc] IPC tuple references banned type 'size_t' via 'std::pair<size_t, _Bool>'.
+IPC_TEST_MESSAGE(__COUNTER__, (char, short, std::pair<size_t, bool>)) // ERROR
+^
+ipc.cpp:190:3: note: expanded from macro 'IPC_TEST_MESSAGE'
+  IPC_MESSAGE_DECL(TestMessage, id, IPC_TUPLE in)
+  ^
+ipc.cpp:186:5: note: expanded from macro 'IPC_MESSAGE_DECL'
+    using InTuple = in_tuple; \
+    ^
+ipc.cpp:202:1: error: [chromium-ipc] IPC tuple references banned type 'long' via 'std::vector<std::vector<long &> &>'.
+IPC_TEST_MESSAGE(__COUNTER__, (std::vector<std::vector<long&>&>&)) // ERROR
+^
+ipc.cpp:190:3: note: expanded from macro 'IPC_TEST_MESSAGE'
+  IPC_MESSAGE_DECL(TestMessage, id, IPC_TUPLE in)
+  ^
+ipc.cpp:186:5: note: expanded from macro 'IPC_MESSAGE_DECL'
+    using InTuple = in_tuple; \
+    ^
+ipc.cpp:216:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'long'.
+  CALL_WRITEPARAM(long) // ERROR
+  ^
+ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
+      IPC::WriteParam(nullptr, p); \
+                               ^
+ipc.cpp:217:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'unsigned long'.
+  CALL_WRITEPARAM(unsigned long) // ERROR
+  ^
+ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
+      IPC::WriteParam(nullptr, p); \
+                               ^
+ipc.cpp:218:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'intmax_t'.
+  CALL_WRITEPARAM(intmax_t) // ERROR
+  ^
+ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
+      IPC::WriteParam(nullptr, p); \
+                               ^
+ipc.cpp:219:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'uintmax_t'.
+  CALL_WRITEPARAM(uintmax_t) // ERROR
+  ^
+ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
+      IPC::WriteParam(nullptr, p); \
+                               ^
+ipc.cpp:220:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'intptr_t'.
+  CALL_WRITEPARAM(intptr_t) // ERROR
+  ^
+ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
+      IPC::WriteParam(nullptr, p); \
+                               ^
+ipc.cpp:221:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'uintptr_t'.
+  CALL_WRITEPARAM(uintptr_t) // ERROR
+  ^
+ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
+      IPC::WriteParam(nullptr, p); \
+                               ^
+ipc.cpp:222:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'wint_t'.
+  CALL_WRITEPARAM(wint_t) // ERROR
+  ^
+ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
+      IPC::WriteParam(nullptr, p); \
+                               ^
+ipc.cpp:223:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'size_t'.
+  CALL_WRITEPARAM(size_t) // ERROR
+  ^
+ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
+      IPC::WriteParam(nullptr, p); \
+                               ^
+ipc.cpp:224:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'rsize_t'.
+  CALL_WRITEPARAM(rsize_t) // ERROR
+  ^
+ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
+      IPC::WriteParam(nullptr, p); \
+                               ^
+ipc.cpp:225:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'ssize_t'.
+  CALL_WRITEPARAM(ssize_t) // ERROR
+  ^
+ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
+      IPC::WriteParam(nullptr, p); \
+                               ^
+ipc.cpp:226:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'ptrdiff_t'.
+  CALL_WRITEPARAM(ptrdiff_t) // ERROR
+  ^
+ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
+      IPC::WriteParam(nullptr, p); \
+                               ^
+ipc.cpp:227:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'dev_t'.
+  CALL_WRITEPARAM(dev_t) // ERROR
+  ^
+ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
+      IPC::WriteParam(nullptr, p); \
+                               ^
+ipc.cpp:228:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'off_t'.
+  CALL_WRITEPARAM(off_t) // ERROR
+  ^
+ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
+      IPC::WriteParam(nullptr, p); \
+                               ^
+ipc.cpp:229:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'clock_t'.
+  CALL_WRITEPARAM(clock_t) // ERROR
+  ^
+ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
+      IPC::WriteParam(nullptr, p); \
+                               ^
+ipc.cpp:230:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'time_t'.
+  CALL_WRITEPARAM(time_t) // ERROR
+  ^
+ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
+      IPC::WriteParam(nullptr, p); \
+                               ^
+ipc.cpp:231:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'suseconds_t'.
+  CALL_WRITEPARAM(suseconds_t) // ERROR
+  ^
+ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
+      IPC::WriteParam(nullptr, p); \
+                               ^
+ipc.cpp:235:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'size_t' via 'my_size'.
+  CALL_WRITEPARAM(my_size) // ERROR
+  ^
+ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
+      IPC::WriteParam(nullptr, p); \
+                               ^
+ipc.cpp:234:18: note: see here
+  typedef size_t my_size;
+                 ^
+ipc.cpp:240:32: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'unsigned long'.
+    IPC::WriteParam(nullptr, p + 1); // ERROR
+                               ^
+ipc.cpp:249:30: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'size_t' via 'my_size'.
+    IPC::WriteParam(nullptr, p); // ERROR
+                             ^
+ipc.cpp:246:32: note: see here
+    typedef const my_size_base my_size;
+                               ^
+ipc.cpp:245:20: note: see here
+    typedef size_t my_size_base;
+                   ^
+ipc.cpp:253:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'long' via 'std::vector<long>'.
+  CALL_WRITEPARAM(std::vector<long>) // ERROR
+  ^
+ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
+      IPC::WriteParam(nullptr, p); \
+                               ^
+ipc.cpp:254:3: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'size_t' via 'std::vector<size_t>'.
+  CALL_WRITEPARAM(std::vector<size_t>) // ERROR
+  ^
+ipc.cpp:212:32: note: expanded from macro 'CALL_WRITEPARAM'
+      IPC::WriteParam(nullptr, p); \
+                               ^
+ipc.cpp:324:28: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'long'.
+  IPC::WriteParam(nullptr, p.get<long>()); // ERROR
+                           ^
+ipc.cpp:325:28: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'long'.
+  IPC::WriteParam(nullptr, p.get_long()); // ERROR
+                           ^
+ipc.cpp:326:30: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'long'.
+  IPC::WriteParam(nullptr, p.long_data); // ERROR
+                             ^
+ipc.cpp:331:28: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'size_t'.
+  IPC::WriteParam(nullptr, p.get_size()); // ERROR
+                           ^
+ipc.cpp:332:30: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'size_t'.
+  IPC::WriteParam(nullptr, p.size_data); // ERROR
+                             ^
+ipc.cpp:336:28: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'unsigned long'.
+  IPC::WriteParam(nullptr, p.get<uint64_t>()); // ERROR
+                           ^
+ipc.cpp:341:28: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'unsigned long' via 'struct std::vector<unsigned long, struct std::allocator<unsigned long> >'.
+  IPC::WriteParam(nullptr, p.get<std::vector<uint64_t>>()); // ERROR
+                           ^
+ipc.cpp:348:28: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'size_t' via 'std::vector<size_t>'.
+  IPC::WriteParam(nullptr, p.get_sizes()); // ERROR
+                           ^
+ipc.cpp:349:30: error: [chromium-ipc] IPC::WriteParam() is called on blacklisted type 'size_t' via 'std::vector<size_t>'.
+  IPC::WriteParam(nullptr, p.sizes_data); // ERROR
+                             ^
+41 errors generated.
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index cd41476..43367b42 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -100,7 +100,8 @@
       'Chromium Win 10': 'tbd',
       'Chromium Win x64 Clobber': 'tbd',
       'ChromiumOS Linux Tests': 'tbd',
-      'ClangToTAndroidASan': 'tbd',
+      'ClangToTAndroidASan':
+        'android_clang_no_chrome_plugins_asan_gyp_debug_bot_minimal_symbols',
       'ClangToTLinux': 'tbd',
       'ClangToTLinux (dbg)': 'tbd',
       'ClangToTLinuxASan': 'tbd',
@@ -901,6 +902,11 @@
       'android', 'cast', 'gyp', 'debug_static_bot',
     ],
 
+    'android_clang_no_chrome_plugins_asan_gyp_debug_bot_minimal_symbols': [
+      'android', 'clang_no_chrome_plugins', 'asan', 'gyp',
+      'debug_bot_minimal_symbols',
+    ],
+
     'android_clang_asan_findbugs_gyp_debug_bot_minimal_symbols': [
       'android', 'clang', 'asan', 'findbugs', 'gyp',
       'debug_bot_minimal_symbols',
@@ -1666,6 +1672,12 @@
       'mixins': ['chromeos'],
     },
 
+    'clang_no_chrome_plugins': {
+      'gn_args': 'clang_use_chrome_plugins=false',
+      'gyp_defines': 'clang_use_chrome_plugins=0',
+      'mixins': ['clang'],
+    },
+
     'clang': {
       'gn_args': 'is_clang=true',
       'gyp_defines': 'clang=1',
diff --git a/tools/perf/benchmarks/tracing.py b/tools/perf/benchmarks/tracing.py
index 95cc44d..4c863dc 100644
--- a/tools/perf/benchmarks/tracing.py
+++ b/tools/perf/benchmarks/tracing.py
@@ -7,8 +7,10 @@
 from telemetry.web_perf import timeline_based_measurement
 
 import page_sets
+from telemetry import benchmark
 
 
+@benchmark.Disabled('android')
 class TracingWithDebugOverhead(perf_benchmark.PerfBenchmark):
 
   page_set = page_sets.Top10PageSet
diff --git a/ui/aura/demo/demo_main.cc b/ui/aura/demo/demo_main.cc
index 4a2467f..ea86753 100644
--- a/ui/aura/demo/demo_main.cc
+++ b/ui/aura/demo/demo_main.cc
@@ -30,7 +30,7 @@
 #include "ui/gl/gl_surface.h"
 
 #if defined(USE_X11)
-#include "ui/gfx/x/x11_connection.h"
+#include "ui/gfx/x/x11_connection.h"  // nogncheck
 #endif
 
 #if defined(OS_WIN)
diff --git a/ui/base/ime/input_method_win.cc b/ui/base/ime/input_method_win.cc
index 39fdd47..47160e5 100644
--- a/ui/base/ime/input_method_win.cc
+++ b/ui/base/ime/input_method_win.cc
@@ -214,10 +214,19 @@
 }
 
 void InputMethodWin::OnCaretBoundsChanged(const TextInputClient* client) {
-  if (!enabled_ || !IsTextInputClientFocused(client) ||
-      !IsWindowFocused(client)) {
+  if (!IsTextInputClientFocused(client) || !IsWindowFocused(client))
     return;
+  TextInputType text_input_type = GetTextInputType();
+  if (client == GetTextInputClient() &&
+      text_input_type != TEXT_INPUT_TYPE_NONE &&
+      text_input_type != TEXT_INPUT_TYPE_PASSWORD && GetEngine()) {
+    // |enabled_| == false could be faked, and the engine should rely on the
+    // real type from GetTextInputType().
+    GetEngine()->SetCompositionBounds(GetCompositionBounds(client));
   }
+  if (!enabled_)
+    return;
+
   // The current text input type should not be NONE if |client| is focused.
   DCHECK(!IsTextInputTypeNone());
   // Tentatively assume that the returned value is DIP (Density Independent
@@ -235,18 +244,20 @@
   gfx::Rect caret_rect(gfx::Point(window_point.x, window_point.y),
                        screen_bounds.size());
   imm32_manager_.UpdateCaretRect(attached_window, caret_rect);
-
-  if (client == GetTextInputClient() &&
-      GetTextInputType() != ui::TEXT_INPUT_TYPE_PASSWORD && GetEngine())
-    GetEngine()->SetCompositionBounds(GetCompositionBounds(client));
 }
 
 void InputMethodWin::CancelComposition(const TextInputClient* client) {
-  if (enabled_ && IsTextInputClientFocused(client)) {
-    imm32_manager_.CancelIME(toplevel_window_handle_);
-
-    if (GetEngine())
+  if (IsTextInputClientFocused(client)) {
+    // |enabled_| == false could be faked, and the engine should rely on the
+    // real type get from GetTextInputType().
+    TextInputType text_input_type = GetTextInputType();
+    if (text_input_type != TEXT_INPUT_TYPE_NONE &&
+        text_input_type != TEXT_INPUT_TYPE_PASSWORD && GetEngine()) {
       GetEngine()->Reset();
+    }
+
+    if (enabled_)
+      imm32_manager_.CancelIME(toplevel_window_handle_);
   }
 }
 
diff --git a/ui/compositor/test/in_process_context_provider.cc b/ui/compositor/test/in_process_context_provider.cc
index 0ec09c4..11f9d28 100644
--- a/ui/compositor/test/in_process_context_provider.cc
+++ b/ui/compositor/test/in_process_context_provider.cc
@@ -134,8 +134,8 @@
   if (gr_context_)
     return gr_context_.get();
 
-  skia::RefPtr<GrGLInterface> interface =
-      skia_bindings::CreateGLES2InterfaceBindings(ContextGL());
+  sk_sp<GrGLInterface> interface(
+      skia_bindings::CreateGLES2InterfaceBindings(ContextGL()));
   gr_context_ = skia::AdoptRef(GrContext::Create(
       // GrContext takes ownership of |interface|.
       kOpenGL_GrBackend, reinterpret_cast<GrBackendContext>(interface.get())));
diff --git a/ui/events/event_unittest.cc b/ui/events/event_unittest.cc
index 7dadd36..3cb6c47 100644
--- a/ui/events/event_unittest.cc
+++ b/ui/events/event_unittest.cc
@@ -18,7 +18,7 @@
 #if defined(USE_X11)
 #include <X11/Xlib.h>
 #include "ui/events/test/events_test_utils_x11.h"
-#include "ui/gfx/x/x11_types.h"
+#include "ui/gfx/x/x11_types.h"  // nogncheck
 #endif
 
 namespace ui {
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn
index b1304fa..4d11b59f 100644
--- a/ui/gfx/BUILD.gn
+++ b/ui/gfx/BUILD.gn
@@ -82,6 +82,7 @@
     "font.h",
     "font_fallback.h",
     "font_fallback_linux.cc",
+    "font_fallback_linux.h",
     "font_fallback_mac.mm",
     "font_fallback_win.cc",
     "font_fallback_win.h",
diff --git a/ui/gfx/blit_unittest.cc b/ui/gfx/blit_unittest.cc
index 12c6c401..7598ef6 100644
--- a/ui/gfx/blit_unittest.cc
+++ b/ui/gfx/blit_unittest.cc
@@ -64,7 +64,7 @@
 TEST(Blit, ScrollCanvas) {
   static const int kCanvasWidth = 5;
   static const int kCanvasHeight = 5;
-  skia::RefPtr<SkCanvas> canvas = skia::AdoptRef(
+  sk_sp<SkCanvas> canvas(
       skia::CreatePlatformCanvas(kCanvasWidth, kCanvasHeight, true));
   uint8_t initial_values[kCanvasHeight][kCanvasWidth] = {
       {0x00, 0x01, 0x02, 0x03, 0x04},
@@ -152,7 +152,7 @@
   base::SharedMemory shared_mem;
   ASSERT_TRUE(shared_mem.CreateAnonymous(kCanvasWidth * kCanvasHeight));
   base::SharedMemoryHandle section = shared_mem.handle();
-  skia::RefPtr<SkCanvas> canvas = skia::AdoptRef(skia::CreatePlatformCanvas(
+  sk_sp<SkCanvas> canvas(skia::CreatePlatformCanvas(
       kCanvasWidth, kCanvasHeight, true, section.GetHandle(),
       skia::RETURN_NULL_ON_FAILURE));
   ASSERT_TRUE(canvas);
diff --git a/ui/gfx/font_fallback_linux.cc b/ui/gfx/font_fallback_linux.cc
index 919ac64..ad690c5 100644
--- a/ui/gfx/font_fallback_linux.cc
+++ b/ui/gfx/font_fallback_linux.cc
@@ -2,15 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ui/gfx/font_fallback.h"
+#include "ui/gfx/font_fallback_linux.h"
 
 #include <fontconfig/fontconfig.h>
 
 #include <map>
+#include <memory>
 #include <string>
 #include <vector>
 
 #include "base/lazy_instance.h"
+#include "base/memory/ptr_util.h"
 #include "ui/gfx/font.h"
 
 namespace gfx {
@@ -62,4 +64,184 @@
   return *fallback_fonts;
 }
 
+namespace {
+
+class CachedFont {
+ public:
+  // Note: We pass the charset explicitly as callers
+  // should not create CachedFont entries without knowing
+  // that the FcPattern contains a valid charset.
+  CachedFont(FcPattern* pattern, FcCharSet* char_set)
+      : supported_characters_(char_set) {
+    DCHECK(pattern);
+    DCHECK(char_set);
+    fallback_font_.name = GetFontName(pattern);
+    fallback_font_.filename = GetFontFilename(pattern);
+    fallback_font_.ttc_index = GetFontTtcIndex(pattern);
+    fallback_font_.is_bold = IsFontBold(pattern);
+    fallback_font_.is_italic = IsFontItalic(pattern);
+  }
+
+  const FallbackFontData& fallback_font() const { return fallback_font_; }
+
+  bool HasGlyphForCharacter(UChar32 c) const {
+    return supported_characters_ && FcCharSetHasChar(supported_characters_, c);
+  }
+
+ private:
+  static std::string GetFontName(FcPattern* pattern) {
+    FcChar8* familyName = nullptr;
+    if (FcPatternGetString(pattern, FC_FAMILY, 0, &familyName) != FcResultMatch)
+      return std::string();
+    return std::string(reinterpret_cast<const char*>(familyName));
+  }
+
+  static std::string GetFontFilename(FcPattern* pattern) {
+    FcChar8* c_filename = nullptr;
+    if (FcPatternGetString(pattern, FC_FILE, 0, &c_filename) != FcResultMatch)
+      return std::string();
+    return std::string(reinterpret_cast<const char*>(c_filename));
+  }
+
+  static int GetFontTtcIndex(FcPattern* pattern) {
+    int ttcIndex = -1;
+    if (FcPatternGetInteger(pattern, FC_INDEX, 0, &ttcIndex) != FcResultMatch ||
+        ttcIndex < 0)
+      return 0;
+    return ttcIndex;
+  }
+
+  static bool IsFontBold(FcPattern* pattern) {
+    int weight = 0;
+    if (FcPatternGetInteger(pattern, FC_WEIGHT, 0, &weight) != FcResultMatch)
+      return false;
+    return weight >= FC_WEIGHT_BOLD;
+  }
+
+  static bool IsFontItalic(FcPattern* pattern) {
+    int slant = 0;
+    if (FcPatternGetInteger(pattern, FC_SLANT, 0, &slant) != FcResultMatch)
+      return false;
+    return slant != FC_SLANT_ROMAN;
+  }
+
+  FallbackFontData fallback_font_;
+  // supported_characters_ is owned by the parent
+  // FcFontSet and should never be freed.
+  FcCharSet* supported_characters_;
+};
+
+class CachedFontSet {
+ public:
+  // CachedFontSet takes ownership of the passed FcFontSet.
+  static std::unique_ptr<CachedFontSet> CreateForLocale(
+      const std::string& locale) {
+    FcFontSet* font_set = CreateFcFontSetForLocale(locale);
+    return base::WrapUnique(new CachedFontSet(font_set));
+  }
+
+  ~CachedFontSet() {
+    fallback_list_.clear();
+    FcFontSetDestroy(font_set_);
+  }
+
+  FallbackFontData GetFallbackFontForChar(UChar32 c) {
+    for (const auto& cached_font : fallback_list_) {
+      if (cached_font.HasGlyphForCharacter(c))
+        return cached_font.fallback_font();
+    }
+    // The previous code just returned garbage if the user didn't
+    // have the necessary fonts, this seems better than garbage.
+    // Current callers happen to ignore any values with an empty family string.
+    return FallbackFontData();
+  }
+
+ private:
+  static FcFontSet* CreateFcFontSetForLocale(const std::string& locale) {
+    FcPattern* pattern = FcPatternCreate();
+
+    if (!locale.empty()) {
+      // FcChar* is unsigned char* so we have to cast.
+      FcPatternAddString(pattern, FC_LANG,
+                         reinterpret_cast<const FcChar8*>(locale.c_str()));
+    }
+
+    FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
+
+    FcConfigSubstitute(0, pattern, FcMatchPattern);
+    FcDefaultSubstitute(pattern);
+
+    if (locale.empty())
+      FcPatternDel(pattern, FC_LANG);
+
+    // The result parameter returns if any fonts were found.
+    // We already handle 0 fonts correctly, so we ignore the param.
+    FcResult result;
+    FcFontSet* font_set = FcFontSort(0, pattern, 0, 0, &result);
+    FcPatternDestroy(pattern);
+
+    // The caller will take ownership of this FcFontSet.
+    return font_set;
+  }
+
+  CachedFontSet(FcFontSet* font_set) : font_set_(font_set) {
+    FillFallbackList();
+  }
+
+  void FillFallbackList() {
+    DCHECK(fallback_list_.empty());
+    if (!font_set_)
+      return;
+
+    for (int i = 0; i < font_set_->nfont; ++i) {
+      FcPattern* pattern = font_set_->fonts[i];
+
+      // Ignore any bitmap fonts users may still have installed from last
+      // century.
+      FcBool is_scalable;
+      if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &is_scalable) !=
+              FcResultMatch ||
+          !is_scalable)
+        continue;
+
+      // Ignore any fonts FontConfig knows about, but that we don't have
+      // permission to read.
+      FcChar8* c_filename;
+      if (FcPatternGetString(pattern, FC_FILE, 0, &c_filename) != FcResultMatch)
+        continue;
+      if (access(reinterpret_cast<char*>(c_filename), R_OK))
+        continue;
+
+      // Make sure this font can tell us what characters it has glyphs for.
+      FcCharSet* char_set;
+      if (FcPatternGetCharSet(pattern, FC_CHARSET, 0, &char_set) !=
+          FcResultMatch)
+        continue;
+
+      fallback_list_.emplace_back(pattern, char_set);
+    }
+  }
+
+  FcFontSet* font_set_;  // Owned by this object.
+  // CachedFont has a FcCharset* which points into the FcFontSet.
+  // If the FcFontSet is ever destroyed, the fallback list
+  // must be cleared first.
+  std::vector<CachedFont> fallback_list_;
+
+  DISALLOW_COPY_AND_ASSIGN(CachedFontSet);
+};
+
+typedef std::map<std::string, std::unique_ptr<CachedFontSet>> FontSetCache;
+base::LazyInstance<FontSetCache>::Leaky g_font_sets_by_locale =
+    LAZY_INSTANCE_INITIALIZER;
+
+}  // namespace
+
+FallbackFontData GetFallbackFontForChar(UChar32 c, const std::string& locale) {
+  auto& cached_font_set = g_font_sets_by_locale.Get()[locale];
+  if (!cached_font_set)
+    cached_font_set = CachedFontSet::CreateForLocale(locale);
+  return cached_font_set->GetFallbackFontForChar(c);
+}
+
 }  // namespace gfx
diff --git a/ui/gfx/font_fallback_linux.h b/ui/gfx/font_fallback_linux.h
new file mode 100644
index 0000000..ac9cd572
--- /dev/null
+++ b/ui/gfx/font_fallback_linux.h
@@ -0,0 +1,38 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GFX_FONT_FALLBACK_LINUX_H_
+#define UI_GFX_FONT_FALLBACK_LINUX_H_
+
+#include <string>
+
+#include "third_party/icu/source/common/unicode/uchar.h"
+#include "ui/gfx/font_fallback.h"
+#include "ui/gfx/gfx_export.h"
+
+namespace gfx {
+
+// Return a font family which provides a glyph for the Unicode code point
+// specified by character.
+//   c: a UTF-32 code point
+//   preferred_locale: preferred locale identifier for the |characters|
+//                     (e.g. "en", "ja", "zh-CN")
+//
+// Returns: the font family instance. The instance has an empty font name if the
+// request could not be satisfied.
+//
+// Previously blink::WebFontInfo::fallbackFontForChar.
+struct FallbackFontData {
+  std::string name;
+  std::string filename;
+  int ttc_index = 0;
+  bool is_bold = false;
+  bool is_italic = false;
+};
+GFX_EXPORT FallbackFontData
+GetFallbackFontForChar(UChar32 c, const std::string& preferred_locale);
+
+}  // namespace gfx
+
+#endif  // UI_GFX_FONT_FALLBACK_LINUX_H_
diff --git a/ui/gfx/gfx.gyp b/ui/gfx/gfx.gyp
index 3891390..e7936ce 100644
--- a/ui/gfx/gfx.gyp
+++ b/ui/gfx/gfx.gyp
@@ -165,6 +165,7 @@
         'font.h',
         'font_fallback.h',
         'font_fallback_linux.cc',
+        'font_fallback_linux.h',
         'font_fallback_mac.mm',
         'font_fallback_win.cc',
         'font_fallback_win.h',
diff --git a/ui/gfx/render_text_unittest.cc b/ui/gfx/render_text_unittest.cc
index d07c8f5..9186d4d0 100644
--- a/ui/gfx/render_text_unittest.cc
+++ b/ui/gfx/render_text_unittest.cc
@@ -3017,8 +3017,8 @@
   const Size kCanvasSize(300, 50);
   const int kTestSize = 10;
 
-  skia::RefPtr<SkSurface> surface = skia::AdoptRef(
-      SkSurface::NewRasterN32Premul(kCanvasSize.width(), kCanvasSize.height()));
+  sk_sp<SkSurface> surface =
+      SkSurface::MakeRasterN32Premul(kCanvasSize.width(), kCanvasSize.height());
   Canvas canvas(skia::SharePtr(surface->getCanvas()), 1.0f);
   scoped_ptr<RenderText> render_text(RenderText::CreateInstance());
   render_text->SetHorizontalAlignment(ALIGN_LEFT);
@@ -3108,8 +3108,8 @@
   const Size kCanvasSize(300, 50);
   const int kTestSize = 10;
 
-  skia::RefPtr<SkSurface> surface = skia::AdoptRef(
-      SkSurface::NewRasterN32Premul(kCanvasSize.width(), kCanvasSize.height()));
+  sk_sp<SkSurface> surface =
+      SkSurface::MakeRasterN32Premul(kCanvasSize.width(), kCanvasSize.height());
   Canvas canvas(skia::SharePtr(surface->getCanvas()), 1.0f);
   scoped_ptr<RenderText> render_text(RenderText::CreateInstance());
   render_text->SetHorizontalAlignment(ALIGN_LEFT);
diff --git a/ui/gl/gl_bindings.cc b/ui/gl/gl_bindings.cc
index bb700c3..0f47871 100644
--- a/ui/gl/gl_bindings.cc
+++ b/ui/gl/gl_bindings.cc
@@ -11,7 +11,7 @@
 #include "ui/gl/gl_bindings.h"
 
 #if defined(USE_X11)
-#include "ui/gfx/x/x11_types.h"
+#include "ui/gfx/x/x11_types.h"  // nogncheck
 #endif
 
 #if defined(OS_WIN)
diff --git a/ui/gl/gl_image_io_surface.h b/ui/gl/gl_image_io_surface.h
index d8b7318..85f2ab4 100644
--- a/ui/gl/gl_image_io_surface.h
+++ b/ui/gl/gl_image_io_surface.h
@@ -53,8 +53,6 @@
   gfx::GenericSharedMemoryId io_surface_id() const { return io_surface_id_; }
   base::ScopedCFTypeRef<IOSurfaceRef> io_surface();
 
-  static void SetLayerForWidget(gfx::AcceleratedWidget widget, CALayer* layer);
-
   static unsigned GetInternalFormatForTesting(gfx::BufferFormat format);
 
  protected:
diff --git a/ui/gl/gl_image_io_surface.mm b/ui/gl/gl_image_io_surface.mm
index 3059333..e0d08003 100644
--- a/ui/gl/gl_image_io_surface.mm
+++ b/ui/gl/gl_image_io_surface.mm
@@ -28,9 +28,6 @@
 namespace gl {
 namespace {
 
-using WidgetToLayerMap = std::map<gfx::AcceleratedWidget, CALayer*>;
-base::LazyInstance<WidgetToLayerMap> g_widget_to_layer_map;
-
 const char kGLSLVersion[] = "#version 110";
 
 const char kTextureRectangleRequired[] =
@@ -410,15 +407,6 @@
 }
 
 // static
-void GLImageIOSurface::SetLayerForWidget(gfx::AcceleratedWidget widget,
-                                         CALayer* layer) {
-  if (layer)
-    g_widget_to_layer_map.Pointer()->insert(std::make_pair(widget, layer));
-  else
-    g_widget_to_layer_map.Pointer()->erase(widget);
-}
-
-// static
 unsigned GLImageIOSurface::GetInternalFormatForTesting(
     gfx::BufferFormat format) {
   DCHECK(ValidFormat(format));
diff --git a/ui/gl/gl_surface_egl.cc b/ui/gl/gl_surface_egl.cc
index 502e697..0db0467e 100644
--- a/ui/gl/gl_surface_egl.cc
+++ b/ui/gl/gl_surface_egl.cc
@@ -8,6 +8,7 @@
 #include <stdint.h>
 
 #include <map>
+#include <vector>
 
 #include "base/command_line.h"
 #include "base/logging.h"
@@ -39,7 +40,7 @@
 #define Status int
 }
 #include "ui/base/x/x11_util_internal.h"
-#include "ui/gfx/x/x11_switches.h"
+#include "ui/gfx/x/x11_switches.h"  // nogncheck
 #endif
 
 #if !defined(EGL_FIXED_SIZE_ANGLE)
diff --git a/ui/ozone/demo/software_renderer.cc b/ui/ozone/demo/software_renderer.cc
index fb567809..175e3799 100644
--- a/ui/ozone/demo/software_renderer.cc
+++ b/ui/ozone/demo/software_renderer.cc
@@ -49,7 +49,7 @@
 
   float fraction = NextFraction();
 
-  skia::RefPtr<SkSurface> surface = software_surface_->GetSurface();
+  sk_sp<SkSurface> surface = software_surface_->GetSurface();
 
   SkColor color =
       SkColorSetARGB(0xff, 0, 0xff * fraction, 0xff * (1 - fraction));
diff --git a/ui/ozone/platform/cast/surface_factory_cast.cc b/ui/ozone/platform/cast/surface_factory_cast.cc
index d4db9d7..72fa4e6 100644
--- a/ui/ozone/platform/cast/surface_factory_cast.cc
+++ b/ui/ozone/platform/cast/surface_factory_cast.cc
@@ -48,11 +48,11 @@
   ~DummySurface() override {}
 
   // SurfaceOzoneCanvas implementation:
-  skia::RefPtr<SkSurface> GetSurface() override { return surface_; }
+  sk_sp<SkSurface> GetSurface() override { return surface_; }
 
   void ResizeCanvas(const gfx::Size& viewport_size) override {
-    surface_ = skia::AdoptRef(SkSurface::NewRaster(SkImageInfo::MakeN32Premul(
-        viewport_size.width(), viewport_size.height())));
+    surface_ = SkSurface::MakeRaster(SkImageInfo::MakeN32Premul(
+        viewport_size.width(), viewport_size.height()));
   }
 
   void PresentCanvas(const gfx::Rect& damage) override {}
@@ -62,7 +62,7 @@
   }
 
  private:
-  skia::RefPtr<SkSurface> surface_;
+  sk_sp<SkSurface> surface_;
 
   DISALLOW_COPY_AND_ASSIGN(DummySurface);
 };
diff --git a/ui/ozone/platform/drm/gpu/drm_buffer.cc b/ui/ozone/platform/drm/gpu/drm_buffer.cc
index bd2e9a9..1c50f1c4 100644
--- a/ui/ozone/platform/drm/gpu/drm_buffer.cc
+++ b/ui/ozone/platform/drm/gpu/drm_buffer.cc
@@ -38,8 +38,6 @@
 }
 
 DrmBuffer::~DrmBuffer() {
-  surface_.clear();
-
   if (framebuffer_ && !drm_->RemoveFramebuffer(framebuffer_))
     PLOG(ERROR) << "DrmBuffer: RemoveFramebuffer: fb " << framebuffer_;
 
@@ -78,8 +76,7 @@
     }
   }
 
-  surface_ =
-      skia::AdoptRef(SkSurface::NewRasterDirect(info, mmap_base_, stride_));
+  surface_ = SkSurface::MakeRasterDirect(info, mmap_base_, stride_);
   if (!surface_) {
     LOG(ERROR) << "DrmBuffer: Failed to create SkSurface: handle " << handle_;
     return false;
diff --git a/ui/ozone/platform/drm/gpu/drm_buffer.h b/ui/ozone/platform/drm/gpu/drm_buffer.h
index 13868e34..726cf119 100644
--- a/ui/ozone/platform/drm/gpu/drm_buffer.h
+++ b/ui/ozone/platform/drm/gpu/drm_buffer.h
@@ -64,7 +64,7 @@
   uint32_t fb_pixel_format_ = 0;
 
   // Wrapper around the native pixel memory.
-  skia::RefPtr<SkSurface> surface_;
+  sk_sp<SkSurface> surface_;
 
   DISALLOW_COPY_AND_ASSIGN(DrmBuffer);
 };
diff --git a/ui/ozone/platform/drm/gpu/drm_console_buffer.cc b/ui/ozone/platform/drm/gpu/drm_console_buffer.cc
index 464c380..0fe4399d 100644
--- a/ui/ozone/platform/drm/gpu/drm_console_buffer.cc
+++ b/ui/ozone/platform/drm/gpu/drm_console_buffer.cc
@@ -44,8 +44,7 @@
     return false;
   }
 
-  surface_ =
-      skia::AdoptRef(SkSurface::NewRasterDirect(info, mmap_base_, stride_));
+  surface_ = SkSurface::MakeRasterDirect(info, mmap_base_, stride_);
   if (!surface_)
     return false;
 
diff --git a/ui/ozone/platform/drm/gpu/drm_console_buffer.h b/ui/ozone/platform/drm/gpu/drm_console_buffer.h
index 2f28b9e..250ca3b 100644
--- a/ui/ozone/platform/drm/gpu/drm_console_buffer.h
+++ b/ui/ozone/platform/drm/gpu/drm_console_buffer.h
@@ -40,7 +40,7 @@
   scoped_refptr<DrmDevice> drm_;
 
   // Wrapper around the native pixel memory.
-  skia::RefPtr<SkSurface> surface_;
+  sk_sp<SkSurface> surface_;
 
   // Length of a row of pixels.
   uint32_t stride_ = 0;
diff --git a/ui/ozone/platform/drm/gpu/drm_window_unittest.cc b/ui/ozone/platform/drm/gpu/drm_window_unittest.cc
index ccda65bde..25d89dc 100644
--- a/ui/ozone/platform/drm/gpu/drm_window_unittest.cc
+++ b/ui/ozone/platform/drm/gpu/drm_window_unittest.cc
@@ -34,9 +34,9 @@
 const uint32_t kDefaultConnector = 2;
 const int kDefaultCursorSize = 64;
 
-std::vector<skia::RefPtr<SkSurface>> GetCursorBuffers(
+std::vector<sk_sp<SkSurface>> GetCursorBuffers(
     const scoped_refptr<ui::MockDrmDevice> drm) {
-  std::vector<skia::RefPtr<SkSurface>> cursor_buffers;
+  std::vector<sk_sp<SkSurface>> cursor_buffers;
   for (const auto& cursor_buffer : drm->buffers()) {
     if (cursor_buffer->width() == kDefaultCursorSize &&
         cursor_buffer->height() == kDefaultCursorSize) {
@@ -120,7 +120,7 @@
                   gfx::Point(4, 2), 0);
 
   SkBitmap cursor;
-  std::vector<skia::RefPtr<SkSurface>> cursor_buffers = GetCursorBuffers(drm_);
+  std::vector<sk_sp<SkSurface>> cursor_buffers = GetCursorBuffers(drm_);
   EXPECT_EQ(2u, cursor_buffers.size());
 
   // Buffers 1 is the cursor backbuffer we just drew in.
diff --git a/ui/ozone/platform/drm/gpu/mock_drm_device.cc b/ui/ozone/platform/drm/gpu/mock_drm_device.cc
index c41f221..9ab4e23 100644
--- a/ui/ozone/platform/drm/gpu/mock_drm_device.cc
+++ b/ui/ozone/platform/drm/gpu/mock_drm_device.cc
@@ -185,8 +185,7 @@
   *handle = allocate_buffer_count_++;
   *stride = info.minRowBytes();
   void* pixels = new char[info.getSafeSize(*stride)];
-  buffers_.push_back(
-      skia::AdoptRef(SkSurface::NewRasterDirect(info, pixels, *stride)));
+  buffers_.push_back(SkSurface::MakeRasterDirect(info, pixels, *stride));
   buffers_[*handle]->getCanvas()->clear(SK_ColorBLACK);
 
   return true;
@@ -196,7 +195,7 @@
   if (handle >= buffers_.size() || !buffers_[handle])
     return false;
 
-  buffers_[handle].clear();
+  buffers_[handle].reset();
   return true;
 }
 
diff --git a/ui/ozone/platform/drm/gpu/mock_drm_device.h b/ui/ozone/platform/drm/gpu/mock_drm_device.h
index 63e6caa0..13506eee 100644
--- a/ui/ozone/platform/drm/gpu/mock_drm_device.h
+++ b/ui/ozone/platform/drm/gpu/mock_drm_device.h
@@ -50,9 +50,7 @@
 
   uint32_t current_framebuffer() const { return current_framebuffer_; }
 
-  const std::vector<skia::RefPtr<SkSurface>> buffers() const {
-    return buffers_;
-  }
+  const std::vector<sk_sp<SkSurface>> buffers() const { return buffers_; }
 
   uint32_t get_cursor_handle_for_crtc(uint32_t crtc) const {
     const auto it = crtc_cursor_map_.find(crtc);
@@ -141,7 +139,7 @@
 
   uint32_t current_framebuffer_;
 
-  std::vector<skia::RefPtr<SkSurface>> buffers_;
+  std::vector<sk_sp<SkSurface>> buffers_;
 
   std::map<uint32_t, uint32_t> crtc_cursor_map_;
 
diff --git a/ui/ozone/platform/drm/mus_thread_proxy.cc b/ui/ozone/platform/drm/mus_thread_proxy.cc
index d3bacc4..1f3e016 100644
--- a/ui/ozone/platform/drm/mus_thread_proxy.cc
+++ b/ui/ozone/platform/drm/mus_thread_proxy.cc
@@ -133,8 +133,8 @@
 
 void MusThreadProxy::Move(gfx::AcceleratedWidget widget,
                           const gfx::Point& location) {
+  // NOTE: Input events skip the main thread to avoid jank.
   DCHECK(drm_thread_->IsRunning());
-  DCHECK(on_window_server_thread_.CalledOnValidThread());
   drm_thread_->task_runner()->PostTask(
       FROM_HERE, base::Bind(&DrmThread::MoveCursor,
                             base::Unretained(drm_thread_), widget, location));
diff --git a/ui/ozone/platform/drm/ozone_platform_gbm.cc b/ui/ozone/platform/drm/ozone_platform_gbm.cc
index 7ebc29510..9ccb57a 100644
--- a/ui/ozone/platform/drm/ozone_platform_gbm.cc
+++ b/ui/ozone/platform/drm/ozone_platform_gbm.cc
@@ -149,6 +149,7 @@
       gl_api_loader_.reset(new GlApiLoader());
       mus_thread_proxy_.reset(new MusThreadProxy());
       adapter = mus_thread_proxy_.get();
+      cursor_->SetDrmCursorProxy(mus_thread_proxy_.get());
     } else {
       gpu_platform_support_host_.reset(
           new DrmGpuPlatformSupportHost(cursor_.get()));
diff --git a/ui/ozone/platform/headless/headless_surface_factory.cc b/ui/ozone/platform/headless/headless_surface_factory.cc
index c9bbe528..a8b9952 100644
--- a/ui/ozone/platform/headless/headless_surface_factory.cc
+++ b/ui/ozone/platform/headless/headless_surface_factory.cc
@@ -39,10 +39,10 @@
 
   // SurfaceOzoneCanvas overrides:
   void ResizeCanvas(const gfx::Size& viewport_size) override {
-    surface_ = skia::AdoptRef(SkSurface::NewRaster(SkImageInfo::MakeN32Premul(
-        viewport_size.width(), viewport_size.height())));
+    surface_ = SkSurface::MakeRaster(SkImageInfo::MakeN32Premul(
+        viewport_size.width(), viewport_size.height()));
   }
-  skia::RefPtr<SkSurface> GetSurface() override { return surface_; }
+  sk_sp<SkSurface> GetSurface() override { return surface_; }
   void PresentCanvas(const gfx::Rect& damage) override {
     if (location_.empty())
       return;
@@ -62,7 +62,7 @@
 
  private:
   base::FilePath location_;
-  skia::RefPtr<SkSurface> surface_;
+  sk_sp<SkSurface> surface_;
 };
 
 class TestPixmap : public ui::NativePixmap {
diff --git a/ui/ozone/public/surface_ozone_canvas.h b/ui/ozone/public/surface_ozone_canvas.h
index 6cab0b4..31bada3 100644
--- a/ui/ozone/public/surface_ozone_canvas.h
+++ b/ui/ozone/public/surface_ozone_canvas.h
@@ -27,7 +27,7 @@
   virtual ~SurfaceOzoneCanvas() {}
 
   // Returns an SkSurface for drawing on the window.
-  virtual skia::RefPtr<SkSurface> GetSurface() = 0;
+  virtual sk_sp<SkSurface> GetSurface() = 0;
 
   // Attempts to resize the canvas to match the viewport size. After
   // resizing, the compositor must call GetCanvas() to get the next
diff --git a/ui/surface/BUILD.gn b/ui/surface/BUILD.gn
index 96130c4..b583c8b 100644
--- a/ui/surface/BUILD.gn
+++ b/ui/surface/BUILD.gn
@@ -6,8 +6,6 @@
 
 component("surface") {
   sources = [
-    "accelerated_surface_mac.cc",
-    "accelerated_surface_mac.h",
     "surface_export.h",
     "transport_dib.cc",
     "transport_dib.h",
@@ -27,12 +25,4 @@
     "//ui/gfx/geometry",
     "//ui/gl",
   ]
-
-  if (is_mac) {
-    # Required by accelerated_surface_mac.cc.
-    libs = [
-      "IOSurface.framework",
-      "OpenGL.framework",
-    ]
-  }
 }
diff --git a/ui/surface/accelerated_surface_mac.cc b/ui/surface/accelerated_surface_mac.cc
deleted file mode 100644
index 630ee7b..0000000
--- a/ui/surface/accelerated_surface_mac.cc
+++ /dev/null
@@ -1,266 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/surface/accelerated_surface_mac.h"
-
-#include "base/logging.h"
-#include "base/mac/scoped_cftyperef.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gl/gl_bindings.h"
-#include "ui/gl/gl_context.h"
-#include "ui/gl/gl_implementation.h"
-#include "ui/gl/gl_surface.h"
-#include "ui/gl/scoped_make_current.h"
-
-// Note that this must be included after gl_bindings.h to avoid conflicts.
-#include <OpenGL/CGLIOSurface.h>
-
-AcceleratedSurface::AcceleratedSurface()
-    : io_surface_id_(0),
-      allocate_fbo_(false),
-      texture_(0),
-      fbo_(0) {
-}
-
-AcceleratedSurface::~AcceleratedSurface() {}
-
-bool AcceleratedSurface::Initialize(
-    gfx::GLContext* share_context,
-    bool allocate_fbo,
-    gfx::GpuPreference gpu_preference) {
-  allocate_fbo_ = allocate_fbo;
-
-  // GL should be initialized by content::SupportsCoreAnimationPlugins().
-  DCHECK_NE(gfx::GetGLImplementation(), gfx::kGLImplementationNone);
-
-  // Drawing to IOSurfaces via OpenGL only works with Apple's GL and
-  // not with the OSMesa software renderer.
-  if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL &&
-      gfx::GetGLImplementation() != gfx::kGLImplementationAppleGL)
-    return false;
-
-  gl_surface_ = gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1));
-  if (!gl_surface_.get()) {
-    Destroy();
-    return false;
-  }
-
-  gfx::GLShareGroup* share_group =
-      share_context ? share_context->share_group() : NULL;
-
-  gl_context_ = gfx::GLContext::CreateGLContext(
-      share_group,
-      gl_surface_.get(),
-      gpu_preference);
-  if (!gl_context_.get()) {
-    Destroy();
-    return false;
-  }
-
-  // Now we're ready to handle SetSurfaceSize calls, which will
-  // allocate and/or reallocate the IOSurface and associated offscreen
-  // OpenGL structures for rendering.
-  return true;
-}
-
-void AcceleratedSurface::Destroy() {
-  // The FBO and texture objects will be destroyed when the OpenGL context,
-  // and any other contexts sharing resources with it, is. We don't want to
-  // make the context current one last time here just in order to delete
-  // these objects.
-  gl_context_ = NULL;
-  gl_surface_ = NULL;
-}
-
-// Call after making changes to the surface which require a visual update.
-// Makes the rendering show up in other processes.
-void AcceleratedSurface::SwapBuffers() {
-  if (io_surface_.get() != NULL) {
-    if (allocate_fbo_) {
-      // Bind and unbind the framebuffer to make changes to the
-      // IOSurface show up in the other process.
-      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
-      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);
-      glFlush();
-    } else {
-      // Copy the current framebuffer's contents into our "live" texture.
-      // Note that the current GL context might not be ours at this point!
-      // This is deliberate, so that surrounding code using GL can produce
-      // rendering results consumed by the AcceleratedSurface.
-      // Need to save and restore OpenGL state around this call.
-      GLint current_texture = 0;
-      GLenum target_binding = GL_TEXTURE_BINDING_RECTANGLE_ARB;
-      GLenum target = GL_TEXTURE_RECTANGLE_ARB;
-      glGetIntegerv(target_binding, &current_texture);
-      glBindTexture(target, texture_);
-      glCopyTexSubImage2D(target, 0,
-                          0, 0,
-                          0, 0,
-                          real_surface_size_.width(),
-                          real_surface_size_.height());
-      glBindTexture(target, current_texture);
-      // This flush is absolutely essential -- it guarantees that the
-      // rendering results are seen by the other process.
-      glFlush();
-    }
-  }
-}
-
-static void AddBooleanValue(CFMutableDictionaryRef dictionary,
-                            const CFStringRef key,
-                            bool value) {
-  CFDictionaryAddValue(dictionary, key,
-                       (value ? kCFBooleanTrue : kCFBooleanFalse));
-}
-
-static void AddIntegerValue(CFMutableDictionaryRef dictionary,
-                            const CFStringRef key,
-                            int32_t value) {
-  base::ScopedCFTypeRef<CFNumberRef> number(
-      CFNumberCreate(NULL, kCFNumberSInt32Type, &value));
-  CFDictionaryAddValue(dictionary, key, number.get());
-}
-
-// Creates a new OpenGL texture object bound to the given texture target.
-// Caller owns the returned texture.
-static GLuint CreateTexture(GLenum target) {
-  GLuint texture = 0;
-  glGenTextures(1, &texture);
-  glBindTexture(target, texture);
-  glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-  glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-  glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-  glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-  return texture;
-}
-
-void AcceleratedSurface::AllocateRenderBuffers(GLenum target,
-                                               const gfx::Size& size) {
-  if (!texture_) {
-    // Generate the texture object.
-    texture_ = CreateTexture(target);
-    // Generate and bind the framebuffer object.
-    glGenFramebuffersEXT(1, &fbo_);
-    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);
-  }
-
-  // Make sure that subsequent set-up code affects the render texture.
-  glBindTexture(target, texture_);
-}
-
-bool AcceleratedSurface::SetupFrameBufferObject(GLenum target) {
-  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_);
-  GLenum fbo_status;
-  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
-                            GL_COLOR_ATTACHMENT0_EXT,
-                            target,
-                            texture_,
-                            0);
-  fbo_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
-  return fbo_status == GL_FRAMEBUFFER_COMPLETE_EXT;
-}
-
-gfx::Size AcceleratedSurface::ClampToValidDimensions(const gfx::Size& size) {
-  return gfx::Size(std::max(size.width(), 1), std::max(size.height(), 1));
-}
-
-bool AcceleratedSurface::MakeCurrent() {
-  if (!gl_context_.get())
-    return false;
-  return gl_context_->MakeCurrent(gl_surface_.get());
-}
-
-void AcceleratedSurface::Clear(const gfx::Rect& rect) {
-  DCHECK(gl_context_->IsCurrent(gl_surface_.get()));
-  glClearColor(0, 0, 0, 0);
-  glViewport(0, 0, rect.width(), rect.height());
-  glMatrixMode(GL_PROJECTION);
-  glLoadIdentity();
-  glOrtho(0, rect.width(), 0, rect.height(), -1, 1);
-  glClear(GL_COLOR_BUFFER_BIT);
-}
-
-uint32_t AcceleratedSurface::SetSurfaceSize(const gfx::Size& size) {
-  if (surface_size_ == size) {
-    // Return 0 to indicate to the caller that no new backing store
-    // allocation occurred.
-    return 0;
-  }
-
-  // Only support IO surfaces if the GL implementation is the native desktop GL.
-  // IO surfaces will not work with, for example, OSMesa software renderer
-  // GL contexts.
-  if (gfx::GetGLImplementation() != gfx::kGLImplementationDesktopGL)
-    return 0;
-
-  ui::ScopedMakeCurrent make_current(gl_context_.get(), gl_surface_.get());
-  if (!make_current.Succeeded())
-    return 0;
-
-  gfx::Size clamped_size = ClampToValidDimensions(size);
-
-  // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on
-  // Mac OS X and is required for IOSurface interoperability.
-  GLenum target = GL_TEXTURE_RECTANGLE_ARB;
-  if (allocate_fbo_) {
-    AllocateRenderBuffers(target, clamped_size);
-  } else if (!texture_) {
-    // Generate the texture object.
-    texture_ = CreateTexture(target);
-  }
-
-  // Allocate a new IOSurface, which is the GPU resource that can be
-  // shared across processes.
-  base::ScopedCFTypeRef<CFMutableDictionaryRef> properties;
-  properties.reset(CFDictionaryCreateMutable(kCFAllocatorDefault,
-                                             0,
-                                             &kCFTypeDictionaryKeyCallBacks,
-                                             &kCFTypeDictionaryValueCallBacks));
-  AddIntegerValue(properties, kIOSurfaceWidth, clamped_size.width());
-  AddIntegerValue(properties, kIOSurfaceHeight, clamped_size.height());
-  AddIntegerValue(properties, kIOSurfaceBytesPerElement, 4);
-  AddBooleanValue(properties, kIOSurfaceIsGlobal, true);
-  // I believe we should be able to unreference the IOSurfaces without
-  // synchronizing with the browser process because they are
-  // ultimately reference counted by the operating system.
-  io_surface_.reset(IOSurfaceCreate(properties));
-
-  // Don't think we need to identify a plane.
-  GLuint plane = 0;
-  CGLError error = CGLTexImageIOSurface2D(
-      static_cast<CGLContextObj>(gl_context_->GetHandle()),
-      target,
-      GL_RGBA,
-      clamped_size.width(),
-      clamped_size.height(),
-      GL_BGRA,
-      GL_UNSIGNED_INT_8_8_8_8_REV,
-      io_surface_.get(),
-      plane);
-  if (error != kCGLNoError) {
-    DLOG(ERROR) << "CGL error " << error << " during CGLTexImageIOSurface2D";
-  }
-  if (allocate_fbo_) {
-    // Set up the frame buffer object.
-    if (!SetupFrameBufferObject(target)) {
-      DLOG(ERROR) << "Failed to set up frame buffer object";
-    }
-  }
-  surface_size_ = size;
-  real_surface_size_ = clamped_size;
-
-  // Now send back an identifier for the IOSurface. We originally
-  // intended to send back a mach port from IOSurfaceCreateMachPort
-  // but it looks like Chrome IPC would need to be modified to
-  // properly send mach ports between processes. For the time being we
-  // make our IOSurfaces global and send back their identifiers. On
-  // the browser process side the identifier is reconstituted into an
-  // IOSurface for on-screen rendering.
-  io_surface_id_ = IOSurfaceGetID(io_surface_);
-  return io_surface_id_;
-}
-
-uint32_t AcceleratedSurface::GetSurfaceId() {
-  return io_surface_id_;
-}
diff --git a/ui/surface/accelerated_surface_mac.h b/ui/surface/accelerated_surface_mac.h
deleted file mode 100644
index 9defa33..0000000
--- a/ui/surface/accelerated_surface_mac.h
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_SURFACE_ACCELERATED_SURFACE_MAC_H_
-#define UI_SURFACE_ACCELERATED_SURFACE_MAC_H_
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <IOSurface/IOSurface.h>
-#include <stdint.h>
-
-#include "base/callback.h"
-#include "base/mac/scoped_cftyperef.h"
-#include "base/memory/scoped_ptr.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gl/gl_context.h"
-#include "ui/gl/gl_surface.h"
-#include "ui/gl/gpu_preference.h"
-#include "ui/surface/surface_export.h"
-
-// Should not include GL headers in a header file. Forward declare these types
-// instead.
-typedef struct _CGLContextObject* CGLContextObj;
-typedef unsigned int GLenum;
-typedef unsigned int GLuint;
-
-namespace gfx {
-class Rect;
-}
-
-// Encapsulates an accelerated GL surface that can be shared across processes
-// on systems that support it (10.6 and above).
-
-class SURFACE_EXPORT AcceleratedSurface {
- public:
-  AcceleratedSurface();
-  virtual ~AcceleratedSurface();
-
-  // Set up internal buffers. |share_context|, if non-NULL, is a context
-  // with which the internally created OpenGL context shares textures and
-  // other resources. |allocate_fbo| indicates whether or not this surface
-  // should allocate an offscreen frame buffer object (FBO) internally. If
-  // not, then the user is expected to allocate one. NOTE that allocating
-  // an FBO internally does NOT work properly with client code which uses
-  // OpenGL (i.e., via GLES2 command buffers), because the GLES2
-  // implementation does not know to bind the accelerated surface's
-  // internal FBO when the default FBO is bound. |gpu_preference| indicates
-  // the GPU preference for the internally allocated GLContext. If
-  // |share_context| is non-NULL, then on platforms supporting dual GPUs,
-  // its GPU preference must match the passed one. Returns false upon
-  // failure.
-  bool Initialize(gfx::GLContext* share_context,
-                  bool allocate_fbo,
-                  gfx::GpuPreference gpu_preference);
-  // Tear down. Must be called before destructor to prevent leaks.
-  void Destroy();
-
-  // These methods are used only once the accelerated surface is initialized.
-
-  // Sets the accelerated surface to the given size, creating a new one if
-  // the height or width changes. Returns a unique id of the IOSurface to
-  // which the surface is bound, or 0 if no changes were made or an error
-  // occurred. MakeCurrent() will have been called on the new surface.
-  uint32_t SetSurfaceSize(const gfx::Size& size);
-
-  // Returns the id of this surface's IOSurface.
-  uint32_t GetSurfaceId();
-
-  // Sets the GL context to be the current one for drawing. Returns true if
-  // it succeeded.
-  bool MakeCurrent();
-  // Clear the surface to be transparent. Assumes the caller has already called
-  // MakeCurrent().
-  void Clear(const gfx::Rect& rect);
-  // Call after making changes to the surface which require a visual update.
-  // Makes the rendering show up in other processes. Assumes the caller has
-  // already called MakeCurrent().
-  //
-  // If this AcceleratedSurface is configured with its own FBO, then
-  // this call causes the color buffer to be transmitted. Otherwise,
-  // it causes the frame buffer of the current GL context to be copied
-  // into an internal texture via glCopyTexSubImage2D.
-  //
-  // The size of the rectangle copied is the size last specified via
-  // SetSurfaceSize.  If another GL context than the one this
-  // AcceleratedSurface contains is responsible for the production of
-  // the pixels, then when this entry point is called, the color
-  // buffer must be in a state where a glCopyTexSubImage2D is
-  // legal. (For example, if using multisampled FBOs, the FBO must
-  // have been resolved into a non-multisampled color texture.)
-  // Additionally, in this situation, the contexts must share
-  // server-side GL objects, so that this AcceleratedSurface's texture
-  // is a legal name in the namespace of the current context.
-  void SwapBuffers();
-
-  CGLContextObj context() {
-    return static_cast<CGLContextObj>(gl_context_->GetHandle());
-  }
-
-  // Get the accelerated surface size.
-  gfx::Size GetSize() const { return surface_size_; }
-
- private:
-  // Helper function to generate names for the backing texture and FBO.  On
-  // return, the resulting names can be attached to |fbo_|.  |target| is
-  // the target type for the color buffer.
-  void AllocateRenderBuffers(GLenum target, const gfx::Size& size);
-
-  // Helper function to attach the buffers previously allocated by a call to
-  // AllocateRenderBuffers().  On return, |fbo_| can be used for
-  // rendering.  |target| must be the same value as used in the call to
-  // AllocateRenderBuffers().  Returns |true| if the resulting framebuffer
-  // object is valid.
-  bool SetupFrameBufferObject(GLenum target);
-
-  gfx::Size ClampToValidDimensions(const gfx::Size& size);
-
-  // The OpenGL context, and pbuffer drawable, used to transfer data
-  // to the shared region (IOSurface).
-  scoped_refptr<gfx::GLSurface> gl_surface_;
-  scoped_refptr<gfx::GLContext> gl_context_;
-  base::ScopedCFTypeRef<IOSurfaceRef> io_surface_;
-
-  // The id of |io_surface_| or 0 if that's NULL.
-  uint32_t io_surface_id_;
-
-  gfx::Size surface_size_;
-  // It's important to avoid allocating zero-width or zero-height
-  // IOSurfaces and textures on the Mac, so we clamp each to a minimum
-  // of 1. This is the real size of the surface; surface_size_ is what
-  // the user requested.
-  gfx::Size real_surface_size_;
-  // TODO(kbr): the FBO management should not be in this class at all.
-  // However, if it is factored out, care needs to be taken to not
-  // introduce another copy of the color data on the GPU; the direct
-  // binding of the internal texture to the IOSurface saves a copy.
-  bool allocate_fbo_;
-  // This texture object is always allocated, regardless of whether
-  // the user requests an FBO be allocated.
-  GLuint texture_;
-  // The FBO and renderbuffer are only allocated if allocate_fbo_ is
-  // true.
-  GLuint fbo_;
-};
-
-#endif  // UI_SURFACE_ACCELERATED_SURFACE_MAC_H_
diff --git a/ui/surface/surface.gyp b/ui/surface/surface.gyp
index a219473..e45e2ae8 100644
--- a/ui/surface/surface.gyp
+++ b/ui/surface/surface.gyp
@@ -13,15 +13,6 @@
           '../../third_party/khronos',
         ],
       }],
-      ['OS == "mac"', {
-        # Required by accelerated_surface_mac.cc.
-        'link_settings': {
-          'libraries': [
-            '$(SDKROOT)/System/Library/Frameworks/IOSurface.framework',
-            '$(SDKROOT)/System/Library/Frameworks/OpenGL.framework',
-          ],
-        },
-      }],
     ],
   },
   'targets': [
@@ -37,8 +28,6 @@
         '../gl/gl.gyp:gl',
       ],
       'sources': [
-        'accelerated_surface_mac.cc',
-        'accelerated_surface_mac.h',
         'surface_export.h',
         'transport_dib.cc',
         'transport_dib.h',
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn
index ff508fa..5b85b89 100644
--- a/ui/views/BUILD.gn
+++ b/ui/views/BUILD.gn
@@ -191,7 +191,10 @@
     deps += [ "//ui/gfx/x" ]
   }
   if (use_ozone || !use_x11) {
-    sources -= [ "test/x11_property_change_waiter.cc" ]
+    sources -= [
+      "test/x11_property_change_waiter.cc",
+      "test/x11_property_change_waiter.h",
+    ]
   }
 }
 
diff --git a/ui/views/examples/examples_main.cc b/ui/views/examples/examples_main.cc
index 572552e..11096a7 100644
--- a/ui/views/examples/examples_main.cc
+++ b/ui/views/examples/examples_main.cc
@@ -37,7 +37,7 @@
 #endif
 
 #if defined(USE_X11)
-#include "ui/gfx/x/x11_connection.h"
+#include "ui/gfx/x/x11_connection.h"  // nogncheck
 #endif
 
 int main(int argc, char** argv) {
diff --git a/ui/views/mus/native_widget_mus.cc b/ui/views/mus/native_widget_mus.cc
index c501c6e..2e98b9cd5 100644
--- a/ui/views/mus/native_widget_mus.cc
+++ b/ui/views/mus/native_widget_mus.cc
@@ -472,11 +472,11 @@
 }
 
 const ui::Compositor* NativeWidgetMus::GetCompositor() const {
-  return window_tree_host_->window()->layer()->GetCompositor();
+  return window_tree_host_->compositor();
 }
 
 const ui::Layer* NativeWidgetMus::GetLayer() const {
-  return window_tree_host_ ? window_tree_host_->window()->layer() : nullptr;
+  return content_ ? content_->layer() : nullptr;
 }
 
 void NativeWidgetMus::ReorderNativeViews() {
diff --git a/ui/views/mus/native_widget_mus_unittest.cc b/ui/views/mus/native_widget_mus_unittest.cc
index a2ff4b0..8dcebbc 100644
--- a/ui/views/mus/native_widget_mus_unittest.cc
+++ b/ui/views/mus/native_widget_mus_unittest.cc
@@ -12,6 +12,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkColor.h"
+#include "ui/aura/window.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/skia_util.h"
@@ -124,5 +125,13 @@
   EXPECT_TRUE(gfx::BitmapsAreEqual(bitmap2, icon));
 }
 
+TEST_F(NativeWidgetMusTest, ValidLayerTree) {
+  scoped_ptr<Widget> widget(CreateWidget(nullptr));
+  View* content = new View;
+  content->SetPaintToLayer(true);
+  widget->GetContentsView()->AddChildView(content);
+  EXPECT_TRUE(widget->GetNativeWindow()->layer()->Contains(content->layer()));
+}
+
 }  // namespace
 }  // namespace views
diff --git a/ui/views/test/widget_test_aura.cc b/ui/views/test/widget_test_aura.cc
index 54525059..457c0efd 100644
--- a/ui/views/test/widget_test_aura.cc
+++ b/ui/views/test/widget_test_aura.cc
@@ -7,17 +7,13 @@
 #include "build/build_config.h"
 #include "ui/aura/client/focus_client.h"
 #include "ui/aura/window.h"
+#include "ui/aura/window_delegate.h"
 #include "ui/aura/window_tree_host.h"
 #include "ui/views/widget/widget.h"
 
 #if defined(USE_X11)
 #include <X11/Xutil.h>
-#include "ui/gfx/x/x11_types.h"
-#endif
-
-#if defined(USE_AURA)
-#include "ui/aura/window.h"
-#include "ui/aura/window_delegate.h"
+#include "ui/gfx/x/x11_types.h"  // nogncheck
 #endif
 
 namespace views {